diff --git a/DEPS b/DEPS index ece0a0b..88a7ebe5 100644 --- a/DEPS +++ b/DEPS
@@ -40,11 +40,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '57bc1e7bc804be4779dd09409046f62c4d43e3cd', + 'skia_revision': '7f9c29a887106ab3babe0ec423a3bcae87ae4788', # 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': 'c2b0acd4835d90ee4c9a60659cf25d3dece5e7f3', + 'v8_revision': '68f430ce82eef2be84afb42cc7e70572ac10a23c', # 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/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc index 3807957..02fdb02 100644 --- a/ash/tooltips/tooltip_controller_unittest.cc +++ b/ash/tooltips/tooltip_controller_unittest.cc
@@ -109,20 +109,21 @@ view->bounds().CenterPoint()); base::string16 expected_tooltip = base::ASCIIToUTF16("Tooltip Text"); - // Fire tooltip timer so tooltip becomes visible. - helper_->FireTooltipTimer(); + // Mouse event triggers tooltip update so it becomes visible. EXPECT_TRUE(helper_->IsTooltipVisible()); - // Hide the cursor and check again. + // Disable mouse event which hides the cursor and check again. ash::Shell::GetInstance()->cursor_manager()->DisableMouseEvents(); - helper_->FireTooltipTimer(); + RunAllPendingInMessageLoop(); + EXPECT_FALSE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible()); + helper_->UpdateIfRequired(); EXPECT_FALSE(helper_->IsTooltipVisible()); - // Show the cursor and re-check. - RunAllPendingInMessageLoop(); + // Enable mouse event which shows the cursor and re-check. ash::Shell::GetInstance()->cursor_manager()->EnableMouseEvents(); RunAllPendingInMessageLoop(); - helper_->FireTooltipTimer(); + EXPECT_TRUE(ash::Shell::GetInstance()->cursor_manager()->IsCursorVisible()); + helper_->UpdateIfRequired(); EXPECT_TRUE(helper_->IsTooltipVisible()); } @@ -147,7 +148,6 @@ ui::test::EventGenerator generator(root_windows[1]); generator.MoveMouseRelativeTo(widget2->GetNativeView(), view2->bounds().CenterPoint()); - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); // Get rid of secondary display. This destroy's the tooltip's aura window. If @@ -161,7 +161,6 @@ ui::test::EventGenerator generator1(root_windows[0]); generator1.MoveMouseRelativeTo(widget1->GetNativeView(), view1->bounds().CenterPoint()); - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); }
diff --git a/base/task_scheduler/scheduler_worker.cc b/base/task_scheduler/scheduler_worker.cc index 970a7d4..14f35658 100644 --- a/base/task_scheduler/scheduler_worker.cc +++ b/base/task_scheduler/scheduler_worker.cc
@@ -216,6 +216,9 @@ void SchedulerWorker::WakeUp() { AutoSchedulerLock auto_lock(thread_lock_); + + DCHECK(!should_exit_for_testing_.IsSet()); + if (!thread_) CreateThreadAssertSynchronized(); @@ -227,17 +230,21 @@ DCHECK(!should_exit_for_testing_.IsSet()); should_exit_for_testing_.Set(); - WakeUp(); + std::unique_ptr<Thread> thread; - // Normally holding a lock and joining is dangerous. However, since this is - // only for testing, we're okay since the only scenario that could impact this - // is a call to Detach, which is disallowed by having the delegate always - // return false for the CanDetach call. - AutoSchedulerLock auto_lock(thread_lock_); - if (thread_) - thread_->Join(); + { + AutoSchedulerLock auto_lock(thread_lock_); - thread_.reset(); + if (thread_) { + // Make sure the thread is awake. It will see that + // |should_exit_for_testing_| is set and exit shortly after. + thread_->WakeUp(); + thread = std::move(thread_); + } + } + + if (thread) + thread->Join(); } bool SchedulerWorker::ThreadAliveForTesting() const { @@ -256,8 +263,14 @@ } std::unique_ptr<SchedulerWorker::Thread> SchedulerWorker::Detach() { - DCHECK(!should_exit_for_testing_.IsSet()) << "Worker was already joined"; AutoSchedulerLock auto_lock(thread_lock_); + + // Do not detach if the thread is being joined. + if (!thread_) { + DCHECK(should_exit_for_testing_.IsSet()); + return nullptr; + } + // If a wakeup is pending, then a WakeUp() came in while we were deciding to // detach. This means we can't go away anymore since we would break the // guarantee that we call GetWork() after a successful wakeup.
diff --git a/base/task_scheduler/scheduler_worker.h b/base/task_scheduler/scheduler_worker.h index f75d45f..87fd8ed 100644 --- a/base/task_scheduler/scheduler_worker.h +++ b/base/task_scheduler/scheduler_worker.h
@@ -76,8 +76,6 @@ // - The next WakeUp() could be more costly due to new thread creation. // - The worker will take this as a signal that it can detach, but it is not // obligated to do so. - // This MUST return false if SchedulerWorker::JoinForTesting() is in - // progress. virtual bool CanDetach(SchedulerWorker* worker) = 0; // Called by a thread before it detaches. This method is not allowed to @@ -117,6 +115,10 @@ // Joins this SchedulerWorker. If a Task is already running, it will be // allowed to complete its execution. This can only be called once. + // + // Note: A thread that detaches before JoinForTesting() is called may still be + // running after JoinForTesting() returns. However, it can't run tasks after + // JoinForTesting() returns. void JoinForTesting(); // Returns true if the worker is alive.
diff --git a/base/task_scheduler/scheduler_worker_pool_impl.h b/base/task_scheduler/scheduler_worker_pool_impl.h index 4693d63..2468b52 100644 --- a/base/task_scheduler/scheduler_worker_pool_impl.h +++ b/base/task_scheduler/scheduler_worker_pool_impl.h
@@ -97,12 +97,10 @@ // allowed to complete their execution. This can only be called once. void JoinForTesting(); - // Disallows worker thread detachment. If the suggested reclaim time is not - // TimeDelta::Max(), then the test should call this before the detach code can - // run. The safest place to do this is before the a set of work is dispatched - // (the worker pool is idle and steady state) or before the last - // synchronization point for all workers (all threads are busy and can't be - // reclaimed). + // Disallows worker detachment. If the suggested reclaim time is not + // TimeDelta::Max(), the test must call this before JoinForTesting() to reduce + // the chance of thread detachment during the process of joining all of the + // threads, and as a result, threads running after JoinForTesting(). void DisallowWorkerDetachmentForTesting(); // Returns the number of workers alive in this worker pool. The value may
diff --git a/base/task_scheduler/task_scheduler.h b/base/task_scheduler/task_scheduler.h index 5d9344b..a73929c 100644 --- a/base/task_scheduler/task_scheduler.h +++ b/base/task_scheduler/task_scheduler.h
@@ -38,6 +38,9 @@ using WorkerPoolIndexForTraitsCallback = Callback<size_t(const TaskTraits& traits)>; + // Destroying a TaskScheduler is not allowed in production; it is always + // leaked. In tests, it should only be destroyed after JoinForTesting() has + // returned. virtual ~TaskScheduler() = default; // Posts |task| with a |delay| and specific |traits|. |delay| can be zero. @@ -85,6 +88,10 @@ // other threads during the call. Returns immediately when shutdown completes. virtual void FlushForTesting() = 0; + // Joins all threads. Tasks that are already running are allowed to complete + // their execution. This can only be called once. + virtual void JoinForTesting() = 0; + // CreateAndSetSimpleTaskScheduler(), CreateAndSetDefaultTaskScheduler(), and // SetInstance() register a TaskScheduler to handle tasks posted through the // post_task.h API for this process. The registered TaskScheduler will only be
diff --git a/base/task_scheduler/task_scheduler_impl.cc b/base/task_scheduler/task_scheduler_impl.cc index 827caae..f727c8c3 100644 --- a/base/task_scheduler/task_scheduler_impl.cc +++ b/base/task_scheduler/task_scheduler_impl.cc
@@ -94,6 +94,8 @@ DCHECK(!join_for_testing_returned_.IsSet()); #endif for (const auto& worker_pool : worker_pools_) + worker_pool->DisallowWorkerDetachmentForTesting(); + for (const auto& worker_pool : worker_pools_) worker_pool->JoinForTesting(); service_thread_.Stop(); #if DCHECK_IS_ON()
diff --git a/base/task_scheduler/task_scheduler_impl.h b/base/task_scheduler/task_scheduler_impl.h index 3e6cfdb..7a083c6 100644 --- a/base/task_scheduler/task_scheduler_impl.h +++ b/base/task_scheduler/task_scheduler_impl.h
@@ -44,9 +44,6 @@ const WorkerPoolIndexForTraitsCallback& worker_pool_index_for_traits_callback); - // Destroying a TaskSchedulerImpl is not allowed in production; it is always - // leaked. In tests, it can only be destroyed after JoinForTesting() has - // returned. ~TaskSchedulerImpl() override; // TaskScheduler: @@ -63,10 +60,7 @@ std::vector<const HistogramBase*> GetHistograms() const override; void Shutdown() override; void FlushForTesting() override; - - // Joins all threads. Tasks that are already running are allowed to complete - // their execution. This can only be called once. - void JoinForTesting(); + void JoinForTesting() override; private: explicit TaskSchedulerImpl(const WorkerPoolIndexForTraitsCallback&
diff --git a/base/test/scoped_task_scheduler.cc b/base/test/scoped_task_scheduler.cc index a57802c3..f068a199 100644 --- a/base/test/scoped_task_scheduler.cc +++ b/base/test/scoped_task_scheduler.cc
@@ -53,6 +53,7 @@ std::vector<const HistogramBase*> GetHistograms() const override; void Shutdown() override; void FlushForTesting() override; + void JoinForTesting() override; // Posts |task| to this TaskScheduler with |sequence_token|. Returns true on // success. @@ -168,6 +169,10 @@ NOTREACHED(); } +void TestTaskScheduler::JoinForTesting() { + // TestTaskScheduler doesn't create threads so this does nothing. +} + bool TestTaskScheduler::PostTask(std::unique_ptr<internal::Task> task, const SequenceToken& sequence_token) { DCHECK(task); @@ -252,6 +257,10 @@ ScopedTaskScheduler::~ScopedTaskScheduler() { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_EQ(task_scheduler_, TaskScheduler::GetInstance()); + + // Per contract, call JoinForTesting() before deleting the TaskScheduler. + TaskScheduler::GetInstance()->JoinForTesting(); + TaskScheduler::SetInstance(nullptr); }
diff --git a/base/threading/sequenced_worker_pool_unittest.cc b/base/threading/sequenced_worker_pool_unittest.cc index 6e20339..5f9c9bfd 100644 --- a/base/threading/sequenced_worker_pool_unittest.cc +++ b/base/threading/sequenced_worker_pool_unittest.cc
@@ -19,7 +19,6 @@ #include "base/synchronization/lock.h" #include "base/task_scheduler/scheduler_worker_pool_params.h" #include "base/task_scheduler/task_scheduler.h" -#include "base/task_scheduler/task_scheduler_impl.h" #include "base/test/sequenced_task_runner_test_template.h" #include "base/test/sequenced_worker_pool_owner.h" #include "base/test/task_runner_test_template.h" @@ -296,8 +295,7 @@ // Destroys and unregisters the registered TaskScheduler, if any. void DeleteTaskScheduler() { if (TaskScheduler::GetInstance()) { - static_cast<internal::TaskSchedulerImpl*>(TaskScheduler::GetInstance()) - ->JoinForTesting(); + TaskScheduler::GetInstance()->JoinForTesting(); TaskScheduler::SetInstance(nullptr); } }
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni index 13b4506..e9e809a 100644 --- a/build/config/compiler/compiler.gni +++ b/build/config/compiler/compiler.gni
@@ -99,7 +99,8 @@ # memory consumption and link times unsustainable (crbug.com/630074). # Clang on windows does not have this issue. symbol_level = 1 - } else if (!is_linux || is_debug || is_official_build || is_chromecast) { + } else if ((!is_nacl && !is_linux) || is_debug || is_official_build || + is_chromecast) { # Linux is slowed by having symbols as part of the target binary, whereas # Mac and Windows have them separate, so in Release Linux, default them off, # but keep them on for Official builds and Chromecast builds.
diff --git a/build/toolchain/nacl/BUILD.gn b/build/toolchain/nacl/BUILD.gn index 78748bd..89e642e 100644 --- a/build/toolchain/nacl/BUILD.gn +++ b/build/toolchain/nacl/BUILD.gn
@@ -222,10 +222,6 @@ toolchain_args = { current_cpu = toolchain_cpu is_clang = true - - # Always build the IRT with full debugging symbols, regardless of - # how Chromium itself is being built (or other NaCl executables). - symbol_level = 2 } # TODO(ncbray): depend on link script
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 911fe486..3a5f4d8 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -452,14 +452,13 @@ "trees/latency_info_swap_promise_monitor.h", "trees/layer_tree.cc", "trees/layer_tree.h", + "trees/layer_tree_host.cc", "trees/layer_tree_host.h", "trees/layer_tree_host_client.h", "trees/layer_tree_host_common.cc", "trees/layer_tree_host_common.h", "trees/layer_tree_host_impl.cc", "trees/layer_tree_host_impl.h", - "trees/layer_tree_host_in_process.cc", - "trees/layer_tree_host_in_process.h", "trees/layer_tree_host_single_thread_client.h", "trees/layer_tree_impl.cc", "trees/layer_tree_impl.h",
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc index d47561b0..28689cbd 100644 --- a/cc/layers/layer_unittest.cc +++ b/cc/layers/layer_unittest.cc
@@ -86,7 +86,7 @@ class MockLayerTree : public LayerTree { public: - MockLayerTree(LayerTreeHostInProcess::InitParams* params, + MockLayerTree(LayerTreeHost::InitParams* params, LayerTreeHost* layer_tree_host) : LayerTree(params->mutator_host, layer_tree_host) {} ~MockLayerTree() override {} @@ -94,11 +94,11 @@ MOCK_METHOD0(SetNeedsFullTreeSync, void()); }; -class MockLayerTreeHost : public LayerTreeHostInProcess { +class MockLayerTreeHost : public LayerTreeHost { public: MockLayerTreeHost(LayerTreeHostSingleThreadClient* single_thread_client, - LayerTreeHostInProcess::InitParams* params) - : LayerTreeHostInProcess( + LayerTreeHost::InitParams* params) + : LayerTreeHost( params, CompositorMode::SINGLE_THREADED, base::MakeUnique<StrictMock<MockLayerTree>>(params, this)) { @@ -129,7 +129,7 @@ void SetUp() override { animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); - LayerTreeHostInProcess::InitParams params; + LayerTreeHost::InitParams params; params.client = &fake_client_; params.settings = &settings_; params.task_graph_runner = &task_graph_runner_; @@ -1039,15 +1039,14 @@ std::unique_ptr<LayerTreeHost> Create(LayerTreeSettings settings, MutatorHost* mutator_host) { - LayerTreeHostInProcess::InitParams params; + LayerTreeHost::InitParams params; params.client = &client_; params.task_graph_runner = &task_graph_runner_; params.settings = &settings; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); params.mutator_host = mutator_host; - return LayerTreeHostInProcess::CreateSingleThreaded(&single_thread_client_, - ¶ms); + return LayerTreeHost::CreateSingleThreaded(&single_thread_client_, ¶ms); } private:
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc index 76d8ec9..a4199c4b 100644 --- a/cc/layers/picture_layer_unittest.cc +++ b/cc/layers/picture_layer_unittest.cc
@@ -302,22 +302,21 @@ auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); - LayerTreeHostInProcess::InitParams params; + LayerTreeHost::InitParams params; params.client = &host_client1; params.settings = &settings; params.task_graph_runner = &task_graph_runner; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); params.mutator_host = animation_host.get(); std::unique_ptr<LayerTreeHost> host1 = - LayerTreeHostInProcess::CreateSingleThreaded(&single_thread_client, - ¶ms); + LayerTreeHost::CreateSingleThreaded(&single_thread_client, ¶ms); host1->SetVisible(true); host_client1.SetLayerTreeHost(host1.get()); auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); // TODO(sad): InitParams will be movable. - LayerTreeHostInProcess::InitParams params2; + LayerTreeHost::InitParams params2; params2.client = &host_client1; params2.settings = &settings; params2.task_graph_runner = &task_graph_runner; @@ -325,8 +324,7 @@ params2.client = &host_client2; params2.mutator_host = animation_host2.get(); std::unique_ptr<LayerTreeHost> host2 = - LayerTreeHostInProcess::CreateSingleThreaded(&single_thread_client, - ¶ms2); + LayerTreeHost::CreateSingleThreaded(&single_thread_client, ¶ms2); host2->SetVisible(true); host_client2.SetLayerTreeHost(host2.get());
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc index 13cfbd8f..82a29c4 100644 --- a/cc/layers/scrollbar_layer_unittest.cc +++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -114,7 +114,7 @@ animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); - LayerTreeHostInProcess::InitParams params; + LayerTreeHost::InitParams params; params.client = &fake_client_; params.settings = &layer_tree_settings_; params.task_graph_runner = &task_graph_runner_;
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 7d10bf7e..f0a6802 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -38,7 +38,7 @@ #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/blocking_task_runner.h" -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" #include "gpu/GLES2/gl2extchromium.h" @@ -65,13 +65,13 @@ gpu::CommandBufferId::FromUnsafeValue(0x123), value); } -class MockLayerTreeHost : public LayerTreeHostInProcess { +class MockLayerTreeHost : public LayerTreeHost { public: static std::unique_ptr<MockLayerTreeHost> Create( FakeLayerTreeHostClient* client, TaskGraphRunner* task_graph_runner, MutatorHost* mutator_host) { - LayerTreeHostInProcess::InitParams params; + LayerTreeHost::InitParams params; params.client = client; params.task_graph_runner = task_graph_runner; params.mutator_host = mutator_host; @@ -87,8 +87,8 @@ MOCK_METHOD0(StopRateLimiter, void()); private: - explicit MockLayerTreeHost(LayerTreeHostInProcess::InitParams* params) - : LayerTreeHostInProcess(params, CompositorMode::SINGLE_THREADED) { + explicit MockLayerTreeHost(LayerTreeHost::InitParams* params) + : LayerTreeHost(params, CompositorMode::SINGLE_THREADED) { InitializeSingleThreaded(&single_thread_client_, base::ThreadTaskRunnerHandle::Get()); }
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc index 8a859f66..f574632 100644 --- a/cc/surfaces/surface_factory.cc +++ b/cc/surfaces/surface_factory.cc
@@ -67,7 +67,7 @@ gfx::Size frame_size; // CompositorFrames may not be populated with a RenderPass in unit tests. if (!frame.render_pass_list.empty()) - frame_size = frame.render_pass_list[0]->output_rect.size(); + frame_size = frame.render_pass_list.back()->output_rect.size(); manager_->SurfaceCreated(SurfaceInfo( surface->surface_id(), frame.metadata.device_scale_factor, frame_size)); }
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc index 8099815..6deff8b 100644 --- a/cc/surfaces/surface_factory_unittest.cc +++ b/cc/surfaces/surface_factory_unittest.cc
@@ -87,6 +87,7 @@ void OnSurfaceCreated(const SurfaceInfo& surface_info) override { EXPECT_EQ(kArbitraryFrameSinkId, surface_info.id().frame_sink_id()); last_created_surface_id_ = surface_info.id(); + last_surface_info_ = surface_info; } void OnSurfaceDamaged(const SurfaceId& id, bool* changed) override { @@ -155,6 +156,7 @@ std::unique_ptr<SurfaceFactory> factory_; LocalFrameId local_frame_id_; SurfaceId last_created_surface_id_; + SurfaceInfo last_surface_info_; // This is the sync token submitted with the frame. It should never be // returned to the client. @@ -669,5 +671,28 @@ EXPECT_TRUE(called3); } +// Check whether the SurfaceInfo object is created and populated correctly +// after the frame submission. +TEST_F(SurfaceFactoryTest, SurfaceInfo) { + CompositorFrame frame; + + auto render_pass = RenderPass::Create(); + render_pass->SetNew(1, gfx::Rect(5, 6), gfx::Rect(), gfx::Transform()); + frame.render_pass_list.push_back(std::move(render_pass)); + + render_pass = RenderPass::Create(); + render_pass->SetNew(2, gfx::Rect(7, 8), gfx::Rect(), gfx::Transform()); + frame.render_pass_list.push_back(std::move(render_pass)); + + frame.metadata.device_scale_factor = 2.5f; + + factory_->SubmitCompositorFrame(local_frame_id_, std::move(frame), + SurfaceFactory::DrawCallback()); + SurfaceId expected_surface_id(factory_->frame_sink_id(), local_frame_id_); + EXPECT_EQ(expected_surface_id, last_surface_info_.id()); + EXPECT_EQ(2.5f, last_surface_info_.device_scale_factor()); + EXPECT_EQ(gfx::Size(7, 8), last_surface_info_.size_in_pixels()); +} + } // namespace } // namespace cc
diff --git a/cc/surfaces/surface_reference_owner.h b/cc/surfaces/surface_reference_owner.h index 78614f7..8aa791c 100644 --- a/cc/surfaces/surface_reference_owner.h +++ b/cc/surfaces/surface_reference_owner.h
@@ -13,6 +13,8 @@ // SurfaceReferenceFactory::CreateReference as the reference owner. class SurfaceReferenceOwner { public: + virtual ~SurfaceReferenceOwner() {} + virtual SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() = 0; };
diff --git a/cc/test/fake_layer_tree_host.cc b/cc/test/fake_layer_tree_host.cc index 6143a46..d15255e 100644 --- a/cc/test/fake_layer_tree_host.cc +++ b/cc/test/fake_layer_tree_host.cc
@@ -27,9 +27,9 @@ } // namespace FakeLayerTreeHost::FakeLayerTreeHost(FakeLayerTreeHostClient* client, - LayerTreeHostInProcess::InitParams* params, + LayerTreeHost::InitParams* params, CompositorMode mode) - : LayerTreeHostInProcess( + : LayerTreeHost( params, mode, base::MakeUnique<FakeLayerTree>(params->mutator_host, this)), @@ -70,7 +70,7 @@ MutatorHost* mutator_host, const LayerTreeSettings& settings, CompositorMode mode) { - LayerTreeHostInProcess::InitParams params; + LayerTreeHost::InitParams params; params.client = client; params.settings = &settings; params.task_graph_runner = task_graph_runner;
diff --git a/cc/test/fake_layer_tree_host.h b/cc/test/fake_layer_tree_host.h index 81e498ea..2aa30c6 100644 --- a/cc/test/fake_layer_tree_host.h +++ b/cc/test/fake_layer_tree_host.h
@@ -9,7 +9,7 @@ #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_layer_tree_host_impl.h" -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/tree_synchronizer.h" @@ -18,7 +18,7 @@ class MutatorHost; class TestTaskGraphRunner; -class FakeLayerTreeHost : public LayerTreeHostInProcess { +class FakeLayerTreeHost : public LayerTreeHost { public: static std::unique_ptr<FakeLayerTreeHost> Create( FakeLayerTreeHostClient* client, @@ -65,14 +65,14 @@ LayerTreeImpl* active_tree() { return host_impl_.active_tree(); } LayerTreeImpl* pending_tree() { return host_impl_.pending_tree(); } - using LayerTreeHostInProcess::ScheduleMicroBenchmark; - using LayerTreeHostInProcess::SendMessageToMicroBenchmark; - using LayerTreeHostInProcess::InitializeSingleThreaded; - using LayerTreeHostInProcess::InitializeForTesting; - using LayerTreeHostInProcess::RecordGpuRasterizationHistogram; - using LayerTreeHostInProcess::SetUIResourceManagerForTesting; + using LayerTreeHost::ScheduleMicroBenchmark; + using LayerTreeHost::SendMessageToMicroBenchmark; + using LayerTreeHost::InitializeSingleThreaded; + using LayerTreeHost::InitializeForTesting; + using LayerTreeHost::RecordGpuRasterizationHistogram; + using LayerTreeHost::SetUIResourceManagerForTesting; - void UpdateLayers() { LayerTreeHostInProcess::UpdateLayers(); } + void UpdateLayers() { LayerTreeHost::UpdateLayers(); } MicroBenchmarkController* GetMicroBenchmarkController() { return µ_benchmark_controller_; @@ -82,7 +82,7 @@ void reset_needs_commit() { needs_commit_ = false; } FakeLayerTreeHost(FakeLayerTreeHostClient* client, - LayerTreeHostInProcess::InitParams* params, + LayerTreeHost::InitParams* params, CompositorMode mode); private:
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index 46cdf6d..149a01ba 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -332,7 +332,7 @@ }; // Adapts LayerTreeHost for test. Injects LayerTreeHostImplForTesting. -class LayerTreeHostForTesting : public LayerTreeHostInProcess { +class LayerTreeHostForTesting : public LayerTreeHost { public: static std::unique_ptr<LayerTreeHostForTesting> Create( TestHooks* test_hooks, @@ -344,7 +344,7 @@ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, MutatorHost* mutator_host) { - LayerTreeHostInProcess::InitParams params; + LayerTreeHost::InitParams params; params.client = client; params.task_graph_runner = task_graph_runner; params.settings = &settings; @@ -386,22 +386,22 @@ void SetNeedsCommit() override { if (!test_started_) return; - LayerTreeHostInProcess::SetNeedsCommit(); + LayerTreeHost::SetNeedsCommit(); } void SetNeedsUpdateLayers() override { if (!test_started_) return; - LayerTreeHostInProcess::SetNeedsUpdateLayers(); + LayerTreeHost::SetNeedsUpdateLayers(); } void set_test_started(bool started) { test_started_ = started; } private: LayerTreeHostForTesting(TestHooks* test_hooks, - LayerTreeHostInProcess::InitParams* params, + LayerTreeHost::InitParams* params, CompositorMode mode) - : LayerTreeHostInProcess(params, mode), + : LayerTreeHost(params, mode), test_hooks_(test_hooks), test_started_(false) {} @@ -594,13 +594,9 @@ animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); - std::unique_ptr<LayerTreeHostForTesting> layer_tree_host_for_testing = - LayerTreeHostForTesting::Create( - this, mode_, client_.get(), client_.get(), task_graph_runner_.get(), - settings_, main_task_runner, impl_task_runner, animation_host_.get()); - layer_tree_host_in_process_ = layer_tree_host_for_testing.get(); - layer_tree_host_ = std::move(layer_tree_host_for_testing); - + layer_tree_host_ = LayerTreeHostForTesting::Create( + this, mode_, client_.get(), client_.get(), task_graph_runner_.get(), + settings_, main_task_runner, impl_task_runner, animation_host_.get()); ASSERT_TRUE(layer_tree_host_); main_task_runner_ = @@ -631,8 +627,8 @@ // Allow commits to happen once BeginTest() has had a chance to post tasks // so that those tasks will happen before the first commit. - if (layer_tree_host_in_process_) { - static_cast<LayerTreeHostForTesting*>(layer_tree_host_in_process_) + if (layer_tree_host_) { + static_cast<LayerTreeHostForTesting*>(layer_tree_host_.get()) ->set_test_started(true); } } @@ -658,10 +654,10 @@ void LayerTreeTest::RealEndTest() { // TODO(mithro): Make this method only end when not inside an impl frame. - bool main_frame_will_happen = layer_tree_host_in_process_ - ? layer_tree_host_in_process_->proxy() - ->MainFrameWillHappenForTesting() - : false; + bool main_frame_will_happen = + layer_tree_host_ + ? layer_tree_host_->proxy()->MainFrameWillHappenForTesting() + : false; if (main_frame_will_happen && !timed_out_) { main_task_runner_->PostTask( @@ -820,7 +816,6 @@ if (layer_tree_host_ && layer_tree_host_->GetLayerTree()->root_layer()) layer_tree_host_->GetLayerTree()->root_layer()->SetLayerTreeHost(NULL); layer_tree_host_ = nullptr; - layer_tree_host_in_process_ = nullptr; } TaskRunnerProvider* LayerTreeTest::task_runner_provider() const { @@ -839,15 +834,8 @@ return layer_tree_host_.get(); } -LayerTreeHostInProcess* LayerTreeTest::layer_tree_host_in_process() { - DCHECK(task_runner_provider()->IsMainThread() || - task_runner_provider()->IsMainThreadBlocked()); - return layer_tree_host_in_process_; -} - Proxy* LayerTreeTest::proxy() { - return layer_tree_host_in_process() ? layer_tree_host_in_process()->proxy() - : NULL; + return layer_tree_host() ? layer_tree_host()->proxy() : NULL; } } // namespace cc
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index b9a5090..fbe9996f 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h
@@ -12,8 +12,8 @@ #include "cc/test/test_hooks.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/compositor_mode.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_impl.h" -#include "cc/trees/layer_tree_host_in_process.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -122,7 +122,6 @@ bool TestEnded() const { return ended_; } LayerTreeHost* layer_tree_host(); - LayerTreeHostInProcess* layer_tree_host_in_process(); LayerTree* layer_tree() { return layer_tree_host()->GetLayerTree(); } SharedBitmapManager* shared_bitmap_manager() const { return shared_bitmap_manager_.get(); @@ -173,7 +172,6 @@ std::unique_ptr<LayerTreeHostClientForTesting> client_; std::unique_ptr<LayerTreeHost> layer_tree_host_; std::unique_ptr<AnimationHost> animation_host_; - LayerTreeHostInProcess* layer_tree_host_in_process_; bool beginning_ = false; bool end_when_begin_returns_ = false;
diff --git a/cc/trees/layer_tree_host_in_process.cc b/cc/trees/layer_tree_host.cc similarity index 83% rename from cc/trees/layer_tree_host_in_process.cc rename to cc/trees/layer_tree_host.cc index 22bee761..b849f50 100644 --- a/cc/trees/layer_tree_host_in_process.cc +++ b/cc/trees/layer_tree_host.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include <stddef.h> #include <stdint.h> @@ -61,43 +61,43 @@ namespace cc { -LayerTreeHostInProcess::InitParams::InitParams() {} +LayerTreeHost::InitParams::InitParams() {} -LayerTreeHostInProcess::InitParams::~InitParams() {} +LayerTreeHost::InitParams::~InitParams() {} -std::unique_ptr<LayerTreeHostInProcess> LayerTreeHostInProcess::CreateThreaded( +std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateThreaded( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, InitParams* params) { DCHECK(params->main_task_runner.get()); DCHECK(impl_task_runner.get()); DCHECK(params->settings); - std::unique_ptr<LayerTreeHostInProcess> layer_tree_host( - new LayerTreeHostInProcess(params, CompositorMode::THREADED)); + std::unique_ptr<LayerTreeHost> layer_tree_host( + new LayerTreeHost(params, CompositorMode::THREADED)); layer_tree_host->InitializeThreaded(params->main_task_runner, impl_task_runner); return layer_tree_host; } -std::unique_ptr<LayerTreeHostInProcess> -LayerTreeHostInProcess::CreateSingleThreaded( +std::unique_ptr<LayerTreeHost> +LayerTreeHost::CreateSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client, InitParams* params) { DCHECK(params->settings); - std::unique_ptr<LayerTreeHostInProcess> layer_tree_host( - new LayerTreeHostInProcess(params, CompositorMode::SINGLE_THREADED)); + std::unique_ptr<LayerTreeHost> layer_tree_host( + new LayerTreeHost(params, CompositorMode::SINGLE_THREADED)); layer_tree_host->InitializeSingleThreaded(single_thread_client, params->main_task_runner); return layer_tree_host; } -LayerTreeHostInProcess::LayerTreeHostInProcess(InitParams* params, +LayerTreeHost::LayerTreeHost(InitParams* params, CompositorMode mode) - : LayerTreeHostInProcess( + : LayerTreeHost( params, mode, base::MakeUnique<LayerTree>(params->mutator_host, this)) {} -LayerTreeHostInProcess::LayerTreeHostInProcess( +LayerTreeHost::LayerTreeHost( InitParams* params, CompositorMode mode, std::unique_ptr<LayerTree> layer_tree) @@ -125,7 +125,7 @@ debug_state_.RecordRenderingStats()); } -void LayerTreeHostInProcess::InitializeThreaded( +void LayerTreeHost::InitializeThreaded( scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { task_runner_provider_ = @@ -135,7 +135,7 @@ InitializeProxy(std::move(proxy_main)); } -void LayerTreeHostInProcess::InitializeSingleThreaded( +void LayerTreeHost::InitializeSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) { task_runner_provider_ = TaskRunnerProvider::Create(main_task_runner, nullptr); @@ -143,25 +143,25 @@ task_runner_provider_.get())); } -void LayerTreeHostInProcess::InitializeForTesting( +void LayerTreeHost::InitializeForTesting( std::unique_ptr<TaskRunnerProvider> task_runner_provider, std::unique_ptr<Proxy> proxy_for_testing) { task_runner_provider_ = std::move(task_runner_provider); InitializeProxy(std::move(proxy_for_testing)); } -void LayerTreeHostInProcess::SetTaskRunnerProviderForTesting( +void LayerTreeHost::SetTaskRunnerProviderForTesting( std::unique_ptr<TaskRunnerProvider> task_runner_provider) { DCHECK(!task_runner_provider_); task_runner_provider_ = std::move(task_runner_provider); } -void LayerTreeHostInProcess::SetUIResourceManagerForTesting( +void LayerTreeHost::SetUIResourceManagerForTesting( std::unique_ptr<UIResourceManager> ui_resource_manager) { ui_resource_manager_ = std::move(ui_resource_manager); } -void LayerTreeHostInProcess::InitializeProxy(std::unique_ptr<Proxy> proxy) { +void LayerTreeHost::InitializeProxy(std::unique_ptr<Proxy> proxy) { TRACE_EVENT0("cc", "LayerTreeHostInProcess::InitializeForReal"); DCHECK(task_runner_provider_); @@ -172,7 +172,7 @@ proxy_->SupportsImplScrolling()); } -LayerTreeHostInProcess::~LayerTreeHostInProcess() { +LayerTreeHost::~LayerTreeHost() { // Track when we're inside a main frame to see if compositor is being // destroyed midway which causes a crash. crbug.com/654672 CHECK(!inside_main_frame_); @@ -190,81 +190,81 @@ } } -int LayerTreeHostInProcess::GetId() const { +int LayerTreeHost::GetId() const { return id_; } -int LayerTreeHostInProcess::SourceFrameNumber() const { +int LayerTreeHost::SourceFrameNumber() const { return source_frame_number_; } -LayerTree* LayerTreeHostInProcess::GetLayerTree() { +LayerTree* LayerTreeHost::GetLayerTree() { return layer_tree_.get(); } -const LayerTree* LayerTreeHostInProcess::GetLayerTree() const { +const LayerTree* LayerTreeHost::GetLayerTree() const { return layer_tree_.get(); } -UIResourceManager* LayerTreeHostInProcess::GetUIResourceManager() const { +UIResourceManager* LayerTreeHost::GetUIResourceManager() const { return ui_resource_manager_.get(); } -TaskRunnerProvider* LayerTreeHostInProcess::GetTaskRunnerProvider() const { +TaskRunnerProvider* LayerTreeHost::GetTaskRunnerProvider() const { return task_runner_provider_.get(); } -SwapPromiseManager* LayerTreeHostInProcess::GetSwapPromiseManager() { +SwapPromiseManager* LayerTreeHost::GetSwapPromiseManager() { return &swap_promise_manager_; } -const LayerTreeSettings& LayerTreeHostInProcess::GetSettings() const { +const LayerTreeSettings& LayerTreeHost::GetSettings() const { return settings_; } -void LayerTreeHostInProcess::SetFrameSinkId(const FrameSinkId& frame_sink_id) { +void LayerTreeHost::SetFrameSinkId(const FrameSinkId& frame_sink_id) { surface_sequence_generator_.set_frame_sink_id(frame_sink_id); } -void LayerTreeHostInProcess::QueueSwapPromise( +void LayerTreeHost::QueueSwapPromise( std::unique_ptr<SwapPromise> swap_promise) { swap_promise_manager_.QueueSwapPromise(std::move(swap_promise)); } SurfaceSequenceGenerator* -LayerTreeHostInProcess::GetSurfaceSequenceGenerator() { +LayerTreeHost::GetSurfaceSequenceGenerator() { return &surface_sequence_generator_; } -void LayerTreeHostInProcess::WillBeginMainFrame() { +void LayerTreeHost::WillBeginMainFrame() { inside_main_frame_ = true; devtools_instrumentation::WillBeginMainThreadFrame(GetId(), SourceFrameNumber()); client_->WillBeginMainFrame(); } -void LayerTreeHostInProcess::DidBeginMainFrame() { +void LayerTreeHost::DidBeginMainFrame() { inside_main_frame_ = false; client_->DidBeginMainFrame(); } -void LayerTreeHostInProcess::BeginMainFrameNotExpectedSoon() { +void LayerTreeHost::BeginMainFrameNotExpectedSoon() { client_->BeginMainFrameNotExpectedSoon(); } -void LayerTreeHostInProcess::BeginMainFrame(const BeginFrameArgs& args) { +void LayerTreeHost::BeginMainFrame(const BeginFrameArgs& args) { client_->BeginMainFrame(args); } -void LayerTreeHostInProcess::DidStopFlinging() { +void LayerTreeHost::DidStopFlinging() { proxy_->MainThreadHasStoppedFlinging(); } -const LayerTreeDebugState& LayerTreeHostInProcess::GetDebugState() const { +const LayerTreeDebugState& LayerTreeHost::GetDebugState() const { return debug_state_; } -void LayerTreeHostInProcess::RequestMainFrameUpdate() { +void LayerTreeHost::RequestMainFrameUpdate() { client_->UpdateLayerTreeHost(); } @@ -273,7 +273,7 @@ // code that is logically a main thread operation, e.g. deletion of a Layer, // should be delayed until the LayerTreeHostInProcess::CommitComplete, which // will run after the commit, but on the main thread. -void LayerTreeHostInProcess::FinishCommitOnImplThread( +void LayerTreeHost::FinishCommitOnImplThread( LayerTreeHostImpl* host_impl) { DCHECK(task_runner_provider_->IsImplThread()); @@ -344,14 +344,14 @@ layer_tree_->property_trees()->ResetAllChangeTracking(); } -void LayerTreeHostInProcess::WillCommit() { +void LayerTreeHost::WillCommit() { swap_promise_manager_.WillCommit(); client_->WillCommit(); } -void LayerTreeHostInProcess::UpdateHudLayer() {} +void LayerTreeHost::UpdateHudLayer() {} -void LayerTreeHostInProcess::CommitComplete() { +void LayerTreeHost::CommitComplete() { source_frame_number_++; client_->DidCommit(); if (did_complete_scale_animation_) { @@ -360,7 +360,7 @@ } } -void LayerTreeHostInProcess::SetCompositorFrameSink( +void LayerTreeHost::SetCompositorFrameSink( std::unique_ptr<CompositorFrameSink> surface) { TRACE_EVENT0("cc", "LayerTreeHostInProcess::SetCompositorFrameSink"); DCHECK(surface); @@ -371,7 +371,7 @@ } std::unique_ptr<CompositorFrameSink> -LayerTreeHostInProcess::ReleaseCompositorFrameSink() { +LayerTreeHost::ReleaseCompositorFrameSink() { DCHECK(!visible_); DidLoseCompositorFrameSink(); @@ -379,17 +379,17 @@ return std::move(current_compositor_frame_sink_); } -void LayerTreeHostInProcess::RequestNewCompositorFrameSink() { +void LayerTreeHost::RequestNewCompositorFrameSink() { client_->RequestNewCompositorFrameSink(); } -void LayerTreeHostInProcess::DidInitializeCompositorFrameSink() { +void LayerTreeHost::DidInitializeCompositorFrameSink() { DCHECK(new_compositor_frame_sink_); current_compositor_frame_sink_ = std::move(new_compositor_frame_sink_); client_->DidInitializeCompositorFrameSink(); } -void LayerTreeHostInProcess::DidFailToInitializeCompositorFrameSink() { +void LayerTreeHost::DidFailToInitializeCompositorFrameSink() { DCHECK(new_compositor_frame_sink_); // Note: It is safe to drop all output surface references here as // LayerTreeHostImpl will not keep a pointer to either the old or @@ -400,7 +400,7 @@ } std::unique_ptr<LayerTreeHostImpl> -LayerTreeHostInProcess::CreateLayerTreeHostImpl( +LayerTreeHost::CreateLayerTreeHostImpl( LayerTreeHostImplClient* client) { DCHECK(task_runner_provider_->IsImplThread()); @@ -420,62 +420,62 @@ return host_impl; } -void LayerTreeHostInProcess::DidLoseCompositorFrameSink() { +void LayerTreeHost::DidLoseCompositorFrameSink() { TRACE_EVENT0("cc", "LayerTreeHostInProcess::DidLoseCompositorFrameSink"); DCHECK(task_runner_provider_->IsMainThread()); SetNeedsCommit(); } -void LayerTreeHostInProcess::SetDeferCommits(bool defer_commits) { +void LayerTreeHost::SetDeferCommits(bool defer_commits) { proxy_->SetDeferCommits(defer_commits); } DISABLE_CFI_PERF -void LayerTreeHostInProcess::SetNeedsAnimate() { +void LayerTreeHost::SetNeedsAnimate() { proxy_->SetNeedsAnimate(); swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit(); } DISABLE_CFI_PERF -void LayerTreeHostInProcess::SetNeedsUpdateLayers() { +void LayerTreeHost::SetNeedsUpdateLayers() { proxy_->SetNeedsUpdateLayers(); swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit(); } -void LayerTreeHostInProcess::SetNeedsCommit() { +void LayerTreeHost::SetNeedsCommit() { proxy_->SetNeedsCommit(); swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit(); } -void LayerTreeHostInProcess::SetNeedsRecalculateRasterScales() { +void LayerTreeHost::SetNeedsRecalculateRasterScales() { next_commit_forces_recalculate_raster_scales_ = true; proxy_->SetNeedsCommit(); } -void LayerTreeHostInProcess::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { +void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { proxy_->SetNeedsRedraw(damage_rect); } -bool LayerTreeHostInProcess::CommitRequested() const { +bool LayerTreeHost::CommitRequested() const { return proxy_->CommitRequested(); } -void LayerTreeHostInProcess::SetNextCommitWaitsForActivation() { +void LayerTreeHost::SetNextCommitWaitsForActivation() { proxy_->SetNextCommitWaitsForActivation(); } -void LayerTreeHostInProcess::SetNextCommitForcesRedraw() { +void LayerTreeHost::SetNextCommitForcesRedraw() { next_commit_forces_redraw_ = true; proxy_->SetNeedsUpdateLayers(); } -void LayerTreeHostInProcess::SetAnimationEvents( +void LayerTreeHost::SetAnimationEvents( std::unique_ptr<MutatorEvents> events) { DCHECK(task_runner_provider_->IsMainThread()); layer_tree_->mutator_host()->SetAnimationEvents(std::move(events)); } -void LayerTreeHostInProcess::SetDebugState( +void LayerTreeHost::SetDebugState( const LayerTreeDebugState& debug_state) { LayerTreeDebugState new_debug_state = LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state); @@ -491,12 +491,12 @@ SetNeedsCommit(); } -void LayerTreeHostInProcess::ResetGpuRasterizationTracking() { +void LayerTreeHost::ResetGpuRasterizationTracking() { content_is_suitable_for_gpu_rasterization_ = true; gpu_rasterization_histogram_recorded_ = false; } -void LayerTreeHostInProcess::SetHasGpuRasterizationTrigger(bool has_trigger) { +void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) { if (has_trigger == has_gpu_rasterization_trigger_) return; @@ -506,7 +506,7 @@ TRACE_EVENT_SCOPE_THREAD, "has_trigger", has_gpu_rasterization_trigger_); } -void LayerTreeHostInProcess::ApplyPageScaleDeltaFromImplSide( +void LayerTreeHost::ApplyPageScaleDeltaFromImplSide( float page_scale_delta) { DCHECK(CommitRequested()); if (page_scale_delta == 1.f) @@ -515,22 +515,22 @@ layer_tree_->SetPageScaleFromImplSide(page_scale); } -void LayerTreeHostInProcess::SetVisible(bool visible) { +void LayerTreeHost::SetVisible(bool visible) { if (visible_ == visible) return; visible_ = visible; proxy_->SetVisible(visible); } -bool LayerTreeHostInProcess::IsVisible() const { +bool LayerTreeHost::IsVisible() const { return visible_; } -void LayerTreeHostInProcess::NotifyInputThrottledUntilCommit() { +void LayerTreeHost::NotifyInputThrottledUntilCommit() { proxy_->NotifyInputThrottledUntilCommit(); } -void LayerTreeHostInProcess::LayoutAndUpdateLayers() { +void LayerTreeHost::LayoutAndUpdateLayers() { DCHECK(IsSingleThreaded()); // This function is only valid when not using the scheduler. DCHECK(!settings_.single_thread_proxy_scheduler); @@ -538,7 +538,7 @@ UpdateLayers(); } -void LayerTreeHostInProcess::Composite(base::TimeTicks frame_begin_time) { +void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) { DCHECK(IsSingleThreaded()); // This function is only valid when not using the scheduler. DCHECK(!settings_.single_thread_proxy_scheduler); @@ -561,7 +561,7 @@ return 4; } -bool LayerTreeHostInProcess::UpdateLayers() { +bool LayerTreeHost::UpdateLayers() { if (!layer_tree_->root_layer()) { layer_tree_->property_trees()->clear(); return false; @@ -584,11 +584,11 @@ return result || next_commit_forces_redraw_; } -void LayerTreeHostInProcess::DidCompletePageScaleAnimation() { +void LayerTreeHost::DidCompletePageScaleAnimation() { did_complete_scale_animation_ = true; } -void LayerTreeHostInProcess::RecordGpuRasterizationHistogram() { +void LayerTreeHost::RecordGpuRasterizationHistogram() { // Gpu rasterization is only supported for Renderer compositors. // Checking for IsSingleThreaded() to exclude Browser compositors. if (gpu_rasterization_histogram_recorded_ || IsSingleThreaded()) @@ -614,7 +614,7 @@ gpu_rasterization_histogram_recorded_ = true; } -bool LayerTreeHostInProcess::DoUpdateLayers(Layer* root_layer) { +bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { TRACE_EVENT1("cc", "LayerTreeHostInProcess::DoUpdateLayers", "source_frame_number", SourceFrameNumber()); @@ -693,7 +693,7 @@ return did_paint_content; } -void LayerTreeHostInProcess::ApplyViewportDeltas(ScrollAndScaleSet* info) { +void LayerTreeHost::ApplyViewportDeltas(ScrollAndScaleSet* info) { gfx::Vector2dF inner_viewport_scroll_delta; if (info->inner_viewport_scroll.layer_id != Layer::INVALID_ID) inner_viewport_scroll_delta = info->inner_viewport_scroll.scroll_delta; @@ -724,7 +724,7 @@ SetNeedsUpdateLayers(); } -void LayerTreeHostInProcess::ApplyScrollAndScale(ScrollAndScaleSet* info) { +void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) { for (auto& swap_promise : info->swap_promises) { TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow", TRACE_ID_DONT_MANGLE(swap_promise->TraceId()), @@ -756,12 +756,12 @@ ApplyViewportDeltas(info); } -const base::WeakPtr<InputHandler>& LayerTreeHostInProcess::GetInputHandler() +const base::WeakPtr<InputHandler>& LayerTreeHost::GetInputHandler() const { return input_handler_weak_ptr_; } -void LayerTreeHostInProcess::UpdateBrowserControlsState( +void LayerTreeHost::UpdateBrowserControlsState( BrowserControlsState constraints, BrowserControlsState current, bool animate) { @@ -770,7 +770,7 @@ proxy_->UpdateBrowserControlsState(constraints, current, animate); } -void LayerTreeHostInProcess::AnimateLayers(base::TimeTicks monotonic_time) { +void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) { MutatorHost* mutator_host = layer_tree_->mutator_host(); std::unique_ptr<MutatorEvents> events = mutator_host->CreateEvents(); @@ -781,7 +781,7 @@ layer_tree_->property_trees()->needs_rebuild = true; } -int LayerTreeHostInProcess::ScheduleMicroBenchmark( +int LayerTreeHost::ScheduleMicroBenchmark( const std::string& benchmark_name, std::unique_ptr<base::Value> value, const MicroBenchmark::DoneCallback& callback) { @@ -789,24 +789,24 @@ std::move(value), callback); } -bool LayerTreeHostInProcess::SendMessageToMicroBenchmark( +bool LayerTreeHost::SendMessageToMicroBenchmark( int id, std::unique_ptr<base::Value> value) { return micro_benchmark_controller_.SendMessage(id, std::move(value)); } -void LayerTreeHostInProcess::SetLayerTreeMutator( +void LayerTreeHost::SetLayerTreeMutator( std::unique_ptr<LayerTreeMutator> mutator) { proxy_->SetMutator(std::move(mutator)); } -bool LayerTreeHostInProcess::IsSingleThreaded() const { +bool LayerTreeHost::IsSingleThreaded() const { DCHECK(compositor_mode_ != CompositorMode::SINGLE_THREADED || !task_runner_provider_->HasImplThread()); return compositor_mode_ == CompositorMode::SINGLE_THREADED; } -bool LayerTreeHostInProcess::IsThreaded() const { +bool LayerTreeHost::IsThreaded() const { DCHECK(compositor_mode_ != CompositorMode::THREADED || task_runner_provider_->HasImplThread()); return compositor_mode_ == CompositorMode::THREADED;
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index f7aade64..7beade4 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -1,94 +1,138 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. +// Copyright 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CC_TREES_LAYER_TREE_HOST_H_ #define CC_TREES_LAYER_TREE_HOST_H_ +#include <stddef.h> +#include <stdint.h> + +#include <limits> +#include <memory> +#include <set> +#include <string> +#include <unordered_map> +#include <vector> + +#include "base/cancelable_callback.h" #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "cc/base/cc_export.h" #include "cc/debug/micro_benchmark.h" +#include "cc/debug/micro_benchmark_controller.h" #include "cc/input/browser_controls_state.h" +#include "cc/input/event_listener_properties.h" +#include "cc/input/input_handler.h" +#include "cc/input/layer_selection_bound.h" +#include "cc/input/scrollbar.h" +#include "cc/layers/layer_collections.h" +#include "cc/layers/layer_list_iterator.h" +#include "cc/output/compositor_frame_sink.h" +#include "cc/output/swap_promise.h" +#include "cc/resources/resource_format.h" #include "cc/surfaces/surface_reference_owner.h" - -namespace base { -class TimeTicks; -} // namespace base - -namespace gfx { -class Rect; -} // namespace gfx +#include "cc/surfaces/surface_sequence_generator.h" +#include "cc/trees/compositor_mode.h" +#include "cc/trees/layer_tree.h" +#include "cc/trees/layer_tree_host_client.h" +#include "cc/trees/layer_tree_settings.h" +#include "cc/trees/proxy.h" +#include "cc/trees/swap_promise_manager.h" +#include "cc/trees/target_property.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/geometry/rect.h" namespace cc { -class FrameSinkId; -class InputHandler; -class LayerTree; -class LayerTreeDebugState; +class MutatorEvents; +class Layer; +class LayerTreeHostClient; +class LayerTreeHostImpl; +class LayerTreeHostImplClient; +class LayerTreeHostSingleThreadClient; class LayerTreeMutator; -class LayerTreeSettings; -class CompositorFrameSink; -class SwapPromise; -class SwapPromiseManager; -class TaskRunnerProvider; +class MutatorHost; +class RenderingStatsInstrumentation; +class TaskGraphRunner; class UIResourceManager; +struct RenderingStats; +struct ScrollAndScaleSet; -// This encapsulates the API for any embedder to use cc. The -// LayerTreeHostInProcess provides the implementation where the compositor -// thread components of this host run within the same process. Use -// LayerTreeHostInProcess::CreateThreaded/CreateSingleThread to get either. class CC_EXPORT LayerTreeHost : public NON_EXPORTED_BASE(SurfaceReferenceOwner) { public: - virtual ~LayerTreeHost() {} + // TODO(sad): InitParams should be a movable type so that it can be + // std::move()d to the Create* functions. + struct CC_EXPORT InitParams { + LayerTreeHostClient* client = nullptr; + TaskGraphRunner* task_graph_runner = nullptr; + LayerTreeSettings const* settings = nullptr; + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner; + MutatorHost* mutator_host = nullptr; + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner; + + InitParams(); + ~InitParams(); + }; + + static std::unique_ptr<LayerTreeHost> CreateThreaded( + scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, + InitParams* params); + + static std::unique_ptr<LayerTreeHost> CreateSingleThreaded( + LayerTreeHostSingleThreadClient* single_thread_client, + InitParams* params); + + ~LayerTreeHost() override; // Returns the process global unique identifier for this LayerTreeHost. - virtual int GetId() const = 0; + int GetId() const; // The current source frame number. This is incremented for each main frame // update(commit) pushed to the compositor thread. - virtual int SourceFrameNumber() const = 0; + int SourceFrameNumber() const; // Returns the LayerTree that holds the main frame state pushed to the // LayerTreeImpl on commit. - virtual LayerTree* GetLayerTree() = 0; - virtual const LayerTree* GetLayerTree() const = 0; + LayerTree* GetLayerTree(); + const LayerTree* GetLayerTree() const; // Returns the UIResourceManager used to create UIResources for // UIResourceLayers pushed to the LayerTree. - virtual UIResourceManager* GetUIResourceManager() const = 0; + UIResourceManager* GetUIResourceManager() const; // Returns the TaskRunnerProvider used to access the main and compositor // thread task runners. - virtual TaskRunnerProvider* GetTaskRunnerProvider() const = 0; + TaskRunnerProvider* GetTaskRunnerProvider() const; // Returns the settings used by this host. - virtual const LayerTreeSettings& GetSettings() const = 0; + const LayerTreeSettings& GetSettings() const; // Sets the client id used to generate the SurfaceId that uniquely identifies // the Surfaces produced by this compositor. - virtual void SetFrameSinkId(const FrameSinkId& frame_sink_id) = 0; + void SetFrameSinkId(const FrameSinkId& frame_sink_id); // Sets the LayerTreeMutator interface used to directly mutate the compositor // state on the compositor thread. (Compositor-Worker) - virtual void SetLayerTreeMutator( - std::unique_ptr<LayerTreeMutator> mutator) = 0; + void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator); // Call this function when you expect there to be a swap buffer. // See swap_promise.h for how to use SwapPromise. - virtual void QueueSwapPromise(std::unique_ptr<SwapPromise> swap_promise) = 0; + void QueueSwapPromise(std::unique_ptr<SwapPromise> swap_promise); // Returns the SwapPromiseManager used to create SwapPromiseMonitors for this // host. - virtual SwapPromiseManager* GetSwapPromiseManager() = 0; + SwapPromiseManager* GetSwapPromiseManager(); // Sets whether the content is suitable to use Gpu Rasterization. - virtual void SetHasGpuRasterizationTrigger(bool has_trigger) = 0; + void SetHasGpuRasterizationTrigger(bool has_trigger); // Visibility and CompositorFrameSink ------------------------------- - virtual void SetVisible(bool visible) = 0; - virtual bool IsVisible() const = 0; + void SetVisible(bool visible); + bool IsVisible() const; // Called in response to an CompositorFrameSink request made to the client // using LayerTreeHostClient::RequestNewCompositorFrameSink. The client will @@ -96,12 +140,12 @@ // DidInitializaCompositorFrameSink or DidFailToInitializeCompositorFrameSink. // The request is completed when the host successfully initializes an // CompositorFrameSink. - virtual void SetCompositorFrameSink( - std::unique_ptr<CompositorFrameSink> compositor_frame_sink) = 0; + void SetCompositorFrameSink( + std::unique_ptr<CompositorFrameSink> compositor_frame_sink); // Forces the host to immediately release all references to the // CompositorFrameSink, if any. Can be safely called any time. - virtual std::unique_ptr<CompositorFrameSink> ReleaseCompositorFrameSink() = 0; + std::unique_ptr<CompositorFrameSink> ReleaseCompositorFrameSink(); // Frame Scheduling (main and compositor frames) requests ------- @@ -109,90 +153,244 @@ // for instance in the case of RequestAnimationFrame from blink to ensure the // main frame update is run on the next tick without pre-emptively forcing a // full commit synchronization or layer updates. - virtual void SetNeedsAnimate() = 0; + void SetNeedsAnimate(); // Requests a main frame update and also ensure that the host pulls layer // updates from the client, even if no content might have changed, without // forcing a full commit synchronization. - virtual void SetNeedsUpdateLayers() = 0; + virtual void SetNeedsUpdateLayers(); // Requests that the next main frame update performs a full commit // synchronization. - virtual void SetNeedsCommit() = 0; + virtual void SetNeedsCommit(); // Requests that the next frame re-chooses crisp raster scales for all layers. - virtual void SetNeedsRecalculateRasterScales() = 0; + void SetNeedsRecalculateRasterScales(); // Returns true if a main frame with commit synchronization has been // requested. - virtual bool CommitRequested() const = 0; + bool CommitRequested() const; // Enables/disables the compositor from requesting main frame updates from the // client. - virtual void SetDeferCommits(bool defer_commits) = 0; + void SetDeferCommits(bool defer_commits); // Synchronously performs a main frame update and layer updates. Used only in // single threaded mode when the compositor's internal scheduling is disabled. - virtual void LayoutAndUpdateLayers() = 0; + void LayoutAndUpdateLayers(); // Synchronously performs a complete main frame update, commit and compositor // frame. Used only in single threaded mode when the compositor's internal // scheduling is disabled. - virtual void Composite(base::TimeTicks frame_begin_time) = 0; + void Composite(base::TimeTicks frame_begin_time); // Requests a redraw (compositor frame) for the given rect. - virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0; + void SetNeedsRedrawRect(const gfx::Rect& damage_rect); // Requests a main frame (including layer updates) and ensures that this main // frame results in a redraw for the complete viewport when producing the // CompositorFrame. - virtual void SetNextCommitForcesRedraw() = 0; + void SetNextCommitForcesRedraw(); // Input Handling --------------------------------------------- // Notifies the compositor that input from the browser is being throttled till // the next commit. The compositor will prioritize activation of the pending // tree so a commit can be performed. - virtual void NotifyInputThrottledUntilCommit() = 0; + void NotifyInputThrottledUntilCommit(); // Sets the state of the browser controls. (Used for URL bar animations on // android). - virtual void UpdateBrowserControlsState(BrowserControlsState constraints, - BrowserControlsState current, - bool animate) = 0; + void UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate); // Returns a reference to the InputHandler used to respond to input events on // the compositor thread. - virtual const base::WeakPtr<InputHandler>& GetInputHandler() const = 0; + const base::WeakPtr<InputHandler>& GetInputHandler() const; // Informs the compositor that an active fling gesture being processed on the // main thread has been finished. - virtual void DidStopFlinging() = 0; + void DidStopFlinging(); // Debugging and benchmarks --------------------------------- - virtual void SetDebugState(const LayerTreeDebugState& debug_state) = 0; - virtual const LayerTreeDebugState& GetDebugState() const = 0; + void SetDebugState(const LayerTreeDebugState& debug_state); + const LayerTreeDebugState& GetDebugState() const; // Returns the id of the benchmark on success, 0 otherwise. - virtual int ScheduleMicroBenchmark( - const std::string& benchmark_name, - std::unique_ptr<base::Value> value, - const MicroBenchmark::DoneCallback& callback) = 0; + int ScheduleMicroBenchmark(const std::string& benchmark_name, + std::unique_ptr<base::Value> value, + const MicroBenchmark::DoneCallback& callback); // Returns true if the message was successfully delivered and handled. - virtual bool SendMessageToMicroBenchmark( - int id, - std::unique_ptr<base::Value> value) = 0; + bool SendMessageToMicroBenchmark(int id, std::unique_ptr<base::Value> value); // When the main thread informs the impl thread that it is ready to commit, // generally it would remain blocked till the main thread state is copied to // the pending tree. Calling this would ensure that the main thread remains // blocked till the pending tree is activated. - virtual void SetNextCommitWaitsForActivation() = 0; + void SetNextCommitWaitsForActivation(); // The LayerTreeHost tracks whether the content is suitable for Gpu raster. // Calling this will reset it back to not suitable state. - virtual void ResetGpuRasterizationTracking() = 0; + void ResetGpuRasterizationTracking(); + + // SurfaceReferenceOwner implementation. + SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() override; + + // LayerTreeHostInProcess interface to Proxy. + void WillBeginMainFrame(); + void DidBeginMainFrame(); + void BeginMainFrame(const BeginFrameArgs& args); + void BeginMainFrameNotExpectedSoon(); + void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); + void RequestMainFrameUpdate(); + void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); + void WillCommit(); + void CommitComplete(); + void RequestNewCompositorFrameSink(); + void DidInitializeCompositorFrameSink(); + void DidFailToInitializeCompositorFrameSink(); + virtual std::unique_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( + LayerTreeHostImplClient* client); + void DidLoseCompositorFrameSink(); + void DidCommitAndDrawFrame() { client_->DidCommitAndDrawFrame(); } + void DidReceiveCompositorFrameAck() { + client_->DidReceiveCompositorFrameAck(); + } + bool UpdateLayers(); + // Called when the compositor completed page scale animation. + void DidCompletePageScaleAnimation(); + void ApplyScrollAndScale(ScrollAndScaleSet* info); + + LayerTreeHostClient* client() { return client_; } + + bool gpu_rasterization_histogram_recorded() const { + return gpu_rasterization_histogram_recorded_; + } + + void CollectRenderingStats(RenderingStats* stats) const; + + RenderingStatsInstrumentation* rendering_stats_instrumentation() const { + return rendering_stats_instrumentation_.get(); + } + + void SetAnimationEvents(std::unique_ptr<MutatorEvents> events); + + bool has_gpu_rasterization_trigger() const { + return has_gpu_rasterization_trigger_; + } + + Proxy* proxy() const { return proxy_.get(); } + + bool IsSingleThreaded() const; + bool IsThreaded() const; + + protected: + // Allow tests to inject the LayerTree. + LayerTreeHost(InitParams* params, + CompositorMode mode, + std::unique_ptr<LayerTree> layer_tree); + LayerTreeHost(InitParams* params, CompositorMode mode); + + void InitializeThreaded( + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); + void InitializeSingleThreaded( + LayerTreeHostSingleThreadClient* single_thread_client, + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); + void InitializeForTesting( + std::unique_ptr<TaskRunnerProvider> task_runner_provider, + std::unique_ptr<Proxy> proxy_for_testing); + void SetTaskRunnerProviderForTesting( + std::unique_ptr<TaskRunnerProvider> task_runner_provider); + void SetUIResourceManagerForTesting( + std::unique_ptr<UIResourceManager> ui_resource_manager); + + // task_graph_runner() returns a valid value only until the LayerTreeHostImpl + // is created in CreateLayerTreeHostImpl(). + TaskGraphRunner* task_graph_runner() const { return task_graph_runner_; } + + void OnCommitForSwapPromises(); + + void RecordGpuRasterizationHistogram(); + + MicroBenchmarkController micro_benchmark_controller_; + + std::unique_ptr<LayerTree> layer_tree_; + + base::WeakPtr<InputHandler> input_handler_weak_ptr_; + + private: + friend class LayerTreeHostSerializationTest; + + // This is the number of consecutive frames in which we want the content to be + // suitable for GPU rasterization before re-enabling it. + enum { kNumFramesToConsiderBeforeGpuRasterization = 60 }; + + void ApplyViewportDeltas(ScrollAndScaleSet* info); + void ApplyPageScaleDeltaFromImplSide(float page_scale_delta); + void InitializeProxy(std::unique_ptr<Proxy> proxy); + + bool DoUpdateLayers(Layer* root_layer); + void UpdateHudLayer(); + + bool AnimateLayersRecursive(Layer* current, base::TimeTicks time); + + void CalculateLCDTextMetricsCallback(Layer* layer); + + void SetPropertyTreesNeedRebuild(); + + const CompositorMode compositor_mode_; + + std::unique_ptr<UIResourceManager> ui_resource_manager_; + + LayerTreeHostClient* client_; + std::unique_ptr<Proxy> proxy_; + std::unique_ptr<TaskRunnerProvider> task_runner_provider_; + + int source_frame_number_; + std::unique_ptr<RenderingStatsInstrumentation> + rendering_stats_instrumentation_; + + SwapPromiseManager swap_promise_manager_; + + // |current_compositor_frame_sink_| can't be updated until we've successfully + // initialized a new CompositorFrameSink. |new_compositor_frame_sink_| + // contains the new CompositorFrameSink that is currently being initialized. + // If initialization is successful then |new_compositor_frame_sink_| replaces + // |current_compositor_frame_sink_|. + std::unique_ptr<CompositorFrameSink> new_compositor_frame_sink_; + std::unique_ptr<CompositorFrameSink> current_compositor_frame_sink_; + + const LayerTreeSettings settings_; + LayerTreeDebugState debug_state_; + + bool visible_; + + bool has_gpu_rasterization_trigger_; + bool content_is_suitable_for_gpu_rasterization_; + bool gpu_rasterization_histogram_recorded_; + + // If set, then page scale animation has completed, but the client hasn't been + // notified about it yet. + bool did_complete_scale_animation_; + + int id_; + bool next_commit_forces_redraw_ = false; + bool next_commit_forces_recalculate_raster_scales_ = false; + // Track when we're inside a main frame to see if compositor is being + // destroyed midway which causes a crash. crbug.com/654672 + bool inside_main_frame_ = false; + + TaskGraphRunner* task_graph_runner_; + + SurfaceSequenceGenerator surface_sequence_generator_; + uint32_t num_consecutive_frames_suitable_for_gpu_ = 0; + + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(LayerTreeHost); }; } // namespace cc
diff --git a/cc/trees/layer_tree_host_in_process.h b/cc/trees/layer_tree_host_in_process.h deleted file mode 100644 index b4fd8af6..0000000 --- a/cc/trees/layer_tree_host_in_process.h +++ /dev/null
@@ -1,291 +0,0 @@ -// Copyright 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CC_TREES_LAYER_TREE_HOST_IN_PROCESS_H_ -#define CC_TREES_LAYER_TREE_HOST_IN_PROCESS_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <limits> -#include <memory> -#include <set> -#include <string> -#include <unordered_map> -#include <vector> - -#include "base/cancelable_callback.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "cc/base/cc_export.h" -#include "cc/debug/micro_benchmark.h" -#include "cc/debug/micro_benchmark_controller.h" -#include "cc/input/browser_controls_state.h" -#include "cc/input/event_listener_properties.h" -#include "cc/input/input_handler.h" -#include "cc/input/layer_selection_bound.h" -#include "cc/input/scrollbar.h" -#include "cc/layers/layer_collections.h" -#include "cc/layers/layer_list_iterator.h" -#include "cc/output/compositor_frame_sink.h" -#include "cc/output/swap_promise.h" -#include "cc/resources/resource_format.h" -#include "cc/surfaces/surface_sequence_generator.h" -#include "cc/trees/compositor_mode.h" -#include "cc/trees/layer_tree.h" -#include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_client.h" -#include "cc/trees/layer_tree_settings.h" -#include "cc/trees/proxy.h" -#include "cc/trees/swap_promise_manager.h" -#include "cc/trees/target_property.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/geometry/rect.h" - -namespace cc { -class MutatorEvents; -class Layer; -class LayerTreeHostClient; -class LayerTreeHostImpl; -class LayerTreeHostImplClient; -class LayerTreeHostSingleThreadClient; -class LayerTreeMutator; -class MutatorHost; -class RenderingStatsInstrumentation; -class TaskGraphRunner; -struct RenderingStats; -struct ScrollAndScaleSet; - -class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { - public: - // TODO(sad): InitParams should be a movable type so that it can be - // std::move()d to the Create* functions. - struct CC_EXPORT InitParams { - LayerTreeHostClient* client = nullptr; - TaskGraphRunner* task_graph_runner = nullptr; - LayerTreeSettings const* settings = nullptr; - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner; - MutatorHost* mutator_host = nullptr; - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner; - - InitParams(); - ~InitParams(); - }; - - static std::unique_ptr<LayerTreeHostInProcess> CreateThreaded( - scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, - InitParams* params); - - static std::unique_ptr<LayerTreeHostInProcess> CreateSingleThreaded( - LayerTreeHostSingleThreadClient* single_thread_client, - InitParams* params); - - ~LayerTreeHostInProcess() override; - - // LayerTreeHost implementation. - int GetId() const override; - int SourceFrameNumber() const override; - LayerTree* GetLayerTree() override; - const LayerTree* GetLayerTree() const override; - UIResourceManager* GetUIResourceManager() const override; - TaskRunnerProvider* GetTaskRunnerProvider() const override; - const LayerTreeSettings& GetSettings() const override; - void SetFrameSinkId(const FrameSinkId& frame_sink_id) override; - void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator) override; - void QueueSwapPromise(std::unique_ptr<SwapPromise> swap_promise) override; - SwapPromiseManager* GetSwapPromiseManager() override; - void SetHasGpuRasterizationTrigger(bool has_trigger) override; - void SetVisible(bool visible) override; - bool IsVisible() const override; - void SetCompositorFrameSink( - std::unique_ptr<CompositorFrameSink> compositor_frame_sink) override; - std::unique_ptr<CompositorFrameSink> ReleaseCompositorFrameSink() override; - void SetNeedsAnimate() override; - void SetNeedsUpdateLayers() override; - void SetNeedsCommit() override; - void SetNeedsRecalculateRasterScales() override; - bool CommitRequested() const override; - void SetDeferCommits(bool defer_commits) override; - void LayoutAndUpdateLayers() override; - void Composite(base::TimeTicks frame_begin_time) override; - void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override; - void SetNextCommitForcesRedraw() override; - void NotifyInputThrottledUntilCommit() override; - void UpdateBrowserControlsState(BrowserControlsState constraints, - BrowserControlsState current, - bool animate) override; - const base::WeakPtr<InputHandler>& GetInputHandler() const override; - void DidStopFlinging() override; - void SetDebugState(const LayerTreeDebugState& debug_state) override; - const LayerTreeDebugState& GetDebugState() const override; - int ScheduleMicroBenchmark( - const std::string& benchmark_name, - std::unique_ptr<base::Value> value, - const MicroBenchmark::DoneCallback& callback) override; - bool SendMessageToMicroBenchmark(int id, - std::unique_ptr<base::Value> value) override; - SurfaceSequenceGenerator* GetSurfaceSequenceGenerator() override; - void SetNextCommitWaitsForActivation() override; - void ResetGpuRasterizationTracking() override; - - // LayerTreeHostInProcess interface to Proxy. - void WillBeginMainFrame(); - void DidBeginMainFrame(); - void BeginMainFrame(const BeginFrameArgs& args); - void BeginMainFrameNotExpectedSoon(); - void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); - void RequestMainFrameUpdate(); - void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); - void WillCommit(); - void CommitComplete(); - void RequestNewCompositorFrameSink(); - void DidInitializeCompositorFrameSink(); - void DidFailToInitializeCompositorFrameSink(); - virtual std::unique_ptr<LayerTreeHostImpl> CreateLayerTreeHostImpl( - LayerTreeHostImplClient* client); - void DidLoseCompositorFrameSink(); - void DidCommitAndDrawFrame() { client_->DidCommitAndDrawFrame(); } - void DidReceiveCompositorFrameAck() { - client_->DidReceiveCompositorFrameAck(); - } - bool UpdateLayers(); - // Called when the compositor completed page scale animation. - void DidCompletePageScaleAnimation(); - void ApplyScrollAndScale(ScrollAndScaleSet* info); - - LayerTreeHostClient* client() { return client_; } - - bool gpu_rasterization_histogram_recorded() const { - return gpu_rasterization_histogram_recorded_; - } - - void CollectRenderingStats(RenderingStats* stats) const; - - RenderingStatsInstrumentation* rendering_stats_instrumentation() const { - return rendering_stats_instrumentation_.get(); - } - - void SetAnimationEvents(std::unique_ptr<MutatorEvents> events); - - bool has_gpu_rasterization_trigger() const { - return has_gpu_rasterization_trigger_; - } - - Proxy* proxy() const { return proxy_.get(); } - - bool IsSingleThreaded() const; - bool IsThreaded() const; - - protected: - // Allow tests to inject the LayerTree. - LayerTreeHostInProcess(InitParams* params, - CompositorMode mode, - std::unique_ptr<LayerTree> layer_tree); - LayerTreeHostInProcess(InitParams* params, CompositorMode mode); - - void InitializeThreaded( - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); - void InitializeSingleThreaded( - LayerTreeHostSingleThreadClient* single_thread_client, - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); - void InitializeForTesting( - std::unique_ptr<TaskRunnerProvider> task_runner_provider, - std::unique_ptr<Proxy> proxy_for_testing); - void SetTaskRunnerProviderForTesting( - std::unique_ptr<TaskRunnerProvider> task_runner_provider); - void SetUIResourceManagerForTesting( - std::unique_ptr<UIResourceManager> ui_resource_manager); - - // task_graph_runner() returns a valid value only until the LayerTreeHostImpl - // is created in CreateLayerTreeHostImpl(). - TaskGraphRunner* task_graph_runner() const { return task_graph_runner_; } - - void OnCommitForSwapPromises(); - - void RecordGpuRasterizationHistogram(); - - MicroBenchmarkController micro_benchmark_controller_; - - std::unique_ptr<LayerTree> layer_tree_; - - base::WeakPtr<InputHandler> input_handler_weak_ptr_; - - private: - friend class LayerTreeHostSerializationTest; - - // This is the number of consecutive frames in which we want the content to be - // suitable for GPU rasterization before re-enabling it. - enum { kNumFramesToConsiderBeforeGpuRasterization = 60 }; - - void ApplyViewportDeltas(ScrollAndScaleSet* info); - void ApplyPageScaleDeltaFromImplSide(float page_scale_delta); - void InitializeProxy(std::unique_ptr<Proxy> proxy); - - bool DoUpdateLayers(Layer* root_layer); - void UpdateHudLayer(); - - bool AnimateLayersRecursive(Layer* current, base::TimeTicks time); - - void CalculateLCDTextMetricsCallback(Layer* layer); - - void SetPropertyTreesNeedRebuild(); - - const CompositorMode compositor_mode_; - - std::unique_ptr<UIResourceManager> ui_resource_manager_; - - LayerTreeHostClient* client_; - std::unique_ptr<Proxy> proxy_; - std::unique_ptr<TaskRunnerProvider> task_runner_provider_; - - int source_frame_number_; - std::unique_ptr<RenderingStatsInstrumentation> - rendering_stats_instrumentation_; - - SwapPromiseManager swap_promise_manager_; - - // |current_compositor_frame_sink_| can't be updated until we've successfully - // initialized a new CompositorFrameSink. |new_compositor_frame_sink_| - // contains the new CompositorFrameSink that is currently being initialized. - // If initialization is successful then |new_compositor_frame_sink_| replaces - // |current_compositor_frame_sink_|. - std::unique_ptr<CompositorFrameSink> new_compositor_frame_sink_; - std::unique_ptr<CompositorFrameSink> current_compositor_frame_sink_; - - const LayerTreeSettings settings_; - LayerTreeDebugState debug_state_; - - bool visible_; - - bool has_gpu_rasterization_trigger_; - bool content_is_suitable_for_gpu_rasterization_; - bool gpu_rasterization_histogram_recorded_; - - // If set, then page scale animation has completed, but the client hasn't been - // notified about it yet. - bool did_complete_scale_animation_; - - int id_; - bool next_commit_forces_redraw_ = false; - bool next_commit_forces_recalculate_raster_scales_ = false; - // Track when we're inside a main frame to see if compositor is being - // destroyed midway which causes a crash. crbug.com/654672 - bool inside_main_frame_ = false; - - TaskGraphRunner* task_graph_runner_; - - SurfaceSequenceGenerator surface_sequence_generator_; - uint32_t num_consecutive_frames_suitable_for_gpu_ = 0; - - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostInProcess); -}; - -} // namespace cc - -#endif // CC_TREES_LAYER_TREE_HOST_IN_PROCESS_H_
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 4128e8a..0d8dec3 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -5187,11 +5187,11 @@ void BeginTest() override { // Verify default value. - EXPECT_FALSE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); // Setting gpu rasterization trigger does not enable gpu rasterization. layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); PostSetNeedsCommitToMainThread(); } @@ -5242,7 +5242,7 @@ void BeginTest() override { // Setting gpu rasterization trigger does not enable gpu rasterization. layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); PostSetNeedsCommitToMainThread(); } @@ -5297,11 +5297,11 @@ void BeginTest() override { // Verify default value. - EXPECT_FALSE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); // Gpu rasterization trigger is relevant. layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is relevant as well. layer_->set_force_unsuitable_for_gpu_rasterization(true); @@ -5365,11 +5365,11 @@ void BeginTest() override { // Verify default value. - EXPECT_FALSE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); // Gpu rasterization trigger is relevant. layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is relevant as well. layer_->set_force_unsuitable_for_gpu_rasterization(true); @@ -5448,11 +5448,11 @@ void BeginTest() override { // Verify default value. - EXPECT_FALSE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); // With gpu rasterization forced, gpu rasterization trigger is irrelevant. layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host_in_process()->has_gpu_rasterization_trigger()); + EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); // Content-based veto is irrelevant as well. layer_->set_force_unsuitable_for_gpu_rasterization(true); @@ -5867,7 +5867,7 @@ void BeginMainFrame(const BeginFrameArgs& args) override { EXPECT_EQ(nullptr, layer_tree()->root_layer()); - layer_tree_host_in_process()->ApplyScrollAndScale(&info_); + layer_tree_host()->ApplyScrollAndScale(&info_); EndTest(); }
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index 2d1b3c8..e1977a44 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1647,9 +1647,8 @@ TargetProperty::Type target_property, int group) override { called_animation_started_ = true; - layer_tree_host_in_process()->AnimateLayers( - base::TimeTicks::FromInternalValue( - std::numeric_limits<int64_t>::max())); + layer_tree_host()->AnimateLayers(base::TimeTicks::FromInternalValue( + std::numeric_limits<int64_t>::max())); PostSetNeedsCommitToMainThread(); }
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc index f02e66da..37d98c1 100644 --- a/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -1318,15 +1318,14 @@ auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); - LayerTreeHostInProcess::InitParams params; + LayerTreeHost::InitParams params; params.client = &layer_tree_host_client; params.task_graph_runner = &task_graph_runner; params.settings = &settings; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); params.mutator_host = animation_host.get(); - std::unique_ptr<LayerTreeHostInProcess> layer_tree_host = - LayerTreeHostInProcess::CreateThreaded(impl_thread.task_runner(), - ¶ms); + std::unique_ptr<LayerTreeHost> layer_tree_host = + LayerTreeHost::CreateThreaded(impl_thread.task_runner(), ¶ms); ThreadCheckingInputHandlerClient input_handler_client( impl_thread.task_runner().get(), &received_stop_flinging);
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index 63e0968..0a8620e 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -19,7 +19,7 @@ #include "cc/output/context_provider.h" #include "cc/scheduler/compositor_timing_history.h" #include "cc/scheduler/delay_based_time_source.h" -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/proxy_main.h" @@ -38,7 +38,7 @@ } // namespace ProxyImpl::ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr, - LayerTreeHostInProcess* layer_tree_host, + LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider) : layer_tree_host_id_(layer_tree_host->GetId()), commit_completion_waits_for_activation_(false), @@ -225,7 +225,7 @@ void ProxyImpl::NotifyReadyToCommitOnImpl( CompletionEvent* completion, - LayerTreeHostInProcess* layer_tree_host, + LayerTreeHost* layer_tree_host, base::TimeTicks main_thread_start_time, bool hold_commit_for_activation) { TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToCommitOnImpl");
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h index fdabbbd3..0aab6133 100644 --- a/cc/trees/proxy_impl.h +++ b/cc/trees/proxy_impl.h
@@ -16,7 +16,7 @@ #include "cc/trees/layer_tree_host_impl.h" namespace cc { -class LayerTreeHostInProcess; +class LayerTreeHost; class ProxyMain; // This class aggregates all the interactions that the main side of the @@ -26,7 +26,7 @@ public NON_EXPORTED_BASE(SchedulerClient) { public: ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr, - LayerTreeHostInProcess* layer_tree_host, + LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider); ~ProxyImpl() override; @@ -49,7 +49,7 @@ void ReleaseCompositorFrameSinkOnImpl(CompletionEvent* completion); void FinishGLOnImpl(CompletionEvent* completion); void NotifyReadyToCommitOnImpl(CompletionEvent* completion, - LayerTreeHostInProcess* layer_tree_host, + LayerTreeHost* layer_tree_host, base::TimeTicks main_thread_start_time, bool hold_commit_for_activation); @@ -62,7 +62,7 @@ struct BlockedMainCommitOnly { BlockedMainCommitOnly(); ~BlockedMainCommitOnly(); - LayerTreeHostInProcess* layer_tree_host; + LayerTreeHost* layer_tree_host; }; // LayerTreeHostImplClient implementation
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc index 15948f0e..bab54a09 100644 --- a/cc/trees/proxy_main.cc +++ b/cc/trees/proxy_main.cc
@@ -18,14 +18,14 @@ #include "cc/output/swap_promise.h" #include "cc/resources/ui_resource_manager.h" #include "cc/trees/blocking_task_runner.h" -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/mutator_host.h" #include "cc/trees/proxy_impl.h" #include "cc/trees/scoped_abort_remaining_swap_promises.h" namespace cc { -ProxyMain::ProxyMain(LayerTreeHostInProcess* layer_tree_host, +ProxyMain::ProxyMain(LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider) : layer_tree_host_(layer_tree_host), task_runner_provider_(task_runner_provider),
diff --git a/cc/trees/proxy_main.h b/cc/trees/proxy_main.h index 5ebf396..29f4880 100644 --- a/cc/trees/proxy_main.h +++ b/cc/trees/proxy_main.h
@@ -16,7 +16,7 @@ class MutatorEvents; class CompletionEvent; class CompositorFrameSink; -class LayerTreeHostInProcess; +class LayerTreeHost; class LayerTreeMutator; class ProxyImpl; @@ -25,7 +25,7 @@ // The class is created and lives on the main thread. class CC_EXPORT ProxyMain : public Proxy { public: - ProxyMain(LayerTreeHostInProcess* layer_tree_host, + ProxyMain(LayerTreeHost* layer_tree_host, TaskRunnerProvider* task_runner_provider); ~ProxyMain() override; @@ -98,7 +98,7 @@ void InitializeOnImplThread(CompletionEvent* completion_event); void DestroyProxyImplOnImplThread(CompletionEvent* completion_event); - LayerTreeHostInProcess* layer_tree_host_; + LayerTreeHost* layer_tree_host_; TaskRunnerProvider* task_runner_provider_;
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 8d743563..7aa7cfc 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc
@@ -18,8 +18,8 @@ #include "cc/scheduler/compositor_timing_history.h" #include "cc/scheduler/delay_based_time_source.h" #include "cc/scheduler/scheduler.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_host_common.h" -#include "cc/trees/layer_tree_host_in_process.h" #include "cc/trees/layer_tree_host_single_thread_client.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" @@ -28,14 +28,14 @@ namespace cc { std::unique_ptr<Proxy> SingleThreadProxy::Create( - LayerTreeHostInProcess* layer_tree_host, + LayerTreeHost* layer_tree_host, LayerTreeHostSingleThreadClient* client, TaskRunnerProvider* task_runner_provider) { return base::WrapUnique( new SingleThreadProxy(layer_tree_host, client, task_runner_provider)); } -SingleThreadProxy::SingleThreadProxy(LayerTreeHostInProcess* layer_tree_host, +SingleThreadProxy::SingleThreadProxy(LayerTreeHost* layer_tree_host, LayerTreeHostSingleThreadClient* client, TaskRunnerProvider* task_runner_provider) : layer_tree_host_(layer_tree_host),
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index eb49421..fbdd70e 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h
@@ -21,7 +21,7 @@ class MutatorEvents; class BeginFrameSource; -class LayerTreeHostInProcess; +class LayerTreeHost; class LayerTreeHostSingleThreadClient; class CC_EXPORT SingleThreadProxy : public Proxy, @@ -29,7 +29,7 @@ public SchedulerClient { public: static std::unique_ptr<Proxy> Create( - LayerTreeHostInProcess* layer_tree_host, + LayerTreeHost* layer_tree_host, LayerTreeHostSingleThreadClient* client, TaskRunnerProvider* task_runner_provider_); ~SingleThreadProxy() override; @@ -102,7 +102,7 @@ void CompositeImmediately(base::TimeTicks frame_begin_time); protected: - SingleThreadProxy(LayerTreeHostInProcess* layer_tree_host, + SingleThreadProxy(LayerTreeHost* layer_tree_host, LayerTreeHostSingleThreadClient* client, TaskRunnerProvider* task_runner_provider); @@ -120,7 +120,7 @@ void ScheduleRequestNewCompositorFrameSink(); // Accessed on main thread only. - LayerTreeHostInProcess* layer_tree_host_; + LayerTreeHost* layer_tree_host_; LayerTreeHostSingleThreadClient* single_thread_client_; TaskRunnerProvider* task_runner_provider_;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java index d8c54711..c92e632 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
@@ -106,7 +106,7 @@ public boolean queueIdle() { Runnable currentTask = mDeferredTasks.poll(); if (currentTask == null) { - if (mDeferredStartupInitializedForApp) { + if (mDeferredStartupInitializedForApp && !mDeferredStartupCompletedForApp) { mDeferredStartupCompletedForApp = true; recordDeferredStartupStats(); } @@ -137,7 +137,6 @@ "UMA.Debug.EnableCrashUpload.DeferredStartUpCompleteTime", SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(), TimeUnit.MILLISECONDS); - LocaleManager.getInstance().recordStartupMetrics(); } /** @@ -219,6 +218,13 @@ } }); + mDeferredTasks.add(new Runnable() { + @Override + public void run() { + LocaleManager.getInstance().recordStartupMetrics(); + } + }); + final ChromeApplication application = (ChromeApplication) mAppContext; mDeferredTasks.add(new Runnable() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java index c15c5d4..2a73e5b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java
@@ -88,12 +88,13 @@ * Get the instance of the evaluation bridge. * @param profile The profile used to get bridge. * @param useEvaluationScheduler True if using the evaluation scheduler instead of the - * GCMNetworkManager one. + * GCMNetworkManager one. + * @param useBackgroundLoader True if using background loader. False for prerenderer. */ public static OfflinePageEvaluationBridge getForProfile( - Profile profile, boolean useEvaluationScheduler) { + Profile profile, boolean useEvaluationScheduler, boolean useBackgroundLoader) { ThreadUtils.assertOnUiThread(); - return nativeGetBridgeForProfile(profile, useEvaluationScheduler); + return nativeGetBridgeForProfile(profile, useEvaluationScheduler, useBackgroundLoader); } private static final String TAG = "OPEvalBridge"; @@ -275,7 +276,7 @@ } private static native OfflinePageEvaluationBridge nativeGetBridgeForProfile( - Profile profile, boolean useEvaluationScheduler); + Profile profile, boolean useEvaluationScheduler, boolean useBackgroundLoader); private native void nativeGetAllPages(long nativeOfflinePageEvaluationBridge, List<OfflinePageItem> offlinePages, final Callback<List<OfflinePageItem>> callback);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java index bfee387..ffaa92df 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageSavePageLaterEvaluationTest.java
@@ -14,6 +14,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Manual; import org.chromium.base.test.util.TimeoutScale; import org.chromium.chrome.browser.ChromeActivity; @@ -44,8 +45,9 @@ * Tests OfflinePageBridge.SavePageLater over a batch of urls. * Tests against a list of top EM urls, try to call SavePageLater on each of the url. It also * record metrics (failure rate, time elapsed etc.) by writing metrics to a file on external - * storage. - * */ + * storage. This will always use prerenderer. + */ +@CommandLineFlags.Add({"disable-features=BackgroundLoader"}) public class OfflinePageSavePageLaterEvaluationTest extends ChromeActivityTestCaseBase<ChromeActivity> { /** @@ -97,6 +99,7 @@ private boolean mIsUserRequested; private boolean mUseTestScheduler; private int mScheduleBatchSize; + private boolean mUseBackgroundLoader; private LongSparseArray<RequestMetadata> mRequestMetadata; @@ -216,15 +219,17 @@ * Initializes the evaluation bridge which will be used. * @param useCustomScheduler True if customized scheduler (the one with immediate scheduling) * will be used. False otherwise. + * @param useBackgroundLoader True if use background loader. False if use prerenderer. */ - private void initializeBridgeForProfile(final boolean useTestingScheduler) - throws InterruptedException { + private void initializeBridgeForProfile(final boolean useTestingScheduler, + final boolean useBackgroundLoader) throws InterruptedException { final Semaphore semaphore = new Semaphore(0); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { Profile profile = Profile.getLastUsedProfile(); - mBridge = OfflinePageEvaluationBridge.getForProfile(profile, useTestingScheduler); + mBridge = OfflinePageEvaluationBridge.getForProfile( + profile, useTestingScheduler, useBackgroundLoader); if (mBridge == null) { fail("OfflinePageEvaluationBridge initialization failed!"); return; @@ -250,8 +255,10 @@ * Set up the input/output, bridge and observer we're going to use. * @param useCustomScheduler True if customized scheduler (the one with immediate scheduling) * will be used. False otherwise. + * @param useBackgroundLoader True if use background loader. False if use prerenderer. */ - protected void setUpIOAndBridge(final boolean useCustomScheduler) throws InterruptedException { + protected void setUpIOAndBridge(final boolean useCustomScheduler, + final boolean useBackgroundLoader) throws InterruptedException { try { getUrlListFromInputFile(INPUT_FILE_PATH); } catch (IOException e) { @@ -264,7 +271,7 @@ mScheduleBatchSize = mUrls.size(); } - initializeBridgeForProfile(useCustomScheduler); + initializeBridgeForProfile(useCustomScheduler, useBackgroundLoader); mObserver = new OfflinePageEvaluationObserver() { public void savePageRequestAdded(SavePageRequest request) { RequestMetadata metadata = new RequestMetadata(); @@ -485,6 +492,8 @@ mIsUserRequested = Boolean.parseBoolean(properties.getProperty("IsUserRequested")); mUseTestScheduler = Boolean.parseBoolean(properties.getProperty("UseTestScheduler")); mScheduleBatchSize = Integer.parseInt(properties.getProperty("ScheduleBatchSize")); + mUseBackgroundLoader = + Boolean.parseBoolean(properties.getProperty("UseBackgroundLoader")); } catch (FileNotFoundException e) { Log.e(TAG, e.getMessage(), e); fail(String.format( @@ -509,7 +518,18 @@ @TimeoutScale(4) public void testFailureRate() throws IOException, InterruptedException { parseConfigFile(); - setUpIOAndBridge(mUseTestScheduler); + setUpIOAndBridge(mUseTestScheduler, mUseBackgroundLoader); processUrls(mUrls); } + + /** + * Runs testFailureRate with background loader enabled. + */ + @Manual + @TimeoutScale(4) + @CommandLineFlags.Add({"enable-features=BackgroundLoader"}) + @CommandLineFlags.Remove({"disable-features=BackgroundLoader"}) + public void testBackgroundLoaderFailureRate() throws IOException, InterruptedException { + testFailureRate(); + } }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index cd54fcc..1b7d34b 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4143,6 +4143,10 @@ "//url/mojo:url_mojom_origin__generator", ] + if (use_vulcanize) { + deps += [ "//chrome/browser/resources/md_downloads:vulcanize" ] + } + if (safe_browsing_mode > 0) { deps += [ "//chrome/browser/resources/safe_browsing:make_file_types_protobuf" ]
diff --git a/chrome/browser/android/offline_pages/evaluation/evaluation_test_scheduler.cc b/chrome/browser/android/offline_pages/evaluation/evaluation_test_scheduler.cc index 8aadb93..e782d7f 100644 --- a/chrome/browser/android/offline_pages/evaluation/evaluation_test_scheduler.cc +++ b/chrome/browser/android/offline_pages/evaluation/evaluation_test_scheduler.cc
@@ -37,13 +37,21 @@ RequestCoordinatorFactory::GetInstance()->GetForBrowserContext(profile); // TODO(romax) Maybe get current real condition. DeviceConditions device_conditions( - true, 0, net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI); + true, 0, net::NetworkChangeNotifier::GetConnectionType()); coordinator->StartImmediateProcessing(device_conditions, base::Bind(&ProcessingDoneCallback)); } } void StartProcessing() { + // If there's no network connection then try in 2 seconds. + if (net::NetworkChangeNotifier::GetConnectionType() == + net::NetworkChangeNotifier::ConnectionType::CONNECTION_NONE) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, base::Bind(&StartProcessing), + base::TimeDelta::FromSeconds(2)); + return; + } Profile* profile = ProfileManager::GetLastUsedProfile(); RequestCoordinator* coordinator = RequestCoordinatorFactory::GetInstance()->GetForBrowserContext(profile); @@ -70,9 +78,19 @@ void EvaluationTestScheduler::BackupSchedule( const TriggerConditions& trigger_conditions, - long delay_in_seconds) {} + long delay_in_seconds) { + // This method is not expected to be called in test harness. Adding a log in + // case we somehow get called here and need to implement the method. + coordinator_->GetLogger()->RecordActivity(std::string(kLogTag) + + " BackupSchedule called!"); +} -void EvaluationTestScheduler::Unschedule() {} +void EvaluationTestScheduler::Unschedule() { + // This method is not expected to be called in test harness. Adding a log in + // case we somehow get called here and need to implement the method. + coordinator_->GetLogger()->RecordActivity(std::string(kLogTag) + + " Unschedule called!"); +} void EvaluationTestScheduler::ImmediateScheduleCallback(bool result) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
diff --git a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc index e6bc455..36a153d 100644 --- a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc +++ b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
@@ -8,8 +8,10 @@ #include "base/android/jni_android.h" #include "base/android/jni_array.h" #include "base/android/jni_string.h" +#include "base/bind.h" #include "base/memory/ptr_util.h" #include "base/sequenced_task_runner.h" +#include "chrome/browser/android/offline_pages/background_loader_offliner.h" #include "chrome/browser/android/offline_pages/background_scheduler_bridge.h" #include "chrome/browser/android/offline_pages/downloads/offline_page_notification_bridge.h" #include "chrome/browser/android/offline_pages/evaluation/evaluation_test_scheduler.h" @@ -123,53 +125,11 @@ base::android::RunCallbackAndroid(j_callback_obj, int(removed_request_results.size())); } -} // namespace -static ScopedJavaLocalRef<jobject> GetBridgeForProfile( - JNIEnv* env, - const JavaParamRef<jclass>& jcaller, - const JavaParamRef<jobject>& j_profile, - const jboolean j_use_evaluation_scheduler) { - Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile); - - OfflinePageModel* offline_page_model = - OfflinePageModelFactory::GetForBrowserContext(profile); - - RequestCoordinator* request_coordinator = nullptr; - - if (j_use_evaluation_scheduler) { - request_coordinator = static_cast<RequestCoordinator*>( - RequestCoordinatorFactory::GetInstance()->SetTestingFactoryAndUse( - profile, - &OfflinePageEvaluationBridge::GetTestingRequestCoordinator)); - } else { - request_coordinator = - RequestCoordinatorFactory::GetForBrowserContext(profile); - } - - if (offline_page_model == nullptr || request_coordinator == nullptr) - return ScopedJavaLocalRef<jobject>(); - - OfflinePageEvaluationBridge* bridge = new OfflinePageEvaluationBridge( - env, profile, offline_page_model, request_coordinator); - - return ScopedJavaLocalRef<jobject>(bridge->java_ref()); -} - -// static -bool OfflinePageEvaluationBridge::Register(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static -std::unique_ptr<KeyedService> -OfflinePageEvaluationBridge::GetTestingRequestCoordinator( - content::BrowserContext* context) { - std::unique_ptr<OfflinerPolicy> policy(new OfflinerPolicy()); - std::unique_ptr<Offliner> prerenderer_offliner(new PrerenderingOffliner( - context, policy.get(), - OfflinePageModelFactory::GetForBrowserContext(context))); - +std::unique_ptr<KeyedService> GetTestingRequestCoordinator( + content::BrowserContext* context, + std::unique_ptr<OfflinerPolicy> policy, + std::unique_ptr<Offliner> offliner) { scoped_refptr<base::SequencedTaskRunner> background_task_runner = content::BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( content::BrowserThread::GetBlockingPool()->GetSequenceToken()); @@ -189,7 +149,7 @@ // dispatcher. std::unique_ptr<RequestCoordinator> request_coordinator = base::MakeUnique<RequestCoordinator>( - std::move(policy), std::move(prerenderer_offliner), std::move(queue), + std::move(policy), std::move(offliner), std::move(queue), std::move(scheduler), network_quality_estimator); request_coordinator->SetInternalStartProcessingCallbackForTest( base::Bind(&android::EvaluationTestScheduler::ImmediateScheduleCallback, @@ -202,6 +162,72 @@ return std::move(request_coordinator); } +std::unique_ptr<KeyedService> GetTestPrerenderRequestCoordinator( + content::BrowserContext* context) { + std::unique_ptr<OfflinerPolicy> policy(new OfflinerPolicy()); + std::unique_ptr<Offliner> offliner(new PrerenderingOffliner( + context, policy.get(), + OfflinePageModelFactory::GetForBrowserContext(context))); + return GetTestingRequestCoordinator(context, std::move(policy), + std::move(offliner)); +} + +std::unique_ptr<KeyedService> GetTestBackgroundLoaderRequestCoordinator( + content::BrowserContext* context) { + std::unique_ptr<OfflinerPolicy> policy(new OfflinerPolicy()); + std::unique_ptr<Offliner> offliner(new BackgroundLoaderOffliner( + context, policy.get(), + OfflinePageModelFactory::GetForBrowserContext(context))); + return GetTestingRequestCoordinator(context, std::move(policy), + std::move(offliner)); +} + +RequestCoordinator* GetRequestCoordinator(Profile* profile, + bool use_evaluation_scheduler, + bool use_background_loader) { + if (!use_evaluation_scheduler) { + return RequestCoordinatorFactory::GetForBrowserContext(profile); + } + if (use_background_loader) { + return static_cast<RequestCoordinator*>( + RequestCoordinatorFactory::GetInstance()->SetTestingFactoryAndUse( + profile, &GetTestBackgroundLoaderRequestCoordinator)); + } + return static_cast<RequestCoordinator*>( + RequestCoordinatorFactory::GetInstance()->SetTestingFactoryAndUse( + profile, &GetTestPrerenderRequestCoordinator)); +} +} // namespace + +// static +bool OfflinePageEvaluationBridge::Register(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +static ScopedJavaLocalRef<jobject> GetBridgeForProfile( + JNIEnv* env, + const JavaParamRef<jclass>& jcaller, + const JavaParamRef<jobject>& j_profile, + const jboolean j_use_evaluation_scheduler, + const jboolean j_use_background_loader) { + Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile); + + OfflinePageModel* offline_page_model = + OfflinePageModelFactory::GetForBrowserContext(profile); + + RequestCoordinator* request_coordinator = GetRequestCoordinator( + profile, static_cast<bool>(j_use_evaluation_scheduler), + static_cast<bool>(j_use_background_loader)); + + if (offline_page_model == nullptr || request_coordinator == nullptr) + return ScopedJavaLocalRef<jobject>(); + + OfflinePageEvaluationBridge* bridge = new OfflinePageEvaluationBridge( + env, profile, offline_page_model, request_coordinator); + + return ScopedJavaLocalRef<jobject>(bridge->java_ref()); +} + OfflinePageEvaluationBridge::OfflinePageEvaluationBridge( JNIEnv* env, content::BrowserContext* browser_context,
diff --git a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h index f6326174..ed92ee5 100644 --- a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h +++ b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h
@@ -30,8 +30,6 @@ public OfflineEventLogger::Client { public: static bool Register(JNIEnv* env); - static std::unique_ptr<KeyedService> GetTestingRequestCoordinator( - content::BrowserContext* context); OfflinePageEvaluationBridge(JNIEnv* env, content::BrowserContext* browser_context,
diff --git a/chrome/browser/android/offline_pages/evaluation/run_offline_page_evaluation_test.py b/chrome/browser/android/offline_pages/evaluation/run_offline_page_evaluation_test.py index 84d9bb7..5f27311 100755 --- a/chrome/browser/android/offline_pages/evaluation/run_offline_page_evaluation_test.py +++ b/chrome/browser/android/offline_pages/evaluation/run_offline_page_evaluation_test.py
@@ -29,14 +29,19 @@ DEFAULT_USER_REQUEST = True DEFAULT_USE_TEST_SCHEDULER = True +DEFAULT_USE_BACKGROUND_LOADER = False # 0 means the batch would be the whole list of urls. DEFAULT_BATCH_SIZE = 0 DEFAULT_VERBOSE = False +PRERENDER_TEST_CMD = 'OfflinePageSavePageLaterEvaluationTest.testFailureRate' +BACKGROUND_LOADER_CMD = 'OfflinePageSavePageLaterEvaluationTest.' \ + 'testBackgroundLoaderFailureRate' CONFIG_FILENAME = 'test_config' CONFIG_TEMPLATE = """\ IsUserRequested = {is_user_requested} UseTestScheduler = {use_test_scheduler} ScheduleBatchSize = {schedule_batch_size} +UseBackgroundLoader = {use_background_loader} """ @@ -87,12 +92,23 @@ parser.add_argument('build_output_dir', help='Path to build directory.') parser.add_argument( 'test_urls_file', help='Path to input file with urls to be tested.') + parser.add_argument( + '--use-background-loader', + dest='use_background_loader', + action='store_true', + help='Use background loader instead of prerenderer.') + parser.add_argument( + '--use-prerenderer', + dest='use_background_loader', + action='store_false', + help='Use prerenderer instead of background loader.') parser.set_defaults( output_dir=os.path.expanduser('~/offline_eval_output'), user_request=DEFAULT_USER_REQUEST, use_test_scheduler=DEFAULT_USE_TEST_SCHEDULER, schedule_batch_size=DEFAULT_BATCH_SIZE, - verbose=DEFAULT_VERBOSE) + verbose=DEFAULT_VERBOSE, + use_background_loader=DEFAULT_USE_BACKGROUND_LOADER) # Get the arguments and several paths. options, extra_args = parser.parse_known_args(args) @@ -131,7 +147,8 @@ CONFIG_TEMPLATE.format( is_user_requested=options.user_request, use_test_scheduler=options.use_test_scheduler, - schedule_batch_size=options.schedule_batch_size)) + schedule_batch_size=options.schedule_batch_size, + use_background_loader=options.use_background_loader)) print 'Uploading config file and input file onto the device.' subprocess.call( @@ -146,7 +163,8 @@ print CONFIG_TEMPLATE.format( is_user_requested=options.user_request, use_test_scheduler=options.use_test_scheduler, - schedule_batch_size=options.schedule_batch_size) + schedule_batch_size=options.schedule_batch_size, + use_background_loader=options.use_background_loader) # Run test with timeout-scale as 20.0 and strict mode off. # This scale is only applied to timeouts which are defined as scalable ones # in the test framework (like the timeout used to decide if Chrome doesn't @@ -158,8 +176,6 @@ # violations when writing to files. test_runner_cmd = [ test_runner_path, - '-f', - 'OfflinePageSavePageLaterEvaluationTest.testFailureRate', '--timeout-scale', '20.0', '--strict-mode', @@ -169,6 +185,11 @@ test_runner_cmd += ['-v'] if options.device_id != None: test_runner_cmd += ['-d', options.device_id] + + if options.use_background_loader: + test_runner_cmd += ['-f', BACKGROUND_LOADER_CMD] + else: + test_runner_cmd += ['-f', PRERENDER_TEST_CMD] subprocess.call(test_runner_cmd) print 'Fetching results from device...'
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index d40c062..6710125 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -13,9 +13,6 @@ <structure name="IDR_APP_LIST_START_PAGE_HTML" file="resources\app_list\start_page.html" flattenhtml="true" type="chrome_html" /> <structure name="IDR_APP_LIST_START_PAGE_JS" file="resources\app_list\start_page.js" flattenhtml="true" type="chrome_html" /> </if> - <if expr="not is_android and not use_vulcanize"> - <structure name="IDR_MD_DOWNLOADS_DOWNLOADS_HTML" file="resources\md_downloads\downloads.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> - </if> <if expr="enable_extensions"> <structure name="IDR_EXTENSIONS_HTML" file="resources\extensions\extensions.html" flattenhtml="true" type="chrome_html" /> <structure name="IDR_MD_EXTENSIONS_EXTENSIONS_HTML" file="resources\md_extensions\extensions.html" flattenhtml="true" allowexternalscript="true" type="chrome_html" /> @@ -144,10 +141,11 @@ <include name="IDR_MD_DOWNLOADS_2X_NO_DOWNLOADS_PNG" file="resources\md_downloads\2x\no_downloads.png" type="BINDATA" /> <if expr="use_vulcanize"> <then> - <include name="IDR_MD_DOWNLOADS_CRISPER_JS" file="resources\md_downloads\crisper.js" flattenhtml="true" type="BINDATA" compress="gzip" /> - <include name="IDR_MD_DOWNLOADS_VULCANIZED_HTML" file="resources\md_downloads\vulcanized.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> + <include name="IDR_MD_DOWNLOADS_VULCANIZED_HTML" file="${root_gen_dir}\chrome\browser\resources\md_downloads\vulcanized.html" use_base_dir="false" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" /> + <include name="IDR_MD_DOWNLOADS_CRISPER_JS" file="${root_gen_dir}\chrome\browser\resources\md_downloads\crisper.js" use_base_dir="false" flattenhtml="true" type="BINDATA" compress="gzip" /> </then> <else> + <include name="IDR_MD_DOWNLOADS_DOWNLOADS_HTML" file="resources\md_downloads\downloads.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_MD_DOWNLOADS_ACTION_SERVICE_HTML" file="resources\md_downloads\action_service.html" type="BINDATA" /> <include name="IDR_MD_DOWNLOADS_ACTION_SERVICE_JS" file="resources\md_downloads\action_service.js" type="BINDATA" /> <include name="IDR_MD_DOWNLOADS_CONSTANTS_HTML" file="resources\md_downloads\constants.html" type="BINDATA" />
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 2bc59ab..5436b5e 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -209,6 +209,8 @@ "app_mode/kiosk_session_plugin_handler_delegate.h", "app_mode/startup_app_launcher.cc", "app_mode/startup_app_launcher.h", + "arc/accessibility/arc_accessibility_helper_bridge.cc", + "arc/accessibility/arc_accessibility_helper_bridge.h", "arc/arc_auth_context.cc", "arc/arc_auth_context.h", "arc/arc_auth_notification.cc",
diff --git a/chrome/browser/chromeos/accessibility/accessibility_highlight_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_highlight_manager.cc index 69f935f..90024dc5 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_highlight_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_highlight_manager.cc
@@ -76,6 +76,12 @@ registered_observers_ = true; } +void AccessibilityHighlightManager::OnViewFocusedInArc( + const gfx::Rect& bounds_in_screen) { + focus_rect_ = bounds_in_screen; + UpdateFocusAndCaretHighlights(); +} + void AccessibilityHighlightManager::OnMouseEvent(ui::MouseEvent* event) { if (event->type() == ui::ET_MOUSE_MOVED) { cursor_point_ = event->location();
diff --git a/chrome/browser/chromeos/accessibility/accessibility_highlight_manager.h b/chrome/browser/chromeos/accessibility/accessibility_highlight_manager.h index bb2b5e120..facbcbb 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_highlight_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_highlight_manager.h
@@ -16,6 +16,10 @@ #include "ui/events/event.h" #include "ui/events/event_handler.h" +namespace gfx { +class Rect; +} // namespace gfx + namespace chromeos { // Manage visual highlights that Chrome OS can draw around the focused @@ -35,6 +39,10 @@ void RegisterObservers(); + // OnViewFocusedInArc is called when a view is focused in arc window and + // accessibility focus highlight is enabled. + void OnViewFocusedInArc(const gfx::Rect& bounds_in_screen); + protected: FRIEND_TEST_ALL_PREFIXES(AccessibilityFocusRingControllerTest, CursorWorksOnMultipleDisplays);
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 913c2af6..6c43cf7 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -544,6 +544,11 @@ EnableSpokenFeedback(true, ash::A11Y_NOTIFICATION_NONE); } +void AccessibilityManager::OnViewFocusedInArc( + const gfx::Rect& bounds_in_screen) { + accessibility_highlight_manager_->OnViewFocusedInArc(bounds_in_screen); +} + bool AccessibilityManager::PlayEarcon(int sound_key, PlaySoundOption option) { DCHECK(sound_key < chromeos::SOUND_COUNT); base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.h b/chrome/browser/chromeos/accessibility/accessibility_manager.h index 3da064d05..4acbe97 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.h +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.h
@@ -28,6 +28,10 @@ class Profile; +namespace gfx { +class Rect; +} // namespace gfx + namespace chromeos { class AccessibilityExtensionLoader; @@ -250,6 +254,9 @@ // Play tick sound indicating spoken feedback will be toggled after countdown. bool PlaySpokenFeedbackToggleCountdown(int tick_count); + // Notify that a view is focused in arc. + void OnViewFocusedInArc(const gfx::Rect& bounds_in_screen); + // Plays an earcon. Earcons are brief and distinctive sounds that indicate // when their mapped event has occurred. The sound key enums can be found in // chromeos/audio/chromeos_sounds.h.
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc new file mode 100644 index 0000000..6e3c1a4 --- /dev/null +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.cc
@@ -0,0 +1,63 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h" + +#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" +#include "components/arc/arc_bridge_service.h" +#include "components/exo/wm_helper.h" +#include "ui/aura/window.h" +#include "ui/gfx/geometry/rect.h" + +namespace arc { + +ArcAccessibilityHelperBridge::ArcAccessibilityHelperBridge( + ArcBridgeService* bridge_service) + : ArcService(bridge_service), binding_(this) { + arc_bridge_service()->accessibility_helper()->AddObserver(this); +} + +ArcAccessibilityHelperBridge::~ArcAccessibilityHelperBridge() { + arc_bridge_service()->accessibility_helper()->RemoveObserver(this); +} + +void ArcAccessibilityHelperBridge::OnInstanceReady() { + auto* instance = ARC_GET_INSTANCE_FOR_METHOD( + arc_bridge_service()->accessibility_helper(), Init); + DCHECK(instance); + instance->Init(binding_.CreateInterfacePtrAndBind()); +} + +void ArcAccessibilityHelperBridge::OnAccessibilityEvent( + mojom::AccessibilityEventType event_type, + mojom::AccessibilityNodeInfoDataPtr event_source) { + if (event_type != mojom::AccessibilityEventType::VIEW_FOCUSED || + event_source.is_null()) { + return; + } + + chromeos::AccessibilityManager* accessibility_manager = + chromeos::AccessibilityManager::Get(); + + if (!accessibility_manager || + !accessibility_manager->IsFocusHighlightEnabled()) { + return; + } + + exo::WMHelper* wmHelper = exo::WMHelper::GetInstance(); + + aura::Window* focused_window = wmHelper->GetFocusedWindow(); + if (!focused_window) + return; + + aura::Window* toplevel_window = focused_window->GetToplevelWindow(); + + gfx::Rect bounds_in_screen = gfx::ScaleToEnclosingRect( + event_source.get()->boundsInScreen, + 1.0f / toplevel_window->layer()->device_scale_factor()); + + accessibility_manager->OnViewFocusedInArc(bounds_in_screen); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h new file mode 100644 index 0000000..ad4abbd --- /dev/null +++ b/chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h
@@ -0,0 +1,44 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_HELPER_BRIDGE_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_HELPER_BRIDGE_H_ + +#include "components/arc/arc_service.h" +#include "components/arc/common/accessibility_helper.mojom.h" +#include "components/arc/instance_holder.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace arc { + +class ArcBridgeService; + +// ArcAccessibilityHelperBridge is an instance to receive converted Android +// accessibility events and info via mojo interface and dispatch them to chrome +// os components. +class ArcAccessibilityHelperBridge + : public ArcService, + public mojom::AccessibilityHelperHost, + public InstanceHolder<mojom::AccessibilityHelperInstance>::Observer { + public: + explicit ArcAccessibilityHelperBridge(ArcBridgeService* bridge_service); + ~ArcAccessibilityHelperBridge() override; + + // InstanceHolder<mojom::AccessibilityHelperInstance>::Observer overrides. + void OnInstanceReady() override; + + // mojom::AccessibilityHelperHost overrides. + void OnAccessibilityEvent( + mojom::AccessibilityEventType event_type, + mojom::AccessibilityNodeInfoDataPtr event_source) override; + + private: + mojo::Binding<mojom::AccessibilityHelperHost> binding_; + + DISALLOW_COPY_AND_ASSIGN(ArcAccessibilityHelperBridge); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_HELPER_BRIDGE_H_
diff --git a/chrome/browser/chromeos/arc/arc_service_launcher.cc b/chrome/browser/chromeos/arc/arc_service_launcher.cc index 1fa45a7..a20b4d7 100644 --- a/chrome/browser/chromeos/arc/arc_service_launcher.cc +++ b/chrome/browser/chromeos/arc/arc_service_launcher.cc
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "chrome/browser/chromeos/app_mode/arc/arc_kiosk_app_service.h" +#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h" #include "chrome/browser/chromeos/arc/arc_auth_service.h" #include "chrome/browser/chromeos/arc/arc_session_manager.h" #include "chrome/browser/chromeos/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" @@ -88,6 +89,8 @@ // List in lexicographical order. arc_service_manager_->AddService( + base::MakeUnique<ArcAccessibilityHelperBridge>(arc_bridge_service)); + arc_service_manager_->AddService( base::MakeUnique<ArcAudioBridge>(arc_bridge_service)); arc_service_manager_->AddService( base::MakeUnique<ArcAuthService>(arc_bridge_service));
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc index 552675f..c4aad82 100644 --- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc +++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc
@@ -118,6 +118,7 @@ // Send settings that need to be synced only on Android first start to // Android. void SyncInitialSettings() const; + void SyncFocusHighlightEnabled() const; void SyncFontSize() const; void SyncLocale() const; void SyncProxySettings() const; @@ -185,16 +186,18 @@ Profile* profile = ProfileManager::GetActiveUserProfile(); registrar_.Init(profile->GetPrefs()); + // Keep these lines ordered lexicographically. + AddPrefToObserve(prefs::kAccessibilityFocusHighlightEnabled); + AddPrefToObserve(prefs::kAccessibilitySpokenFeedbackEnabled); + AddPrefToObserve(prefs::kAccessibilityVirtualKeyboardEnabled); + AddPrefToObserve(prefs::kArcBackupRestoreEnabled); + AddPrefToObserve(prefs::kUse24HourClock); AddPrefToObserve(prefs::kWebKitDefaultFixedFontSize); AddPrefToObserve(prefs::kWebKitDefaultFontSize); AddPrefToObserve(prefs::kWebKitMinimumFontSize); - AddPrefToObserve(prefs::kAccessibilitySpokenFeedbackEnabled); - AddPrefToObserve(prefs::kUse24HourClock); - AddPrefToObserve(prefs::kArcBackupRestoreEnabled); AddPrefToObserve(proxy_config::prefs::kProxy); AddPrefToObserve(onc::prefs::kDeviceOpenNetworkConfiguration); AddPrefToObserve(onc::prefs::kOpenNetworkConfiguration); - AddPrefToObserve(prefs::kAccessibilityVirtualKeyboardEnabled); reporting_consent_subscription_ = CrosSettings::Get()->AddSettingsObserver( chromeos::kStatsReportingPref, @@ -227,6 +230,9 @@ } void ArcSettingsServiceImpl::SyncRuntimeSettings() const { + // Keep these lines ordered lexicographically. + SyncAccessibilityVirtualKeyboardEnabled(); + SyncFocusHighlightEnabled(); SyncFontSize(); SyncLocale(); SyncProxySettings(); @@ -234,7 +240,6 @@ SyncSpokenFeedbackEnabled(); SyncTimeZone(); SyncUse24HourClock(); - SyncAccessibilityVirtualKeyboardEnabled(); const PrefService* const prefs = ProfileManager::GetActiveUserProfile()->GetPrefs(); @@ -273,7 +278,9 @@ } void ArcSettingsServiceImpl::OnPrefChanged(const std::string& pref_name) const { - if (pref_name == prefs::kAccessibilitySpokenFeedbackEnabled) { + if (pref_name == prefs::kAccessibilityFocusHighlightEnabled) { + SyncFocusHighlightEnabled(); + } else if (pref_name == prefs::kAccessibilitySpokenFeedbackEnabled) { SyncSpokenFeedbackEnabled(); } else if (pref_name == prefs::kWebKitDefaultFixedFontSize || pref_name == prefs::kWebKitDefaultFontSize || @@ -342,6 +349,12 @@ SendSettingsBroadcast(action, extras); } +void ArcSettingsServiceImpl::SyncFocusHighlightEnabled() const { + SendBoolPrefSettingsBroadcast( + prefs::kAccessibilityFocusHighlightEnabled, + "org.chromium.arc.intent_helper.SET_FOCUS_HIGHLIGHT_ENABLED"); +} + void ArcSettingsServiceImpl::SyncSpokenFeedbackEnabled() const { SendBoolPrefSettingsBroadcast( prefs::kAccessibilitySpokenFeedbackEnabled,
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 7daaef1..325a624 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1795,7 +1795,10 @@ ExecuteCodeInTabFunction::~ExecuteCodeInTabFunction() {} bool ExecuteCodeInTabFunction::HasPermission() { - if (Init() && + if (Init() == SUCCESS && + // TODO(devlin/lazyboy): Consider removing the following check as it isn't + // doing anything. The fallback to ExtensionFunction::HasPermission() + // below dictates what this function returns. extension_->permissions_data()->HasAPIPermissionForTab( execute_tab_id_, APIPermission::kTab)) { return true; @@ -1803,38 +1806,40 @@ return ExtensionFunction::HasPermission(); } -bool ExecuteCodeInTabFunction::Init() { - if (details_.get()) - return true; +ExecuteCodeFunction::InitResult ExecuteCodeInTabFunction::Init() { + if (init_result_) + return init_result_.value(); // |tab_id| is optional so it's ok if it's not there. int tab_id = -1; - if (args_->GetInteger(0, &tab_id)) - EXTENSION_FUNCTION_VALIDATE(tab_id >= 0); + if (args_->GetInteger(0, &tab_id) && tab_id < 0) + return set_init_result(VALIDATION_FAILURE); // |details| are not optional. base::DictionaryValue* details_value = NULL; if (!args_->GetDictionary(1, &details_value)) - return false; + return set_init_result(VALIDATION_FAILURE); std::unique_ptr<InjectDetails> details(new InjectDetails()); if (!InjectDetails::Populate(*details_value, details.get())) - return false; + return set_init_result(VALIDATION_FAILURE); // If the tab ID wasn't given then it needs to be converted to the // currently active tab's ID. if (tab_id == -1) { Browser* browser = chrome_details_.GetCurrentBrowser(); + // Can happen during shutdown. if (!browser) - return false; + return set_init_result_error(keys::kNoCurrentWindowError); content::WebContents* web_contents = NULL; + // Can happen during shutdown. if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, &tab_id)) - return false; + return set_init_result_error(keys::kNoTabInBrowserWindowError); } execute_tab_id_ = tab_id; details_ = std::move(details); set_host_id(HostID(HostID::EXTENSIONS, extension()->id())); - return true; + return set_init_result(SUCCESS); } bool ExecuteCodeInTabFunction::CanExecuteScriptOnPage() {
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.h b/chrome/browser/extensions/api/tabs/tabs_api.h index 82b5d1b..c8e4071 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.h +++ b/chrome/browser/extensions/api/tabs/tabs_api.h
@@ -234,9 +234,8 @@ // ExtensionFunction: bool HasPermission() override; - // Initialize the |execute_tab_id_| and |details_| if they haven't already - // been. Returns whether initialization was successful. - bool Init() override; + // Initializes |execute_tab_id_| and |details_|. + InitResult Init() override; bool CanExecuteScriptOnPage() override; ScriptExecutor* GetScriptExecutor() override; bool IsWebView() const override;
diff --git a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc index 506cc94..1128010 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
@@ -5,6 +5,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/api/tabs/tabs_api.h" +#include "chrome/browser/extensions/api/tabs/tabs_constants.h" #include "chrome/browser/extensions/extension_function_test_utils.h" #include "chrome/browser/extensions/extension_service_test_base.h" #include "chrome/browser/extensions/extension_tab_util.h" @@ -270,4 +271,30 @@ base::RunLoop().RunUntilIdle(); } +// Tests that non-validation failure in tabs.executeScript results in error, and +// not bad_message. +// Regression test for https://crbug.com/642794. +TEST_F(TabsApiUnitTest, ExecuteScriptNoTabIsNonFatalError) { + // An extension with "tabs" permission. + scoped_refptr<const Extension> extension = + ExtensionBuilder() + .SetManifest( + DictionaryBuilder() + .Set("name", "Extension with tabs permission") + .Set("version", "1.0") + .Set("manifest_version", 2) + .Set("permissions", ListBuilder().Append("tabs").Build()) + .Build()) + .Build(); + scoped_refptr<TabsExecuteScriptFunction> function( + new TabsExecuteScriptFunction()); + function->set_extension(extension); + const char* kArgs = R"(["", {"code": ""}])"; + std::string error = extension_function_test_utils::RunFunctionAndReturnError( + function.get(), kArgs, + browser(), // browser() doesn't have any tabs. + extension_function_test_utils::NONE); + EXPECT_EQ(tabs_constants::kNoTabInBrowserWindowError, error); +} + } // namespace extensions
diff --git a/chrome/browser/extensions/api/tabs/tabs_constants.cc b/chrome/browser/extensions/api/tabs/tabs_constants.cc index 8df23c8..4d60c1a 100644 --- a/chrome/browser/extensions/api/tabs/tabs_constants.cc +++ b/chrome/browser/extensions/api/tabs/tabs_constants.cc
@@ -81,6 +81,7 @@ "I'm sorry. I'm afraid I can't do that."; const char kNoCurrentWindowError[] = "No current window"; const char kNoLastFocusedWindowError[] = "No last-focused window"; +const char kNoTabInBrowserWindowError[] = "There is no tab in browser window."; const char kPerOriginOnlyInAutomaticError[] = "Can only set scope to " "\"per-origin\" in \"automatic\" mode."; const char kWindowNotFoundError[] = "No window with id: *.";
diff --git a/chrome/browser/extensions/api/tabs/tabs_constants.h b/chrome/browser/extensions/api/tabs/tabs_constants.h index 92f6661..d4a399b 100644 --- a/chrome/browser/extensions/api/tabs/tabs_constants.h +++ b/chrome/browser/extensions/api/tabs/tabs_constants.h
@@ -82,6 +82,7 @@ extern const char kNoCrashBrowserError[]; extern const char kNoCurrentWindowError[]; extern const char kNoLastFocusedWindowError[]; +extern const char kNoTabInBrowserWindowError[]; extern const char kPerOriginOnlyInAutomaticError[]; extern const char kWindowNotFoundError[]; extern const char kTabIndexNotFoundError[];
diff --git a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc index d666f55..22ae267 100644 --- a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc +++ b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
@@ -15,7 +15,6 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_client.h" @@ -363,10 +362,6 @@ return browser()->tab_strip_model()->GetActiveWebContents(); } - content::RenderViewHost* render_view_host() { - return active_contents()->GetRenderViewHost(); - } - // static // Adds an <input> field to a given frame by executing javascript code. // The input can be added as the first element or the last element of @@ -911,9 +906,9 @@ } // This test tracks page level focused editable element tracking using -// RenderViewHost. In a page with multiple frames, a frame is selected and +// WebContents. In a page with multiple frames, a frame is selected and // focused. Then the <input> inside frame is both focused and blurred and and -// in both cases the test verifies that RendeViewHost is aware whether or not a +// in both cases the test verifies that WebContents is aware whether or not a // focused editable element exists on the page. IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, TrackPageFocusEditableElement) { @@ -938,17 +933,17 @@ focus_frame(frame); // Focus the <input>. set_input_focus(frame, true); - EXPECT_TRUE(render_view_host()->IsFocusedElementEditable()); + EXPECT_TRUE(active_contents()->IsFocusedElementEditable()); // No blur <input>. set_input_focus(frame, false); - EXPECT_FALSE(render_view_host()->IsFocusedElementEditable()); + EXPECT_FALSE(active_contents()->IsFocusedElementEditable()); } } // TODO(ekaramad): Could this become a unit test instead? // This test focuses <input> elements on the page and verifies that -// RenderViewHost knows about the focused editable element. Then it asks the -// RenderViewHost to clear focused element and verifies that there is no longer +// WebContents knows about the focused editable element. Then it asks the +// WebContents to clear focused element and verifies that there is no longer // a focused editable element on the page. IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, ClearFocusedElementOnPage) { @@ -967,9 +962,9 @@ for (auto* frame : frames) { focus_frame_and_input(frame); - EXPECT_TRUE(render_view_host()->IsFocusedElementEditable()); - render_view_host()->ClearFocusedElement(); - EXPECT_FALSE(render_view_host()->IsFocusedElementEditable()); + EXPECT_TRUE(active_contents()->IsFocusedElementEditable()); + active_contents()->ClearFocusedElement(); + EXPECT_FALSE(active_contents()->IsFocusedElementEditable()); } }
diff --git a/chrome/browser/resources/chromeos/first_run/app/main.html b/chrome/browser/resources/chromeos/first_run/app/main.html index a8c6df8..32e52a3 100644 --- a/chrome/browser/resources/chromeos/first_run/app/main.html +++ b/chrome/browser/resources/chromeos/first_run/app/main.html
@@ -26,14 +26,14 @@ </div> </div> </div> - <h1>$i18n{greetingHeader}</h1> + <h1 i18n-content="greetingHeader"></h1> <p> - <span>$i18n{greetingText1}</span><br> - <span>$i18n{greetingText2}</span> + <span i18n-content="greetingText1"></span><br> + <span i18n-content="greetingText2"></span> </p> <div class="controls"> - <button class="next-button custom-appearance blue-button" tabindex="0"> - $i18n{greetingButton} + <button i18n-content="greetingButton" + class="next-button custom-appearance blue-button" tabindex="0"> </button> </div> <include src="greeting_image_[GREETING_IMAGE].html">
diff --git a/chrome/browser/resources/chromeos/first_run/app_list_step.html b/chrome/browser/resources/chromeos/first_run/app_list_step.html index 7cb2e4d..bdc51ce 100644 --- a/chrome/browser/resources/chromeos/first_run/app_list_step.html +++ b/chrome/browser/resources/chromeos/first_run/app_list_step.html
@@ -1,12 +1,11 @@ <div id="app-list" class="step bubble transparent hidden"> - <h1>$i18n{appListHeader}</h1> + <h1 i18n-content="appListHeader"></h1> <p> - <span>$i18n{appListText1}</span><br> - <span>$i18n{appListText2}</span> + <span i18n-content="appListText1"></span><br> + <span i18n-content="appListText2"></span> </p> <div class="controls"> - <button class="next-button custom-appearance blue-button"> - $i18n{nextButton} - </button> + <button i18n-content="nextButton" + class="next-button custom-appearance blue-button"></button> </div> </div>
diff --git a/chrome/browser/resources/chromeos/first_run/help_step.html b/chrome/browser/resources/chromeos/first_run/help_step.html index 44659862..0a9c513 100644 --- a/chrome/browser/resources/chromeos/first_run/help_step.html +++ b/chrome/browser/resources/chromeos/first_run/help_step.html
@@ -1,14 +1,12 @@ <div id="help" class="step bubble transparent hidden"> <div id="completion-image"></div> - <h1>$i18n{helpHeader}</h1> - <p>$i18n{helpText1}</p> - <p>$i18n{helpText2}</p> + <h1 i18n-content="helpHeader"></h1> + <p i18n-content="helpText1"></p> + <p i18n-content="helpText2"></p> <div class="controls"> - <button class="help-button custom-appearance blue-button"> - $i18n{helpKeepExploringButton} - </button> - <button class="next-button custom-appearance white-button"> - $i18n{helpFinishButton} - </button> + <button i18n-content="helpKeepExploringButton" + class="help-button custom-appearance blue-button"></button> + <button i18n-content="helpFinishButton" + class="next-button custom-appearance white-button"></button> </div> </div>
diff --git a/chrome/browser/resources/chromeos/first_run/tray_step.html b/chrome/browser/resources/chromeos/first_run/tray_step.html index ed96e21..2b7b9e7 100644 --- a/chrome/browser/resources/chromeos/first_run/tray_step.html +++ b/chrome/browser/resources/chromeos/first_run/tray_step.html
@@ -1,9 +1,8 @@ <div id="tray" class="step bubble transparent hidden"> - <h1>$i18n{trayHeader}</h1> - <p>$i18n{trayText}<p> + <h1 i18n-content="trayHeader"></h1> + <p i18n-content="trayText"><p> <div class="controls"> - <button class="next-button custom-appearance blue-button"> - $i18n{nextButton} - </button> + <button i18n-content="nextButton" + class="next-button custom-appearance blue-button"></button> </div> </div>
diff --git a/chrome/browser/resources/md_bookmarks/PRESUBMIT.py b/chrome/browser/resources/md_bookmarks/PRESUBMIT.py new file mode 100644 index 0000000..1b816b29 --- /dev/null +++ b/chrome/browser/resources/md_bookmarks/PRESUBMIT.py
@@ -0,0 +1,7 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +def CheckChangeOnUpload(input_api, output_api): + return input_api.canned_checks.CheckPatchFormatted( + input_api, output_api, check_js=True)
diff --git a/chrome/browser/resources/md_downloads/BUILD.gn b/chrome/browser/resources/md_downloads/BUILD.gn new file mode 100644 index 0000000..1dc2cab --- /dev/null +++ b/chrome/browser/resources/md_downloads/BUILD.gn
@@ -0,0 +1,12 @@ +import("../vulcanize.gni") + +vulcanize("vulcanize") { + host = "downloads" + html_in_file = "downloads.html" + html_out_file = "vulcanized.html" + + input_type = "FOLDER" + input = rebase_path(".", root_build_dir) + js_out_file = "crisper.js" + deps = [] +}
diff --git a/chrome/browser/resources/md_downloads/compiled_resources2.gyp b/chrome/browser/resources/md_downloads/compiled_resources2.gyp index be6ef51..9d15a90 100644 --- a/chrome/browser/resources/md_downloads/compiled_resources2.gyp +++ b/chrome/browser/resources/md_downloads/compiled_resources2.gyp
@@ -64,6 +64,7 @@ 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', + '<(DEPTH)/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp:cr_action_menu', '<(DEPTH)/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp:cr_toolbar', '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-menu/compiled_resources2.gyp:paper-menu-extracted', 'action_service',
diff --git a/chrome/browser/resources/md_downloads/crisper.js b/chrome/browser/resources/md_downloads/crisper.js deleted file mode 100644 index e28586a1..0000000 --- a/chrome/browser/resources/md_downloads/crisper.js +++ /dev/null
@@ -1,71 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -function assert(condition,opt_message){if(!condition){var message="Assertion failed";if(opt_message)message=message+": "+opt_message;var error=new Error(message);var global=function(){return this}();if(global.traceAssertionsForTesting)console.warn(error.stack);throw error}return condition}function assertNotReached(opt_message){assert(false,opt_message||"Unreachable code hit")}function assertInstanceof(value,type,opt_message){if(!(value instanceof type)){assertNotReached(opt_message||"Value "+value+" is not a[n] "+(type.name||typeof type))}return value} -// 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. -function PromiseResolver(){this.resolve_;this.reject_;this.promise_=new Promise(function(resolve,reject){this.resolve_=resolve;this.reject_=reject}.bind(this))}PromiseResolver.prototype={get promise(){return this.promise_},set promise(p){assertNotReached()},get resolve(){return this.resolve_},set resolve(r){assertNotReached()},get reject(){return this.reject_},set reject(s){assertNotReached()}}; -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -var global=this;var WebUIListener;var cr=cr||function(){"use strict";function exportPath(name,opt_object,opt_objectToExportTo){var parts=name.split(".");var cur=opt_objectToExportTo||global;for(var part;parts.length&&(part=parts.shift());){if(!parts.length&&opt_object!==undefined){cur[part]=opt_object}else if(part in cur){cur=cur[part]}else{cur=cur[part]={}}}return cur}function dispatchPropertyChange(target,propertyName,newValue,oldValue){var e=new Event(propertyName+"Change");e.propertyName=propertyName;e.newValue=newValue;e.oldValue=oldValue;target.dispatchEvent(e)}function getAttributeName(jsName){return jsName.replace(/([A-Z])/g,"-$1").toLowerCase()}var PropertyKind={JS:"js",ATTR:"attr",BOOL_ATTR:"boolAttr"};function getGetter(name,kind){switch(kind){case PropertyKind.JS:var privateName=name+"_";return function(){return this[privateName]};case PropertyKind.ATTR:var attributeName=getAttributeName(name);return function(){return this.getAttribute(attributeName)};case PropertyKind.BOOL_ATTR:var attributeName=getAttributeName(name);return function(){return this.hasAttribute(attributeName)}}throw"not reached"}function getSetter(name,kind,opt_setHook){switch(kind){case PropertyKind.JS:var privateName=name+"_";return function(value){var oldValue=this[name];if(value!==oldValue){this[privateName]=value;if(opt_setHook)opt_setHook.call(this,value,oldValue);dispatchPropertyChange(this,name,value,oldValue)}};case PropertyKind.ATTR:var attributeName=getAttributeName(name);return function(value){var oldValue=this[name];if(value!==oldValue){if(value==undefined)this.removeAttribute(attributeName);else this.setAttribute(attributeName,value);if(opt_setHook)opt_setHook.call(this,value,oldValue);dispatchPropertyChange(this,name,value,oldValue)}};case PropertyKind.BOOL_ATTR:var attributeName=getAttributeName(name);return function(value){var oldValue=this[name];if(value!==oldValue){if(value)this.setAttribute(attributeName,name);else this.removeAttribute(attributeName);if(opt_setHook)opt_setHook.call(this,value,oldValue);dispatchPropertyChange(this,name,value,oldValue)}}}throw"not reached"}function defineProperty(obj,name,opt_kind,opt_setHook){if(typeof obj=="function")obj=obj.prototype;var kind=opt_kind||PropertyKind.JS;if(!obj.__lookupGetter__(name))obj.__defineGetter__(name,getGetter(name,kind));if(!obj.__lookupSetter__(name))obj.__defineSetter__(name,getSetter(name,kind,opt_setHook))}var uidCounter=1;function createUid(){return uidCounter++}function getUid(item){if(item.hasOwnProperty("uid"))return item.uid;return item.uid=createUid()}function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable){var e=new Event(type,{bubbles:opt_bubbles,cancelable:opt_cancelable===undefined||opt_cancelable});return target.dispatchEvent(e)}function define(name,fun){var obj=exportPath(name);var exports=fun();for(var propertyName in exports){var propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor)Object.defineProperty(obj,propertyName,propertyDescriptor)}}function addSingletonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instance_=new ctor)}}function makePublic(ctor,methods,opt_target){methods.forEach(function(method){ctor[method]=function(){var target=opt_target?document.getElementById(opt_target):ctor.getInstance();return target[method+"_"].apply(target,arguments)}})}var chromeSendResolverMap={};function webUIResponse(id,isSuccess,response){var resolver=chromeSendResolverMap[id];delete chromeSendResolverMap[id];if(isSuccess)resolver.resolve(response);else resolver.reject(response)}function sendWithPromise(methodName,var_args){var args=Array.prototype.slice.call(arguments,1);var promiseResolver=new PromiseResolver;var id=methodName+"_"+createUid();chromeSendResolverMap[id]=promiseResolver;chrome.send(methodName,[id].concat(args));return promiseResolver.promise}var webUIListenerMap={};function webUIListenerCallback(event,var_args){var eventListenersMap=webUIListenerMap[event];if(!eventListenersMap){return}var args=Array.prototype.slice.call(arguments,1);for(var listenerId in eventListenersMap){eventListenersMap[listenerId].apply(null,args)}}function addWebUIListener(eventName,callback){webUIListenerMap[eventName]=webUIListenerMap[eventName]||{};var uid=createUid();webUIListenerMap[eventName][uid]=callback;return{eventName:eventName,uid:uid}}function removeWebUIListener(listener){var listenerExists=webUIListenerMap[listener.eventName]&&webUIListenerMap[listener.eventName][listener.uid];if(listenerExists){delete webUIListenerMap[listener.eventName][listener.uid];return true}return false}return{addSingletonGetter:addSingletonGetter,createUid:createUid,define:define,defineProperty:defineProperty,dispatchPropertyChange:dispatchPropertyChange,dispatchSimpleEvent:dispatchSimpleEvent,exportPath:exportPath,getUid:getUid,makePublic:makePublic,PropertyKind:PropertyKind,addWebUIListener:addWebUIListener,removeWebUIListener:removeWebUIListener,sendWithPromise:sendWithPromise,webUIListenerCallback:webUIListenerCallback,webUIResponse:webUIResponse,get doc(){return document},get isMac(){return/Mac/.test(navigator.platform)},get isWindows(){return/Win/.test(navigator.platform)},get isChromeOS(){return/CrOS/.test(navigator.userAgent)},get isLinux(){return/Linux/.test(navigator.userAgent)},get isAndroid(){return/Android/.test(navigator.userAgent)},get isIOS(){return/iPad|iPhone|iPod/.test(navigator.platform)}}}(); -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -cr.define("cr.ui",function(){function decorate(source,constr){var elements;if(typeof source=="string")elements=cr.doc.querySelectorAll(source);else elements=[source];for(var i=0,el;el=elements[i];i++){if(!(el instanceof constr))constr.decorate(el)}}function createElementHelper(tagName,opt_bag){var doc;if(opt_bag&&opt_bag.ownerDocument)doc=opt_bag.ownerDocument;else doc=cr.doc;return doc.createElement(tagName)}function define(tagNameOrFunction){var createFunction,tagName;if(typeof tagNameOrFunction=="function"){createFunction=tagNameOrFunction;tagName=""}else{createFunction=createElementHelper;tagName=tagNameOrFunction}function f(opt_propertyBag){var el=createFunction(tagName,opt_propertyBag);f.decorate(el);for(var propertyName in opt_propertyBag){el[propertyName]=opt_propertyBag[propertyName]}return el}f.decorate=function(el){el.__proto__=f.prototype;el.decorate()};return f}function limitInputWidth(el,parentEl,min,opt_scale){el.style.width="10px";var doc=el.ownerDocument;var win=doc.defaultView;var computedStyle=win.getComputedStyle(el);var parentComputedStyle=win.getComputedStyle(parentEl);var rtl=computedStyle.direction=="rtl";var inputRect=el.getBoundingClientRect();var parentRect=parentEl.getBoundingClientRect();var startPos=rtl?parentRect.right-inputRect.right:inputRect.left-parentRect.left;var inner=parseInt(computedStyle.borderLeftWidth,10)+parseInt(computedStyle.paddingLeft,10)+parseInt(computedStyle.paddingRight,10)+parseInt(computedStyle.borderRightWidth,10);var parentPadding=rtl?parseInt(parentComputedStyle.paddingLeft,10):parseInt(parentComputedStyle.paddingRight,10);var max=parentEl.clientWidth-startPos-inner-parentPadding;if(opt_scale)max*=opt_scale;function limit(){if(el.scrollWidth>max){el.style.width=max+"px"}else{el.style.width=0;var sw=el.scrollWidth;if(sw<min){el.style.width=min+"px"}else{el.style.width=sw+"px"}}}el.addEventListener("input",limit);limit()}function toCssPx(pixels){if(!window.isFinite(pixels))console.error("Pixel value is not a number: "+pixels);return Math.round(pixels)+"px"}function swallowDoubleClick(e){var doc=e.target.ownerDocument;var counter=Math.min(1,e.detail);function swallow(e){e.stopPropagation();e.preventDefault()}function onclick(e){if(e.detail>counter){counter=e.detail;swallow(e)}else{doc.removeEventListener("dblclick",swallow,true);doc.removeEventListener("click",onclick,true)}}setTimeout(function(){doc.addEventListener("click",onclick,true);doc.addEventListener("dblclick",swallow,true)},0)}return{decorate:decorate,define:define,limitInputWidth:limitInputWidth,toCssPx:toCssPx,swallowDoubleClick:swallowDoubleClick}}); -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -cr.define("cr.ui",function(){function KeyboardShortcut(shortcut){var mods={};var ident="";shortcut.split("|").forEach(function(part){var partLc=part.toLowerCase();switch(partLc){case"alt":case"ctrl":case"meta":case"shift":mods[partLc+"Key"]=true;break;default:if(ident)throw Error("Invalid shortcut");ident=part}});this.ident_=ident;this.mods_=mods}KeyboardShortcut.prototype={matchesEvent:function(e){if(e.key==this.ident_){var mods=this.mods_;return["altKey","ctrlKey","metaKey","shiftKey"].every(function(k){return e[k]==!!mods[k]})}return false}};var Command=cr.ui.define("command");Command.prototype={__proto__:HTMLElement.prototype,decorate:function(){CommandManager.init(assert(this.ownerDocument));if(this.hasAttribute("shortcut"))this.shortcut=this.getAttribute("shortcut")},execute:function(opt_element){if(this.disabled)return;var doc=this.ownerDocument;if(doc.activeElement){var e=new Event("command",{bubbles:true});e.command=this;(opt_element||doc.activeElement).dispatchEvent(e)}},canExecuteChange:function(opt_node){dispatchCanExecuteEvent(this,opt_node||this.ownerDocument.activeElement)},shortcut_:"",get shortcut(){return this.shortcut_},set shortcut(shortcut){var oldShortcut=this.shortcut_;if(shortcut!==oldShortcut){this.keyboardShortcuts_=shortcut.split(/\s+/).map(function(shortcut){return new KeyboardShortcut(shortcut)});this.shortcut_=shortcut;cr.dispatchPropertyChange(this,"shortcut",this.shortcut_,oldShortcut)}},matchesEvent:function(e){if(!this.keyboardShortcuts_)return false;return this.keyboardShortcuts_.some(function(keyboardShortcut){return keyboardShortcut.matchesEvent(e)})}};cr.defineProperty(Command,"label",cr.PropertyKind.ATTR);cr.defineProperty(Command,"disabled",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"hidden",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"checked",cr.PropertyKind.BOOL_ATTR);cr.defineProperty(Command,"hideShortcutText",cr.PropertyKind.BOOL_ATTR);function dispatchCanExecuteEvent(command,target){var e=new CanExecuteEvent(command);target.dispatchEvent(e);command.disabled=!e.canExecute}var commandManagers={};function CommandManager(doc){doc.addEventListener("focus",this.handleFocus_.bind(this),true);doc.addEventListener("keydown",this.handleKeyDown_.bind(this),false)}CommandManager.init=function(doc){var uid=cr.getUid(doc);if(!(uid in commandManagers)){commandManagers[uid]=new CommandManager(doc)}};CommandManager.prototype={handleFocus_:function(e){var target=e.target;if(target.menu||target.command)return;var commands=Array.prototype.slice.call(target.ownerDocument.querySelectorAll("command"));commands.forEach(function(command){dispatchCanExecuteEvent(command,target)})},handleKeyDown_:function(e){var target=e.target;var commands=Array.prototype.slice.call(target.ownerDocument.querySelectorAll("command"));for(var i=0,command;command=commands[i];i++){if(command.matchesEvent(e)){command.canExecuteChange();if(!command.disabled){e.preventDefault();e.stopPropagation();command.execute();return}}}}};function CanExecuteEvent(command){var e=new Event("canExecute",{bubbles:true,cancelable:true});e.__proto__=CanExecuteEvent.prototype;e.command=command;return e}CanExecuteEvent.prototype={__proto__:Event.prototype,command:null,canExecute_:false,get canExecute(){return this.canExecute_},set canExecute(canExecute){this.canExecute_=!!canExecute;this.stopPropagation();this.preventDefault()}};return{Command:Command,CanExecuteEvent:CanExecuteEvent}}); -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -function $(id){var el=document.getElementById(id);return el?assertInstanceof(el,HTMLElement):null}function getSVGElement(id){var el=document.getElementById(id);return el?assertInstanceof(el,Element):null}function announceAccessibleMessage(msg){var element=document.createElement("div");element.setAttribute("aria-live","polite");element.style.position="fixed";element.style.left="-9999px";element.style.height="0px";element.innerText=msg;document.body.appendChild(element);window.setTimeout(function(){document.body.removeChild(element)},0)}function url(s){var s2=s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g,"\\$1");if(/\\\\$/.test(s2)){s2+=" "}return'url("'+s2+'")'}function parseQueryParams(location){var params={};var query=unescape(location.search.substring(1));var vars=query.split("&");for(var i=0;i<vars.length;i++){var pair=vars[i].split("=");params[pair[0]]=pair[1]}return params}function setQueryParam(location,key,value){var query=parseQueryParams(location);query[encodeURIComponent(key)]=encodeURIComponent(value);var newQuery="";for(var q in query){newQuery+=(newQuery?"&":"?")+q+"="+query[q]}return location.origin+location.pathname+newQuery+location.hash}function findAncestorByClass(el,className){return findAncestor(el,function(el){return el.classList&&el.classList.contains(className)})}function findAncestor(node,predicate){var last=false;while(node!=null&&!(last=predicate(node))){node=node.parentNode}return last?node:null}function swapDomNodes(a,b){var afterA=a.nextSibling;if(afterA==b){swapDomNodes(b,a);return}var aParent=a.parentNode;b.parentNode.replaceChild(a,b);aParent.insertBefore(b,afterA)}function disableTextSelectAndDrag(opt_allowSelectStart,opt_allowDragStart){document.onselectstart=function(e){if(!(opt_allowSelectStart&&opt_allowSelectStart.call(this,e)))e.preventDefault()};document.ondragstart=function(e){if(!(opt_allowDragStart&&opt_allowDragStart.call(this,e)))e.preventDefault()}}function preventDefaultOnPoundLinkClicks(){document.addEventListener("click",function(e){var anchor=findAncestor(e.target,function(el){return el.tagName=="A"});if(anchor&&anchor.getAttribute("href")=="#")e.preventDefault()})}function isRTL(){return document.documentElement.dir=="rtl"}function getRequiredElement(id){return assertInstanceof($(id),HTMLElement,"Missing required element: "+id)}function queryRequiredElement(selectors,opt_context){var element=(opt_context||document).querySelector(selectors);return assertInstanceof(element,HTMLElement,"Missing required element: "+selectors)}["click","auxclick"].forEach(function(eventName){document.addEventListener(eventName,function(e){if(e.button>1)return;if(e.defaultPrevented)return;var eventPath=e.path;var anchor=null;if(eventPath){for(var i=0;i<eventPath.length;i++){var element=eventPath[i];if(element.tagName==="A"&&element.href){anchor=element;break}}}var el=e.target;if(!anchor&&el.nodeType==Node.ELEMENT_NODE&&el.webkitMatchesSelector("A, A *")){while(el.tagName!="A"){el=el.parentElement}anchor=el}if(!anchor)return;anchor=anchor;if((anchor.protocol=="file:"||anchor.protocol=="about:")&&(e.button==0||e.button==1)){chrome.send("navigateToUrl",[anchor.href,anchor.target,e.button,e.altKey,e.ctrlKey,e.metaKey,e.shiftKey]);e.preventDefault()}})});function appendParam(url,key,value){var param=encodeURIComponent(key)+"="+encodeURIComponent(value);if(url.indexOf("?")==-1)return url+"?"+param;return url+"&"+param}function createElementWithClassName(type,className){var elm=document.createElement(type);elm.className=className;return elm}function ensureTransitionEndEvent(el,opt_timeOut){if(opt_timeOut===undefined){var style=getComputedStyle(el);opt_timeOut=parseFloat(style.transitionDuration)*1e3;opt_timeOut+=50}var fired=false;el.addEventListener("webkitTransitionEnd",function f(e){el.removeEventListener("webkitTransitionEnd",f);fired=true});window.setTimeout(function(){if(!fired)cr.dispatchSimpleEvent(el,"webkitTransitionEnd",true)},opt_timeOut)}function scrollTopForDocument(doc){return doc.documentElement.scrollTop||doc.body.scrollTop}function setScrollTopForDocument(doc,value){doc.documentElement.scrollTop=doc.body.scrollTop=value}function scrollLeftForDocument(doc){return doc.documentElement.scrollLeft||doc.body.scrollLeft}function setScrollLeftForDocument(doc,value){doc.documentElement.scrollLeft=doc.body.scrollLeft=value}function HTMLEscape(original){return original.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function elide(original,maxLength){if(original.length<=maxLength)return original;return original.substring(0,maxLength-1)+"…"}function quoteString(str){return str.replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g,"\\$1")}function listenOnce(target,eventNames,callback){if(!Array.isArray(eventNames))eventNames=eventNames.split(/ +/);var removeAllAndCallCallback=function(event){eventNames.forEach(function(eventName){target.removeEventListener(eventName,removeAllAndCallCallback,false)});return callback(event)};eventNames.forEach(function(eventName){target.addEventListener(eventName,removeAllAndCallCallback,false)})} -// <if expr="is_ios"> -if(!("key"in KeyboardEvent.prototype)){Object.defineProperty(KeyboardEvent.prototype,"key",{get:function(){if(this.keyCode>=48&&this.keyCode<=57)return String.fromCharCode(this.keyCode);if(this.keyCode>=65&&this.keyCode<=90){var result=String.fromCharCode(this.keyCode).toLowerCase();if(this.shiftKey)result=result.toUpperCase();return result}switch(this.keyCode){case 8:return"Backspace";case 9:return"Tab";case 13:return"Enter";case 16:return"Shift";case 17:return"Control";case 18:return"Alt";case 27:return"Escape";case 32:return" ";case 33:return"PageUp";case 34:return"PageDown";case 35:return"End";case 36:return"Home";case 37:return"ArrowLeft";case 38:return"ArrowUp";case 39:return"ArrowRight";case 40:return"ArrowDown";case 45:return"Insert";case 46:return"Delete";case 91:return"Meta";case 112:return"F1";case 113:return"F2";case 114:return"F3";case 115:return"F4";case 116:return"F5";case 117:return"F6";case 118:return"F7";case 119:return"F8";case 120:return"F9";case 121:return"F10";case 122:return"F11";case 123:return"F12";case 187:return"=";case 189:return"-";case 219:return"[";case 221:return"]"}return"Unidentified"}})}else{window.console.log("KeyboardEvent.Key polyfill not required")} -// </if> /* is_ios */ -function importModules(moduleNames){return new Promise(function(resolve){define(moduleNames,function(){resolve(Array.from(arguments))})})}function hasKeyModifiers(e){return!!(e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)}Polymer.IronResizableBehavior={properties:{_parentResizable:{type:Object,observer:"_parentResizableChanged"},_notifyingDescendant:{type:Boolean,value:false}},listeners:{"iron-request-resize-notifications":"_onIronRequestResizeNotifications"},created:function(){this._interestedResizables=[];this._boundNotifyResize=this.notifyResize.bind(this)},attached:function(){this.fire("iron-request-resize-notifications",null,{node:this,bubbles:true,cancelable:true});if(!this._parentResizable){window.addEventListener("resize",this._boundNotifyResize);this.notifyResize()}},detached:function(){if(this._parentResizable){this._parentResizable.stopResizeNotificationsFor(this)}else{window.removeEventListener("resize",this._boundNotifyResize)}this._parentResizable=null},notifyResize:function(){if(!this.isAttached){return}this._interestedResizables.forEach(function(resizable){if(this.resizerShouldNotify(resizable)){this._notifyDescendant(resizable)}},this);this._fireResize()},assignParentResizable:function(parentResizable){this._parentResizable=parentResizable},stopResizeNotificationsFor:function(target){var index=this._interestedResizables.indexOf(target);if(index>-1){this._interestedResizables.splice(index,1);this.unlisten(target,"iron-resize","_onDescendantIronResize")}},resizerShouldNotify:function(element){return true},_onDescendantIronResize:function(event){if(this._notifyingDescendant){event.stopPropagation();return}if(!Polymer.Settings.useShadow){this._fireResize()}},_fireResize:function(){this.fire("iron-resize",null,{node:this,bubbles:false})},_onIronRequestResizeNotifications:function(event){var target=event.path?event.path[0]:event.target;if(target===this){return}if(this._interestedResizables.indexOf(target)===-1){this._interestedResizables.push(target);this.listen(target,"iron-resize","_onDescendantIronResize")}target.assignParentResizable(this);this._notifyDescendant(target);event.stopPropagation()},_parentResizableChanged:function(parentResizable){if(parentResizable){window.removeEventListener("resize",this._boundNotifyResize)}},_notifyDescendant:function(descendant){if(!this.isAttached){return}this._notifyingDescendant=true;descendant.notifyResize();this._notifyingDescendant=false}};(function(){"use strict";var KEY_IDENTIFIER={"U+0008":"backspace","U+0009":"tab","U+001B":"esc","U+0020":"space","U+007F":"del"};var KEY_CODE={8:"backspace",9:"tab",13:"enter",27:"esc",33:"pageup",34:"pagedown",35:"end",36:"home",32:"space",37:"left",38:"up",39:"right",40:"down",46:"del",106:"*"};var MODIFIER_KEYS={shift:"shiftKey",ctrl:"ctrlKey",alt:"altKey",meta:"metaKey"};var KEY_CHAR=/[a-z0-9*]/;var IDENT_CHAR=/U\+/;var ARROW_KEY=/^arrow/;var SPACE_KEY=/^space(bar)?/;var ESC_KEY=/^escape$/;function transformKey(key,noSpecialChars){var validKey="";if(key){var lKey=key.toLowerCase();if(lKey===" "||SPACE_KEY.test(lKey)){validKey="space"}else if(ESC_KEY.test(lKey)){validKey="esc"}else if(lKey.length==1){if(!noSpecialChars||KEY_CHAR.test(lKey)){validKey=lKey}}else if(ARROW_KEY.test(lKey)){validKey=lKey.replace("arrow","")}else if(lKey=="multiply"){validKey="*"}else{validKey=lKey}}return validKey}function transformKeyIdentifier(keyIdent){var validKey="";if(keyIdent){if(keyIdent in KEY_IDENTIFIER){validKey=KEY_IDENTIFIER[keyIdent]}else if(IDENT_CHAR.test(keyIdent)){keyIdent=parseInt(keyIdent.replace("U+","0x"),16);validKey=String.fromCharCode(keyIdent).toLowerCase()}else{validKey=keyIdent.toLowerCase()}}return validKey}function transformKeyCode(keyCode){var validKey="";if(Number(keyCode)){if(keyCode>=65&&keyCode<=90){validKey=String.fromCharCode(32+keyCode)}else if(keyCode>=112&&keyCode<=123){validKey="f"+(keyCode-112)}else if(keyCode>=48&&keyCode<=57){validKey=String(keyCode-48)}else if(keyCode>=96&&keyCode<=105){validKey=String(keyCode-96)}else{validKey=KEY_CODE[keyCode]}}return validKey}function normalizedKeyForEvent(keyEvent,noSpecialChars){if(keyEvent.key){return transformKey(keyEvent.key,noSpecialChars)}if(keyEvent.detail&&keyEvent.detail.key){return transformKey(keyEvent.detail.key,noSpecialChars)}return transformKeyIdentifier(keyEvent.keyIdentifier)||transformKeyCode(keyEvent.keyCode)||""}function keyComboMatchesEvent(keyCombo,event){var keyEvent=normalizedKeyForEvent(event,keyCombo.hasModifiers);return keyEvent===keyCombo.key&&(!keyCombo.hasModifiers||!!event.shiftKey===!!keyCombo.shiftKey&&!!event.ctrlKey===!!keyCombo.ctrlKey&&!!event.altKey===!!keyCombo.altKey&&!!event.metaKey===!!keyCombo.metaKey)}function parseKeyComboString(keyComboString){if(keyComboString.length===1){return{combo:keyComboString,key:keyComboString,event:"keydown"}}return keyComboString.split("+").reduce(function(parsedKeyCombo,keyComboPart){var eventParts=keyComboPart.split(":");var keyName=eventParts[0];var event=eventParts[1];if(keyName in MODIFIER_KEYS){parsedKeyCombo[MODIFIER_KEYS[keyName]]=true;parsedKeyCombo.hasModifiers=true}else{parsedKeyCombo.key=keyName;parsedKeyCombo.event=event||"keydown"}return parsedKeyCombo},{combo:keyComboString.split(":").shift()})}function parseEventString(eventString){return eventString.trim().split(" ").map(function(keyComboString){return parseKeyComboString(keyComboString)})}Polymer.IronA11yKeysBehavior={properties:{keyEventTarget:{type:Object,value:function(){return this}},stopKeyboardEventPropagation:{type:Boolean,value:false},_boundKeyHandlers:{type:Array,value:function(){return[]}},_imperativeKeyBindings:{type:Object,value:function(){return{}}}},observers:["_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)"],keyBindings:{},registered:function(){this._prepKeyBindings()},attached:function(){this._listenKeyEventListeners()},detached:function(){this._unlistenKeyEventListeners()},addOwnKeyBinding:function(eventString,handlerName){this._imperativeKeyBindings[eventString]=handlerName;this._prepKeyBindings();this._resetKeyEventListeners()},removeOwnKeyBindings:function(){this._imperativeKeyBindings={};this._prepKeyBindings();this._resetKeyEventListeners()},keyboardEventMatchesKeys:function(event,eventString){var keyCombos=parseEventString(eventString);for(var i=0;i<keyCombos.length;++i){if(keyComboMatchesEvent(keyCombos[i],event)){return true}}return false},_collectKeyBindings:function(){var keyBindings=this.behaviors.map(function(behavior){return behavior.keyBindings});if(keyBindings.indexOf(this.keyBindings)===-1){keyBindings.push(this.keyBindings)}return keyBindings},_prepKeyBindings:function(){this._keyBindings={};this._collectKeyBindings().forEach(function(keyBindings){for(var eventString in keyBindings){this._addKeyBinding(eventString,keyBindings[eventString])}},this);for(var eventString in this._imperativeKeyBindings){this._addKeyBinding(eventString,this._imperativeKeyBindings[eventString])}for(var eventName in this._keyBindings){this._keyBindings[eventName].sort(function(kb1,kb2){var b1=kb1[0].hasModifiers;var b2=kb2[0].hasModifiers;return b1===b2?0:b1?-1:1})}},_addKeyBinding:function(eventString,handlerName){parseEventString(eventString).forEach(function(keyCombo){this._keyBindings[keyCombo.event]=this._keyBindings[keyCombo.event]||[];this._keyBindings[keyCombo.event].push([keyCombo,handlerName])},this)},_resetKeyEventListeners:function(){this._unlistenKeyEventListeners();if(this.isAttached){this._listenKeyEventListeners()}},_listenKeyEventListeners:function(){if(!this.keyEventTarget){return}Object.keys(this._keyBindings).forEach(function(eventName){var keyBindings=this._keyBindings[eventName];var boundKeyHandler=this._onKeyBindingEvent.bind(this,keyBindings);this._boundKeyHandlers.push([this.keyEventTarget,eventName,boundKeyHandler]);this.keyEventTarget.addEventListener(eventName,boundKeyHandler)},this)},_unlistenKeyEventListeners:function(){var keyHandlerTuple;var keyEventTarget;var eventName;var boundKeyHandler;while(this._boundKeyHandlers.length){keyHandlerTuple=this._boundKeyHandlers.pop();keyEventTarget=keyHandlerTuple[0];eventName=keyHandlerTuple[1];boundKeyHandler=keyHandlerTuple[2];keyEventTarget.removeEventListener(eventName,boundKeyHandler)}},_onKeyBindingEvent:function(keyBindings,event){if(this.stopKeyboardEventPropagation){event.stopPropagation()}if(event.defaultPrevented){return}for(var i=0;i<keyBindings.length;i++){var keyCombo=keyBindings[i][0];var handlerName=keyBindings[i][1];if(keyComboMatchesEvent(keyCombo,event)){this._triggerKeyHandler(keyCombo,handlerName,event);if(event.defaultPrevented){return}}}},_triggerKeyHandler:function(keyCombo,handlerName,keyboardEvent){var detail=Object.create(keyCombo);detail.keyboardEvent=keyboardEvent;var event=new CustomEvent(keyCombo.event,{detail:detail,cancelable:true});this[handlerName].call(this,event);if(event.defaultPrevented){keyboardEvent.preventDefault()}}}})();Polymer.IronScrollTargetBehavior={properties:{scrollTarget:{type:HTMLElement,value:function(){return this._defaultScrollTarget}}},observers:["_scrollTargetChanged(scrollTarget, isAttached)"],_shouldHaveListener:true,_scrollTargetChanged:function(scrollTarget,isAttached){var eventTarget;if(this._oldScrollTarget){this._toggleScrollListener(false,this._oldScrollTarget);this._oldScrollTarget=null}if(!isAttached){return}if(scrollTarget==="document"){this.scrollTarget=this._doc}else if(typeof scrollTarget==="string"){this.scrollTarget=this.domHost?this.domHost.$[scrollTarget]:Polymer.dom(this.ownerDocument).querySelector("#"+scrollTarget)}else if(this._isValidScrollTarget()){this._boundScrollHandler=this._boundScrollHandler||this._scrollHandler.bind(this);this._oldScrollTarget=scrollTarget;this._toggleScrollListener(this._shouldHaveListener,scrollTarget)}},_scrollHandler:function scrollHandler(){},get _defaultScrollTarget(){return this._doc},get _doc(){return this.ownerDocument.documentElement},get _scrollTop(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.pageYOffset:this.scrollTarget.scrollTop}return 0},get _scrollLeft(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.pageXOffset:this.scrollTarget.scrollLeft}return 0},set _scrollTop(top){if(this.scrollTarget===this._doc){window.scrollTo(window.pageXOffset,top)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollTop=top}},set _scrollLeft(left){if(this.scrollTarget===this._doc){window.scrollTo(left,window.pageYOffset)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollLeft=left}},scroll:function(left,top){if(this.scrollTarget===this._doc){window.scrollTo(left,top)}else if(this._isValidScrollTarget()){this.scrollTarget.scrollLeft=left;this.scrollTarget.scrollTop=top}},get _scrollTargetWidth(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.innerWidth:this.scrollTarget.offsetWidth}return 0},get _scrollTargetHeight(){if(this._isValidScrollTarget()){return this.scrollTarget===this._doc?window.innerHeight:this.scrollTarget.offsetHeight}return 0},_isValidScrollTarget:function(){return this.scrollTarget instanceof HTMLElement},_toggleScrollListener:function(yes,scrollTarget){if(!this._boundScrollHandler){return}var eventTarget=scrollTarget===this._doc?window:scrollTarget;if(yes){eventTarget.addEventListener("scroll",this._boundScrollHandler)}else{eventTarget.removeEventListener("scroll",this._boundScrollHandler)}},toggleScrollListener:function(yes){this._shouldHaveListener=yes;this._toggleScrollListener(yes,this.scrollTarget)}};(function(){var IOS=navigator.userAgent.match(/iP(?:hone|ad;(?: U;)? CPU) OS (\d+)/);var IOS_TOUCH_SCROLLING=IOS&&IOS[1]>=8;var DEFAULT_PHYSICAL_COUNT=3;var HIDDEN_Y="-10000px";var ITEM_WIDTH=0;var ITEM_HEIGHT=1;var SECRET_TABINDEX=-100;Polymer({is:"iron-list",properties:{items:{type:Array},maxPhysicalCount:{type:Number,value:500},as:{type:String,value:"item"},indexAs:{type:String,value:"index"},selectedAs:{type:String,value:"selected"},grid:{type:Boolean,value:false,reflectToAttribute:true},selectionEnabled:{type:Boolean,value:false},selectedItem:{type:Object,notify:true},selectedItems:{type:Object,notify:true},multiSelection:{type:Boolean,value:false}},observers:["_itemsChanged(items.*)","_selectionEnabledChanged(selectionEnabled)","_multiSelectionChanged(multiSelection)","_setOverflow(scrollTarget)"],behaviors:[Polymer.Templatizer,Polymer.IronResizableBehavior,Polymer.IronA11yKeysBehavior,Polymer.IronScrollTargetBehavior],keyBindings:{up:"_didMoveUp",down:"_didMoveDown",enter:"_didEnter"},_ratio:.5,_scrollerPaddingTop:0,_scrollPosition:0,_physicalSize:0,_physicalAverage:0,_physicalAverageCount:0,_physicalTop:0,_virtualCount:0,_physicalIndexForKey:null,_estScrollHeight:0,_scrollHeight:0,_viewportHeight:0,_viewportWidth:0,_physicalItems:null,_physicalSizes:null,_firstVisibleIndexVal:null,_lastVisibleIndexVal:null,_collection:null,_maxPages:2,_focusedItem:null,_focusedIndex:-1,_offscreenFocusedItem:null,_focusBackfillItem:null,_itemsPerRow:1,_itemWidth:0,_rowHeight:0,_templateCost:0,get _physicalBottom(){return this._physicalTop+this._physicalSize},get _scrollBottom(){return this._scrollPosition+this._viewportHeight},get _virtualEnd(){return this._virtualStart+this._physicalCount-1},get _hiddenContentSize(){var size=this.grid?this._physicalRows*this._rowHeight:this._physicalSize;return size-this._viewportHeight},get _maxScrollTop(){return this._estScrollHeight-this._viewportHeight+this._scrollerPaddingTop},_minVirtualStart:0,get _maxVirtualStart(){return Math.max(0,this._virtualCount-this._physicalCount)},_virtualStartVal:0,set _virtualStart(val){this._virtualStartVal=Math.min(this._maxVirtualStart,Math.max(this._minVirtualStart,val))},get _virtualStart(){return this._virtualStartVal||0},_physicalStartVal:0,set _physicalStart(val){this._physicalStartVal=val%this._physicalCount;if(this._physicalStartVal<0){this._physicalStartVal=this._physicalCount+this._physicalStartVal}this._physicalEnd=(this._physicalStart+this._physicalCount-1)%this._physicalCount},get _physicalStart(){return this._physicalStartVal||0},_physicalCountVal:0,set _physicalCount(val){this._physicalCountVal=val;this._physicalEnd=(this._physicalStart+this._physicalCount-1)%this._physicalCount},get _physicalCount(){return this._physicalCountVal},_physicalEnd:0,get _optPhysicalSize(){if(this.grid){return this._estRowsInView*this._rowHeight*this._maxPages}return this._viewportHeight*this._maxPages},get _isVisible(){return Boolean(this.offsetWidth||this.offsetHeight)},get firstVisibleIndex(){if(this._firstVisibleIndexVal===null){var physicalOffset=Math.floor(this._physicalTop+this._scrollerPaddingTop);this._firstVisibleIndexVal=this._iterateItems(function(pidx,vidx){physicalOffset+=this._getPhysicalSizeIncrement(pidx);if(physicalOffset>this._scrollPosition){return this.grid?vidx-vidx%this._itemsPerRow:vidx}if(this.grid&&this._virtualCount-1===vidx){return vidx-vidx%this._itemsPerRow}})||0}return this._firstVisibleIndexVal},get lastVisibleIndex(){if(this._lastVisibleIndexVal===null){if(this.grid){var lastIndex=this.firstVisibleIndex+this._estRowsInView*this._itemsPerRow-1;this._lastVisibleIndexVal=Math.min(this._virtualCount,lastIndex)}else{var physicalOffset=this._physicalTop;this._iterateItems(function(pidx,vidx){if(physicalOffset<this._scrollBottom){this._lastVisibleIndexVal=vidx}else{return true}physicalOffset+=this._getPhysicalSizeIncrement(pidx)})}}return this._lastVisibleIndexVal},get _defaultScrollTarget(){return this},get _virtualRowCount(){return Math.ceil(this._virtualCount/this._itemsPerRow)},get _estRowsInView(){return Math.ceil(this._viewportHeight/this._rowHeight)},get _physicalRows(){return Math.ceil(this._physicalCount/this._itemsPerRow)},ready:function(){this.addEventListener("focus",this._didFocus.bind(this),true)},attached:function(){if(this._physicalCount===0){this._debounceTemplate(this._render)}this.listen(this,"iron-resize","_resizeHandler")},detached:function(){this.unlisten(this,"iron-resize","_resizeHandler")},_setOverflow:function(scrollTarget){this.style.webkitOverflowScrolling=scrollTarget===this?"touch":"";this.style.overflow=scrollTarget===this?"auto":""},updateViewportBoundaries:function(){this._scrollerPaddingTop=this.scrollTarget===this?0:parseInt(window.getComputedStyle(this)["padding-top"],10);this._viewportWidth=this.$.items.offsetWidth;this._viewportHeight=this._scrollTargetHeight;this.grid&&this._updateGridMetrics()},_scrollHandler:function(){var scrollTop=Math.max(0,Math.min(this._maxScrollTop,this._scrollTop));var delta=scrollTop-this._scrollPosition;var isScrollingDown=delta>=0;this._scrollPosition=scrollTop;this._firstVisibleIndexVal=null;this._lastVisibleIndexVal=null;if(Math.abs(delta)>this._physicalSize){var idxAdjustment=Math.round(delta/this._physicalAverage)*this._itemsPerRow;this._physicalTop=this._physicalTop+delta;this._virtualStart=this._virtualStart+idxAdjustment;this._physicalStart=this._physicalStart+idxAdjustment;this._update()}else{var reusables=this._getReusables(isScrollingDown);if(isScrollingDown){this._physicalTop=reusables.physicalTop;this._virtualStart=this._virtualStart+reusables.indexes.length;this._physicalStart=this._physicalStart+reusables.indexes.length}else{this._virtualStart=this._virtualStart-reusables.indexes.length;this._physicalStart=this._physicalStart-reusables.indexes.length}if(reusables.indexes.length===0){this._increasePoolIfNeeded()}else{this._update(reusables.indexes,isScrollingDown?null:reusables.indexes)}}},_getReusables:function(fromTop){var ith,lastIth,offsetContent,physicalItemHeight;var idxs=[];var protectedOffsetContent=this._hiddenContentSize*this._ratio;var virtualStart=this._virtualStart;var virtualEnd=this._virtualEnd;var physicalCount=this._physicalCount;var physicalTop=this._physicalTop+this._scrollerPaddingTop;var scrollTop=this._scrollTop;var scrollBottom=this._scrollBottom;if(fromTop){ith=this._physicalStart;lastIth=this._physicalEnd;offsetContent=scrollTop-physicalTop}else{ith=this._physicalEnd;lastIth=this._physicalStart;offsetContent=this._physicalBottom-scrollBottom}while(true){physicalItemHeight=this._getPhysicalSizeIncrement(ith);offsetContent=offsetContent-physicalItemHeight;if(idxs.length>=physicalCount||offsetContent<=protectedOffsetContent){break}if(fromTop){if(virtualEnd+idxs.length+1>=this._virtualCount){break}if(physicalTop+physicalItemHeight>=scrollTop){break}idxs.push(ith);physicalTop=physicalTop+physicalItemHeight;ith=(ith+1)%physicalCount}else{if(virtualStart-idxs.length<=0){break}if(physicalTop+this._physicalSize-physicalItemHeight<=scrollBottom){break}idxs.push(ith);physicalTop=physicalTop-physicalItemHeight;ith=ith===0?physicalCount-1:ith-1}}return{indexes:idxs,physicalTop:physicalTop-this._scrollerPaddingTop}},_update:function(itemSet,movingUp){if(itemSet&&itemSet.length===0){return}this._manageFocus();this._assignModels(itemSet);this._updateMetrics(itemSet);if(movingUp){while(movingUp.length){var idx=movingUp.pop();this._physicalTop-=this._getPhysicalSizeIncrement(idx)}}this._positionItems();this._updateScrollerSize();this._increasePoolIfNeeded()},_createPool:function(size){var physicalItems=new Array(size);this._ensureTemplatized();for(var i=0;i<size;i++){var inst=this.stamp(null);physicalItems[i]=inst.root.querySelector("*");Polymer.dom(this).appendChild(inst.root)}return physicalItems},_increasePoolIfNeeded:function(){if(this._viewportHeight===0){return false}var self=this;var isClientFull=this._physicalBottom>=this._scrollBottom&&this._physicalTop<=this._scrollPosition;if(this._physicalSize>=this._optPhysicalSize&&isClientFull){return false}var maxPoolSize=Math.round(this._physicalCount*.5);if(!isClientFull){this._debounceTemplate(this._increasePool.bind(this,maxPoolSize));return true}this._yield(function(){self._increasePool(Math.min(maxPoolSize,Math.max(1,Math.round(50/self._templateCost))))});return true},_yield:function(cb){var g=window;var handle=g.requestIdleCallback?g.requestIdleCallback(cb):g.setTimeout(cb,16);Polymer.dom.addDebouncer({complete:function(){g.cancelIdleCallback?g.cancelIdleCallback(handle):g.clearTimeout(handle);cb()}})},_increasePool:function(missingItems){var nextPhysicalCount=Math.min(this._physicalCount+missingItems,this._virtualCount-this._virtualStart,Math.max(this.maxPhysicalCount,DEFAULT_PHYSICAL_COUNT));var prevPhysicalCount=this._physicalCount;var delta=nextPhysicalCount-prevPhysicalCount;var ts=window.performance.now();if(delta<=0){return}[].push.apply(this._physicalItems,this._createPool(delta));[].push.apply(this._physicalSizes,new Array(delta));this._physicalCount=prevPhysicalCount+delta;if(this._physicalStart>this._physicalEnd&&this._isIndexRendered(this._focusedIndex)&&this._getPhysicalIndex(this._focusedIndex)<this._physicalEnd){this._physicalStart=this._physicalStart+delta}this._update();this._templateCost=(window.performance.now()-ts)/delta},_render:function(){if(this.isAttached&&this._isVisible){if(this._physicalCount===0){this.updateViewportBoundaries();this._increasePool(DEFAULT_PHYSICAL_COUNT)}else{var reusables=this._getReusables(true);this._physicalTop=reusables.physicalTop;this._virtualStart=this._virtualStart+reusables.indexes.length;this._physicalStart=this._physicalStart+reusables.indexes.length;this._update(reusables.indexes);this._update()}}},_ensureTemplatized:function(){if(!this.ctor){var props={};props.__key__=true;props[this.as]=true;props[this.indexAs]=true;props[this.selectedAs]=true;props.tabIndex=true;this._instanceProps=props;this._userTemplate=Polymer.dom(this).querySelector("template");if(this._userTemplate){this.templatize(this._userTemplate)}else{console.warn("iron-list requires a template to be provided in light-dom")}}},_getStampedChildren:function(){return this._physicalItems},_forwardInstancePath:function(inst,path,value){if(path.indexOf(this.as+".")===0){this.notifyPath("items."+inst.__key__+"."+path.slice(this.as.length+1),value)}},_forwardParentProp:function(prop,value){if(this._physicalItems){this._physicalItems.forEach(function(item){item._templateInstance[prop]=value},this)}},_forwardParentPath:function(path,value){if(this._physicalItems){this._physicalItems.forEach(function(item){item._templateInstance.notifyPath(path,value,true)},this)}},_forwardItemPath:function(path,value){if(!this._physicalIndexForKey){return}var dot=path.indexOf(".");var key=path.substring(0,dot<0?path.length:dot);var idx=this._physicalIndexForKey[key];var offscreenItem=this._offscreenFocusedItem;var el=offscreenItem&&offscreenItem._templateInstance.__key__===key?offscreenItem:this._physicalItems[idx];if(!el||el._templateInstance.__key__!==key){return}if(dot>=0){path=this.as+"."+path.substring(dot+1);el._templateInstance.notifyPath(path,value,true)}else{var currentItem=el._templateInstance[this.as];if(Array.isArray(this.selectedItems)){for(var i=0;i<this.selectedItems.length;i++){if(this.selectedItems[i]===currentItem){this.set("selectedItems."+i,value);break}}}else if(this.selectedItem===currentItem){this.set("selectedItem",value)}el._templateInstance[this.as]=value}},_itemsChanged:function(change){if(change.path==="items"){this._virtualStart=0;this._physicalTop=0;this._virtualCount=this.items?this.items.length:0;this._collection=this.items?Polymer.Collection.get(this.items):null;this._physicalIndexForKey={};this._firstVisibleIndexVal=null;this._lastVisibleIndexVal=null;this._physicalCount=this._physicalCount||0;this._physicalItems=this._physicalItems||[];this._physicalSizes=this._physicalSizes||[];this._physicalStart=0;this._resetScrollPosition(0);this._removeFocusedItem();this._debounceTemplate(this._render)}else if(change.path==="items.splices"){this._adjustVirtualIndex(change.value.indexSplices);this._virtualCount=this.items?this.items.length:0;this._debounceTemplate(this._render)}else{this._forwardItemPath(change.path.split(".").slice(1).join("."),change.value)}},_adjustVirtualIndex:function(splices){splices.forEach(function(splice){splice.removed.forEach(this._removeItem,this);if(splice.index<this._virtualStart){var delta=Math.max(splice.addedCount-splice.removed.length,splice.index-this._virtualStart);this._virtualStart=this._virtualStart+delta;if(this._focusedIndex>=0){this._focusedIndex=this._focusedIndex+delta}}},this)},_removeItem:function(item){this.$.selector.deselect(item);if(this._focusedItem&&this._focusedItem._templateInstance[this.as]===item){this._removeFocusedItem()}},_iterateItems:function(fn,itemSet){var pidx,vidx,rtn,i;if(arguments.length===2&&itemSet){for(i=0;i<itemSet.length;i++){pidx=itemSet[i];vidx=this._computeVidx(pidx);if((rtn=fn.call(this,pidx,vidx))!=null){return rtn}}}else{pidx=this._physicalStart;vidx=this._virtualStart;for(;pidx<this._physicalCount;pidx++,vidx++){if((rtn=fn.call(this,pidx,vidx))!=null){return rtn}}for(pidx=0;pidx<this._physicalStart;pidx++,vidx++){if((rtn=fn.call(this,pidx,vidx))!=null){return rtn}}}},_computeVidx:function(pidx){if(pidx>=this._physicalStart){return this._virtualStart+(pidx-this._physicalStart)}return this._virtualStart+(this._physicalCount-this._physicalStart)+pidx},_assignModels:function(itemSet){this._iterateItems(function(pidx,vidx){var el=this._physicalItems[pidx];var inst=el._templateInstance;var item=this.items&&this.items[vidx];if(item!=null){inst[this.as]=item;inst.__key__=this._collection.getKey(item);inst[this.selectedAs]=this.$.selector.isSelected(item);inst[this.indexAs]=vidx;inst.tabIndex=this._focusedIndex===vidx?0:-1;this._physicalIndexForKey[inst.__key__]=pidx;el.removeAttribute("hidden")}else{inst.__key__=null;el.setAttribute("hidden","")}},itemSet)},_updateMetrics:function(itemSet){Polymer.dom.flush();var newPhysicalSize=0;var oldPhysicalSize=0;var prevAvgCount=this._physicalAverageCount;var prevPhysicalAvg=this._physicalAverage;this._iterateItems(function(pidx,vidx){oldPhysicalSize+=this._physicalSizes[pidx]||0;this._physicalSizes[pidx]=this._physicalItems[pidx].offsetHeight;newPhysicalSize+=this._physicalSizes[pidx];this._physicalAverageCount+=this._physicalSizes[pidx]?1:0},itemSet);if(this.grid){this._updateGridMetrics();this._physicalSize=Math.ceil(this._physicalCount/this._itemsPerRow)*this._rowHeight}else{this._physicalSize=this._physicalSize+newPhysicalSize-oldPhysicalSize}if(this._physicalAverageCount!==prevAvgCount){this._physicalAverage=Math.round((prevPhysicalAvg*prevAvgCount+newPhysicalSize)/this._physicalAverageCount)}},_updateGridMetrics:function(){this._itemWidth=this._physicalCount>0?this._physicalItems[0].getBoundingClientRect().width:200;this._rowHeight=this._physicalCount>0?this._physicalItems[0].offsetHeight:200;this._itemsPerRow=this._itemWidth?Math.floor(this._viewportWidth/this._itemWidth):this._itemsPerRow},_positionItems:function(){this._adjustScrollPosition();var y=this._physicalTop;if(this.grid){var totalItemWidth=this._itemsPerRow*this._itemWidth;var rowOffset=(this._viewportWidth-totalItemWidth)/2;this._iterateItems(function(pidx,vidx){var modulus=vidx%this._itemsPerRow;var x=Math.floor(modulus*this._itemWidth+rowOffset);this.translate3d(x+"px",y+"px",0,this._physicalItems[pidx]);if(this._shouldRenderNextRow(vidx)){y+=this._rowHeight}})}else{this._iterateItems(function(pidx,vidx){this.translate3d(0,y+"px",0,this._physicalItems[pidx]);y+=this._physicalSizes[pidx]})}},_getPhysicalSizeIncrement:function(pidx){if(!this.grid){return this._physicalSizes[pidx]}if(this._computeVidx(pidx)%this._itemsPerRow!==this._itemsPerRow-1){return 0}return this._rowHeight},_shouldRenderNextRow:function(vidx){return vidx%this._itemsPerRow===this._itemsPerRow-1},_adjustScrollPosition:function(){var deltaHeight=this._virtualStart===0?this._physicalTop:Math.min(this._scrollPosition+this._physicalTop,0);if(deltaHeight){this._physicalTop=this._physicalTop-deltaHeight;if(!IOS_TOUCH_SCROLLING&&this._physicalTop!==0){this._resetScrollPosition(this._scrollTop-deltaHeight)}}},_resetScrollPosition:function(pos){if(this.scrollTarget){this._scrollTop=pos;this._scrollPosition=this._scrollTop}},_updateScrollerSize:function(forceUpdate){if(this.grid){this._estScrollHeight=this._virtualRowCount*this._rowHeight}else{this._estScrollHeight=this._physicalBottom+Math.max(this._virtualCount-this._physicalCount-this._virtualStart,0)*this._physicalAverage}forceUpdate=forceUpdate||this._scrollHeight===0;forceUpdate=forceUpdate||this._scrollPosition>=this._estScrollHeight-this._physicalSize;forceUpdate=forceUpdate||this.grid&&this.$.items.style.height<this._estScrollHeight;if(forceUpdate||Math.abs(this._estScrollHeight-this._scrollHeight)>=this._optPhysicalSize){this.$.items.style.height=this._estScrollHeight+"px";this._scrollHeight=this._estScrollHeight}},scrollToItem:function(item){return this.scrollToIndex(this.items.indexOf(item))},scrollToIndex:function(idx){if(typeof idx!=="number"||idx<0||idx>this.items.length-1){return}Polymer.dom.flush();if(this._physicalCount===0){return}idx=Math.min(Math.max(idx,0),this._virtualCount-1);if(!this._isIndexRendered(idx)||idx>=this._maxVirtualStart){this._virtualStart=this.grid?idx-this._itemsPerRow*2:idx-1}this._manageFocus();this._assignModels();this._updateMetrics();this._physicalTop=Math.floor(this._virtualStart/this._itemsPerRow)*this._physicalAverage;var currentTopItem=this._physicalStart;var currentVirtualItem=this._virtualStart;var targetOffsetTop=0;var hiddenContentSize=this._hiddenContentSize;while(currentVirtualItem<idx&&targetOffsetTop<=hiddenContentSize){targetOffsetTop=targetOffsetTop+this._getPhysicalSizeIncrement(currentTopItem);currentTopItem=(currentTopItem+1)%this._physicalCount;currentVirtualItem++}this._updateScrollerSize(true);this._positionItems();this._resetScrollPosition(this._physicalTop+this._scrollerPaddingTop+targetOffsetTop);this._increasePoolIfNeeded();this._firstVisibleIndexVal=null;this._lastVisibleIndexVal=null},_resetAverage:function(){this._physicalAverage=0;this._physicalAverageCount=0},_resizeHandler:function(){var delta=Math.abs(this._viewportHeight-this._scrollTargetHeight);if(IOS&&delta>0&&delta<100){return}Polymer.dom.addDebouncer(this.debounce("_debounceTemplate",function(){this.updateViewportBoundaries();this._render();if(this._isVisible){this.toggleScrollListener(true);if(this._physicalCount>0){this._resetAverage();this.scrollToIndex(this.firstVisibleIndex)}}else{this.toggleScrollListener(false)}}.bind(this),1))},_getModelFromItem:function(item){var key=this._collection.getKey(item);var pidx=this._physicalIndexForKey[key];if(pidx!=null){return this._physicalItems[pidx]._templateInstance}return null},_getNormalizedItem:function(item){if(this._collection.getKey(item)===undefined){if(typeof item==="number"){item=this.items[item];if(!item){throw new RangeError("<item> not found")}return item}throw new TypeError("<item> should be a valid item")}return item},selectItem:function(item){item=this._getNormalizedItem(item);var model=this._getModelFromItem(item);if(!this.multiSelection&&this.selectedItem){this.deselectItem(this.selectedItem)}if(model){model[this.selectedAs]=true}this.$.selector.select(item);this.updateSizeForItem(item)},deselectItem:function(item){item=this._getNormalizedItem(item);var model=this._getModelFromItem(item);if(model){model[this.selectedAs]=false}this.$.selector.deselect(item);this.updateSizeForItem(item)},toggleSelectionForItem:function(item){item=this._getNormalizedItem(item);if(this.$.selector.isSelected(item)){this.deselectItem(item)}else{this.selectItem(item)}},clearSelection:function(){function unselect(item){var model=this._getModelFromItem(item);if(model){model[this.selectedAs]=false}}if(Array.isArray(this.selectedItems)){this.selectedItems.forEach(unselect,this)}else if(this.selectedItem){unselect.call(this,this.selectedItem)}this.$.selector.clearSelection()},_selectionEnabledChanged:function(selectionEnabled){var handler=selectionEnabled?this.listen:this.unlisten;handler.call(this,this,"tap","_selectionHandler")},_selectionHandler:function(e){var model=this.modelForElement(e.target);if(!model){return}var modelTabIndex,activeElTabIndex;var target=Polymer.dom(e).path[0];var activeEl=Polymer.dom(this.domHost?this.domHost.root:document).activeElement; - -var physicalItem=this._physicalItems[this._getPhysicalIndex(model[this.indexAs])];if(target.localName==="input"||target.localName==="button"||target.localName==="select"){return}modelTabIndex=model.tabIndex;model.tabIndex=SECRET_TABINDEX;activeElTabIndex=activeEl?activeEl.tabIndex:-1;model.tabIndex=modelTabIndex;if(activeEl&&physicalItem!==activeEl&&physicalItem.contains(activeEl)&&activeElTabIndex!==SECRET_TABINDEX){return}this.toggleSelectionForItem(model[this.as])},_multiSelectionChanged:function(multiSelection){this.clearSelection();this.$.selector.multi=multiSelection},updateSizeForItem:function(item){item=this._getNormalizedItem(item);var key=this._collection.getKey(item);var pidx=this._physicalIndexForKey[key];if(pidx!=null){this._updateMetrics([pidx]);this._positionItems()}},_manageFocus:function(){var fidx=this._focusedIndex;if(fidx>=0&&fidx<this._virtualCount){if(this._isIndexRendered(fidx)){this._restoreFocusedItem()}else{this._createFocusBackfillItem()}}else if(this._virtualCount>0&&this._physicalCount>0){this._focusedIndex=this._virtualStart;this._focusedItem=this._physicalItems[this._physicalStart]}},_isIndexRendered:function(idx){return idx>=this._virtualStart&&idx<=this._virtualEnd},_isIndexVisible:function(idx){return idx>=this.firstVisibleIndex&&idx<=this.lastVisibleIndex},_getPhysicalIndex:function(idx){return this._physicalIndexForKey[this._collection.getKey(this._getNormalizedItem(idx))]},_focusPhysicalItem:function(idx){if(idx<0||idx>=this._virtualCount){return}this._restoreFocusedItem();if(!this._isIndexRendered(idx)){this.scrollToIndex(idx)}var physicalItem=this._physicalItems[this._getPhysicalIndex(idx)];var model=physicalItem._templateInstance;var focusable;model.tabIndex=SECRET_TABINDEX;if(physicalItem.tabIndex===SECRET_TABINDEX){focusable=physicalItem}if(!focusable){focusable=Polymer.dom(physicalItem).querySelector('[tabindex="'+SECRET_TABINDEX+'"]')}model.tabIndex=0;this._focusedIndex=idx;focusable&&focusable.focus()},_removeFocusedItem:function(){if(this._offscreenFocusedItem){Polymer.dom(this).removeChild(this._offscreenFocusedItem)}this._offscreenFocusedItem=null;this._focusBackfillItem=null;this._focusedItem=null;this._focusedIndex=-1},_createFocusBackfillItem:function(){var fidx=this._focusedIndex;var pidx=this._getPhysicalIndex(fidx);if(this._offscreenFocusedItem||pidx==null||fidx<0){return}if(!this._focusBackfillItem){var stampedTemplate=this.stamp(null);this._focusBackfillItem=stampedTemplate.root.querySelector("*");Polymer.dom(this).appendChild(stampedTemplate.root)}this._offscreenFocusedItem=this._physicalItems[pidx];this._offscreenFocusedItem._templateInstance.tabIndex=0;this._physicalItems[pidx]=this._focusBackfillItem;this.translate3d(0,HIDDEN_Y,0,this._offscreenFocusedItem)},_restoreFocusedItem:function(){var pidx,fidx=this._focusedIndex;if(!this._offscreenFocusedItem||this._focusedIndex<0){return}this._assignModels();pidx=this._getPhysicalIndex(fidx);if(pidx!=null){this._focusBackfillItem=this._physicalItems[pidx];this._focusBackfillItem._templateInstance.tabIndex=-1;this._physicalItems[pidx]=this._offscreenFocusedItem;this._offscreenFocusedItem=null;this.translate3d(0,HIDDEN_Y,0,this._focusBackfillItem)}},_didFocus:function(e){var targetModel=this.modelForElement(e.target);var focusedModel=this._focusedItem?this._focusedItem._templateInstance:null;var hasOffscreenFocusedItem=this._offscreenFocusedItem!==null;var fidx=this._focusedIndex;if(!targetModel||!focusedModel){return}if(focusedModel===targetModel){if(!this._isIndexVisible(fidx)){this.scrollToIndex(fidx)}}else{this._restoreFocusedItem();focusedModel.tabIndex=-1;targetModel.tabIndex=0;fidx=targetModel[this.indexAs];this._focusedIndex=fidx;this._focusedItem=this._physicalItems[this._getPhysicalIndex(fidx)];if(hasOffscreenFocusedItem&&!this._offscreenFocusedItem){this._update()}}},_didMoveUp:function(){this._focusPhysicalItem(this._focusedIndex-1)},_didMoveDown:function(e){e.detail.keyboardEvent.preventDefault();this._focusPhysicalItem(this._focusedIndex+1)},_didEnter:function(e){this._focusPhysicalItem(this._focusedIndex);this._selectionHandler(e.detail.keyboardEvent)}})})(); -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -cr.define("downloads",function(){function chromeSendWithId(chromeSendName){return function(id){chrome.send(chromeSendName,[id])}}function ActionService(){this.searchTerms_=[]}function trim(s){return s.trim()}function truthy(value){return!!value}ActionService.splitTerms=function(searchText){return searchText.split(/"([^"]*)"/).map(trim).filter(truthy)};ActionService.prototype={cancel:chromeSendWithId("cancel"),clearAll:function(){if(loadTimeData.getBoolean("allowDeletingHistory")){chrome.send("clearAll");this.search("")}},discardDangerous:chromeSendWithId("discardDangerous"),download:function(url){var a=document.createElement("a");a.href=url;a.setAttribute("download","");a.click()},drag:chromeSendWithId("drag"),loadMore:function(){chrome.send("getDownloads",this.searchTerms_)},isSearching:function(){return this.searchTerms_.length>0},openDownloadsFolder:function(){chrome.send("openDownloadsFolderRequiringGesture")},openFile:chromeSendWithId("openFileRequiringGesture"),pause:chromeSendWithId("pause"),remove:chromeSendWithId("remove"),resume:chromeSendWithId("resume"),saveDangerous:chromeSendWithId("saveDangerousRequiringGesture"),search:function(searchText){var searchTerms=ActionService.splitTerms(searchText);var sameTerms=searchTerms.length==this.searchTerms_.length;for(var i=0;sameTerms&&i<searchTerms.length;++i){if(searchTerms[i]!=this.searchTerms_[i])sameTerms=false}if(sameTerms)return false;this.searchTerms_=searchTerms;this.loadMore();return true},show:chromeSendWithId("show"),undo:chrome.send.bind(chrome,"undo")};cr.addSingletonGetter(ActionService);return{ActionService:ActionService}}); -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -cr.define("downloads",function(){var DangerType={NOT_DANGEROUS:"NOT_DANGEROUS",DANGEROUS_FILE:"DANGEROUS_FILE",DANGEROUS_URL:"DANGEROUS_URL",DANGEROUS_CONTENT:"DANGEROUS_CONTENT",UNCOMMON_CONTENT:"UNCOMMON_CONTENT",DANGEROUS_HOST:"DANGEROUS_HOST",POTENTIALLY_UNWANTED:"POTENTIALLY_UNWANTED"};var States={IN_PROGRESS:"IN_PROGRESS",CANCELLED:"CANCELLED",COMPLETE:"COMPLETE",PAUSED:"PAUSED",DANGEROUS:"DANGEROUS",INTERRUPTED:"INTERRUPTED"};return{DangerType:DangerType,States:States}}); -// Copyright 2014 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. -var ActionLink=document.registerElement("action-link",{prototype:{__proto__:HTMLAnchorElement.prototype,createdCallback:function(){this.tabIndex=this.disabled?-1:0;if(!this.hasAttribute("role"))this.setAttribute("role","link");this.addEventListener("keydown",function(e){if(!this.disabled&&e.key=="Enter"&&!this.href){window.setTimeout(this.click.bind(this),0)}});function preventDefault(e){e.preventDefault()}function removePreventDefault(){document.removeEventListener("selectstart",preventDefault);document.removeEventListener("mouseup",removePreventDefault)}this.addEventListener("mousedown",function(){document.addEventListener("selectstart",preventDefault);document.addEventListener("mouseup",removePreventDefault);if(document.activeElement!=this)this.classList.add("no-outline")});this.addEventListener("blur",function(){this.classList.remove("no-outline")})},set disabled(disabled){if(disabled)HTMLAnchorElement.prototype.setAttribute.call(this,"disabled","");else HTMLAnchorElement.prototype.removeAttribute.call(this,"disabled");this.tabIndex=disabled?-1:0},get disabled(){return this.hasAttribute("disabled")},setAttribute:function(attr,val){if(attr.toLowerCase()=="disabled")this.disabled=true;else HTMLAnchorElement.prototype.setAttribute.apply(this,arguments)},removeAttribute:function(attr){if(attr.toLowerCase()=="disabled")this.disabled=false;else HTMLAnchorElement.prototype.removeAttribute.apply(this,arguments)}},"extends":"a"});(function(){var metaDatas={};var metaArrays={};var singleton=null;Polymer.IronMeta=Polymer({is:"iron-meta",properties:{type:{type:String,value:"default",observer:"_typeChanged"},key:{type:String,observer:"_keyChanged"},value:{type:Object,notify:true,observer:"_valueChanged"},self:{type:Boolean,observer:"_selfChanged"},list:{type:Array,notify:true}},hostAttributes:{hidden:true},factoryImpl:function(config){if(config){for(var n in config){switch(n){case"type":case"key":case"value":this[n]=config[n];break}}}},created:function(){this._metaDatas=metaDatas;this._metaArrays=metaArrays},_keyChanged:function(key,old){this._resetRegistration(old)},_valueChanged:function(value){this._resetRegistration(this.key)},_selfChanged:function(self){if(self){this.value=this}},_typeChanged:function(type){this._unregisterKey(this.key);if(!metaDatas[type]){metaDatas[type]={}}this._metaData=metaDatas[type];if(!metaArrays[type]){metaArrays[type]=[]}this.list=metaArrays[type];this._registerKeyValue(this.key,this.value)},byKey:function(key){return this._metaData&&this._metaData[key]},_resetRegistration:function(oldKey){this._unregisterKey(oldKey);this._registerKeyValue(this.key,this.value)},_unregisterKey:function(key){this._unregister(key,this._metaData,this.list)},_registerKeyValue:function(key,value){this._register(key,value,this._metaData,this.list)},_register:function(key,value,data,list){if(key&&data&&value!==undefined){data[key]=value;list.push(value)}},_unregister:function(key,data,list){if(key&&data){if(key in data){var value=data[key];delete data[key];this.arrayDelete(list,value)}}}});Polymer.IronMeta.getIronMeta=function getIronMeta(){if(singleton===null){singleton=new Polymer.IronMeta}return singleton};Polymer.IronMetaQuery=Polymer({is:"iron-meta-query",properties:{type:{type:String,value:"default",observer:"_typeChanged"},key:{type:String,observer:"_keyChanged"},value:{type:Object,notify:true,readOnly:true},list:{type:Array,notify:true}},factoryImpl:function(config){if(config){for(var n in config){switch(n){case"type":case"key":this[n]=config[n];break}}}},created:function(){this._metaDatas=metaDatas;this._metaArrays=metaArrays},_keyChanged:function(key){this._setValue(this._metaData&&this._metaData[key])},_typeChanged:function(type){this._metaData=metaDatas[type];this.list=metaArrays[type];if(this.key){this._keyChanged(this.key)}},byKey:function(key){return this._metaData&&this._metaData[key]}})})();Polymer({is:"iron-icon",properties:{icon:{type:String,observer:"_iconChanged"},theme:{type:String,observer:"_updateIcon"},src:{type:String,observer:"_srcChanged"},_meta:{value:Polymer.Base.create("iron-meta",{type:"iconset"}),observer:"_updateIcon"}},_DEFAULT_ICONSET:"icons",_iconChanged:function(icon){var parts=(icon||"").split(":");this._iconName=parts.pop();this._iconsetName=parts.pop()||this._DEFAULT_ICONSET;this._updateIcon()},_srcChanged:function(src){this._updateIcon()},_usesIconset:function(){return this.icon||!this.src},_updateIcon:function(){if(this._usesIconset()){if(this._img&&this._img.parentNode){Polymer.dom(this.root).removeChild(this._img)}if(this._iconName===""){if(this._iconset){this._iconset.removeIcon(this)}}else if(this._iconsetName&&this._meta){this._iconset=this._meta.byKey(this._iconsetName);if(this._iconset){this._iconset.applyIcon(this,this._iconName,this.theme);this.unlisten(window,"iron-iconset-added","_updateIcon")}else{this.listen(window,"iron-iconset-added","_updateIcon")}}}else{if(this._iconset){this._iconset.removeIcon(this)}if(!this._img){this._img=document.createElement("img");this._img.style.width="100%";this._img.style.height="100%";this._img.draggable=false}this._img.src=this.src;Polymer.dom(this.root).appendChild(this._img)}}});Polymer.IronControlState={properties:{focused:{type:Boolean,value:false,notify:true,readOnly:true,reflectToAttribute:true},disabled:{type:Boolean,value:false,notify:true,observer:"_disabledChanged",reflectToAttribute:true},_oldTabIndex:{type:Number},_boundFocusBlurHandler:{type:Function,value:function(){return this._focusBlurHandler.bind(this)}}},observers:["_changedControlState(focused, disabled)"],ready:function(){this.addEventListener("focus",this._boundFocusBlurHandler,true);this.addEventListener("blur",this._boundFocusBlurHandler,true)},_focusBlurHandler:function(event){if(event.target===this){this._setFocused(event.type==="focus")}else if(!this.shadowRoot){var target=Polymer.dom(event).localTarget;if(!this.isLightDescendant(target)){this.fire(event.type,{sourceEvent:event},{node:this,bubbles:event.bubbles,cancelable:event.cancelable})}}},_disabledChanged:function(disabled,old){this.setAttribute("aria-disabled",disabled?"true":"false");this.style.pointerEvents=disabled?"none":"";if(disabled){this._oldTabIndex=this.tabIndex;this._setFocused(false);this.tabIndex=-1;this.blur()}else if(this._oldTabIndex!==undefined){this.tabIndex=this._oldTabIndex}},_changedControlState:function(){if(this._controlStateChanged){this._controlStateChanged()}}};Polymer.IronButtonStateImpl={properties:{pressed:{type:Boolean,readOnly:true,value:false,reflectToAttribute:true,observer:"_pressedChanged"},toggles:{type:Boolean,value:false,reflectToAttribute:true},active:{type:Boolean,value:false,notify:true,reflectToAttribute:true},pointerDown:{type:Boolean,readOnly:true,value:false},receivedFocusFromKeyboard:{type:Boolean,readOnly:true},ariaActiveAttribute:{type:String,value:"aria-pressed",observer:"_ariaActiveAttributeChanged"}},listeners:{down:"_downHandler",up:"_upHandler",tap:"_tapHandler"},observers:["_detectKeyboardFocus(focused)","_activeChanged(active, ariaActiveAttribute)"],keyBindings:{"enter:keydown":"_asyncClick","space:keydown":"_spaceKeyDownHandler","space:keyup":"_spaceKeyUpHandler"},_mouseEventRe:/^mouse/,_tapHandler:function(){if(this.toggles){this._userActivate(!this.active)}else{this.active=false}},_detectKeyboardFocus:function(focused){this._setReceivedFocusFromKeyboard(!this.pointerDown&&focused)},_userActivate:function(active){if(this.active!==active){this.active=active;this.fire("change")}},_downHandler:function(event){this._setPointerDown(true);this._setPressed(true);this._setReceivedFocusFromKeyboard(false)},_upHandler:function(){this._setPointerDown(false);this._setPressed(false)},_spaceKeyDownHandler:function(event){var keyboardEvent=event.detail.keyboardEvent;var target=Polymer.dom(keyboardEvent).localTarget;if(this.isLightDescendant(target))return;keyboardEvent.preventDefault();keyboardEvent.stopImmediatePropagation();this._setPressed(true)},_spaceKeyUpHandler:function(event){var keyboardEvent=event.detail.keyboardEvent;var target=Polymer.dom(keyboardEvent).localTarget;if(this.isLightDescendant(target))return;if(this.pressed){this._asyncClick()}this._setPressed(false)},_asyncClick:function(){this.async(function(){this.click()},1)},_pressedChanged:function(pressed){this._changedButtonState()},_ariaActiveAttributeChanged:function(value,oldValue){if(oldValue&&oldValue!=value&&this.hasAttribute(oldValue)){this.removeAttribute(oldValue)}},_activeChanged:function(active,ariaActiveAttribute){if(this.toggles){this.setAttribute(this.ariaActiveAttribute,active?"true":"false")}else{this.removeAttribute(this.ariaActiveAttribute)}this._changedButtonState()},_controlStateChanged:function(){if(this.disabled){this._setPressed(false)}else{this._changedButtonState()}},_changedButtonState:function(){if(this._buttonStateChanged){this._buttonStateChanged()}}};Polymer.IronButtonState=[Polymer.IronA11yKeysBehavior,Polymer.IronButtonStateImpl];(function(){var Utility={distance:function(x1,y1,x2,y2){var xDelta=x1-x2;var yDelta=y1-y2;return Math.sqrt(xDelta*xDelta+yDelta*yDelta)},now:window.performance&&window.performance.now?window.performance.now.bind(window.performance):Date.now};function ElementMetrics(element){this.element=element;this.width=this.boundingRect.width;this.height=this.boundingRect.height;this.size=Math.max(this.width,this.height)}ElementMetrics.prototype={get boundingRect(){return this.element.getBoundingClientRect()},furthestCornerDistanceFrom:function(x,y){var topLeft=Utility.distance(x,y,0,0);var topRight=Utility.distance(x,y,this.width,0);var bottomLeft=Utility.distance(x,y,0,this.height);var bottomRight=Utility.distance(x,y,this.width,this.height);return Math.max(topLeft,topRight,bottomLeft,bottomRight)}};function Ripple(element){this.element=element;this.color=window.getComputedStyle(element).color;this.wave=document.createElement("div");this.waveContainer=document.createElement("div");this.wave.style.backgroundColor=this.color;this.wave.classList.add("wave");this.waveContainer.classList.add("wave-container");Polymer.dom(this.waveContainer).appendChild(this.wave);this.resetInteractionState()}Ripple.MAX_RADIUS=300;Ripple.prototype={get recenters(){return this.element.recenters},get center(){return this.element.center},get mouseDownElapsed(){var elapsed;if(!this.mouseDownStart){return 0}elapsed=Utility.now()-this.mouseDownStart;if(this.mouseUpStart){elapsed-=this.mouseUpElapsed}return elapsed},get mouseUpElapsed(){return this.mouseUpStart?Utility.now()-this.mouseUpStart:0},get mouseDownElapsedSeconds(){return this.mouseDownElapsed/1e3},get mouseUpElapsedSeconds(){return this.mouseUpElapsed/1e3},get mouseInteractionSeconds(){return this.mouseDownElapsedSeconds+this.mouseUpElapsedSeconds},get initialOpacity(){return this.element.initialOpacity},get opacityDecayVelocity(){return this.element.opacityDecayVelocity},get radius(){var width2=this.containerMetrics.width*this.containerMetrics.width;var height2=this.containerMetrics.height*this.containerMetrics.height;var waveRadius=Math.min(Math.sqrt(width2+height2),Ripple.MAX_RADIUS)*1.1+5;var duration=1.1-.2*(waveRadius/Ripple.MAX_RADIUS);var timeNow=this.mouseInteractionSeconds/duration;var size=waveRadius*(1-Math.pow(80,-timeNow));return Math.abs(size)},get opacity(){if(!this.mouseUpStart){return this.initialOpacity}return Math.max(0,this.initialOpacity-this.mouseUpElapsedSeconds*this.opacityDecayVelocity)},get outerOpacity(){var outerOpacity=this.mouseUpElapsedSeconds*.3;var waveOpacity=this.opacity;return Math.max(0,Math.min(outerOpacity,waveOpacity))},get isOpacityFullyDecayed(){return this.opacity<.01&&this.radius>=Math.min(this.maxRadius,Ripple.MAX_RADIUS)},get isRestingAtMaxRadius(){return this.opacity>=this.initialOpacity&&this.radius>=Math.min(this.maxRadius,Ripple.MAX_RADIUS)},get isAnimationComplete(){return this.mouseUpStart?this.isOpacityFullyDecayed:this.isRestingAtMaxRadius},get translationFraction(){return Math.min(1,this.radius/this.containerMetrics.size*2/Math.sqrt(2))},get xNow(){if(this.xEnd){return this.xStart+this.translationFraction*(this.xEnd-this.xStart)}return this.xStart},get yNow(){if(this.yEnd){return this.yStart+this.translationFraction*(this.yEnd-this.yStart)}return this.yStart},get isMouseDown(){return this.mouseDownStart&&!this.mouseUpStart},resetInteractionState:function(){this.maxRadius=0;this.mouseDownStart=0;this.mouseUpStart=0;this.xStart=0;this.yStart=0;this.xEnd=0;this.yEnd=0;this.slideDistance=0;this.containerMetrics=new ElementMetrics(this.element)},draw:function(){var scale;var translateString;var dx;var dy;this.wave.style.opacity=this.opacity;scale=this.radius/(this.containerMetrics.size/2);dx=this.xNow-this.containerMetrics.width/2;dy=this.yNow-this.containerMetrics.height/2;this.waveContainer.style.webkitTransform="translate("+dx+"px, "+dy+"px)";this.waveContainer.style.transform="translate3d("+dx+"px, "+dy+"px, 0)";this.wave.style.webkitTransform="scale("+scale+","+scale+")";this.wave.style.transform="scale3d("+scale+","+scale+",1)"},downAction:function(event){var xCenter=this.containerMetrics.width/2;var yCenter=this.containerMetrics.height/2;this.resetInteractionState();this.mouseDownStart=Utility.now();if(this.center){this.xStart=xCenter;this.yStart=yCenter;this.slideDistance=Utility.distance(this.xStart,this.yStart,this.xEnd,this.yEnd)}else{this.xStart=event?event.detail.x-this.containerMetrics.boundingRect.left:this.containerMetrics.width/2;this.yStart=event?event.detail.y-this.containerMetrics.boundingRect.top:this.containerMetrics.height/2}if(this.recenters){this.xEnd=xCenter;this.yEnd=yCenter;this.slideDistance=Utility.distance(this.xStart,this.yStart,this.xEnd,this.yEnd)}this.maxRadius=this.containerMetrics.furthestCornerDistanceFrom(this.xStart,this.yStart);this.waveContainer.style.top=(this.containerMetrics.height-this.containerMetrics.size)/2+"px";this.waveContainer.style.left=(this.containerMetrics.width-this.containerMetrics.size)/2+"px";this.waveContainer.style.width=this.containerMetrics.size+"px";this.waveContainer.style.height=this.containerMetrics.size+"px"},upAction:function(event){if(!this.isMouseDown){return}this.mouseUpStart=Utility.now()},remove:function(){Polymer.dom(this.waveContainer.parentNode).removeChild(this.waveContainer)}};Polymer({is:"paper-ripple",behaviors:[Polymer.IronA11yKeysBehavior],properties:{initialOpacity:{type:Number,value:.25},opacityDecayVelocity:{type:Number,value:.8},recenters:{type:Boolean,value:false},center:{type:Boolean,value:false},ripples:{type:Array,value:function(){return[]}},animating:{type:Boolean,readOnly:true,reflectToAttribute:true,value:false},holdDown:{type:Boolean,value:false,observer:"_holdDownChanged"},noink:{type:Boolean,value:false},_animating:{type:Boolean},_boundAnimate:{type:Function,value:function(){return this.animate.bind(this)}}},get target(){return this.keyEventTarget},keyBindings:{"enter:keydown":"_onEnterKeydown","space:keydown":"_onSpaceKeydown","space:keyup":"_onSpaceKeyup"},attached:function(){if(this.parentNode.nodeType==11){this.keyEventTarget=Polymer.dom(this).getOwnerRoot().host}else{this.keyEventTarget=this.parentNode}var keyEventTarget=this.keyEventTarget;this.listen(keyEventTarget,"up","uiUpAction");this.listen(keyEventTarget,"down","uiDownAction")},detached:function(){this.unlisten(this.keyEventTarget,"up","uiUpAction");this.unlisten(this.keyEventTarget,"down","uiDownAction");this.keyEventTarget=null},get shouldKeepAnimating(){for(var index=0;index<this.ripples.length;++index){if(!this.ripples[index].isAnimationComplete){return true}}return false},simulatedRipple:function(){this.downAction(null);this.async(function(){this.upAction()},1)},uiDownAction:function(event){if(!this.noink){this.downAction(event)}},downAction:function(event){if(this.holdDown&&this.ripples.length>0){return}var ripple=this.addRipple();ripple.downAction(event);if(!this._animating){this._animating=true;this.animate()}},uiUpAction:function(event){if(!this.noink){this.upAction(event)}},upAction:function(event){if(this.holdDown){return}this.ripples.forEach(function(ripple){ripple.upAction(event)});this._animating=true;this.animate()},onAnimationComplete:function(){this._animating=false;this.$.background.style.backgroundColor=null;this.fire("transitionend")},addRipple:function(){var ripple=new Ripple(this);Polymer.dom(this.$.waves).appendChild(ripple.waveContainer);this.$.background.style.backgroundColor=ripple.color;this.ripples.push(ripple);this._setAnimating(true);return ripple},removeRipple:function(ripple){var rippleIndex=this.ripples.indexOf(ripple);if(rippleIndex<0){return}this.ripples.splice(rippleIndex,1);ripple.remove();if(!this.ripples.length){this._setAnimating(false)}},animate:function(){if(!this._animating){return}var index;var ripple;for(index=0;index<this.ripples.length;++index){ripple=this.ripples[index];ripple.draw();this.$.background.style.opacity=ripple.outerOpacity;if(ripple.isOpacityFullyDecayed&&!ripple.isRestingAtMaxRadius){this.removeRipple(ripple)}}if(!this.shouldKeepAnimating&&this.ripples.length===0){this.onAnimationComplete()}else{window.requestAnimationFrame(this._boundAnimate)}},_onEnterKeydown:function(){this.uiDownAction();this.async(this.uiUpAction,1)},_onSpaceKeydown:function(){this.uiDownAction()},_onSpaceKeyup:function(){this.uiUpAction()},_holdDownChanged:function(newVal,oldVal){if(oldVal===undefined){return}if(newVal){this.downAction()}else{this.upAction()}}})})();Polymer.PaperRippleBehavior={properties:{noink:{type:Boolean,observer:"_noinkChanged"},_rippleContainer:{type:Object}},_buttonStateChanged:function(){if(this.focused){this.ensureRipple()}},_downHandler:function(event){Polymer.IronButtonStateImpl._downHandler.call(this,event);if(this.pressed){this.ensureRipple(event)}},ensureRipple:function(optTriggeringEvent){if(!this.hasRipple()){this._ripple=this._createRipple();this._ripple.noink=this.noink;var rippleContainer=this._rippleContainer||this.root;if(rippleContainer){Polymer.dom(rippleContainer).appendChild(this._ripple)}if(optTriggeringEvent){var domContainer=Polymer.dom(this._rippleContainer||this);var target=Polymer.dom(optTriggeringEvent).rootTarget;if(domContainer.deepContains(target)){this._ripple.uiDownAction(optTriggeringEvent)}}}},getRipple:function(){this.ensureRipple();return this._ripple},hasRipple:function(){return Boolean(this._ripple)},_createRipple:function(){return document.createElement("paper-ripple")},_noinkChanged:function(noink){if(this.hasRipple()){this._ripple.noink=noink}}};Polymer.PaperButtonBehaviorImpl={properties:{elevation:{type:Number,reflectToAttribute:true,readOnly:true}},observers:["_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)","_computeKeyboardClass(receivedFocusFromKeyboard)"],hostAttributes:{role:"button",tabindex:"0",animated:true},_calculateElevation:function(){var e=1;if(this.disabled){e=0}else if(this.active||this.pressed){e=4}else if(this.receivedFocusFromKeyboard){e=3}this._setElevation(e)},_computeKeyboardClass:function(receivedFocusFromKeyboard){this.toggleClass("keyboard-focus",receivedFocusFromKeyboard)},_spaceKeyDownHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyDownHandler.call(this,event);if(this.hasRipple()&&this.getRipple().ripples.length<1){this._ripple.uiDownAction()}},_spaceKeyUpHandler:function(event){Polymer.IronButtonStateImpl._spaceKeyUpHandler.call(this,event);if(this.hasRipple()){this._ripple.uiUpAction()}}};Polymer.PaperButtonBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperButtonBehaviorImpl];Polymer({is:"paper-button",behaviors:[Polymer.PaperButtonBehavior],properties:{raised:{type:Boolean,reflectToAttribute:true,value:false,observer:"_calculateElevation"}},_calculateElevation:function(){if(!this.raised){this._setElevation(0)}else{Polymer.PaperButtonBehaviorImpl._calculateElevation.apply(this)}}});Polymer({is:"paper-icon-button-light","extends":"button",behaviors:[Polymer.PaperRippleBehavior],listeners:{down:"_rippleDown",up:"_rippleUp",focus:"_rippleDown",blur:"_rippleUp"},_rippleDown:function(){this.getRipple().downAction()},_rippleUp:function(){this.getRipple().upAction()},ensureRipple:function(var_args){var lastRipple=this._ripple;Polymer.PaperRippleBehavior.ensureRipple.apply(this,arguments);if(this._ripple&&this._ripple!==lastRipple){this._ripple.center=true;this._ripple.classList.add("circle")}}});Polymer.IronRangeBehavior={properties:{value:{type:Number,value:0,notify:true,reflectToAttribute:true},min:{type:Number,value:0,notify:true},max:{type:Number,value:100,notify:true},step:{type:Number,value:1,notify:true},ratio:{type:Number,value:0,readOnly:true,notify:true}},observers:["_update(value, min, max, step)"],_calcRatio:function(value){return(this._clampValue(value)-this.min)/(this.max-this.min)},_clampValue:function(value){return Math.min(this.max,Math.max(this.min,this._calcStep(value)))},_calcStep:function(value){value=parseFloat(value);if(!this.step){return value}var numSteps=Math.round((value-this.min)/this.step);if(this.step<1){return numSteps/(1/this.step)+this.min}else{return numSteps*this.step+this.min}},_validateValue:function(){var v=this._clampValue(this.value);this.value=this.oldValue=isNaN(v)?this.oldValue:v;return this.value!==v},_update:function(){this._validateValue();this._setRatio(this._calcRatio(this.value)*100)}};Polymer({is:"paper-progress",behaviors:[Polymer.IronRangeBehavior],properties:{secondaryProgress:{type:Number,value:0},secondaryRatio:{type:Number,value:0,readOnly:true},indeterminate:{type:Boolean,value:false,observer:"_toggleIndeterminate"},disabled:{type:Boolean,value:false,reflectToAttribute:true,observer:"_disabledChanged"}},observers:["_progressChanged(secondaryProgress, value, min, max)"],hostAttributes:{role:"progressbar"},_toggleIndeterminate:function(indeterminate){this.toggleClass("indeterminate",indeterminate,this.$.primaryProgress)},_transformProgress:function(progress,ratio){var transform="scaleX("+ratio/100+")";progress.style.transform=progress.style.webkitTransform=transform},_mainRatioChanged:function(ratio){this._transformProgress(this.$.primaryProgress,ratio)},_progressChanged:function(secondaryProgress,value,min,max){secondaryProgress=this._clampValue(secondaryProgress);value=this._clampValue(value);var secondaryRatio=this._calcRatio(secondaryProgress)*100;var mainRatio=this._calcRatio(value)*100;this._setSecondaryRatio(secondaryRatio);this._transformProgress(this.$.secondaryProgress,secondaryRatio);this._transformProgress(this.$.primaryProgress,mainRatio);this.secondaryProgress=secondaryProgress;this.setAttribute("aria-valuenow",value);this.setAttribute("aria-valuemin",min);this.setAttribute("aria-valuemax",max)},_disabledChanged:function(disabled){this.setAttribute("aria-disabled",disabled?"true":"false")},_hideSecondaryProgress:function(secondaryRatio){return secondaryRatio===0}});Polymer({is:"iron-iconset-svg",properties:{name:{type:String,observer:"_nameChanged"},size:{type:Number,value:24},rtlMirroring:{type:Boolean,value:false}},_targetIsRTL:function(target){if(target&&target.nodeType!==Node.ELEMENT_NODE){target=target.host}return target&&window.getComputedStyle(target)["direction"]==="rtl"},attached:function(){this.style.display="none"},getIconNames:function(){this._icons=this._createIconMap();return Object.keys(this._icons).map(function(n){return this.name+":"+n},this)},applyIcon:function(element,iconName){element=element.root||element;this.removeIcon(element);var svg=this._cloneIcon(iconName,this.rtlMirroring&&this._targetIsRTL(element));if(svg){var pde=Polymer.dom(element);pde.insertBefore(svg,pde.childNodes[0]);return element._svgIcon=svg}return null},removeIcon:function(element){element=element.root||element;if(element._svgIcon){Polymer.dom(element).removeChild(element._svgIcon);element._svgIcon=null}},_nameChanged:function(){new Polymer.IronMeta({type:"iconset",key:this.name,value:this});this.async(function(){this.fire("iron-iconset-added",this,{node:window})})},_createIconMap:function(){var icons=Object.create(null);Polymer.dom(this).querySelectorAll("[id]").forEach(function(icon){icons[icon.id]=icon});return icons},_cloneIcon:function(id,mirrorAllowed){this._icons=this._icons||this._createIconMap();return this._prepareSvgClone(this._icons[id],this.size,mirrorAllowed)},_prepareSvgClone:function(sourceSvg,size,mirrorAllowed){if(sourceSvg){var content=sourceSvg.cloneNode(true),svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),viewBox=content.getAttribute("viewBox")||"0 0 "+size+" "+size,cssText="pointer-events: none; display: block; width: 100%; height: 100%;";if(mirrorAllowed&&content.hasAttribute("mirror-in-rtl")){cssText+="-webkit-transform:scale(-1,1);transform:scale(-1,1);"}svg.setAttribute("viewBox",viewBox);svg.setAttribute("preserveAspectRatio","xMidYMid meet");svg.style.cssText=cssText;svg.appendChild(content).removeAttribute("id");return svg}return null}}); -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -cr.define("downloads",function(){var Item=Polymer({is:"downloads-item",properties:{data:{type:Object},completelyOnDisk_:{computed:"computeCompletelyOnDisk_("+"data.state, data.file_externally_removed)",type:Boolean,value:true},controlledBy_:{computed:"computeControlledBy_(data.by_ext_id, data.by_ext_name)",type:String,value:""},isActive_:{computed:"computeIsActive_("+"data.state, data.file_externally_removed)",type:Boolean,value:true},isDangerous_:{computed:"computeIsDangerous_(data.state)",type:Boolean,value:false},isMalware_:{computed:"computeIsMalware_(isDangerous_, data.danger_type)",type:Boolean,value:false},isInProgress_:{computed:"computeIsInProgress_(data.state)",type:Boolean,value:false},pauseOrResumeText_:{computed:"computePauseOrResumeText_(isInProgress_, data.resume)",type:String},showCancel_:{computed:"computeShowCancel_(data.state)",type:Boolean,value:false},showProgress_:{computed:"computeShowProgress_(showCancel_, data.percent)",type:Boolean,value:false}},observers:["observeControlledBy_(controlledBy_)","observeIsDangerous_(isDangerous_, data)"],ready:function(){this.content=this.$.content},chopUrl_:function(url){return url.slice(0,300)},computeClass_:function(){var classes=[];if(this.isActive_)classes.push("is-active");if(this.isDangerous_)classes.push("dangerous");if(this.showProgress_)classes.push("show-progress");return classes.join(" ")},computeCompletelyOnDisk_:function(){return this.data.state==downloads.States.COMPLETE&&!this.data.file_externally_removed},computeControlledBy_:function(){if(!this.data.by_ext_id||!this.data.by_ext_name)return"";var url="chrome://extensions#"+this.data.by_ext_id;var name=this.data.by_ext_name;return loadTimeData.getStringF("controlledByUrl",url,HTMLEscape(name))},computeDangerIcon_:function(){return this.isDangerous_?"cr:warning":""},computeDate_:function(){assert(typeof this.data.hideDate=="boolean");if(this.data.hideDate)return"";return assert(this.data.since_string||this.data.date_string)},computeDescription_:function(){var data=this.data;switch(data.state){case downloads.States.DANGEROUS:var fileName=data.file_name;switch(data.danger_type){case downloads.DangerType.DANGEROUS_FILE:return loadTimeData.getString("dangerFileDesc");case downloads.DangerType.DANGEROUS_URL:case downloads.DangerType.DANGEROUS_CONTENT:case downloads.DangerType.DANGEROUS_HOST:return loadTimeData.getString("dangerDownloadDesc");case downloads.DangerType.UNCOMMON_CONTENT:return loadTimeData.getString("dangerUncommonDesc");case downloads.DangerType.POTENTIALLY_UNWANTED:return loadTimeData.getString("dangerSettingsDesc")}break;case downloads.States.IN_PROGRESS:case downloads.States.PAUSED:return data.progress_status_text}return""},computeIsActive_:function(){return this.data.state!=downloads.States.CANCELLED&&this.data.state!=downloads.States.INTERRUPTED&&!this.data.file_externally_removed},computeIsDangerous_:function(){return this.data.state==downloads.States.DANGEROUS},computeIsInProgress_:function(){return this.data.state==downloads.States.IN_PROGRESS},computeIsMalware_:function(){return this.isDangerous_&&(this.data.danger_type==downloads.DangerType.DANGEROUS_CONTENT||this.data.danger_type==downloads.DangerType.DANGEROUS_HOST||this.data.danger_type==downloads.DangerType.DANGEROUS_URL||this.data.danger_type==downloads.DangerType.POTENTIALLY_UNWANTED)},computePauseOrResumeText_:function(){if(this.isInProgress_)return loadTimeData.getString("controlPause");if(this.data.resume)return loadTimeData.getString("controlResume");return""},computeRemoveStyle_:function(){var canDelete=loadTimeData.getBoolean("allowDeletingHistory");var hideRemove=this.isDangerous_||this.showCancel_||!canDelete;return hideRemove?"visibility: hidden":""},computeShowCancel_:function(){return this.data.state==downloads.States.IN_PROGRESS||this.data.state==downloads.States.PAUSED},computeShowProgress_:function(){return this.showCancel_&&this.data.percent>=-1},computeTag_:function(){switch(this.data.state){case downloads.States.CANCELLED:return loadTimeData.getString("statusCancelled");case downloads.States.INTERRUPTED:return this.data.last_reason_text;case downloads.States.COMPLETE:return this.data.file_externally_removed?loadTimeData.getString("statusRemoved"):""}return""},isIndeterminate_:function(){return this.data.percent==-1},observeControlledBy_:function(){this.$["controlled-by"].innerHTML=this.controlledBy_},observeIsDangerous_:function(){if(!this.data)return;if(this.isDangerous_){this.$.url.removeAttribute("href")}else{this.$.url.href=assert(this.data.url);var filePath=encodeURIComponent(this.data.file_path);var scaleFactor="?scale="+window.devicePixelRatio+"x";this.$["file-icon"].src="chrome://fileicon/"+filePath+scaleFactor}},onCancelTap_:function(){downloads.ActionService.getInstance().cancel(this.data.id)},onDiscardDangerousTap_:function(){downloads.ActionService.getInstance().discardDangerous(this.data.id)},onDragStart_:function(e){e.preventDefault();downloads.ActionService.getInstance().drag(this.data.id)},onFileLinkTap_:function(e){e.preventDefault();downloads.ActionService.getInstance().openFile(this.data.id)},onPauseOrResumeTap_:function(){if(this.isInProgress_)downloads.ActionService.getInstance().pause(this.data.id);else downloads.ActionService.getInstance().resume(this.data.id)},onRemoveTap_:function(){downloads.ActionService.getInstance().remove(this.data.id)},onRetryTap_:function(){downloads.ActionService.getInstance().download(this.data.url)},onSaveDangerousTap_:function(){downloads.ActionService.getInstance().saveDangerous(this.data.id)},onShowTap_:function(){downloads.ActionService.getInstance().show(this.data.id)}});return{Item:Item}});Polymer.PaperItemBehaviorImpl={hostAttributes:{role:"option",tabindex:"0"}};Polymer.PaperItemBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperItemBehaviorImpl];Polymer({is:"paper-item",behaviors:[Polymer.PaperItemBehavior]});Polymer.IronSelection=function(selectCallback){this.selection=[];this.selectCallback=selectCallback};Polymer.IronSelection.prototype={get:function(){return this.multi?this.selection.slice():this.selection[0]},clear:function(excludes){this.selection.slice().forEach(function(item){if(!excludes||excludes.indexOf(item)<0){this.setItemSelected(item,false)}},this)},isSelected:function(item){return this.selection.indexOf(item)>=0},setItemSelected:function(item,isSelected){if(item!=null){if(isSelected!==this.isSelected(item)){if(isSelected){this.selection.push(item)}else{var i=this.selection.indexOf(item);if(i>=0){this.selection.splice(i,1)}}if(this.selectCallback){this.selectCallback(item,isSelected)}}}},select:function(item){if(this.multi){this.toggle(item)}else if(this.get()!==item){this.setItemSelected(this.get(),false);this.setItemSelected(item,true)}},toggle:function(item){this.setItemSelected(item,!this.isSelected(item))}};Polymer.IronSelectableBehavior={properties:{attrForSelected:{type:String,value:null},selected:{type:String,notify:true},selectedItem:{type:Object,readOnly:true,notify:true},activateEvent:{type:String,value:"tap",observer:"_activateEventChanged"},selectable:String,selectedClass:{type:String,value:"iron-selected"},selectedAttribute:{type:String,value:null},fallbackSelection:{type:String,value:null},items:{type:Array,readOnly:true,notify:true,value:function(){return[]}},_excludedLocalNames:{type:Object,value:function(){return{template:1}}}},observers:["_updateAttrForSelected(attrForSelected)","_updateSelected(selected)","_checkFallback(fallbackSelection)"],created:function(){this._bindFilterItem=this._filterItem.bind(this);this._selection=new Polymer.IronSelection(this._applySelection.bind(this))},attached:function(){this._observer=this._observeItems(this);this._updateItems();if(!this._shouldUpdateSelection){this._updateSelected()}this._addListener(this.activateEvent)},detached:function(){if(this._observer){Polymer.dom(this).unobserveNodes(this._observer)}this._removeListener(this.activateEvent)},indexOf:function(item){return this.items.indexOf(item)},select:function(value){this.selected=value},selectPrevious:function(){var length=this.items.length;var index=(Number(this._valueToIndex(this.selected))-1+length)%length;this.selected=this._indexToValue(index)},selectNext:function(){var index=(Number(this._valueToIndex(this.selected))+1)%this.items.length;this.selected=this._indexToValue(index)},selectIndex:function(index){this.select(this._indexToValue(index))},forceSynchronousItemUpdate:function(){this._updateItems()},get _shouldUpdateSelection(){return this.selected!=null},_checkFallback:function(){if(this._shouldUpdateSelection){this._updateSelected()}},_addListener:function(eventName){this.listen(this,eventName,"_activateHandler")},_removeListener:function(eventName){this.unlisten(this,eventName,"_activateHandler")},_activateEventChanged:function(eventName,old){this._removeListener(old);this._addListener(eventName)},_updateItems:function(){var nodes=Polymer.dom(this).queryDistributedElements(this.selectable||"*");nodes=Array.prototype.filter.call(nodes,this._bindFilterItem);this._setItems(nodes)},_updateAttrForSelected:function(){if(this._shouldUpdateSelection){this.selected=this._indexToValue(this.indexOf(this.selectedItem))}},_updateSelected:function(){this._selectSelected(this.selected)},_selectSelected:function(selected){this._selection.select(this._valueToItem(this.selected));if(this.fallbackSelection&&this.items.length&&this._selection.get()===undefined){this.selected=this.fallbackSelection}},_filterItem:function(node){return!this._excludedLocalNames[node.localName]},_valueToItem:function(value){return value==null?null:this.items[this._valueToIndex(value)]},_valueToIndex:function(value){if(this.attrForSelected){for(var i=0,item;item=this.items[i];i++){if(this._valueForItem(item)==value){return i}}}else{return Number(value)}},_indexToValue:function(index){if(this.attrForSelected){var item=this.items[index];if(item){return this._valueForItem(item)}}else{return index}},_valueForItem:function(item){var propValue=item[Polymer.CaseMap.dashToCamelCase(this.attrForSelected)];return propValue!=undefined?propValue:item.getAttribute(this.attrForSelected)},_applySelection:function(item,isSelected){if(this.selectedClass){this.toggleClass(this.selectedClass,isSelected,item)}if(this.selectedAttribute){this.toggleAttribute(this.selectedAttribute,isSelected,item)}this._selectionChange();this.fire("iron-"+(isSelected?"select":"deselect"),{item:item})},_selectionChange:function(){this._setSelectedItem(this._selection.get())},_observeItems:function(node){return Polymer.dom(node).observeNodes(function(mutation){this._updateItems();if(this._shouldUpdateSelection){this._updateSelected()}this.fire("iron-items-changed",mutation,{bubbles:false,cancelable:false})})},_activateHandler:function(e){var t=e.target;var items=this.items;while(t&&t!=this){var i=items.indexOf(t);if(i>=0){var value=this._indexToValue(i);this._itemActivate(value,t);return}t=t.parentNode}},_itemActivate:function(value,item){if(!this.fire("iron-activate",{selected:value,item:item},{cancelable:true}).defaultPrevented){this.select(value)}}};Polymer.IronMultiSelectableBehaviorImpl={properties:{multi:{type:Boolean,value:false,observer:"multiChanged"},selectedValues:{type:Array,notify:true},selectedItems:{type:Array,readOnly:true,notify:true}},observers:["_updateSelected(selectedValues.splices)"],select:function(value){if(this.multi){if(this.selectedValues){this._toggleSelected(value)}else{this.selectedValues=[value]}}else{this.selected=value}},multiChanged:function(multi){this._selection.multi=multi},get _shouldUpdateSelection(){return this.selected!=null||this.selectedValues!=null&&this.selectedValues.length},_updateAttrForSelected:function(){if(!this.multi){Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this)}else if(this._shouldUpdateSelection){this.selectedValues=this.selectedItems.map(function(selectedItem){return this._indexToValue(this.indexOf(selectedItem))},this).filter(function(unfilteredValue){return unfilteredValue!=null},this)}},_updateSelected:function(){if(this.multi){this._selectMulti(this.selectedValues)}else{this._selectSelected(this.selected)}},_selectMulti:function(values){if(values){var selectedItems=this._valuesToItems(values);this._selection.clear(selectedItems);for(var i=0;i<selectedItems.length;i++){this._selection.setItemSelected(selectedItems[i],true)}if(this.fallbackSelection&&this.items.length&&!this._selection.get().length){var fallback=this._valueToItem(this.fallbackSelection);if(fallback){this.selectedValues=[this.fallbackSelection]}}}else{this._selection.clear()}},_selectionChange:function(){var s=this._selection.get();if(this.multi){this._setSelectedItems(s)}else{this._setSelectedItems([s]);this._setSelectedItem(s)}},_toggleSelected:function(value){var i=this.selectedValues.indexOf(value);var unselected=i<0;if(unselected){this.push("selectedValues",value)}else{this.splice("selectedValues",i,1)}},_valuesToItems:function(values){return values==null?null:values.map(function(value){return this._valueToItem(value)},this)}};Polymer.IronMultiSelectableBehavior=[Polymer.IronSelectableBehavior,Polymer.IronMultiSelectableBehaviorImpl];Polymer.IronMenuBehaviorImpl={properties:{focusedItem:{observer:"_focusedItemChanged",readOnly:true,type:Object},attrForItemTitle:{type:String}},hostAttributes:{role:"menu",tabindex:"0"},observers:["_updateMultiselectable(multi)"],listeners:{focus:"_onFocus",keydown:"_onKeydown","iron-items-changed":"_onIronItemsChanged"},keyBindings:{up:"_onUpKey",down:"_onDownKey",esc:"_onEscKey","shift+tab:keydown":"_onShiftTabDown"},attached:function(){this._resetTabindices()},select:function(value){if(this._defaultFocusAsync){this.cancelAsync(this._defaultFocusAsync);this._defaultFocusAsync=null}var item=this._valueToItem(value);if(item&&item.hasAttribute("disabled"))return;this._setFocusedItem(item);Polymer.IronMultiSelectableBehaviorImpl.select.apply(this,arguments)},_resetTabindices:function(){var selectedItem=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this.items.forEach(function(item){item.setAttribute("tabindex",item===selectedItem?"0":"-1")},this)},_updateMultiselectable:function(multi){if(multi){this.setAttribute("aria-multiselectable","true")}else{this.removeAttribute("aria-multiselectable")}},_focusWithKeyboardEvent:function(event){for(var i=0,item;item=this.items[i];i++){var attr=this.attrForItemTitle||"textContent";var title=item[attr]||item.getAttribute(attr);if(!item.hasAttribute("disabled")&&title&&title.trim().charAt(0).toLowerCase()===String.fromCharCode(event.keyCode).toLowerCase()){this._setFocusedItem(item);break}}},_focusPrevious:function(){var length=this.items.length;var curFocusIndex=Number(this.indexOf(this.focusedItem));for(var i=1;i<length+1;i++){var item=this.items[(curFocusIndex-i+length)%length];if(!item.hasAttribute("disabled")){var owner=Polymer.dom(item).getOwnerRoot()||document;this._setFocusedItem(item);if(Polymer.dom(owner).activeElement==item){return}}}},_focusNext:function(){var length=this.items.length;var curFocusIndex=Number(this.indexOf(this.focusedItem));for(var i=1;i<length+1;i++){var item=this.items[(curFocusIndex+i)%length];if(!item.hasAttribute("disabled")){var owner=Polymer.dom(item).getOwnerRoot()||document;this._setFocusedItem(item);if(Polymer.dom(owner).activeElement==item){return}}}},_applySelection:function(item,isSelected){if(isSelected){item.setAttribute("aria-selected","true")}else{item.removeAttribute("aria-selected")}Polymer.IronSelectableBehavior._applySelection.apply(this,arguments)},_focusedItemChanged:function(focusedItem,old){old&&old.setAttribute("tabindex","-1");if(focusedItem){focusedItem.setAttribute("tabindex","0");focusedItem.focus()}},_onIronItemsChanged:function(event){if(event.detail.addedNodes.length){this._resetTabindices()}},_onShiftTabDown:function(event){var oldTabIndex=this.getAttribute("tabindex");Polymer.IronMenuBehaviorImpl._shiftTabPressed=true;this._setFocusedItem(null);this.setAttribute("tabindex","-1");this.async(function(){this.setAttribute("tabindex",oldTabIndex);Polymer.IronMenuBehaviorImpl._shiftTabPressed=false},1)},_onFocus:function(event){if(Polymer.IronMenuBehaviorImpl._shiftTabPressed){return}var rootTarget=Polymer.dom(event).rootTarget;if(rootTarget!==this&&typeof rootTarget.tabIndex!=="undefined"&&!this.isLightDescendant(rootTarget)){return}this._defaultFocusAsync=this.async(function(){var selectedItem=this.multi?this.selectedItems&&this.selectedItems[0]:this.selectedItem;this._setFocusedItem(null);if(selectedItem){this._setFocusedItem(selectedItem)}else if(this.items[0]){this._focusNext()}})},_onUpKey:function(event){this._focusPrevious();event.detail.keyboardEvent.preventDefault()},_onDownKey:function(event){this._focusNext();event.detail.keyboardEvent.preventDefault()},_onEscKey:function(event){this.focusedItem.blur()},_onKeydown:function(event){if(!this.keyboardEventMatchesKeys(event,"up down esc")){this._focusWithKeyboardEvent(event)}event.stopPropagation()},_activateHandler:function(event){Polymer.IronSelectableBehavior._activateHandler.call(this,event);event.stopPropagation()}};Polymer.IronMenuBehaviorImpl._shiftTabPressed=false;Polymer.IronMenuBehavior=[Polymer.IronMultiSelectableBehavior,Polymer.IronA11yKeysBehavior,Polymer.IronMenuBehaviorImpl];(function(){Polymer({is:"paper-menu",behaviors:[Polymer.IronMenuBehavior]})})();Polymer.IronFitBehavior={properties:{sizingTarget:{type:Object,value:function(){return this}},fitInto:{type:Object,value:window},noOverlap:{type:Boolean},positionTarget:{type:Element},horizontalAlign:{type:String},verticalAlign:{type:String},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:true},verticalOffset:{type:Number,value:0,notify:true},autoFitOnAttach:{type:Boolean,value:false},_fitInfo:{type:Object}},get _fitWidth(){var fitWidth;if(this.fitInto===window){fitWidth=this.fitInto.innerWidth}else{fitWidth=this.fitInto.getBoundingClientRect().width}return fitWidth},get _fitHeight(){var fitHeight;if(this.fitInto===window){fitHeight=this.fitInto.innerHeight}else{fitHeight=this.fitInto.getBoundingClientRect().height}return fitHeight},get _fitLeft(){var fitLeft;if(this.fitInto===window){fitLeft=0}else{fitLeft=this.fitInto.getBoundingClientRect().left}return fitLeft},get _fitTop(){var fitTop;if(this.fitInto===window){fitTop=0}else{fitTop=this.fitInto.getBoundingClientRect().top}return fitTop},get _defaultPositionTarget(){var parent=Polymer.dom(this).parentNode;if(parent&&parent.nodeType===Node.DOCUMENT_FRAGMENT_NODE){parent=parent.host}return parent},get _localeHorizontalAlign(){if(this._isRTL){if(this.horizontalAlign==="right"){return"left"}if(this.horizontalAlign==="left"){return"right"}}return this.horizontalAlign},attached:function(){this._isRTL=window.getComputedStyle(this).direction=="rtl";this.positionTarget=this.positionTarget||this._defaultPositionTarget;if(this.autoFitOnAttach){if(window.getComputedStyle(this).display==="none"){setTimeout(function(){this.fit()}.bind(this))}else{this.fit()}}},fit:function(){this.position();this.constrain();this.center()},_discoverInfo:function(){if(this._fitInfo){return}var target=window.getComputedStyle(this);var sizer=window.getComputedStyle(this.sizingTarget);this._fitInfo={inlineStyle:{top:this.style.top||"",left:this.style.left||"",position:this.style.position||""},sizerInlineStyle:{maxWidth:this.sizingTarget.style.maxWidth||"",maxHeight:this.sizingTarget.style.maxHeight||"",boxSizing:this.sizingTarget.style.boxSizing||""},positionedBy:{vertically:target.top!=="auto"?"top":target.bottom!=="auto"?"bottom":null,horizontally:target.left!=="auto"?"left":target.right!=="auto"?"right":null},sizedBy:{height:sizer.maxHeight!=="none",width:sizer.maxWidth!=="none",minWidth:parseInt(sizer.minWidth,10)||0,minHeight:parseInt(sizer.minHeight,10)||0},margin:{top:parseInt(target.marginTop,10)||0,right:parseInt(target.marginRight,10)||0,bottom:parseInt(target.marginBottom,10)||0,left:parseInt(target.marginLeft,10)||0}};if(this.verticalOffset){this._fitInfo.margin.top=this._fitInfo.margin.bottom=this.verticalOffset;this._fitInfo.inlineStyle.marginTop=this.style.marginTop||"";this._fitInfo.inlineStyle.marginBottom=this.style.marginBottom||"";this.style.marginTop=this.style.marginBottom=this.verticalOffset+"px"}if(this.horizontalOffset){this._fitInfo.margin.left=this._fitInfo.margin.right=this.horizontalOffset;this._fitInfo.inlineStyle.marginLeft=this.style.marginLeft||"";this._fitInfo.inlineStyle.marginRight=this.style.marginRight||"";this.style.marginLeft=this.style.marginRight=this.horizontalOffset+"px"}},resetFit:function(){var info=this._fitInfo||{};for(var property in info.sizerInlineStyle){this.sizingTarget.style[property]=info.sizerInlineStyle[property]}for(var property in info.inlineStyle){this.style[property]=info.inlineStyle[property]}this._fitInfo=null},refit:function(){var scrollLeft=this.sizingTarget.scrollLeft;var scrollTop=this.sizingTarget.scrollTop;this.resetFit();this.fit();this.sizingTarget.scrollLeft=scrollLeft;this.sizingTarget.scrollTop=scrollTop},position:function(){if(!this.horizontalAlign&&!this.verticalAlign){return}this._discoverInfo();this.style.position="fixed";this.sizingTarget.style.boxSizing="border-box";this.style.left="0px";this.style.top="0px";var rect=this.getBoundingClientRect();var positionRect=this.__getNormalizedRect(this.positionTarget);var fitRect=this.__getNormalizedRect(this.fitInto);var margin=this._fitInfo.margin;var size={width:rect.width+margin.left+margin.right,height:rect.height+margin.top+margin.bottom};var position=this.__getPosition(this._localeHorizontalAlign,this.verticalAlign,size,positionRect,fitRect);var left=position.left+margin.left;var top=position.top+margin.top;var right=Math.min(fitRect.right-margin.right,left+rect.width);var bottom=Math.min(fitRect.bottom-margin.bottom,top+rect.height);var minWidth=this._fitInfo.sizedBy.minWidth;var minHeight=this._fitInfo.sizedBy.minHeight;if(left<margin.left){left=margin.left;if(right-left<minWidth){left=right-minWidth}}if(top<margin.top){top=margin.top;if(bottom-top<minHeight){top=bottom-minHeight}}this.sizingTarget.style.maxWidth=right-left+"px";this.sizingTarget.style.maxHeight=bottom-top+"px";this.style.left=left-rect.left+"px";this.style.top=top-rect.top+"px"},constrain:function(){if(this.horizontalAlign||this.verticalAlign){return}this._discoverInfo();var info=this._fitInfo;if(!info.positionedBy.vertically){this.style.position="fixed";this.style.top="0px"}if(!info.positionedBy.horizontally){this.style.position="fixed";this.style.left="0px"}this.sizingTarget.style.boxSizing="border-box";var rect=this.getBoundingClientRect();if(!info.sizedBy.height){this.__sizeDimension(rect,info.positionedBy.vertically,"top","bottom","Height")}if(!info.sizedBy.width){this.__sizeDimension(rect,info.positionedBy.horizontally,"left","right","Width")}},_sizeDimension:function(rect,positionedBy,start,end,extent){this.__sizeDimension(rect,positionedBy,start,end,extent)},__sizeDimension:function(rect,positionedBy,start,end,extent){var info=this._fitInfo;var fitRect=this.__getNormalizedRect(this.fitInto);var max=extent==="Width"?fitRect.width:fitRect.height;var flip=positionedBy===end;var offset=flip?max-rect[end]:rect[start];var margin=info.margin[flip?start:end];var offsetExtent="offset"+extent;var sizingOffset=this[offsetExtent]-this.sizingTarget[offsetExtent];this.sizingTarget.style["max"+extent]=max-margin-offset-sizingOffset+"px"},center:function(){if(this.horizontalAlign||this.verticalAlign){return}this._discoverInfo();var positionedBy=this._fitInfo.positionedBy;if(positionedBy.vertically&&positionedBy.horizontally){return}this.style.position="fixed";if(!positionedBy.vertically){this.style.top="0px"}if(!positionedBy.horizontally){this.style.left="0px"}var rect=this.getBoundingClientRect();var fitRect=this.__getNormalizedRect(this.fitInto);if(!positionedBy.vertically){var top=fitRect.top-rect.top+(fitRect.height-rect.height)/2;this.style.top=top+"px"}if(!positionedBy.horizontally){var left=fitRect.left-rect.left+(fitRect.width-rect.width)/2;this.style.left=left+"px"}},__getNormalizedRect:function(target){if(target===document.documentElement||target===window){return{top:0,left:0,width:window.innerWidth,height:window.innerHeight,right:window.innerWidth,bottom:window.innerHeight}}return target.getBoundingClientRect()},__getCroppedArea:function(position,size,fitRect){var verticalCrop=Math.min(0,position.top)+Math.min(0,fitRect.bottom-(position.top+size.height));var horizontalCrop=Math.min(0,position.left)+Math.min(0,fitRect.right-(position.left+size.width));return Math.abs(verticalCrop)*size.width+Math.abs(horizontalCrop)*size.height},__getPosition:function(hAlign,vAlign,size,positionRect,fitRect){var positions=[{verticalAlign:"top",horizontalAlign:"left",top:positionRect.top,left:positionRect.left},{verticalAlign:"top",horizontalAlign:"right",top:positionRect.top,left:positionRect.right-size.width},{verticalAlign:"bottom",horizontalAlign:"left",top:positionRect.bottom-size.height,left:positionRect.left},{verticalAlign:"bottom",horizontalAlign:"right",top:positionRect.bottom-size.height,left:positionRect.right-size.width}];if(this.noOverlap){for(var i=0,l=positions.length;i<l;i++){var copy={};for(var key in positions[i]){copy[key]=positions[i][key]}positions.push(copy)}positions[0].top=positions[1].top+=positionRect.height;positions[2].top=positions[3].top-=positionRect.height;positions[4].left=positions[6].left+=positionRect.width;positions[5].left=positions[7].left-=positionRect.width}vAlign=vAlign==="auto"?null:vAlign;hAlign=hAlign==="auto"?null:hAlign;var position;for(var i=0;i<positions.length;i++){var pos=positions[i];if(!this.dynamicAlign&&!this.noOverlap&&pos.verticalAlign===vAlign&&pos.horizontalAlign===hAlign){position=pos;break}var alignOk=(!vAlign||pos.verticalAlign===vAlign)&&(!hAlign||pos.horizontalAlign===hAlign);if(!this.dynamicAlign&&!alignOk){continue}position=position||pos;pos.croppedArea=this.__getCroppedArea(pos,size,fitRect);var diff=pos.croppedArea-position.croppedArea;if(diff<0||diff===0&&alignOk){position=pos}if(position.croppedArea===0&&alignOk){break}}return position}};(function(){"use strict";Polymer({is:"iron-overlay-backdrop",properties:{opened:{reflectToAttribute:true,type:Boolean,value:false,observer:"_openedChanged"}},listeners:{transitionend:"_onTransitionend"},created:function(){this.__openedRaf=null},attached:function(){this.opened&&this._openedChanged(this.opened)},prepare:function(){if(this.opened&&!this.parentNode){Polymer.dom(document.body).appendChild(this)}},open:function(){this.opened=true},close:function(){this.opened=false},complete:function(){if(!this.opened&&this.parentNode===document.body){Polymer.dom(this.parentNode).removeChild(this)}},_onTransitionend:function(event){if(event&&event.target===this){this.complete()}},_openedChanged:function(opened){if(opened){this.prepare()}else{var cs=window.getComputedStyle(this);if(cs.transitionDuration==="0s"||cs.opacity==0){this.complete()}}if(!this.isAttached){return}if(this.__openedRaf){window.cancelAnimationFrame(this.__openedRaf);this.__openedRaf=null}this.scrollTop=this.scrollTop;this.__openedRaf=window.requestAnimationFrame(function(){this.__openedRaf=null;this.toggleClass("opened",this.opened)}.bind(this))}})})();Polymer.IronOverlayManagerClass=function(){this._overlays=[];this._minimumZ=101;this._backdropElement=null;Polymer.Gestures.add(document,"tap",this._onCaptureClick.bind(this));document.addEventListener("focus",this._onCaptureFocus.bind(this),true);document.addEventListener("keydown",this._onCaptureKeyDown.bind(this),true)};Polymer.IronOverlayManagerClass.prototype={constructor:Polymer.IronOverlayManagerClass,get backdropElement(){if(!this._backdropElement){this._backdropElement=document.createElement("iron-overlay-backdrop")}return this._backdropElement},get deepActiveElement(){var active=document.activeElement||document.body;while(active.root&&Polymer.dom(active.root).activeElement){active=Polymer.dom(active.root).activeElement}return active},_bringOverlayAtIndexToFront:function(i){var overlay=this._overlays[i];if(!overlay){return}var lastI=this._overlays.length-1;var currentOverlay=this._overlays[lastI];if(currentOverlay&&this._shouldBeBehindOverlay(overlay,currentOverlay)){lastI--}if(i>=lastI){return}var minimumZ=Math.max(this.currentOverlayZ(),this._minimumZ);if(this._getZ(overlay)<=minimumZ){this._applyOverlayZ(overlay,minimumZ)}while(i<lastI){this._overlays[i]=this._overlays[i+1];i++}this._overlays[lastI]=overlay},addOrRemoveOverlay:function(overlay){if(overlay.opened){this.addOverlay(overlay)}else{this.removeOverlay(overlay)}},addOverlay:function(overlay){var i=this._overlays.indexOf(overlay);if(i>=0){this._bringOverlayAtIndexToFront(i);this.trackBackdrop();return}var insertionIndex=this._overlays.length;var currentOverlay=this._overlays[insertionIndex-1];var minimumZ=Math.max(this._getZ(currentOverlay),this._minimumZ);var newZ=this._getZ(overlay);if(currentOverlay&&this._shouldBeBehindOverlay(overlay,currentOverlay)){this._applyOverlayZ(currentOverlay,minimumZ);insertionIndex--;var previousOverlay=this._overlays[insertionIndex-1];minimumZ=Math.max(this._getZ(previousOverlay),this._minimumZ)}if(newZ<=minimumZ){this._applyOverlayZ(overlay,minimumZ)}this._overlays.splice(insertionIndex,0,overlay);this.trackBackdrop()},removeOverlay:function(overlay){var i=this._overlays.indexOf(overlay);if(i===-1){return}this._overlays.splice(i,1);this.trackBackdrop()},currentOverlay:function(){var i=this._overlays.length-1;return this._overlays[i]},currentOverlayZ:function(){return this._getZ(this.currentOverlay())},ensureMinimumZ:function(minimumZ){this._minimumZ=Math.max(this._minimumZ,minimumZ)},focusOverlay:function(){var current=this.currentOverlay();if(current){current._applyFocus()}},trackBackdrop:function(){var overlay=this._overlayWithBackdrop();if(!overlay&&!this._backdropElement){return}this.backdropElement.style.zIndex=this._getZ(overlay)-1;this.backdropElement.opened=!!overlay},getBackdrops:function(){var backdrops=[];for(var i=0;i<this._overlays.length;i++){if(this._overlays[i].withBackdrop){backdrops.push(this._overlays[i])}}return backdrops},backdropZ:function(){return this._getZ(this._overlayWithBackdrop())-1},_overlayWithBackdrop:function(){for(var i=0;i<this._overlays.length;i++){if(this._overlays[i].withBackdrop){return this._overlays[i]}}},_getZ:function(overlay){var z=this._minimumZ;if(overlay){var z1=Number(overlay.style.zIndex||window.getComputedStyle(overlay).zIndex);if(z1===z1){z=z1}}return z},_setZ:function(element,z){element.style.zIndex=z},_applyOverlayZ:function(overlay,aboveZ){this._setZ(overlay,aboveZ+2)},_overlayInPath:function(path){path=path||[];for(var i=0;i<path.length;i++){if(path[i]._manager===this){return path[i]}}},_onCaptureClick:function(event){var overlay=this.currentOverlay();if(overlay&&this._overlayInPath(Polymer.dom(event).path)!==overlay){overlay._onCaptureClick(event)}},_onCaptureFocus:function(event){var overlay=this.currentOverlay();if(overlay){overlay._onCaptureFocus(event)}},_onCaptureKeyDown:function(event){var overlay=this.currentOverlay();if(overlay){if(Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event,"esc")){overlay._onCaptureEsc(event)}else if(Polymer.IronA11yKeysBehavior.keyboardEventMatchesKeys(event,"tab")){overlay._onCaptureTab(event)}}},_shouldBeBehindOverlay:function(overlay1,overlay2){return!overlay1.alwaysOnTop&&overlay2.alwaysOnTop}};Polymer.IronOverlayManager=new Polymer.IronOverlayManagerClass;(function(){"use strict";var p=Element.prototype;var matches=p.matches||p.matchesSelector||p.mozMatchesSelector||p.msMatchesSelector||p.oMatchesSelector||p.webkitMatchesSelector;Polymer.IronFocusablesHelper={getTabbableNodes:function(node){var result=[];var needsSortByTabIndex=this._collectTabbableNodes(node,result);if(needsSortByTabIndex){return this._sortByTabIndex(result)}return result},isFocusable:function(element){if(matches.call(element,"input, select, textarea, button, object")){ -return matches.call(element,":not([disabled])")}return matches.call(element,"a[href], area[href], iframe, [tabindex], [contentEditable]")},isTabbable:function(element){return this.isFocusable(element)&&matches.call(element,':not([tabindex="-1"])')&&this._isVisible(element)},_normalizedTabIndex:function(element){if(this.isFocusable(element)){var tabIndex=element.getAttribute("tabindex")||0;return Number(tabIndex)}return-1},_collectTabbableNodes:function(node,result){if(node.nodeType!==Node.ELEMENT_NODE||!this._isVisible(node)){return false}var element=node;var tabIndex=this._normalizedTabIndex(element);var needsSortByTabIndex=tabIndex>0;if(tabIndex>=0){result.push(element)}var children;if(element.localName==="content"){children=Polymer.dom(element).getDistributedNodes()}else{children=Polymer.dom(element.root||element).children}for(var i=0;i<children.length;i++){var needsSort=this._collectTabbableNodes(children[i],result);needsSortByTabIndex=needsSortByTabIndex||needsSort}return needsSortByTabIndex},_isVisible:function(element){var style=element.style;if(style.visibility!=="hidden"&&style.display!=="none"){style=window.getComputedStyle(element);return style.visibility!=="hidden"&&style.display!=="none"}return false},_sortByTabIndex:function(tabbables){var len=tabbables.length;if(len<2){return tabbables}var pivot=Math.ceil(len/2);var left=this._sortByTabIndex(tabbables.slice(0,pivot));var right=this._sortByTabIndex(tabbables.slice(pivot));return this._mergeSortByTabIndex(left,right)},_mergeSortByTabIndex:function(left,right){var result=[];while(left.length>0&&right.length>0){if(this._hasLowerTabOrder(left[0],right[0])){result.push(right.shift())}else{result.push(left.shift())}}return result.concat(left,right)},_hasLowerTabOrder:function(a,b){var ati=Math.max(a.tabIndex,0);var bti=Math.max(b.tabIndex,0);return ati===0||bti===0?bti>ati:ati>bti}}})();(function(){"use strict";Polymer.IronOverlayBehaviorImpl={properties:{opened:{observer:"_openedChanged",type:Boolean,value:false,notify:true},canceled:{observer:"_canceledChanged",readOnly:true,type:Boolean,value:false},withBackdrop:{observer:"_withBackdropChanged",type:Boolean},noAutoFocus:{type:Boolean,value:false},noCancelOnEscKey:{type:Boolean,value:false},noCancelOnOutsideClick:{type:Boolean,value:false},closingReason:{type:Object},restoreFocusOnClose:{type:Boolean,value:false},alwaysOnTop:{type:Boolean},_manager:{type:Object,value:Polymer.IronOverlayManager},_focusedChild:{type:Object}},listeners:{"iron-resize":"_onIronResize"},get backdropElement(){return this._manager.backdropElement},get _focusNode(){return this._focusedChild||Polymer.dom(this).querySelector("[autofocus]")||this},get _focusableNodes(){return Polymer.IronFocusablesHelper.getTabbableNodes(this)},ready:function(){this.__isAnimating=false;this.__shouldRemoveTabIndex=false;this.__firstFocusableNode=this.__lastFocusableNode=null;this.__raf=null;this.__restoreFocusNode=null;this._ensureSetup()},attached:function(){if(this.opened){this._openedChanged(this.opened)}this._observer=Polymer.dom(this).observeNodes(this._onNodesChange)},detached:function(){Polymer.dom(this).unobserveNodes(this._observer);this._observer=null;if(this.__raf){window.cancelAnimationFrame(this.__raf);this.__raf=null}this._manager.removeOverlay(this)},toggle:function(){this._setCanceled(false);this.opened=!this.opened},open:function(){this._setCanceled(false);this.opened=true},close:function(){this._setCanceled(false);this.opened=false},cancel:function(event){var cancelEvent=this.fire("iron-overlay-canceled",event,{cancelable:true});if(cancelEvent.defaultPrevented){return}this._setCanceled(true);this.opened=false},invalidateTabbables:function(){this.__firstFocusableNode=this.__lastFocusableNode=null},_ensureSetup:function(){if(this._overlaySetup){return}this._overlaySetup=true;this.style.outline="none";this.style.display="none"},_openedChanged:function(opened){if(opened){this.removeAttribute("aria-hidden")}else{this.setAttribute("aria-hidden","true")}if(!this.isAttached){return}this.__isAnimating=true;this.__onNextAnimationFrame(this.__openedChanged)},_canceledChanged:function(){this.closingReason=this.closingReason||{};this.closingReason.canceled=this.canceled},_withBackdropChanged:function(){if(this.withBackdrop&&!this.hasAttribute("tabindex")){this.setAttribute("tabindex","-1");this.__shouldRemoveTabIndex=true}else if(this.__shouldRemoveTabIndex){this.removeAttribute("tabindex");this.__shouldRemoveTabIndex=false}if(this.opened&&this.isAttached){this._manager.trackBackdrop()}},_prepareRenderOpened:function(){this.__restoreFocusNode=this._manager.deepActiveElement;this._preparePositioning();this.refit();this._finishPositioning();if(this.noAutoFocus&&document.activeElement===this._focusNode){this._focusNode.blur();this.__restoreFocusNode.focus()}},_renderOpened:function(){this._finishRenderOpened()},_renderClosed:function(){this._finishRenderClosed()},_finishRenderOpened:function(){this.notifyResize();this.__isAnimating=false;this.fire("iron-overlay-opened")},_finishRenderClosed:function(){this.style.display="none";this.style.zIndex="";this.notifyResize();this.__isAnimating=false;this.fire("iron-overlay-closed",this.closingReason)},_preparePositioning:function(){this.style.transition=this.style.webkitTransition="none";this.style.transform=this.style.webkitTransform="none";this.style.display=""},_finishPositioning:function(){this.style.display="none";this.scrollTop=this.scrollTop;this.style.transition=this.style.webkitTransition="";this.style.transform=this.style.webkitTransform="";this.style.display="";this.scrollTop=this.scrollTop},_applyFocus:function(){if(this.opened){if(!this.noAutoFocus){this._focusNode.focus()}}else{this._focusNode.blur();this._focusedChild=null;if(this.restoreFocusOnClose&&this.__restoreFocusNode){this.__restoreFocusNode.focus()}this.__restoreFocusNode=null;var currentOverlay=this._manager.currentOverlay();if(currentOverlay&&this!==currentOverlay){currentOverlay._applyFocus()}}},_onCaptureClick:function(event){if(!this.noCancelOnOutsideClick){this.cancel(event)}},_onCaptureFocus:function(event){if(!this.withBackdrop){return}var path=Polymer.dom(event).path;if(path.indexOf(this)===-1){event.stopPropagation();this._applyFocus()}else{this._focusedChild=path[0]}},_onCaptureEsc:function(event){if(!this.noCancelOnEscKey){this.cancel(event)}},_onCaptureTab:function(event){if(!this.withBackdrop){return}this.__ensureFirstLastFocusables();var shift=event.shiftKey;var nodeToCheck=shift?this.__firstFocusableNode:this.__lastFocusableNode;var nodeToSet=shift?this.__lastFocusableNode:this.__firstFocusableNode;var shouldWrap=false;if(nodeToCheck===nodeToSet){shouldWrap=true}else{var focusedNode=this._manager.deepActiveElement;shouldWrap=focusedNode===nodeToCheck||focusedNode===this}if(shouldWrap){event.preventDefault();this._focusedChild=nodeToSet;this._applyFocus()}},_onIronResize:function(){if(this.opened&&!this.__isAnimating){this.__onNextAnimationFrame(this.refit)}},_onNodesChange:function(){if(this.opened&&!this.__isAnimating){this.invalidateTabbables();this.notifyResize()}},__ensureFirstLastFocusables:function(){if(!this.__firstFocusableNode||!this.__lastFocusableNode){var focusableNodes=this._focusableNodes;this.__firstFocusableNode=focusableNodes[0];this.__lastFocusableNode=focusableNodes[focusableNodes.length-1]}},__openedChanged:function(){if(this.opened){this._prepareRenderOpened();this._manager.addOverlay(this);this._applyFocus();this._renderOpened()}else{this._manager.removeOverlay(this);this._applyFocus();this._renderClosed()}},__onNextAnimationFrame:function(callback){if(this.__raf){window.cancelAnimationFrame(this.__raf)}var self=this;this.__raf=window.requestAnimationFrame(function nextAnimationFrame(){self.__raf=null;callback.call(self)})}};Polymer.IronOverlayBehavior=[Polymer.IronFitBehavior,Polymer.IronResizableBehavior,Polymer.IronOverlayBehaviorImpl]})();Polymer.NeonAnimatableBehavior={properties:{animationConfig:{type:Object},entryAnimation:{observer:"_entryAnimationChanged",type:String},exitAnimation:{observer:"_exitAnimationChanged",type:String}},_entryAnimationChanged:function(){this.animationConfig=this.animationConfig||{};this.animationConfig["entry"]=[{name:this.entryAnimation,node:this}]},_exitAnimationChanged:function(){this.animationConfig=this.animationConfig||{};this.animationConfig["exit"]=[{name:this.exitAnimation,node:this}]},_copyProperties:function(config1,config2){for(var property in config2){config1[property]=config2[property]}},_cloneConfig:function(config){var clone={isClone:true};this._copyProperties(clone,config);return clone},_getAnimationConfigRecursive:function(type,map,allConfigs){if(!this.animationConfig){return}if(this.animationConfig.value&&typeof this.animationConfig.value==="function"){this._warn(this._logf("playAnimation","Please put 'animationConfig' inside of your components 'properties' object instead of outside of it."));return}var thisConfig;if(type){thisConfig=this.animationConfig[type]}else{thisConfig=this.animationConfig}if(!Array.isArray(thisConfig)){thisConfig=[thisConfig]}if(thisConfig){for(var config,index=0;config=thisConfig[index];index++){if(config.animatable){config.animatable._getAnimationConfigRecursive(config.type||type,map,allConfigs)}else{if(config.id){var cachedConfig=map[config.id];if(cachedConfig){if(!cachedConfig.isClone){map[config.id]=this._cloneConfig(cachedConfig);cachedConfig=map[config.id]}this._copyProperties(cachedConfig,config)}else{map[config.id]=config}}else{allConfigs.push(config)}}}}},getAnimationConfig:function(type){var map={};var allConfigs=[];this._getAnimationConfigRecursive(type,map,allConfigs);for(var key in map){allConfigs.push(map[key])}return allConfigs}};Polymer.NeonAnimationRunnerBehaviorImpl={_configureAnimations:function(configs){var results=[];if(configs.length>0){for(var config,index=0;config=configs[index];index++){var neonAnimation=document.createElement(config.name);if(neonAnimation.isNeonAnimation){var result=null;try{result=neonAnimation.configure(config);if(typeof result.cancel!="function"){result=document.timeline.play(result)}}catch(e){result=null;console.warn("Couldnt play","(",config.name,").",e)}if(result){results.push({neonAnimation:neonAnimation,config:config,animation:result})}}else{console.warn(this.is+":",config.name,"not found!")}}}return results},_shouldComplete:function(activeEntries){var finished=true;for(var i=0;i<activeEntries.length;i++){if(activeEntries[i].animation.playState!="finished"){finished=false;break}}return finished},_complete:function(activeEntries){for(var i=0;i<activeEntries.length;i++){activeEntries[i].neonAnimation.complete(activeEntries[i].config)}for(var i=0;i<activeEntries.length;i++){activeEntries[i].animation.cancel()}},playAnimation:function(type,cookie){var configs=this.getAnimationConfig(type);if(!configs){return}this._active=this._active||{};if(this._active[type]){this._complete(this._active[type]);delete this._active[type]}var activeEntries=this._configureAnimations(configs);if(activeEntries.length==0){this.fire("neon-animation-finish",cookie,{bubbles:false});return}this._active[type]=activeEntries;for(var i=0;i<activeEntries.length;i++){activeEntries[i].animation.onfinish=function(){if(this._shouldComplete(activeEntries)){this._complete(activeEntries);delete this._active[type];this.fire("neon-animation-finish",cookie,{bubbles:false})}}.bind(this)}},cancelAnimation:function(){for(var k in this._animations){this._animations[k].cancel()}this._animations={}}};Polymer.NeonAnimationRunnerBehavior=[Polymer.NeonAnimatableBehavior,Polymer.NeonAnimationRunnerBehaviorImpl];Polymer.NeonAnimationBehavior={properties:{animationTiming:{type:Object,value:function(){return{duration:500,easing:"cubic-bezier(0.4, 0, 0.2, 1)",fill:"both"}}}},isNeonAnimation:true,timingFromConfig:function(config){if(config.timing){for(var property in config.timing){this.animationTiming[property]=config.timing[property]}}return this.animationTiming},setPrefixedProperty:function(node,property,value){var map={transform:["webkitTransform"],transformOrigin:["mozTransformOrigin","webkitTransformOrigin"]};var prefixes=map[property];for(var prefix,index=0;prefix=prefixes[index];index++){node.style[prefix]=value}node.style[property]=value},complete:function(){}};Polymer({is:"opaque-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;this._effect=new KeyframeEffect(node,[{opacity:"1"},{opacity:"1"}],this.timingFromConfig(config));node.style.opacity="0";return this._effect},complete:function(config){config.node.style.opacity=""}});(function(){"use strict";var LAST_TOUCH_POSITION={pageX:0,pageY:0};var ROOT_TARGET=null;var SCROLLABLE_NODES=[];Polymer.IronDropdownScrollManager={get currentLockingElement(){return this._lockingElements[this._lockingElements.length-1]},elementIsScrollLocked:function(element){var currentLockingElement=this.currentLockingElement;if(currentLockingElement===undefined)return false;var scrollLocked;if(this._hasCachedLockedElement(element)){return true}if(this._hasCachedUnlockedElement(element)){return false}scrollLocked=!!currentLockingElement&¤tLockingElement!==element&&!this._composedTreeContains(currentLockingElement,element);if(scrollLocked){this._lockedElementCache.push(element)}else{this._unlockedElementCache.push(element)}return scrollLocked},pushScrollLock:function(element){if(this._lockingElements.indexOf(element)>=0){return}if(this._lockingElements.length===0){this._lockScrollInteractions()}this._lockingElements.push(element);this._lockedElementCache=[];this._unlockedElementCache=[]},removeScrollLock:function(element){var index=this._lockingElements.indexOf(element);if(index===-1){return}this._lockingElements.splice(index,1);this._lockedElementCache=[];this._unlockedElementCache=[];if(this._lockingElements.length===0){this._unlockScrollInteractions()}},_lockingElements:[],_lockedElementCache:null,_unlockedElementCache:null,_hasCachedLockedElement:function(element){return this._lockedElementCache.indexOf(element)>-1},_hasCachedUnlockedElement:function(element){return this._unlockedElementCache.indexOf(element)>-1},_composedTreeContains:function(element,child){var contentElements;var distributedNodes;var contentIndex;var nodeIndex;if(element.contains(child)){return true}contentElements=Polymer.dom(element).querySelectorAll("content");for(contentIndex=0;contentIndex<contentElements.length;++contentIndex){distributedNodes=Polymer.dom(contentElements[contentIndex]).getDistributedNodes();for(nodeIndex=0;nodeIndex<distributedNodes.length;++nodeIndex){if(this._composedTreeContains(distributedNodes[nodeIndex],child)){return true}}}return false},_scrollInteractionHandler:function(event){if(event.cancelable&&this._shouldPreventScrolling(event)){event.preventDefault()}if(event.targetTouches){var touch=event.targetTouches[0];LAST_TOUCH_POSITION.pageX=touch.pageX;LAST_TOUCH_POSITION.pageY=touch.pageY}},_lockScrollInteractions:function(){this._boundScrollHandler=this._boundScrollHandler||this._scrollInteractionHandler.bind(this);document.addEventListener("wheel",this._boundScrollHandler,true);document.addEventListener("mousewheel",this._boundScrollHandler,true);document.addEventListener("DOMMouseScroll",this._boundScrollHandler,true);document.addEventListener("touchstart",this._boundScrollHandler,true);document.addEventListener("touchmove",this._boundScrollHandler,true)},_unlockScrollInteractions:function(){document.removeEventListener("wheel",this._boundScrollHandler,true);document.removeEventListener("mousewheel",this._boundScrollHandler,true);document.removeEventListener("DOMMouseScroll",this._boundScrollHandler,true);document.removeEventListener("touchstart",this._boundScrollHandler,true);document.removeEventListener("touchmove",this._boundScrollHandler,true)},_shouldPreventScrolling:function(event){var target=Polymer.dom(event).rootTarget;if(event.type!=="touchmove"&&ROOT_TARGET!==target){ROOT_TARGET=target;SCROLLABLE_NODES=this._getScrollableNodes(Polymer.dom(event).path)}if(!SCROLLABLE_NODES.length){return true}if(event.type==="touchstart"){return false}var info=this._getScrollInfo(event);return!this._getScrollingNode(SCROLLABLE_NODES,info.deltaX,info.deltaY)},_getScrollableNodes:function(nodes){var scrollables=[];var lockingIndex=nodes.indexOf(this.currentLockingElement);for(var i=0;i<=lockingIndex;i++){var node=nodes[i];if(node.nodeType===11){continue}var style=node.style;if(style.overflow!=="scroll"&&style.overflow!=="auto"){style=window.getComputedStyle(node)}if(style.overflow==="scroll"||style.overflow==="auto"){scrollables.push(node)}}return scrollables},_getScrollingNode:function(nodes,deltaX,deltaY){if(!deltaX&&!deltaY){return}var verticalScroll=Math.abs(deltaY)>=Math.abs(deltaX);for(var i=0;i<nodes.length;i++){var node=nodes[i];var canScroll=false;if(verticalScroll){canScroll=deltaY<0?node.scrollTop>0:node.scrollTop<node.scrollHeight-node.clientHeight}else{canScroll=deltaX<0?node.scrollLeft>0:node.scrollLeft<node.scrollWidth-node.clientWidth}if(canScroll){return node}}},_getScrollInfo:function(event){var info={deltaX:event.deltaX,deltaY:event.deltaY};if("deltaX"in event){}else if("wheelDeltaX"in event){info.deltaX=-event.wheelDeltaX;info.deltaY=-event.wheelDeltaY}else if("axis"in event){info.deltaX=event.axis===1?event.detail:0;info.deltaY=event.axis===2?event.detail:0}else if(event.targetTouches){var touch=event.targetTouches[0];info.deltaX=LAST_TOUCH_POSITION.pageX-touch.pageX;info.deltaY=LAST_TOUCH_POSITION.pageY-touch.pageY}return info}}})();(function(){"use strict";Polymer({is:"iron-dropdown",behaviors:[Polymer.IronControlState,Polymer.IronA11yKeysBehavior,Polymer.IronOverlayBehavior,Polymer.NeonAnimationRunnerBehavior],properties:{horizontalAlign:{type:String,value:"left",reflectToAttribute:true},verticalAlign:{type:String,value:"top",reflectToAttribute:true},openAnimationConfig:{type:Object},closeAnimationConfig:{type:Object},focusTarget:{type:Object},noAnimations:{type:Boolean,value:false},allowOutsideScroll:{type:Boolean,value:false},_boundOnCaptureScroll:{type:Function,value:function(){return this._onCaptureScroll.bind(this)}}},listeners:{"neon-animation-finish":"_onNeonAnimationFinish"},observers:["_updateOverlayPosition(positionTarget, verticalAlign, horizontalAlign, verticalOffset, horizontalOffset)"],get containedElement(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},get _focusTarget(){return this.focusTarget||this.containedElement},ready:function(){this._scrollTop=0;this._scrollLeft=0;this._refitOnScrollRAF=null},attached:function(){if(!this.sizingTarget||this.sizingTarget===this){this.sizingTarget=this.containedElement}},detached:function(){this.cancelAnimation();document.removeEventListener("scroll",this._boundOnCaptureScroll);Polymer.IronDropdownScrollManager.removeScrollLock(this)},_openedChanged:function(){if(this.opened&&this.disabled){this.cancel()}else{this.cancelAnimation();this._updateAnimationConfig();this._saveScrollPosition();if(this.opened){document.addEventListener("scroll",this._boundOnCaptureScroll);!this.allowOutsideScroll&&Polymer.IronDropdownScrollManager.pushScrollLock(this)}else{document.removeEventListener("scroll",this._boundOnCaptureScroll);Polymer.IronDropdownScrollManager.removeScrollLock(this)}Polymer.IronOverlayBehaviorImpl._openedChanged.apply(this,arguments)}},_renderOpened:function(){if(!this.noAnimations&&this.animationConfig.open){this.$.contentWrapper.classList.add("animating");this.playAnimation("open")}else{Polymer.IronOverlayBehaviorImpl._renderOpened.apply(this,arguments)}},_renderClosed:function(){if(!this.noAnimations&&this.animationConfig.close){this.$.contentWrapper.classList.add("animating");this.playAnimation("close")}else{Polymer.IronOverlayBehaviorImpl._renderClosed.apply(this,arguments)}},_onNeonAnimationFinish:function(){this.$.contentWrapper.classList.remove("animating");if(this.opened){this._finishRenderOpened()}else{this._finishRenderClosed()}},_onCaptureScroll:function(){if(!this.allowOutsideScroll){this._restoreScrollPosition()}else{this._refitOnScrollRAF&&window.cancelAnimationFrame(this._refitOnScrollRAF);this._refitOnScrollRAF=window.requestAnimationFrame(this.refit.bind(this))}},_saveScrollPosition:function(){if(document.scrollingElement){this._scrollTop=document.scrollingElement.scrollTop;this._scrollLeft=document.scrollingElement.scrollLeft}else{this._scrollTop=Math.max(document.documentElement.scrollTop,document.body.scrollTop);this._scrollLeft=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft)}},_restoreScrollPosition:function(){if(document.scrollingElement){document.scrollingElement.scrollTop=this._scrollTop;document.scrollingElement.scrollLeft=this._scrollLeft}else{document.documentElement.scrollTop=this._scrollTop;document.documentElement.scrollLeft=this._scrollLeft;document.body.scrollTop=this._scrollTop;document.body.scrollLeft=this._scrollLeft}},_updateAnimationConfig:function(){var animations=(this.openAnimationConfig||[]).concat(this.closeAnimationConfig||[]);for(var i=0;i<animations.length;i++){animations[i].node=this.containedElement}this.animationConfig={open:this.openAnimationConfig,close:this.closeAnimationConfig}},_updateOverlayPosition:function(){if(this.isAttached){this.notifyResize()}},_applyFocus:function(){var focusTarget=this.focusTarget||this.containedElement;if(focusTarget&&this.opened&&!this.noAutoFocus){focusTarget.focus()}else{Polymer.IronOverlayBehaviorImpl._applyFocus.apply(this,arguments)}}})})();Polymer({is:"fade-in-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;this._effect=new KeyframeEffect(node,[{opacity:"0"},{opacity:"1"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"fade-out-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;this._effect=new KeyframeEffect(node,[{opacity:"1"},{opacity:"0"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"paper-menu-grow-height-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;var rect=node.getBoundingClientRect();var height=rect.height;this._effect=new KeyframeEffect(node,[{height:height/2+"px"},{height:height+"px"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"paper-menu-grow-width-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;var rect=node.getBoundingClientRect();var width=rect.width;this._effect=new KeyframeEffect(node,[{width:width/2+"px"},{width:width+"px"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"paper-menu-shrink-width-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;var rect=node.getBoundingClientRect();var width=rect.width;this._effect=new KeyframeEffect(node,[{width:width+"px"},{width:width-width/20+"px"}],this.timingFromConfig(config));return this._effect}});Polymer({is:"paper-menu-shrink-height-animation",behaviors:[Polymer.NeonAnimationBehavior],configure:function(config){var node=config.node;var rect=node.getBoundingClientRect();var height=rect.height;var top=rect.top;this.setPrefixedProperty(node,"transformOrigin","0 0");this._effect=new KeyframeEffect(node,[{height:height+"px",transform:"translateY(0)"},{height:height/2+"px",transform:"translateY(-20px)"}],this.timingFromConfig(config));return this._effect}});(function(){"use strict";var config={ANIMATION_CUBIC_BEZIER:"cubic-bezier(.3,.95,.5,1)",MAX_ANIMATION_TIME_MS:400};var PaperMenuButton=Polymer({is:"paper-menu-button",behaviors:[Polymer.IronA11yKeysBehavior,Polymer.IronControlState],properties:{opened:{type:Boolean,value:false,notify:true,observer:"_openedChanged"},horizontalAlign:{type:String,value:"left",reflectToAttribute:true},verticalAlign:{type:String,value:"top",reflectToAttribute:true},dynamicAlign:{type:Boolean},horizontalOffset:{type:Number,value:0,notify:true},verticalOffset:{type:Number,value:0,notify:true},noOverlap:{type:Boolean},noAnimations:{type:Boolean,value:false},ignoreSelect:{type:Boolean,value:false},closeOnActivate:{type:Boolean,value:false},openAnimationConfig:{type:Object,value:function(){return[{name:"fade-in-animation",timing:{delay:100,duration:200}},{name:"paper-menu-grow-width-animation",timing:{delay:100,duration:150,easing:config.ANIMATION_CUBIC_BEZIER}},{name:"paper-menu-grow-height-animation",timing:{delay:100,duration:275,easing:config.ANIMATION_CUBIC_BEZIER}}]}},closeAnimationConfig:{type:Object,value:function(){return[{name:"fade-out-animation",timing:{duration:150}},{name:"paper-menu-shrink-width-animation",timing:{delay:100,duration:50,easing:config.ANIMATION_CUBIC_BEZIER}},{name:"paper-menu-shrink-height-animation",timing:{duration:200,easing:"ease-in"}}]}},allowOutsideScroll:{type:Boolean,value:false},restoreFocusOnClose:{type:Boolean,value:true},_dropdownContent:{type:Object}},hostAttributes:{role:"group","aria-haspopup":"true"},listeners:{"iron-activate":"_onIronActivate","iron-select":"_onIronSelect"},get contentElement(){return Polymer.dom(this.$.content).getDistributedNodes()[0]},toggle:function(){if(this.opened){this.close()}else{this.open()}},open:function(){if(this.disabled){return}this.$.dropdown.open()},close:function(){this.$.dropdown.close()},_onIronSelect:function(event){if(!this.ignoreSelect){this.close()}},_onIronActivate:function(event){if(this.closeOnActivate){this.close()}},_openedChanged:function(opened,oldOpened){if(opened){this._dropdownContent=this.contentElement;this.fire("paper-dropdown-open")}else if(oldOpened!=null){this.fire("paper-dropdown-close")}},_disabledChanged:function(disabled){Polymer.IronControlState._disabledChanged.apply(this,arguments);if(disabled&&this.opened){this.close()}},__onIronOverlayCanceled:function(event){var uiEvent=event.detail;var target=Polymer.dom(uiEvent).rootTarget;var trigger=this.$.trigger;var path=Polymer.dom(uiEvent).path;if(path.indexOf(trigger)>-1){event.preventDefault()}}});Object.keys(config).forEach(function(key){PaperMenuButton[key]=config[key]});Polymer.PaperMenuButton=PaperMenuButton})();Polymer.PaperInkyFocusBehaviorImpl={observers:["_focusedChanged(receivedFocusFromKeyboard)"],_focusedChanged:function(receivedFocusFromKeyboard){if(receivedFocusFromKeyboard){this.ensureRipple()}if(this.hasRipple()){this._ripple.holdDown=receivedFocusFromKeyboard}},_createRipple:function(){var ripple=Polymer.PaperRippleBehavior._createRipple();ripple.id="ink";ripple.setAttribute("center","");ripple.classList.add("circle");return ripple}};Polymer.PaperInkyFocusBehavior=[Polymer.IronButtonState,Polymer.IronControlState,Polymer.PaperRippleBehavior,Polymer.PaperInkyFocusBehaviorImpl];Polymer({is:"paper-icon-button",hostAttributes:{role:"button",tabindex:"0"},behaviors:[Polymer.PaperInkyFocusBehavior],properties:{src:{type:String},icon:{type:String},alt:{type:String,observer:"_altChanged"}},_altChanged:function(newValue,oldValue){var label=this.getAttribute("aria-label");if(!label||oldValue==label){this.setAttribute("aria-label",newValue)}}});Polymer({is:"iron-media-query",properties:{queryMatches:{type:Boolean,value:false,readOnly:true,notify:true},query:{type:String,observer:"queryChanged"},full:{type:Boolean,value:false},_boundMQHandler:{value:function(){return this.queryHandler.bind(this)}},_mq:{value:null}},attached:function(){this.style.display="none";this.queryChanged()},detached:function(){this._remove()},_add:function(){if(this._mq){this._mq.addListener(this._boundMQHandler)}},_remove:function(){if(this._mq){this._mq.removeListener(this._boundMQHandler)}this._mq=null},queryChanged:function(){this._remove();var query=this.query;if(!query){return}if(!this.full&&query[0]!=="("){query="("+query+")"}this._mq=window.matchMedia(query);this._add();this.queryHandler(this._mq)},queryHandler:function(mq){this._setQueryMatches(mq.matches)}});Polymer.PaperSpinnerBehavior={listeners:{animationend:"__reset",webkitAnimationEnd:"__reset"},properties:{active:{type:Boolean,value:false,reflectToAttribute:true,observer:"__activeChanged"},alt:{type:String,value:"loading",observer:"__altChanged"},__coolingDown:{type:Boolean,value:false}},__computeContainerClasses:function(active,coolingDown){return[active||coolingDown?"active":"",coolingDown?"cooldown":""].join(" ")},__activeChanged:function(active,old){this.__setAriaHidden(!active);this.__coolingDown=!active&&old},__altChanged:function(alt){if(alt===this.getPropertyInfo("alt").value){this.alt=this.getAttribute("aria-label")||alt}else{this.__setAriaHidden(alt==="");this.setAttribute("aria-label",alt)}},__setAriaHidden:function(hidden){var attr="aria-hidden";if(hidden){this.setAttribute(attr,"true")}else{this.removeAttribute(attr)}},__reset:function(){this.active=false;this.__coolingDown=false}};Polymer({is:"paper-spinner-lite",behaviors:[Polymer.PaperSpinnerBehavior]}); -// 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. -var CrSearchFieldBehavior={properties:{label:{type:String,value:""},clearLabel:{type:String,value:""},hasSearchText:{type:Boolean,reflectToAttribute:true,value:false},lastValue_:{type:String,value:""}},getSearchInput:function(){},getValue:function(){return this.getSearchInput().value},setValue:function(value,opt_noEvent){var searchInput=this.getSearchInput();searchInput.value=value;this.onSearchTermInput();this.onValueChanged_(value,!!opt_noEvent)},onSearchTermSearch:function(){this.onValueChanged_(this.getValue(),false)},onSearchTermInput:function(){this.hasSearchText=this.$.searchInput.value!=""},onValueChanged_:function(newValue,noEvent){if(newValue==this.lastValue_)return;this.lastValue_=newValue;if(!noEvent)this.fire("search-changed",newValue)}}; -// 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. -Polymer({is:"cr-toolbar-search-field",behaviors:[CrSearchFieldBehavior],properties:{narrow:{type:Boolean,reflectToAttribute:true},showingSearch:{type:Boolean,value:false,notify:true,observer:"showingSearchChanged_",reflectToAttribute:true},label:String,clearLabel:String,spinnerActive:{type:Boolean,reflectToAttribute:true},isSpinnerShown_:{type:Boolean,computed:"computeIsSpinnerShown_(spinnerActive, showingSearch)"},searchFocused_:{type:Boolean,value:false}},listeners:{click:"showSearch_"},getSearchInput:function(){return this.$.searchInput},isSearchFocused:function(){return this.searchFocused_},showAndFocus:function(){this.showingSearch=true;this.focus_()},onSearchTermInput:function(){CrSearchFieldBehavior.onSearchTermInput.call(this);this.showingSearch=this.hasSearchText||this.isSearchFocused()},focus_:function(){this.getSearchInput().focus()},computeIconTabIndex_:function(narrow){return narrow?0:-1},computeIsSpinnerShown_:function(){return this.spinnerActive&&this.showingSearch},onInputFocus_:function(){this.searchFocused_=true},onInputBlur_:function(){this.searchFocused_=false;if(!this.hasSearchText)this.showingSearch=false},onSearchTermKeydown_:function(e){if(e.key=="Escape")this.showingSearch=false},showSearch_:function(e){if(e.target!=this.$.clearSearch)this.showingSearch=true},clearSearch_:function(e){this.setValue("");this.focus_()},showingSearchChanged_:function(current,previous){if(previous==undefined)return;if(this.showingSearch){this.focus_();return}this.setValue("");this.getSearchInput().blur()}}); -// 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. -Polymer({is:"cr-toolbar",properties:{pageName:String,searchPrompt:String,clearLabel:String,menuLabel:String,menuPromo:String,spinnerActive:Boolean,showMenu:{type:Boolean,value:false},showMenuPromo:{type:Boolean,value:false},closeMenuPromo:String,narrow_:{type:Boolean,reflectToAttribute:true},showingSearch_:{type:Boolean,reflectToAttribute:true}},observers:["possiblyShowMenuPromo_(showMenu, showMenuPromo, showingSearch_)"],getSearchField:function(){return this.$.search},onClosePromoTap_:function(){this.fire("cr-toolbar-menu-promo-close")},onMenuTap_:function(){this.fire("cr-toolbar-menu-tap")},possiblyShowMenuPromo_:function(){Polymer.RenderStatus.afterNextRender(this,function(){if(this.showMenu&&this.showMenuPromo&&!this.showingSearch_){this.$$("#menuPromo").animate({opacity:[0,.9]},{duration:500,fill:"forwards"});this.fire("cr-toolbar-menu-promo-shown")}}.bind(this))},titleIfNotShowMenuPromo_:function(title,showMenuPromo){return showMenuPromo?"":title}}); -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -cr.define("downloads",function(){var Toolbar=Polymer({is:"downloads-toolbar",properties:{downloadsShowing:{reflectToAttribute:true,type:Boolean,value:false,observer:"downloadsShowingChanged_"},spinnerActive:{type:Boolean,notify:true}},listeners:{"paper-dropdown-close":"onPaperDropdownClose_","paper-dropdown-open":"onPaperDropdownOpen_"},canUndo:function(){return!this.$.toolbar.getSearchField().isSearchFocused()},canClearAll:function(){return!this.$.toolbar.getSearchField().getValue()&&this.downloadsShowing},onFindCommand:function(){this.$.toolbar.getSearchField().showAndFocus()},closeMoreActions_:function(){this.$.more.close()},downloadsShowingChanged_:function(){this.updateClearAll_()},onClearAllTap_:function(){assert(this.canClearAll());downloads.ActionService.getInstance().clearAll()},onPaperDropdownClose_:function(){window.removeEventListener("resize",assert(this.boundClose_))},onItemBlur_:function(e){var menu=this.$$("paper-menu");if(menu.items.indexOf(e.relatedTarget)>=0)return;this.$.more.restoreFocusOnClose=false;this.closeMoreActions_();this.$.more.restoreFocusOnClose=true},onPaperDropdownOpen_:function(){this.boundClose_=this.boundClose_||this.closeMoreActions_.bind(this);window.addEventListener("resize",this.boundClose_)},onSearchChanged_:function(event){var actionService=downloads.ActionService.getInstance();if(actionService.search(event.detail))this.spinnerActive=actionService.isSearching();this.updateClearAll_()},onOpenDownloadsFolderTap_:function(){downloads.ActionService.getInstance().openDownloadsFolder()},updateClearAll_:function(){this.$$("paper-menu .clear-all").hidden=!this.canClearAll()}});return{Toolbar:Toolbar}}); -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -cr.define("downloads",function(){var Manager=Polymer({is:"downloads-manager",properties:{hasDownloads_:{observer:"hasDownloadsChanged_",type:Boolean},hasShadow_:{type:Boolean,value:false,reflectToAttribute:true},inSearchMode_:{type:Boolean,value:false},items_:{type:Array,value:function(){return[]}},spinnerActive_:{type:Boolean,notify:true}},hostAttributes:{loading:true},listeners:{"downloads-list.scroll":"onListScroll_","toolbar.search-changed":"onSearchChanged_"},observers:["itemsChanged_(items_.*)"],loaded_:new PromiseResolver,clearAll_:function(){this.set("items_",[])},hasDownloadsChanged_:function(){if(loadTimeData.getBoolean("allowDeletingHistory"))this.$.toolbar.downloadsShowing=this.hasDownloads_;if(this.hasDownloads_)this.$["downloads-list"].fire("iron-resize")},insertItems_:function(index,list){this.splice.apply(this,["items_",index,0].concat(list));this.updateHideDates_(index,index+list.length);if(this.hasAttribute("loading")){this.removeAttribute("loading");this.loaded_.resolve()}this.spinnerActive_=false},itemsChanged_:function(){this.hasDownloads_=this.items_.length>0},noDownloadsText_:function(){return loadTimeData.getString(this.inSearchMode_?"noSearchResults":"noDownloads")},onCanExecute_:function(e){e=e;switch(e.command.id){case"undo-command":e.canExecute=this.$.toolbar.canUndo();break;case"clear-all-command":e.canExecute=this.$.toolbar.canClearAll();break;case"find-command":e.canExecute=true;break}},onCommand_:function(e){if(e.command.id=="clear-all-command")downloads.ActionService.getInstance().clearAll();else if(e.command.id=="undo-command")downloads.ActionService.getInstance().undo();else if(e.command.id=="find-command")this.$.toolbar.onFindCommand()},onListScroll_:function(){var list=this.$["downloads-list"];if(list.scrollHeight-list.scrollTop-list.offsetHeight<=100){downloads.ActionService.getInstance().loadMore()}this.hasShadow_=list.scrollTop>0},onLoad_:function(){cr.ui.decorate("command",cr.ui.Command);document.addEventListener("canExecute",this.onCanExecute_.bind(this));document.addEventListener("command",this.onCommand_.bind(this));downloads.ActionService.getInstance().loadMore();return this.loaded_.promise},onSearchChanged_:function(){this.inSearchMode_=downloads.ActionService.getInstance().isSearching()},removeItem_:function(index){this.splice("items_",index,1);this.updateHideDates_(index,index);this.onListScroll_()},updateHideDates_:function(start,end){for(var i=start;i<=end;++i){var current=this.items_[i];if(!current)continue;var prev=this.items_[i-1];var hideDate=!!prev&&prev.date_string==current.date_string;this.set("items_."+i+".hideDate",hideDate)}},updateItem_:function(index,data){this.set("items_."+index,data);this.updateHideDates_(index,index);var list=this.$["downloads-list"];list.updateSizeForItem(index)}});Manager.clearAll=function(){Manager.get().clearAll_()};Manager.get=function(){return queryRequiredElement("downloads-manager")};Manager.insertItems=function(index,list){Manager.get().insertItems_(index,list)};Manager.onLoad=function(){return Manager.get().onLoad_()};Manager.removeItem=function(index){Manager.get().removeItem_(index)};Manager.updateItem=function(index,data){Manager.get().updateItem_(index,data)};return{Manager:Manager}}); -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -window.addEventListener("load",function(){downloads.Manager.onLoad().then(function(){requestIdleCallback(function(){chrome.send("metricsHandler:recordTime",["Download.ResultsRenderedTime",window.performance.now()]);document.fonts.load("bold 12px Roboto")})})}); \ No newline at end of file
diff --git a/chrome/browser/resources/md_downloads/item.html b/chrome/browser/resources/md_downloads/item.html index c54bd38..d1b4ec0 100644 --- a/chrome/browser/resources/md_downloads/item.html +++ b/chrome/browser/resources/md_downloads/item.html
@@ -1,3 +1,4 @@ +<link rel="import" href="chrome://resources/cr_elements/icons.html"> <link rel="import" href="chrome://resources/html/action_link.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/polymer.html">
diff --git a/chrome/browser/resources/md_downloads/toolbar.html b/chrome/browser/resources/md_downloads/toolbar.html index d2cd8e2..da1cb35 100644 --- a/chrome/browser/resources/md_downloads/toolbar.html +++ b/chrome/browser/resources/md_downloads/toolbar.html
@@ -3,10 +3,9 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/util.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu/paper-menu.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-menu-button/paper-menu-button.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button-light.html"> +<link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html"> <link rel="import" href="chrome://resources/cr_elements/icons.html"> @@ -30,59 +29,34 @@ flex: 1; } - paper-icon-button { + #moreActions { --iron-icon-height: 20px; --iron-icon-width: 20px; - --paper-icon-button: { - height: 32px; - padding: 6px; - width: 32px; - }; - } - - #more { - --paper-menu-button: { - padding: 6px; - }; - } - - paper-menu { - --paper-menu-selected-item: { - font-weight: normal; - }; - } - - paper-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - min-height: 40px; - /* TODO(michaelpg): fix this for everybody ever. - * https://github.com/PolymerElements/paper-menu-button/issues/56 */ - white-space: nowrap; + height: 32px; + padding: 6px; + width: 32px; } </style> <cr-toolbar id="toolbar" page-name="$i18n{title}" search-prompt="$i18n{search}" clear-label="$i18n{clearSearch}" spinner-active="{{spinnerActive}}" on-search-changed="onSearchChanged_"> - <div class="more-actions"> - <paper-menu-button id="more" horizontal-align="right" - allow-outside-scroll> - <paper-icon-button icon="cr:more-vert" title="$i18n{moreActions}" - class="dropdown-trigger"></paper-icon-button> - <paper-menu class="dropdown-content"> - <paper-item class="clear-all" on-tap="onClearAllTap_" - role="menuitem" on-blur="onItemBlur_"> - $i18n{clearAll} - </paper-item> - <paper-item on-tap="onOpenDownloadsFolderTap_" - role="menuitem" on-blur="onItemBlur_"> - $i18n{openDownloadsFolder} - </paper-item> - </paper-menu> - </paper-menu-button> - </div> + <button is="paper-icon-button-light" class="more-actions" id="moreActions" + title="$i18n{moreActions}" class="dropdown-trigger" + on-tap="onMoreActionsTap_"> + <iron-icon icon="cr:more-vert"></iron-icon> + </button> </cr-toolbar> + <!-- TODO(dbeam): should cr-action-menu be role="menu" by default? --> + <dialog is="cr-action-menu" id="moreActionsMenu" role="menu"> + <button class="dropdown-item clear-all" on-tap="onClearAllTap_" + role="menuitem"> + $i18n{clearAll} + </div> + <button class="dropdown-item" on-tap="onOpenDownloadsFolderTap_" + role="menuitem"> + $i18n{openDownloadsFolder} + </button> + </dialog> </template> <script src="chrome://downloads/toolbar.js"></script> </dom-module>
diff --git a/chrome/browser/resources/md_downloads/toolbar.js b/chrome/browser/resources/md_downloads/toolbar.js index 726f3a4..4a40daa 100644 --- a/chrome/browser/resources/md_downloads/toolbar.js +++ b/chrome/browser/resources/md_downloads/toolbar.js
@@ -20,11 +20,6 @@ }, }, - listeners: { - 'paper-dropdown-close': 'onPaperDropdownClose_', - 'paper-dropdown-open': 'onPaperDropdownOpen_', - }, - /** @return {boolean} Whether removal can be undone. */ canUndo: function() { return !this.$.toolbar.getSearchField().isSearchFocused(); @@ -41,11 +36,6 @@ }, /** @private */ - closeMoreActions_: function() { - this.$.more.close(); - }, - - /** @private */ downloadsShowingChanged_: function() { this.updateClearAll_(); }, @@ -54,31 +44,12 @@ onClearAllTap_: function() { assert(this.canClearAll()); downloads.ActionService.getInstance().clearAll(); + this.$.moreActionsMenu.close(); }, /** @private */ - onPaperDropdownClose_: function() { - window.removeEventListener('resize', assert(this.boundClose_)); - }, - - /** - * @param {!Event} e - * @private - */ - onItemBlur_: function(e) { - var menu = /** @type {PaperMenuElement} */(this.$$('paper-menu')); - if (menu.items.indexOf(e.relatedTarget) >= 0) - return; - - this.$.more.restoreFocusOnClose = false; - this.closeMoreActions_(); - this.$.more.restoreFocusOnClose = true; - }, - - /** @private */ - onPaperDropdownOpen_: function() { - this.boundClose_ = this.boundClose_ || this.closeMoreActions_.bind(this); - window.addEventListener('resize', this.boundClose_); + onMoreActionsTap_: function() { + this.$.moreActionsMenu.showAt(this.$.moreActions); }, /** @@ -95,11 +66,12 @@ /** @private */ onOpenDownloadsFolderTap_: function() { downloads.ActionService.getInstance().openDownloadsFolder(); + this.$.moreActionsMenu.close(); }, /** @private */ updateClearAll_: function() { - this.$$('paper-menu .clear-all').hidden = !this.canClearAll(); + this.$$('.clear-all').hidden = !this.canClearAll(); }, });
diff --git a/chrome/browser/resources/md_downloads/vulcanized.html b/chrome/browser/resources/md_downloads/vulcanized.html deleted file mode 100644 index cb5cfb6..0000000 --- a/chrome/browser/resources/md_downloads/vulcanized.html +++ /dev/null
@@ -1,3380 +0,0 @@ -<!DOCTYPE html><html dir="$i18n{textdirection}" lang="$i18n{language}"><head><!-- -@license -Copyright (c) 2014 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---><!-- -@license -Copyright (c) 2016 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---><!-- -@license -Copyright (c) 2015 The Polymer Project Authors. All rights reserved. -This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt -The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt -The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt -Code distributed by Google as part of the polymer project is also -subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt ---> - <meta charset="utf-8"> - <title>$i18n{title}</title> - <link rel="stylesheet" href="chrome://resources/css/text_defaults_md.css"> - <style> -/* 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. */ - -:root { - /* This is a custom, Chrome-specific color that does not have a --paper or - * --google equivalent. */ - --md-background-color: #f1f1f1; - --md-loading-message-color: #6e6e6e; - /* This is --google-blue-700, rewritten as a native custom property for speed. - */ - --md-toolbar-color: rgb(51, 103, 214); -} - -</style> - <style> - html { - background: var(--md-background-color); - } - - html, - body { - height: 100%; - } - - body { - display: flex; - margin: 0; - } - - :root { - --downloads-card-margin: 24px; - --downloads-card-width: 640px; - } - </style> -</head> -<body> - <downloads-manager></downloads-manager> -<if expr="is_macosx"> - <command id="clear-all-command" shortcut="Alt|c Alt|ç"></command> - <command id="undo-command" shortcut="Meta|z"></command> - <command id="find-command" shortcut="Meta|f"></command> -</if> -<if expr="not is_macosx"> - <command id="clear-all-command" shortcut="Alt|c"></command> - <command id="undo-command" shortcut="Ctrl|z"></command> - <command id="find-command" shortcut="Ctrl|f"></command> -</if> - <div hidden="" by-vulcanize=""></div><link rel="import" href="chrome://resources/html/polymer.html"> - <div hidden="" by-vulcanize=""><script src="chrome://resources/js/load_time_data.js"></script> -<script src="chrome://downloads/strings.js"></script> -</div><div hidden="" by-vulcanize=""><dom-module id="iron-list" assetpath="chrome://resources/polymer/v1_0/iron-list/" css-build="shadow"> - <template> - <style scope="iron-list">:host { - display: block; - position: relative; -} - -@media only screen and (-webkit-max-device-pixel-ratio: 1) { -:host { - will-change: transform; -} - -} - -#items { - ; - position: relative; -} - -:host(:not([grid])) #items > ::content > * { - width: 100%; -} - -#items > ::content > * { - box-sizing: border-box; - margin: 0; - position: absolute; - top: 0; - will-change: transform; -} - -</style> - - <array-selector id="selector" items="{{items}}" selected="{{selectedItems}}" selected-item="{{selectedItem}}"> - </array-selector> - - <div id="items"> - <content></content> - </div> - - </template> -</dom-module> - -<style> - /* IE 10 support for HTML5 hidden attr */ - [hidden] { - display: none !important; - } -</style><style is="custom-style" css-build="shadow">html { - --layout_-_display: flex;; - - --layout-inline_-_display: inline-flex;; - - --layout-horizontal_-_display: var(--layout_-_display); --layout-horizontal_-_-ms-flex-direction: row; --layout-horizontal_-_-webkit-flex-direction: row; --layout-horizontal_-_flex-direction: row;; - - --layout-horizontal-reverse_-_display: var(--layout_-_display); --layout-horizontal-reverse_-_-ms-flex-direction: row-reverse; --layout-horizontal-reverse_-_-webkit-flex-direction: row-reverse; --layout-horizontal-reverse_-_flex-direction: row-reverse;; - - --layout-vertical_-_display: var(--layout_-_display); --layout-vertical_-_-ms-flex-direction: column; --layout-vertical_-_-webkit-flex-direction: column; --layout-vertical_-_flex-direction: column;; - - --layout-vertical-reverse_-_display: var(--layout_-_display); --layout-vertical-reverse_-_-ms-flex-direction: column-reverse; --layout-vertical-reverse_-_-webkit-flex-direction: column-reverse; --layout-vertical-reverse_-_flex-direction: column-reverse;; - - --layout-wrap_-_-ms-flex-wrap: wrap; --layout-wrap_-_-webkit-flex-wrap: wrap; --layout-wrap_-_flex-wrap: wrap;; - - --layout-wrap-reverse_-_-ms-flex-wrap: wrap-reverse; --layout-wrap-reverse_-_-webkit-flex-wrap: wrap-reverse; --layout-wrap-reverse_-_flex-wrap: wrap-reverse;; - - --layout-flex-auto_-_-ms-flex: 1 1 auto; --layout-flex-auto_-_-webkit-flex: 1 1 auto; --layout-flex-auto_-_flex: 1 1 auto;; - - --layout-flex-none_-_-ms-flex: none; --layout-flex-none_-_-webkit-flex: none; --layout-flex-none_-_flex: none;; - - --layout-flex_-_-ms-flex: 1 1 0.000000001px; --layout-flex_-_-webkit-flex: 1; --layout-flex_-_flex: 1; --layout-flex_-_-webkit-flex-basis: 0.000000001px; --layout-flex_-_flex-basis: 0.000000001px;; - - --layout-flex-2_-_-ms-flex: 2; --layout-flex-2_-_-webkit-flex: 2; --layout-flex-2_-_flex: 2;; - - --layout-flex-3_-_-ms-flex: 3; --layout-flex-3_-_-webkit-flex: 3; --layout-flex-3_-_flex: 3;; - - --layout-flex-4_-_-ms-flex: 4; --layout-flex-4_-_-webkit-flex: 4; --layout-flex-4_-_flex: 4;; - - --layout-flex-5_-_-ms-flex: 5; --layout-flex-5_-_-webkit-flex: 5; --layout-flex-5_-_flex: 5;; - - --layout-flex-6_-_-ms-flex: 6; --layout-flex-6_-_-webkit-flex: 6; --layout-flex-6_-_flex: 6;; - - --layout-flex-7_-_-ms-flex: 7; --layout-flex-7_-_-webkit-flex: 7; --layout-flex-7_-_flex: 7;; - - --layout-flex-8_-_-ms-flex: 8; --layout-flex-8_-_-webkit-flex: 8; --layout-flex-8_-_flex: 8;; - - --layout-flex-9_-_-ms-flex: 9; --layout-flex-9_-_-webkit-flex: 9; --layout-flex-9_-_flex: 9;; - - --layout-flex-10_-_-ms-flex: 10; --layout-flex-10_-_-webkit-flex: 10; --layout-flex-10_-_flex: 10;; - - --layout-flex-11_-_-ms-flex: 11; --layout-flex-11_-_-webkit-flex: 11; --layout-flex-11_-_flex: 11;; - - --layout-flex-12_-_-ms-flex: 12; --layout-flex-12_-_-webkit-flex: 12; --layout-flex-12_-_flex: 12;; - - - - --layout-start_-_-ms-flex-align: start; --layout-start_-_-webkit-align-items: flex-start; --layout-start_-_align-items: flex-start;; - - --layout-center_-_-ms-flex-align: center; --layout-center_-_-webkit-align-items: center; --layout-center_-_align-items: center;; - - --layout-end_-_-ms-flex-align: end; --layout-end_-_-webkit-align-items: flex-end; --layout-end_-_align-items: flex-end;; - - --layout-baseline_-_-ms-flex-align: baseline; --layout-baseline_-_-webkit-align-items: baseline; --layout-baseline_-_align-items: baseline;; - - - - --layout-start-justified_-_-ms-flex-pack: start; --layout-start-justified_-_-webkit-justify-content: flex-start; --layout-start-justified_-_justify-content: flex-start;; - - --layout-center-justified_-_-ms-flex-pack: center; --layout-center-justified_-_-webkit-justify-content: center; --layout-center-justified_-_justify-content: center;; - - --layout-end-justified_-_-ms-flex-pack: end; --layout-end-justified_-_-webkit-justify-content: flex-end; --layout-end-justified_-_justify-content: flex-end;; - - --layout-around-justified_-_-ms-flex-pack: distribute; --layout-around-justified_-_-webkit-justify-content: space-around; --layout-around-justified_-_justify-content: space-around;; - - --layout-justified_-_-ms-flex-pack: justify; --layout-justified_-_-webkit-justify-content: space-between; --layout-justified_-_justify-content: space-between;; - - --layout-center-center_-_-ms-flex-align: var(--layout-center_-_-ms-flex-align); --layout-center-center_-_-webkit-align-items: var(--layout-center_-_-webkit-align-items); --layout-center-center_-_align-items: var(--layout-center_-_align-items); --layout-center-center_-_-ms-flex-pack: var(--layout-center-justified_-_-ms-flex-pack); --layout-center-center_-_-webkit-justify-content: var(--layout-center-justified_-_-webkit-justify-content); --layout-center-center_-_justify-content: var(--layout-center-justified_-_justify-content);; - - - - --layout-self-start_-_-ms-align-self: flex-start; --layout-self-start_-_-webkit-align-self: flex-start; --layout-self-start_-_align-self: flex-start;; - - --layout-self-center_-_-ms-align-self: center; --layout-self-center_-_-webkit-align-self: center; --layout-self-center_-_align-self: center;; - - --layout-self-end_-_-ms-align-self: flex-end; --layout-self-end_-_-webkit-align-self: flex-end; --layout-self-end_-_align-self: flex-end;; - - --layout-self-stretch_-_-ms-align-self: stretch; --layout-self-stretch_-_-webkit-align-self: stretch; --layout-self-stretch_-_align-self: stretch;; - - --layout-self-baseline_-_-ms-align-self: baseline; --layout-self-baseline_-_-webkit-align-self: baseline; --layout-self-baseline_-_align-self: baseline;; - - - - --layout-start-aligned_-_-ms-flex-line-pack: start; --layout-start-aligned_-_-ms-align-content: flex-start; --layout-start-aligned_-_-webkit-align-content: flex-start; --layout-start-aligned_-_align-content: flex-start;; - - --layout-end-aligned_-_-ms-flex-line-pack: end; --layout-end-aligned_-_-ms-align-content: flex-end; --layout-end-aligned_-_-webkit-align-content: flex-end; --layout-end-aligned_-_align-content: flex-end;; - - --layout-center-aligned_-_-ms-flex-line-pack: center; --layout-center-aligned_-_-ms-align-content: center; --layout-center-aligned_-_-webkit-align-content: center; --layout-center-aligned_-_align-content: center;; - - --layout-between-aligned_-_-ms-flex-line-pack: justify; --layout-between-aligned_-_-ms-align-content: space-between; --layout-between-aligned_-_-webkit-align-content: space-between; --layout-between-aligned_-_align-content: space-between;; - - --layout-around-aligned_-_-ms-flex-line-pack: distribute; --layout-around-aligned_-_-ms-align-content: space-around; --layout-around-aligned_-_-webkit-align-content: space-around; --layout-around-aligned_-_align-content: space-around;; - - - - --layout-block_-_display: block;; - - --layout-invisible_-_visibility: hidden !important;; - - --layout-relative_-_position: relative;; - - --layout-fit_-_position: absolute; --layout-fit_-_top: 0; --layout-fit_-_right: 0; --layout-fit_-_bottom: 0; --layout-fit_-_left: 0;; - - --layout-scroll_-_-webkit-overflow-scrolling: touch; --layout-scroll_-_overflow: auto;; - - --layout-fullbleed_-_margin: 0; --layout-fullbleed_-_height: 100vh;; - - - - --layout-fixed-top_-_position: fixed; --layout-fixed-top_-_top: 0; --layout-fixed-top_-_left: 0; --layout-fixed-top_-_right: 0;; - - --layout-fixed-right_-_position: fixed; --layout-fixed-right_-_top: 0; --layout-fixed-right_-_right: 0; --layout-fixed-right_-_bottom: 0;; - - --layout-fixed-bottom_-_position: fixed; --layout-fixed-bottom_-_right: 0; --layout-fixed-bottom_-_bottom: 0; --layout-fixed-bottom_-_left: 0;; - - --layout-fixed-left_-_position: fixed; --layout-fixed-left_-_top: 0; --layout-fixed-left_-_bottom: 0; --layout-fixed-left_-_left: 0;; -} - -</style><dom-module id="iron-icon" assetpath="chrome://resources/polymer/v1_0/iron-icon/" css-build="shadow"> - <template> - <style scope="iron-icon">:host { - display: var(--layout-inline_-_display); - -ms-flex-align: var(--layout-center-center_-_-ms-flex-align); -webkit-align-items: var(--layout-center-center_-_-webkit-align-items); align-items: var(--layout-center-center_-_align-items); -ms-flex-pack: var(--layout-center-center_-_-ms-flex-pack); -webkit-justify-content: var(--layout-center-center_-_-webkit-justify-content); justify-content: var(--layout-center-center_-_justify-content); - position: relative; - - vertical-align: middle; - - fill: var(--iron-icon-fill-color, currentcolor); - stroke: var(--iron-icon-stroke-color, none); - - width: var(--iron-icon-width, 24px); - height: var(--iron-icon-height, 24px); - ; -} - -</style> - </template> - - </dom-module> -<dom-module id="paper-ripple" assetpath="chrome://resources/polymer/v1_0/paper-ripple/" css-build="shadow"> - - <template> - <style scope="paper-ripple">:host { - display: block; - position: absolute; - border-radius: inherit; - overflow: hidden; - top: 0; - left: 0; - right: 0; - bottom: 0; - - - pointer-events: none; -} - -:host([animating]) { - -webkit-transform: translate(0, 0); - transform: translate3d(0, 0, 0); -} - -#background, #waves, .wave-container, .wave { - pointer-events: none; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} - -#background, .wave { - opacity: 0; -} - -#waves, .wave { - overflow: hidden; -} - -.wave-container, .wave { - border-radius: 50%; -} - -:host(.circle) #background, :host(.circle) #waves { - border-radius: 50%; -} - -:host(.circle) .wave-container { - overflow: hidden; -} - -</style> - - <div id="background"></div> - <div id="waves"></div> - </template> -</dom-module> -<style is="custom-style" css-build="shadow">html { - --shadow-transition_-_transition: box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);; - - --shadow-none_-_box-shadow: none;; - - - - --shadow-elevation-2dp_-_box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), - 0 1px 5px 0 rgba(0, 0, 0, 0.12), - 0 3px 1px -2px rgba(0, 0, 0, 0.2);; - - --shadow-elevation-3dp_-_box-shadow: 0 3px 4px 0 rgba(0, 0, 0, 0.14), - 0 1px 8px 0 rgba(0, 0, 0, 0.12), - 0 3px 3px -2px rgba(0, 0, 0, 0.4);; - - --shadow-elevation-4dp_-_box-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), - 0 1px 10px 0 rgba(0, 0, 0, 0.12), - 0 2px 4px -1px rgba(0, 0, 0, 0.4);; - - --shadow-elevation-6dp_-_box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), - 0 1px 18px 0 rgba(0, 0, 0, 0.12), - 0 3px 5px -1px rgba(0, 0, 0, 0.4);; - - --shadow-elevation-8dp_-_box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), - 0 3px 14px 2px rgba(0, 0, 0, 0.12), - 0 5px 5px -3px rgba(0, 0, 0, 0.4);; - - --shadow-elevation-12dp_-_box-shadow: 0 12px 16px 1px rgba(0, 0, 0, 0.14), - 0 4px 22px 3px rgba(0, 0, 0, 0.12), - 0 6px 7px -4px rgba(0, 0, 0, 0.4);; - - --shadow-elevation-16dp_-_box-shadow: 0 16px 24px 2px rgba(0, 0, 0, 0.14), - 0 6px 30px 5px rgba(0, 0, 0, 0.12), - 0 8px 10px -5px rgba(0, 0, 0, 0.4);; -} - -</style><dom-module id="paper-material-shared-styles" assetpath="chrome://resources/polymer/v1_0/paper-material/" css-build="shadow"> - <template> - <style scope="paper-material-shared-styles">:host { - display: block; - position: relative; -} - -:host([elevation="1"]) { - box-shadow: var(--shadow-elevation-2dp_-_box-shadow); -} - -:host([elevation="2"]) { - box-shadow: var(--shadow-elevation-4dp_-_box-shadow); -} - -:host([elevation="3"]) { - box-shadow: var(--shadow-elevation-6dp_-_box-shadow); -} - -:host([elevation="4"]) { - box-shadow: var(--shadow-elevation-8dp_-_box-shadow); -} - -:host([elevation="5"]) { - box-shadow: var(--shadow-elevation-16dp_-_box-shadow); -} - -</style> - </template> -</dom-module> -<dom-module id="paper-button" assetpath="chrome://resources/polymer/v1_0/paper-button/" css-build="shadow"> - <template strip-whitespace=""> - <style scope="paper-button">:host { - display: block; - position: relative; -} - -:host([elevation="1"]) { - box-shadow: var(--shadow-elevation-2dp_-_box-shadow); -} - -:host([elevation="2"]) { - box-shadow: var(--shadow-elevation-4dp_-_box-shadow); -} - -:host([elevation="3"]) { - box-shadow: var(--shadow-elevation-6dp_-_box-shadow); -} - -:host([elevation="4"]) { - box-shadow: var(--shadow-elevation-8dp_-_box-shadow); -} - -:host([elevation="5"]) { - box-shadow: var(--shadow-elevation-16dp_-_box-shadow); -} - -:host { - display: var(--layout-inline_-_display); - -ms-flex-align: var(--layout-center-center_-_-ms-flex-align); -webkit-align-items: var(--layout-center-center_-_-webkit-align-items); align-items: var(--layout-center-center_-_align-items); -ms-flex-pack: var(--layout-center-center_-_-ms-flex-pack); -webkit-justify-content: var(--layout-center-center_-_-webkit-justify-content); justify-content: var(--layout-center-center_-_justify-content); - position: relative; - box-sizing: border-box; - min-width: 5.14em; - margin: 0 0.29em; - background: transparent; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-tap-highlight-color: transparent; - font: inherit; - text-transform: uppercase; - outline-width: 0; - border-radius: 3px; - -moz-user-select: none; - -ms-user-select: none; - -webkit-user-select: none; - user-select: none; - cursor: pointer; - z-index: 0; - padding: 0.7em 0.57em; - - font-family: var(--paper-font-common-base_-_font-family); -webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); - ; -} - -:host([hidden]) { - display: none !important; -} - -:host([raised].keyboard-focus) { - font-weight: bold; - ; -} - -:host(:not([raised]).keyboard-focus) { - font-weight: bold; - ; -} - -:host([disabled]) { - background: #eaeaea; - color: #a8a8a8; - cursor: auto; - pointer-events: none; - - ; -} - -:host([animated]) { - transition: var(--shadow-transition_-_transition); -} - -paper-ripple { - color: var(--paper-button-ink-color); -} - -</style> - - <content></content> - </template> - - </dom-module> -<dom-module id="paper-icon-button-light" assetpath="chrome://resources/polymer/v1_0/paper-icon-button/" css-build="shadow"> - <template strip-whitespace=""> - <style scope="paper-icon-button-light">:host { - vertical-align: middle; - color: inherit; - outline: none; - width: 24px; - height: 24px; - background: none; - margin: 0; - border: none; - padding: 0; - - position: relative; - cursor: pointer; - - - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-tap-highlight-color: transparent; -} - -:host([disabled]) { - color: #9b9b9b; - pointer-events: none; - cursor: auto; -} - -paper-ripple { - opacity: 0.6; - color: currentColor; -} - -</style> - <content></content> - </template> - </dom-module> -<style is="custom-style" css-build="shadow">html { - --google-red-100: #f4c7c3; - --google-red-300: #e67c73; - --google-red-500: #db4437; - --google-red-700: #c53929; - - --google-blue-100: #c6dafc; - --google-blue-300: #7baaf7; - --google-blue-500: #4285f4; - --google-blue-700: #3367d6; - - --google-green-100: #b7e1cd; - --google-green-300: #57bb8a; - --google-green-500: #0f9d58; - --google-green-700: #0b8043; - - --google-yellow-100: #fce8b2; - --google-yellow-300: #f7cb4d; - --google-yellow-500: #f4b400; - --google-yellow-700: #f09300; - - --google-grey-100: #f5f5f5; - --google-grey-300: #e0e0e0; - --google-grey-500: #9e9e9e; - --google-grey-700: #616161; - - - - --paper-red-50: #ffebee; - --paper-red-100: #ffcdd2; - --paper-red-200: #ef9a9a; - --paper-red-300: #e57373; - --paper-red-400: #ef5350; - --paper-red-500: #f44336; - --paper-red-600: #e53935; - --paper-red-700: #d32f2f; - --paper-red-800: #c62828; - --paper-red-900: #b71c1c; - --paper-red-a100: #ff8a80; - --paper-red-a200: #ff5252; - --paper-red-a400: #ff1744; - --paper-red-a700: #d50000; - - --paper-pink-50: #fce4ec; - --paper-pink-100: #f8bbd0; - --paper-pink-200: #f48fb1; - --paper-pink-300: #f06292; - --paper-pink-400: #ec407a; - --paper-pink-500: #e91e63; - --paper-pink-600: #d81b60; - --paper-pink-700: #c2185b; - --paper-pink-800: #ad1457; - --paper-pink-900: #880e4f; - --paper-pink-a100: #ff80ab; - --paper-pink-a200: #ff4081; - --paper-pink-a400: #f50057; - --paper-pink-a700: #c51162; - - --paper-purple-50: #f3e5f5; - --paper-purple-100: #e1bee7; - --paper-purple-200: #ce93d8; - --paper-purple-300: #ba68c8; - --paper-purple-400: #ab47bc; - --paper-purple-500: #9c27b0; - --paper-purple-600: #8e24aa; - --paper-purple-700: #7b1fa2; - --paper-purple-800: #6a1b9a; - --paper-purple-900: #4a148c; - --paper-purple-a100: #ea80fc; - --paper-purple-a200: #e040fb; - --paper-purple-a400: #d500f9; - --paper-purple-a700: #aa00ff; - - --paper-deep-purple-50: #ede7f6; - --paper-deep-purple-100: #d1c4e9; - --paper-deep-purple-200: #b39ddb; - --paper-deep-purple-300: #9575cd; - --paper-deep-purple-400: #7e57c2; - --paper-deep-purple-500: #673ab7; - --paper-deep-purple-600: #5e35b1; - --paper-deep-purple-700: #512da8; - --paper-deep-purple-800: #4527a0; - --paper-deep-purple-900: #311b92; - --paper-deep-purple-a100: #b388ff; - --paper-deep-purple-a200: #7c4dff; - --paper-deep-purple-a400: #651fff; - --paper-deep-purple-a700: #6200ea; - - --paper-indigo-50: #e8eaf6; - --paper-indigo-100: #c5cae9; - --paper-indigo-200: #9fa8da; - --paper-indigo-300: #7986cb; - --paper-indigo-400: #5c6bc0; - --paper-indigo-500: #3f51b5; - --paper-indigo-600: #3949ab; - --paper-indigo-700: #303f9f; - --paper-indigo-800: #283593; - --paper-indigo-900: #1a237e; - --paper-indigo-a100: #8c9eff; - --paper-indigo-a200: #536dfe; - --paper-indigo-a400: #3d5afe; - --paper-indigo-a700: #304ffe; - - --paper-blue-50: #e3f2fd; - --paper-blue-100: #bbdefb; - --paper-blue-200: #90caf9; - --paper-blue-300: #64b5f6; - --paper-blue-400: #42a5f5; - --paper-blue-500: #2196f3; - --paper-blue-600: #1e88e5; - --paper-blue-700: #1976d2; - --paper-blue-800: #1565c0; - --paper-blue-900: #0d47a1; - --paper-blue-a100: #82b1ff; - --paper-blue-a200: #448aff; - --paper-blue-a400: #2979ff; - --paper-blue-a700: #2962ff; - - --paper-light-blue-50: #e1f5fe; - --paper-light-blue-100: #b3e5fc; - --paper-light-blue-200: #81d4fa; - --paper-light-blue-300: #4fc3f7; - --paper-light-blue-400: #29b6f6; - --paper-light-blue-500: #03a9f4; - --paper-light-blue-600: #039be5; - --paper-light-blue-700: #0288d1; - --paper-light-blue-800: #0277bd; - --paper-light-blue-900: #01579b; - --paper-light-blue-a100: #80d8ff; - --paper-light-blue-a200: #40c4ff; - --paper-light-blue-a400: #00b0ff; - --paper-light-blue-a700: #0091ea; - - --paper-cyan-50: #e0f7fa; - --paper-cyan-100: #b2ebf2; - --paper-cyan-200: #80deea; - --paper-cyan-300: #4dd0e1; - --paper-cyan-400: #26c6da; - --paper-cyan-500: #00bcd4; - --paper-cyan-600: #00acc1; - --paper-cyan-700: #0097a7; - --paper-cyan-800: #00838f; - --paper-cyan-900: #006064; - --paper-cyan-a100: #84ffff; - --paper-cyan-a200: #18ffff; - --paper-cyan-a400: #00e5ff; - --paper-cyan-a700: #00b8d4; - - --paper-teal-50: #e0f2f1; - --paper-teal-100: #b2dfdb; - --paper-teal-200: #80cbc4; - --paper-teal-300: #4db6ac; - --paper-teal-400: #26a69a; - --paper-teal-500: #009688; - --paper-teal-600: #00897b; - --paper-teal-700: #00796b; - --paper-teal-800: #00695c; - --paper-teal-900: #004d40; - --paper-teal-a100: #a7ffeb; - --paper-teal-a200: #64ffda; - --paper-teal-a400: #1de9b6; - --paper-teal-a700: #00bfa5; - - --paper-green-50: #e8f5e9; - --paper-green-100: #c8e6c9; - --paper-green-200: #a5d6a7; - --paper-green-300: #81c784; - --paper-green-400: #66bb6a; - --paper-green-500: #4caf50; - --paper-green-600: #43a047; - --paper-green-700: #388e3c; - --paper-green-800: #2e7d32; - --paper-green-900: #1b5e20; - --paper-green-a100: #b9f6ca; - --paper-green-a200: #69f0ae; - --paper-green-a400: #00e676; - --paper-green-a700: #00c853; - - --paper-light-green-50: #f1f8e9; - --paper-light-green-100: #dcedc8; - --paper-light-green-200: #c5e1a5; - --paper-light-green-300: #aed581; - --paper-light-green-400: #9ccc65; - --paper-light-green-500: #8bc34a; - --paper-light-green-600: #7cb342; - --paper-light-green-700: #689f38; - --paper-light-green-800: #558b2f; - --paper-light-green-900: #33691e; - --paper-light-green-a100: #ccff90; - --paper-light-green-a200: #b2ff59; - --paper-light-green-a400: #76ff03; - --paper-light-green-a700: #64dd17; - - --paper-lime-50: #f9fbe7; - --paper-lime-100: #f0f4c3; - --paper-lime-200: #e6ee9c; - --paper-lime-300: #dce775; - --paper-lime-400: #d4e157; - --paper-lime-500: #cddc39; - --paper-lime-600: #c0ca33; - --paper-lime-700: #afb42b; - --paper-lime-800: #9e9d24; - --paper-lime-900: #827717; - --paper-lime-a100: #f4ff81; - --paper-lime-a200: #eeff41; - --paper-lime-a400: #c6ff00; - --paper-lime-a700: #aeea00; - - --paper-yellow-50: #fffde7; - --paper-yellow-100: #fff9c4; - --paper-yellow-200: #fff59d; - --paper-yellow-300: #fff176; - --paper-yellow-400: #ffee58; - --paper-yellow-500: #ffeb3b; - --paper-yellow-600: #fdd835; - --paper-yellow-700: #fbc02d; - --paper-yellow-800: #f9a825; - --paper-yellow-900: #f57f17; - --paper-yellow-a100: #ffff8d; - --paper-yellow-a200: #ffff00; - --paper-yellow-a400: #ffea00; - --paper-yellow-a700: #ffd600; - - --paper-amber-50: #fff8e1; - --paper-amber-100: #ffecb3; - --paper-amber-200: #ffe082; - --paper-amber-300: #ffd54f; - --paper-amber-400: #ffca28; - --paper-amber-500: #ffc107; - --paper-amber-600: #ffb300; - --paper-amber-700: #ffa000; - --paper-amber-800: #ff8f00; - --paper-amber-900: #ff6f00; - --paper-amber-a100: #ffe57f; - --paper-amber-a200: #ffd740; - --paper-amber-a400: #ffc400; - --paper-amber-a700: #ffab00; - - --paper-orange-50: #fff3e0; - --paper-orange-100: #ffe0b2; - --paper-orange-200: #ffcc80; - --paper-orange-300: #ffb74d; - --paper-orange-400: #ffa726; - --paper-orange-500: #ff9800; - --paper-orange-600: #fb8c00; - --paper-orange-700: #f57c00; - --paper-orange-800: #ef6c00; - --paper-orange-900: #e65100; - --paper-orange-a100: #ffd180; - --paper-orange-a200: #ffab40; - --paper-orange-a400: #ff9100; - --paper-orange-a700: #ff6500; - - --paper-deep-orange-50: #fbe9e7; - --paper-deep-orange-100: #ffccbc; - --paper-deep-orange-200: #ffab91; - --paper-deep-orange-300: #ff8a65; - --paper-deep-orange-400: #ff7043; - --paper-deep-orange-500: #ff5722; - --paper-deep-orange-600: #f4511e; - --paper-deep-orange-700: #e64a19; - --paper-deep-orange-800: #d84315; - --paper-deep-orange-900: #bf360c; - --paper-deep-orange-a100: #ff9e80; - --paper-deep-orange-a200: #ff6e40; - --paper-deep-orange-a400: #ff3d00; - --paper-deep-orange-a700: #dd2c00; - - --paper-brown-50: #efebe9; - --paper-brown-100: #d7ccc8; - --paper-brown-200: #bcaaa4; - --paper-brown-300: #a1887f; - --paper-brown-400: #8d6e63; - --paper-brown-500: #795548; - --paper-brown-600: #6d4c41; - --paper-brown-700: #5d4037; - --paper-brown-800: #4e342e; - --paper-brown-900: #3e2723; - - --paper-grey-50: #fafafa; - --paper-grey-100: #f5f5f5; - --paper-grey-200: #eeeeee; - --paper-grey-300: #e0e0e0; - --paper-grey-400: #bdbdbd; - --paper-grey-500: #9e9e9e; - --paper-grey-600: #757575; - --paper-grey-700: #616161; - --paper-grey-800: #424242; - --paper-grey-900: #212121; - - --paper-blue-grey-50: #eceff1; - --paper-blue-grey-100: #cfd8dc; - --paper-blue-grey-200: #b0bec5; - --paper-blue-grey-300: #90a4ae; - --paper-blue-grey-400: #78909c; - --paper-blue-grey-500: #607d8b; - --paper-blue-grey-600: #546e7a; - --paper-blue-grey-700: #455a64; - --paper-blue-grey-800: #37474f; - --paper-blue-grey-900: #263238; - - - --dark-divider-opacity: 0.12; - --dark-disabled-opacity: 0.38; - --dark-secondary-opacity: 0.54; - --dark-primary-opacity: 0.87; - - - --light-divider-opacity: 0.12; - --light-disabled-opacity: 0.3; - --light-secondary-opacity: 0.7; - --light-primary-opacity: 1.0; -} - -</style><dom-module id="paper-progress" assetpath="chrome://resources/polymer/v1_0/paper-progress/" css-build="shadow"> - <template> - <style scope="paper-progress">:host { - display: block; - width: 200px; - position: relative; - overflow: hidden; -} - -:host([hidden]) { - display: none !important; -} - -#progressContainer { - ; - position: relative; -} - -#progressContainer, .indeterminate::after { - height: var(--paper-progress-height, 4px); -} - -#primaryProgress, #secondaryProgress, .indeterminate::after { - position: var(--layout-fit_-_position); top: var(--layout-fit_-_top); right: var(--layout-fit_-_right); bottom: var(--layout-fit_-_bottom); left: var(--layout-fit_-_left); -} - -#progressContainer, .indeterminate::after { - background: var(--paper-progress-container-color,var(--google-grey-300)); -} - -:host(.transiting) #primaryProgress, :host(.transiting) #secondaryProgress { - -webkit-transition-property: -webkit-transform; - transition-property: transform; - - - -webkit-transition-duration: var(--paper-progress-transition-duration, 0.08s); - transition-duration: var(--paper-progress-transition-duration, 0.08s); - - - -webkit-transition-timing-function: var(--paper-progress-transition-timing-function, ease); - transition-timing-function: var(--paper-progress-transition-timing-function, ease); - - - -webkit-transition-delay: var(--paper-progress-transition-delay, 0s); - transition-delay: var(--paper-progress-transition-delay, 0s); -} - -#primaryProgress, #secondaryProgress { - position: var(--layout-fit_-_position); top: var(--layout-fit_-_top); right: var(--layout-fit_-_right); bottom: var(--layout-fit_-_bottom); left: var(--layout-fit_-_left); - -webkit-transform-origin: left center; - transform-origin: left center; - -webkit-transform: scaleX(0); - transform: scaleX(0); - will-change: transform; -} - -#primaryProgress { - background: var(--paper-progress-active-color,var(--google-green-500)); -} - -#secondaryProgress { - background: var(--paper-progress-secondary-color,var(--google-green-100)); -} - -:host([disabled]) #primaryProgress { - background: var(--paper-progress-disabled-active-color,var(--google-grey-500)); -} - -:host([disabled]) #secondaryProgress { - background: var(--paper-progress-disabled-secondary-color,var(--google-grey-300)); -} - -:host(:not([disabled])) #primaryProgress.indeterminate { - -webkit-transform-origin: right center; - transform-origin: right center; - -webkit-animation: indeterminate-bar var(--paper-progress-indeterminate-cycle-duration, 2s) linear infinite; - animation: indeterminate-bar var(--paper-progress-indeterminate-cycle-duration, 2s) linear infinite; -} - -:host(:not([disabled])) #primaryProgress.indeterminate::after { - content: ""; - -webkit-transform-origin: center center; - transform-origin: center center; - - -webkit-animation: indeterminate-splitter var(--paper-progress-indeterminate-cycle-duration, 2s) linear infinite; - animation: indeterminate-splitter var(--paper-progress-indeterminate-cycle-duration, 2s) linear infinite; -} - -@-webkit-keyframes indeterminate-bar { -0% { - -webkit-transform: scaleX(1) translateX(-100%); -} - -50% { - -webkit-transform: scaleX(1) translateX(0%); -} - -75% { - -webkit-transform: scaleX(1) translateX(0%); - -webkit-animation-timing-function: cubic-bezier(.28,.62,.37,.91); -} - -100% { - -webkit-transform: scaleX(0) translateX(0%); -} - -} - -@-webkit-keyframes indeterminate-splitter { -0% { - -webkit-transform: scaleX(.75) translateX(-125%); -} - -30% { - -webkit-transform: scaleX(.75) translateX(-125%); - -webkit-animation-timing-function: cubic-bezier(.42,0,.6,.8); -} - -90% { - -webkit-transform: scaleX(.75) translateX(125%); -} - -100% { - -webkit-transform: scaleX(.75) translateX(125%); -} - -} - -@keyframes indeterminate-bar { -0% { - transform: scaleX(1) translateX(-100%); -} - -50% { - transform: scaleX(1) translateX(0%); -} - -75% { - transform: scaleX(1) translateX(0%); - animation-timing-function: cubic-bezier(.28,.62,.37,.91); -} - -100% { - transform: scaleX(0) translateX(0%); -} - -} - -@keyframes indeterminate-splitter { -0% { - transform: scaleX(.75) translateX(-125%); -} - -30% { - transform: scaleX(.75) translateX(-125%); - animation-timing-function: cubic-bezier(.42,0,.6,.8); -} - -90% { - transform: scaleX(.75) translateX(125%); -} - -100% { - transform: scaleX(.75) translateX(125%); -} - -} - -</style> - - <div id="progressContainer"> - <div id="secondaryProgress" hidden$="[[_hideSecondaryProgress(secondaryRatio)]]"></div> - <div id="primaryProgress"></div> - </div> - </template> -</dom-module> - -<iron-iconset-svg name="downloads" size="24"> - <svg> - <defs> - - <g id="remove-circle"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z"></path></g> - </defs> - </svg> -</iron-iconset-svg> -<dom-module id="downloads-item" assetpath="chrome://downloads/" css-build="shadow"> - <template> - <style scope="downloads-item">[is='action-link'] { - cursor: pointer; - display: inline-block; - text-decoration: none; -} - -[is='action-link']:hover { - text-decoration: underline; -} - -[is='action-link']:active { - color: rgb(5, 37, 119); - text-decoration: underline; -} - -[is='action-link'][disabled] { - color: #999; - cursor: default; - pointer-events: none; - text-decoration: none; -} - -[is='action-link'].no-outline { - outline: none; -} - -:host { - display: flex; - flex-direction: column; -} - -[hidden] { - display: none !important; -} - -paper-button { - font-weight: 500; - margin: 0; - min-width: auto; -} - -#date { - color: var(--paper-grey-700); - font-size: 100%; - font-weight: 500; - margin: 24px auto 10px; - width: var(--downloads-card-width); -} - -#date:empty { - display: none; -} - -#content { - background: white; - border-radius: 2px; - display: flex; - flex: none; - margin: 6px auto; - min-height: 103px; - position: relative; - width: var(--downloads-card-width); -} - -#content.is-active { - box-shadow: var(--shadow-elevation-2dp_-_box-shadow); -} - -#content:not(.is-active) { - background: rgba(255, 255, 255, .6); - box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .03), - 0 1px 4px 0 rgba(0, 0, 0, .048), - 0 3px 1px -2px rgba(0, 0, 0, .12); -} - -#details { - -webkit-border-start: 1px #d8d8d8 solid; - -webkit-padding-end: 16px; - -webkit-padding-start: var(--downloads-card-margin); - display: flex; - flex: 1; - flex-direction: column; - min-width: 0; - padding-bottom: 12px; - padding-top: 16px; -} - -#content:not(.is-active) #details { - color: rgba(27, 27, 27, .6); -} - -#content:not(.is-active) #name { - text-decoration: line-through; -} - -.icon-wrapper { - align-self: center; - flex: none; - justify-content: center; - margin: 0 24px; -} - -.icon { - height: 32px; - width: 32px; -} - -#content:-webkit-any(.show-progress, .dangerous) #file-icon-wrapper { - align-self: flex-start; - padding-top: 16px; -} - -#content:not(.is-active) .icon { - -webkit-filter: grayscale(100%); - opacity: .5; -} - -#danger-icon { - height: 32px; - width: 32px; -} - -#danger-icon[icon='cr:warning'], .dangerous #description { - color: var(--google-red-700); -} - -#name, #file-link, #url { - max-width: 100%; -} - -#name, #file-link { - font-weight: 500; - word-break: break-all; -} - -#name { - -webkit-margin-end: 12px; -} - -#pause-or-resume, .is-active :-webkit-any(#name, #file-link, #show) { - color: rgb(51, 103, 214); -} - -#tag { - color: #5a5a5a; - font-weight: 500; -} - -#url { - color: inherit; - margin-top: 6px; - min-height: 0; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; -} - -.is-active #url { - color: var(--paper-grey-600); -} - -#progress, #description:not(:empty), .controls { - margin-top: 16px; -} - -.is-active #description { - color: #616161; -} - -#progress { - --paper-progress-active-color: rgb(54, 126, 237); - --paper-progress-container-color: rgb(223, 222, 223); - width: auto; -} - -.controls { - -webkit-margin-start: -.57em; -} - -#cancel, #retry, .keep, .discard { - color: #5a5a5a; -} - -#show { - margin: .7em .57em; -} - -#controlled-by { - -webkit-margin-start: 8px; -} - -#controlled-by, #controlled-by a { - color: #5a5a5a; -} - -.is-active #controlled-by { - color: #333; -} - -.is-active #controlled-by a { - color: rgb(51, 103, 214); -} - -#remove-wrapper { - align-self: flex-start; - margin: 0; -} - -#remove { - color: var(--paper-grey-700); - font-size: 16px; - height: 32px; - line-height: 17px; - width: 32px; -} - -#incognito { - bottom: 20px; - content: -webkit-image-set( - url("chrome://downloads/1x/incognito_marker.png") 1x, - url("chrome://downloads/2x/incognito_marker.png") 2x); - position: absolute; - right: 10px; -} - -</style> - - <h3 id="date">[[computeDate_(data.hideDate, data.since_string, data.date_string)]]</h3> - - <div id="content" on-dragstart="onDragStart_" class$="[[computeClass_(isActive_, isDangerous_, showProgress_)]]"> - <div id="file-icon-wrapper" class="icon-wrapper"> - <img class="icon" id="file-icon" alt="" hidden="[[isDangerous_]]"> - <iron-icon id="danger-icon" icon$="[[computeDangerIcon_(isDangerous_, data.danger_type)]]" hidden="[[!isDangerous_]]"></iron-icon> - </div> - - <div id="details"> - <div id="title-area"><a is="action-link" id="file-link" href="[[data.url]]" on-tap="onFileLinkTap_" hidden="[[!completelyOnDisk_]]">[[data.file_name]]</a><span id="name" hidden="[[completelyOnDisk_]]">[[data.file_name]]</span> - <span id="tag">[[computeTag_(data.state, data.last_reason_text, data.file_externally_removed)]]</span> - </div> - - <a id="url" target="_blank">[[chopUrl_(data.url)]]</a> - - <div id="description">[[computeDescription_(data.state, data.danger_type, data.file_name, data.progress_status_text)]]</div> - - <template is="dom-if" if="[[showProgress_]]"> - <paper-progress id="progress" indeterminate="[[isIndeterminate_(data.percent)]]" value="[[data.percent]]"></paper-progress> - </template> - - <div id="safe" class="controls" hidden="[[isDangerous_]]"> - <a is="action-link" id="show" on-tap="onShowTap_" hidden="[[!completelyOnDisk_]]">$i18n{controlShowInFolder}</a> - <template is="dom-if" if="[[data.retry]]"> - <paper-button id="retry" on-tap="onRetryTap_"> - $i18n{controlRetry} - </paper-button> - </template> - <template is="dom-if" if="[[pauseOrResumeText_]]"> - <paper-button id="pause-or-resume" on-tap="onPauseOrResumeTap_"> - [[pauseOrResumeText_]] - </paper-button> - </template> - <template is="dom-if" if="[[showCancel_]]"> - <paper-button id="cancel" on-tap="onCancelTap_"> - $i18n{controlCancel} - </paper-button> - </template> - <span id="controlled-by"></span> - </div> - - <template is="dom-if" if="[[isDangerous_]]"> - <div id="dangerous" class="controls"> - - <template is="dom-if" if="[[!isMalware_]]"> - <paper-button id="discard" on-tap="onDiscardDangerousTap_" class="discard">$i18n{dangerDiscard}</paper-button> - <paper-button id="save" on-tap="onSaveDangerousTap_" class="keep">$i18n{dangerSave}</paper-button> - </template> - - - <template is="dom-if" if="[[isMalware_]]"> - <paper-button id="danger-remove" on-tap="onDiscardDangerousTap_" class="discard">$i18n{controlRemoveFromList}</paper-button> - <paper-button id="restore" on-tap="onSaveDangerousTap_" class="keep">$i18n{dangerRestore}</paper-button> - </template> - </div> - </template> - </div> - - <div id="remove-wrapper" class="icon-wrapper"> - <button is="paper-icon-button-light" id="remove" title="$i18n{controlRemoveFromList}" style$="[[computeRemoveStyle_(isDangerous_, showCancel_)]]" on-tap="onRemoveTap_">✕</button> - </div> - - <div id="incognito" title="$i18n{inIncognito}" hidden="[[!data.otr]]"> - </div> - </div> - - </template> - - </dom-module> - - - - -<style is="custom-style" css-build="shadow">html { - --primary-text-color: var(--light-theme-text-color); - --primary-background-color: var(--light-theme-background-color); - --secondary-text-color: var(--light-theme-secondary-color); - --disabled-text-color: var(--light-theme-disabled-color); - --divider-color: var(--light-theme-divider-color); - --error-color: var(--paper-deep-orange-a700); - - - --primary-color: var(--paper-indigo-500); - --light-primary-color: var(--paper-indigo-100); - --dark-primary-color: var(--paper-indigo-700); - - --accent-color: var(--paper-pink-a200); - --light-accent-color: var(--paper-pink-a100); - --dark-accent-color: var(--paper-pink-a400); - - - - --light-theme-background-color: #ffffff; - --light-theme-base-color: #000000; - --light-theme-text-color: var(--paper-grey-900); - --light-theme-secondary-color: #737373; - --light-theme-disabled-color: #9b9b9b; - --light-theme-divider-color: #dbdbdb; - - - --dark-theme-background-color: var(--paper-grey-900); - --dark-theme-base-color: #ffffff; - --dark-theme-text-color: #ffffff; - --dark-theme-secondary-color: #bcbcbc; - --dark-theme-disabled-color: #646464; - --dark-theme-divider-color: #3c3c3c; - - - --text-primary-color: var(--dark-theme-text-color); - --default-primary-color: var(--primary-color); -} - -</style><style> -/* Copyright 2015 The Chromium Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. */ - -<if expr="not chromeos and not is_android"> -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 400; - src: local('Roboto'), local('Roboto-Regular'), - url("chrome://resources/roboto/roboto-regular.woff2") format('woff2'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 500; - src: local('Roboto Medium'), local('Roboto-Medium'), - url("chrome://resources/roboto/roboto-medium.woff2") format('woff2'); -} - -@font-face { - font-family: 'Roboto'; - font-style: normal; - font-weight: 700; - src: local('Roboto Bold'), local('Roboto-Bold'), - url("chrome://resources/roboto/roboto-bold.woff2") format('woff2'); -} -</if> - -</style> -<style is="custom-style" css-build="shadow">html { - --paper-font-common-base_-_font-family: 'Roboto', 'Noto', sans-serif; --paper-font-common-base_-_-webkit-font-smoothing: antialiased;; - - --paper-font-common-code_-_font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace; --paper-font-common-code_-_-webkit-font-smoothing: antialiased;; - - --paper-font-common-expensive-kerning_-_text-rendering: optimizeLegibility;; - - --paper-font-common-nowrap_-_white-space: nowrap; --paper-font-common-nowrap_-_overflow: hidden; --paper-font-common-nowrap_-_text-overflow: ellipsis;; - - - - --paper-font-display4_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-display4_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-display4_-_white-space: var(--paper-font-common-nowrap_-_white-space); --paper-font-display4_-_overflow: var(--paper-font-common-nowrap_-_overflow); --paper-font-display4_-_text-overflow: var(--paper-font-common-nowrap_-_text-overflow); --paper-font-display4_-_font-size: 112px; --paper-font-display4_-_font-weight: 300; --paper-font-display4_-_letter-spacing: -.044em; --paper-font-display4_-_line-height: 120px;; - - --paper-font-display3_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-display3_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-display3_-_white-space: var(--paper-font-common-nowrap_-_white-space); --paper-font-display3_-_overflow: var(--paper-font-common-nowrap_-_overflow); --paper-font-display3_-_text-overflow: var(--paper-font-common-nowrap_-_text-overflow); --paper-font-display3_-_font-size: 56px; --paper-font-display3_-_font-weight: 400; --paper-font-display3_-_letter-spacing: -.026em; --paper-font-display3_-_line-height: 60px;; - - --paper-font-display2_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-display2_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-display2_-_font-size: 45px; --paper-font-display2_-_font-weight: 400; --paper-font-display2_-_letter-spacing: -.018em; --paper-font-display2_-_line-height: 48px;; - - --paper-font-display1_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-display1_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-display1_-_font-size: 34px; --paper-font-display1_-_font-weight: 400; --paper-font-display1_-_letter-spacing: -.01em; --paper-font-display1_-_line-height: 40px;; - - --paper-font-headline_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-headline_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-headline_-_font-size: 24px; --paper-font-headline_-_font-weight: 400; --paper-font-headline_-_letter-spacing: -.012em; --paper-font-headline_-_line-height: 32px;; - - --paper-font-title_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-title_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-title_-_white-space: var(--paper-font-common-nowrap_-_white-space); --paper-font-title_-_overflow: var(--paper-font-common-nowrap_-_overflow); --paper-font-title_-_text-overflow: var(--paper-font-common-nowrap_-_text-overflow); --paper-font-title_-_font-size: 20px; --paper-font-title_-_font-weight: 500; --paper-font-title_-_line-height: 28px;; - - --paper-font-subhead_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-subhead_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-subhead_-_font-size: 16px; --paper-font-subhead_-_font-weight: 400; --paper-font-subhead_-_line-height: 24px;; - - --paper-font-body2_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-body2_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-body2_-_font-size: 14px; --paper-font-body2_-_font-weight: 500; --paper-font-body2_-_line-height: 24px;; - - --paper-font-body1_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-body1_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-body1_-_font-size: 14px; --paper-font-body1_-_font-weight: 400; --paper-font-body1_-_line-height: 20px;; - - --paper-font-caption_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-caption_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-caption_-_white-space: var(--paper-font-common-nowrap_-_white-space); --paper-font-caption_-_overflow: var(--paper-font-common-nowrap_-_overflow); --paper-font-caption_-_text-overflow: var(--paper-font-common-nowrap_-_text-overflow); --paper-font-caption_-_font-size: 12px; --paper-font-caption_-_font-weight: 400; --paper-font-caption_-_letter-spacing: 0.011em; --paper-font-caption_-_line-height: 20px;; - - --paper-font-menu_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-menu_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-menu_-_white-space: var(--paper-font-common-nowrap_-_white-space); --paper-font-menu_-_overflow: var(--paper-font-common-nowrap_-_overflow); --paper-font-menu_-_text-overflow: var(--paper-font-common-nowrap_-_text-overflow); --paper-font-menu_-_font-size: 13px; --paper-font-menu_-_font-weight: 500; --paper-font-menu_-_line-height: 24px;; - - --paper-font-button_-_font-family: var(--paper-font-common-base_-_font-family); --paper-font-button_-_-webkit-font-smoothing: var(--paper-font-common-base_-_-webkit-font-smoothing); --paper-font-button_-_white-space: var(--paper-font-common-nowrap_-_white-space); --paper-font-button_-_overflow: var(--paper-font-common-nowrap_-_overflow); --paper-font-button_-_text-overflow: var(--paper-font-common-nowrap_-_text-overflow); --paper-font-button_-_font-size: 14px; --paper-font-button_-_font-weight: 500; --paper-font-button_-_letter-spacing: 0.018em; --paper-font-button_-_line-height: 24px; --paper-font-button_-_text-transform: uppercase;; - - --paper-font-code2_-_font-family: var(--paper-font-common-code_-_font-family); --paper-font-code2_-_-webkit-font-smoothing: var(--paper-font-common-code_-_-webkit-font-smoothing); --paper-font-code2_-_font-size: 14px; --paper-font-code2_-_font-weight: 700; --paper-font-code2_-_line-height: 20px;; - - --paper-font-code1_-_font-family: var(--paper-font-common-code_-_font-family); --paper-font-code1_-_-webkit-font-smoothing: var(--paper-font-common-code_-_-webkit-font-smoothing); --paper-font-code1_-_font-size: 14px; --paper-font-code1_-_font-weight: 500; --paper-font-code1_-_line-height: 20px;; -} - -</style><dom-module id="paper-item-shared-styles" assetpath="chrome://resources/polymer/v1_0/paper-item/" css-build="shadow"> - <template> - <style scope="paper-item-shared-styles">:host, .paper-item { - display: block; - position: relative; - min-height: var(--paper-item-min-height, 48px); - padding: 0px 16px; -} - -.paper-item { - font-family: var(--paper-font-subhead_-_font-family); -webkit-font-smoothing: var(--paper-font-subhead_-_-webkit-font-smoothing); font-size: var(--paper-font-subhead_-_font-size); font-weight: var(--paper-font-subhead_-_font-weight); line-height: var(--paper-font-subhead_-_line-height); - border:none; - outline: none; - background: white; - width: 100%; - text-align: left; -} - -:host([hidden]), .paper-item[hidden] { - display: none !important; -} - -:host(.iron-selected), .paper-item.iron-selected { - font-weight: var(--paper-item-selected-weight, bold); - - ; -} - -:host([disabled]), .paper-item[disabled] { - color: var(--paper-item-disabled-color,var(--disabled-text-color)); - - ; -} - -:host(:focus), .paper-item:focus { - position: relative; - outline: 0; - - ; -} - -:host(:focus):before, .paper-item:focus:before { - position: var(--layout-fit_-_position); top: var(--layout-fit_-_top); right: var(--layout-fit_-_right); bottom: var(--layout-fit_-_bottom); left: var(--layout-fit_-_left); - - background: currentColor; - content: ''; - opacity: var(--dark-divider-opacity); - pointer-events: none; - - ; -} - -</style> - </template> -</dom-module> -<dom-module id="paper-item" assetpath="chrome://resources/polymer/v1_0/paper-item/" css-build="shadow"> - <template> - - <style scope="paper-item">:host, .paper-item { - display: block; - position: relative; - min-height: var(--paper-item-min-height, 48px); - padding: 0px 16px; -} - -.paper-item { - font-family: var(--paper-font-subhead_-_font-family); -webkit-font-smoothing: var(--paper-font-subhead_-_-webkit-font-smoothing); font-size: var(--paper-font-subhead_-_font-size); font-weight: var(--paper-font-subhead_-_font-weight); line-height: var(--paper-font-subhead_-_line-height); - border:none; - outline: none; - background: white; - width: 100%; - text-align: left; -} - -:host([hidden]), .paper-item[hidden] { - display: none !important; -} - -:host(.iron-selected), .paper-item.iron-selected { - font-weight: var(--paper-item-selected-weight, bold); - - ; -} - -:host([disabled]), .paper-item[disabled] { - color: var(--paper-item-disabled-color,var(--disabled-text-color)); - - ; -} - -:host(:focus), .paper-item:focus { - position: relative; - outline: 0; - - ; -} - -:host(:focus):before, .paper-item:focus:before { - position: var(--layout-fit_-_position); top: var(--layout-fit_-_top); right: var(--layout-fit_-_right); bottom: var(--layout-fit_-_bottom); left: var(--layout-fit_-_left); - - background: currentColor; - content: ''; - opacity: var(--dark-divider-opacity); - pointer-events: none; - - ; -} - -:host { - display: var(--layout-horizontal_-_display); -ms-flex-direction: var(--layout-horizontal_-_-ms-flex-direction); -webkit-flex-direction: var(--layout-horizontal_-_-webkit-flex-direction); flex-direction: var(--layout-horizontal_-_flex-direction); - -ms-flex-align: var(--layout-center_-_-ms-flex-align); -webkit-align-items: var(--layout-center_-_-webkit-align-items); align-items: var(--layout-center_-_align-items); - font-family: var(--paper-font-subhead_-_font-family); -webkit-font-smoothing: var(--paper-font-subhead_-_-webkit-font-smoothing); font-size: var(--paper-font-subhead_-_font-size); font-weight: var(--paper-font-subhead_-_font-weight); line-height: var(--paper-font-subhead_-_line-height); - - ; -} - -</style> - - <content></content> - </template> - - </dom-module> -<dom-module id="paper-menu-shared-styles" assetpath="chrome://resources/polymer/v1_0/paper-menu/" css-build="shadow"> - <template> - <style scope="paper-menu-shared-styles">.selectable-content > ::content > .iron-selected { - font-weight: bold; - - font-weight: var(--paper-menu-selected-item_-_font-weight, bold); -} - -.selectable-content > ::content > [disabled] { - color: var(--paper-menu-disabled-color,var(--disabled-text-color)); -} - -.selectable-content > ::content > *:focus { - position: relative; - outline: 0; - - ; -} - -.selectable-content > ::content > *:focus:after { - position: var(--layout-fit_-_position); top: var(--layout-fit_-_top); right: var(--layout-fit_-_right); bottom: var(--layout-fit_-_bottom); left: var(--layout-fit_-_left); - background: currentColor; - opacity: var(--dark-divider-opacity); - content: ''; - pointer-events: none; - - ; -} - -.selectable-content > ::content > *[colored]:focus:after { - opacity: 0.26; -} - -</style> - </template> -</dom-module> -<dom-module id="paper-menu" assetpath="chrome://resources/polymer/v1_0/paper-menu/" css-build="shadow"> - <template> - - <style scope="paper-menu">.selectable-content > ::content > .iron-selected { - font-weight: bold; - - font-weight: var(--paper-menu-selected-item_-_font-weight, bold); -} - -.selectable-content > ::content > [disabled] { - color: var(--paper-menu-disabled-color,var(--disabled-text-color)); -} - -.selectable-content > ::content > *:focus { - position: relative; - outline: 0; - - ; -} - -.selectable-content > ::content > *:focus:after { - position: var(--layout-fit_-_position); top: var(--layout-fit_-_top); right: var(--layout-fit_-_right); bottom: var(--layout-fit_-_bottom); left: var(--layout-fit_-_left); - background: currentColor; - opacity: var(--dark-divider-opacity); - content: ''; - pointer-events: none; - - ; -} - -.selectable-content > ::content > *[colored]:focus:after { - opacity: 0.26; -} - -:host { - display: block; - padding: 8px 0; - - background: var(--paper-menu-background-color,var(--primary-background-color)); - color: var(--paper-menu-color,var(--primary-text-color)); - - ; -} - -</style> - - <div class="selectable-content"> - <content></content> - </div> - </template> - - </dom-module> -<dom-module id="iron-overlay-backdrop" assetpath="" css-build="shadow"> - - <template> - <style scope="iron-overlay-backdrop">:host { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: var(--iron-overlay-backdrop-background-color, #000); - opacity: 0; - transition: opacity 0.2s; - pointer-events: none; - ; -} - -:host(.opened) { - opacity: var(--iron-overlay-backdrop-opacity, 0.6); - pointer-events: auto; - ; -} - -</style> - - <content></content> - </template> - -</dom-module> - -<script src="chrome://resources/polymer/v1_0/web-animations-js/web-animations-next-lite.min.js"></script> -<dom-module id="iron-dropdown" assetpath="chrome://resources/polymer/v1_0/iron-dropdown/" css-build="shadow"> - <template> - <style scope="iron-dropdown">:host { - position: fixed; -} - -#contentWrapper ::content > * { - overflow: auto; -} - -#contentWrapper.animating ::content > * { - overflow: hidden; -} - -</style> - - <div id="contentWrapper"> - <content id="content" select=".dropdown-content"></content> - </div> - </template> - - </dom-module> -<dom-module id="paper-menu-button" assetpath="chrome://resources/polymer/v1_0/paper-menu-button/" css-build="shadow"> - <template> - <style scope="paper-menu-button">:host { - display: inline-block; - position: relative; - padding: 8px; - outline: none; - - padding: var(--paper-menu-button_-_padding, 8px); -} - -:host([disabled]) { - cursor: auto; - color: var(--disabled-text-color); - - ; -} - -iron-dropdown { - ; -} - -.dropdown-content { - box-shadow: var(--shadow-elevation-2dp_-_box-shadow); - - position: relative; - border-radius: 2px; - background-color: var(--paper-menu-button-dropdown-background,var(--primary-background-color)); - - ; -} - -:host([vertical-align="top"]) .dropdown-content { - margin-bottom: 20px; - margin-top: -10px; - top: 10px; -} - -:host([vertical-align="bottom"]) .dropdown-content { - bottom: 10px; - margin-bottom: -10px; - margin-top: 20px; -} - -#trigger { - cursor: pointer; -} - -</style> - - <div id="trigger" on-tap="toggle"> - <content select=".dropdown-trigger"></content> - </div> - - <iron-dropdown id="dropdown" opened="{{opened}}" horizontal-align="[[horizontalAlign]]" vertical-align="[[verticalAlign]]" dynamic-align="[[dynamicAlign]]" horizontal-offset="[[horizontalOffset]]" vertical-offset="[[verticalOffset]]" no-overlap="[[noOverlap]]" open-animation-config="[[openAnimationConfig]]" close-animation-config="[[closeAnimationConfig]]" no-animations="[[noAnimations]]" focus-target="[[_dropdownContent]]" allow-outside-scroll="[[allowOutsideScroll]]" restore-focus-on-close="[[restoreFocusOnClose]]" on-iron-overlay-canceled="__onIronOverlayCanceled"> - <div class="dropdown-content"> - <content id="content" select=".dropdown-content"></content> - </div> - </iron-dropdown> - </template> - - </dom-module> -<dom-module id="paper-icon-button" assetpath="chrome://resources/polymer/v1_0/paper-icon-button/" css-build="shadow"> - <template strip-whitespace=""> - <style scope="paper-icon-button">:host { - display: inline-block; - position: relative; - padding: 8px; - outline: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - cursor: pointer; - z-index: 0; - line-height: 1; - - width: 40px; - height: 40px; - - - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-tap-highlight-color: transparent; - - - box-sizing: border-box !important; - - height: var(--paper-icon-button_-_height, 40px); padding: var(--paper-icon-button_-_padding, 8px); width: var(--paper-icon-button_-_width, 40px); -} - -:host #ink { - color: var(--paper-icon-button-ink-color,var(--primary-text-color)); - opacity: 0.6; -} - -:host([disabled]) { - color: var(--paper-icon-button-disabled-text,var(--disabled-text-color)); - pointer-events: none; - cursor: auto; - - ; -} - -:host(:hover) { - ; -} - -iron-icon { - --iron-icon-width: 100%; - --iron-icon-height: 100%; -} - -</style> - - <iron-icon id="icon" src="[[src]]" icon="[[icon]]" alt$="[[alt]]"></iron-icon> - </template> - - </dom-module> -<dom-module id="paper-spinner-styles" assetpath="chrome://resources/polymer/v1_0/paper-spinner/" css-build="shadow"> - <template> - <style scope="paper-spinner-styles">:host { - display: inline-block; - position: relative; - width: 28px; - height: 28px; - - - --paper-spinner-container-rotation-duration: 1568ms; - - - --paper-spinner-expand-contract-duration: 1333ms; - - - --paper-spinner-full-cycle-duration: 5332ms; - - - --paper-spinner-cooldown-duration: 400ms; -} - -#spinnerContainer { - width: 100%; - height: 100%; - - - direction: ltr; -} - -#spinnerContainer.active { - -webkit-animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite; - animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite; -} - -@-webkit-keyframes container-rotate { -to { - -webkit-transform: rotate(360deg) -} - -} - -@keyframes container-rotate { -to { - transform: rotate(360deg) -} - -} - -.spinner-layer { - position: absolute; - width: 100%; - height: 100%; - opacity: 0; - white-space: nowrap; - border-color: var(--paper-spinner-color,var(--google-blue-500)); -} - -.layer-1 { - border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500)); -} - -.layer-2 { - border-color: var(--paper-spinner-layer-2-color,var(--google-red-500)); -} - -.layer-3 { - border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500)); -} - -.layer-4 { - border-color: var(--paper-spinner-layer-4-color,var(--google-green-500)); -} - -.active .spinner-layer { - -webkit-animation-name: fill-unfill-rotate; - -webkit-animation-duration: var(--paper-spinner-full-cycle-duration); - -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1); - -webkit-animation-iteration-count: infinite; - animation-name: fill-unfill-rotate; - animation-duration: var(--paper-spinner-full-cycle-duration); - animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1); - animation-iteration-count: infinite; - opacity: 1; -} - -.active .spinner-layer.layer-1 { - -webkit-animation-name: fill-unfill-rotate, layer-1-fade-in-out; - animation-name: fill-unfill-rotate, layer-1-fade-in-out; -} - -.active .spinner-layer.layer-2 { - -webkit-animation-name: fill-unfill-rotate, layer-2-fade-in-out; - animation-name: fill-unfill-rotate, layer-2-fade-in-out; -} - -.active .spinner-layer.layer-3 { - -webkit-animation-name: fill-unfill-rotate, layer-3-fade-in-out; - animation-name: fill-unfill-rotate, layer-3-fade-in-out; -} - -.active .spinner-layer.layer-4 { - -webkit-animation-name: fill-unfill-rotate, layer-4-fade-in-out; - animation-name: fill-unfill-rotate, layer-4-fade-in-out; -} - -@-webkit-keyframes fill-unfill-rotate { -12.5% { - -webkit-transform: rotate(135deg) -} - -25% { - -webkit-transform: rotate(270deg) -} - -37.5% { - -webkit-transform: rotate(405deg) -} - -50% { - -webkit-transform: rotate(540deg) -} - -62.5% { - -webkit-transform: rotate(675deg) -} - -75% { - -webkit-transform: rotate(810deg) -} - -87.5% { - -webkit-transform: rotate(945deg) -} - -to { - -webkit-transform: rotate(1080deg) -} - -} - -@keyframes fill-unfill-rotate { -12.5% { - transform: rotate(135deg) -} - -25% { - transform: rotate(270deg) -} - -37.5% { - transform: rotate(405deg) -} - -50% { - transform: rotate(540deg) -} - -62.5% { - transform: rotate(675deg) -} - -75% { - transform: rotate(810deg) -} - -87.5% { - transform: rotate(945deg) -} - -to { - transform: rotate(1080deg) -} - -} - -@-webkit-keyframes layer-1-fade-in-out { -0% { - opacity: 1 -} - -25% { - opacity: 1 -} - -26% { - opacity: 0 -} - -89% { - opacity: 0 -} - -90% { - opacity: 1 -} - -to { - opacity: 1 -} - -} - -@keyframes layer-1-fade-in-out { -0% { - opacity: 1 -} - -25% { - opacity: 1 -} - -26% { - opacity: 0 -} - -89% { - opacity: 0 -} - -90% { - opacity: 1 -} - -to { - opacity: 1 -} - -} - -@-webkit-keyframes layer-2-fade-in-out { -0% { - opacity: 0 -} - -15% { - opacity: 0 -} - -25% { - opacity: 1 -} - -50% { - opacity: 1 -} - -51% { - opacity: 0 -} - -to { - opacity: 0 -} - -} - -@keyframes layer-2-fade-in-out { -0% { - opacity: 0 -} - -15% { - opacity: 0 -} - -25% { - opacity: 1 -} - -50% { - opacity: 1 -} - -51% { - opacity: 0 -} - -to { - opacity: 0 -} - -} - -@-webkit-keyframes layer-3-fade-in-out { -0% { - opacity: 0 -} - -40% { - opacity: 0 -} - -50% { - opacity: 1 -} - -75% { - opacity: 1 -} - -76% { - opacity: 0 -} - -to { - opacity: 0 -} - -} - -@keyframes layer-3-fade-in-out { -0% { - opacity: 0 -} - -40% { - opacity: 0 -} - -50% { - opacity: 1 -} - -75% { - opacity: 1 -} - -76% { - opacity: 0 -} - -to { - opacity: 0 -} - -} - -@-webkit-keyframes layer-4-fade-in-out { -0% { - opacity: 0 -} - -65% { - opacity: 0 -} - -75% { - opacity: 1 -} - -90% { - opacity: 1 -} - -to { - opacity: 0 -} - -} - -@keyframes layer-4-fade-in-out { -0% { - opacity: 0 -} - -65% { - opacity: 0 -} - -75% { - opacity: 1 -} - -90% { - opacity: 1 -} - -to { - opacity: 0 -} - -} - -.circle-clipper { - display: inline-block; - position: relative; - width: 50%; - height: 100%; - overflow: hidden; - border-color: inherit; -} - -.spinner-layer::after { - left: 45%; - width: 10%; - border-top-style: solid; -} - -.spinner-layer::after, .circle-clipper::after { - content: ''; - box-sizing: border-box; - position: absolute; - top: 0; - border-width: var(--paper-spinner-stroke-width, 3px); - border-color: inherit; - border-radius: 50%; -} - -.circle-clipper::after { - bottom: 0; - width: 200%; - border-style: solid; - border-bottom-color: transparent !important; -} - -.circle-clipper.left::after { - left: 0; - border-right-color: transparent !important; - -webkit-transform: rotate(129deg); - transform: rotate(129deg); -} - -.circle-clipper.right::after { - left: -100%; - border-left-color: transparent !important; - -webkit-transform: rotate(-129deg); - transform: rotate(-129deg); -} - -.active .gap-patch::after, .active .circle-clipper::after { - -webkit-animation-duration: var(--paper-spinner-expand-contract-duration); - -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1); - -webkit-animation-iteration-count: infinite; - animation-duration: var(--paper-spinner-expand-contract-duration); - animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1); - animation-iteration-count: infinite; -} - -.active .circle-clipper.left::after { - -webkit-animation-name: left-spin; - animation-name: left-spin; -} - -.active .circle-clipper.right::after { - -webkit-animation-name: right-spin; - animation-name: right-spin; -} - -@-webkit-keyframes left-spin { -0% { - -webkit-transform: rotate(130deg) -} - -50% { - -webkit-transform: rotate(-5deg) -} - -to { - -webkit-transform: rotate(130deg) -} - -} - -@keyframes left-spin { -0% { - transform: rotate(130deg) -} - -50% { - transform: rotate(-5deg) -} - -to { - transform: rotate(130deg) -} - -} - -@-webkit-keyframes right-spin { -0% { - -webkit-transform: rotate(-130deg) -} - -50% { - -webkit-transform: rotate(5deg) -} - -to { - -webkit-transform: rotate(-130deg) -} - -} - -@keyframes right-spin { -0% { - transform: rotate(-130deg) -} - -50% { - transform: rotate(5deg) -} - -to { - transform: rotate(-130deg) -} - -} - -#spinnerContainer.cooldown { - -webkit-animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite, fade-out var(--paper-spinner-cooldown-duration) cubic-bezier(0.4, 0.0, 0.2, 1); - animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite, fade-out var(--paper-spinner-cooldown-duration) cubic-bezier(0.4, 0.0, 0.2, 1); -} - -@-webkit-keyframes fade-out { -0% { - opacity: 1 -} - -to { - opacity: 0 -} - -} - -@keyframes fade-out { -0% { - opacity: 1 -} - -to { - opacity: 0 -} - -} - -</style> - </template> -</dom-module> -<dom-module id="paper-spinner-lite" assetpath="chrome://resources/polymer/v1_0/paper-spinner/" css-build="shadow"> - <template strip-whitespace=""> - <style scope="paper-spinner-lite">:host { - display: inline-block; - position: relative; - width: 28px; - height: 28px; - - - --paper-spinner-container-rotation-duration: 1568ms; - - - --paper-spinner-expand-contract-duration: 1333ms; - - - --paper-spinner-full-cycle-duration: 5332ms; - - - --paper-spinner-cooldown-duration: 400ms; -} - -#spinnerContainer { - width: 100%; - height: 100%; - - - direction: ltr; -} - -#spinnerContainer.active { - -webkit-animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite; - animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite; -} - -@-webkit-keyframes container-rotate { -to { - -webkit-transform: rotate(360deg) -} - -} - -@keyframes container-rotate { -to { - transform: rotate(360deg) -} - -} - -.spinner-layer { - position: absolute; - width: 100%; - height: 100%; - opacity: 0; - white-space: nowrap; - border-color: var(--paper-spinner-color,var(--google-blue-500)); -} - -.layer-1 { - border-color: var(--paper-spinner-layer-1-color,var(--google-blue-500)); -} - -.layer-2 { - border-color: var(--paper-spinner-layer-2-color,var(--google-red-500)); -} - -.layer-3 { - border-color: var(--paper-spinner-layer-3-color,var(--google-yellow-500)); -} - -.layer-4 { - border-color: var(--paper-spinner-layer-4-color,var(--google-green-500)); -} - -.active .spinner-layer { - -webkit-animation-name: fill-unfill-rotate; - -webkit-animation-duration: var(--paper-spinner-full-cycle-duration); - -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1); - -webkit-animation-iteration-count: infinite; - animation-name: fill-unfill-rotate; - animation-duration: var(--paper-spinner-full-cycle-duration); - animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1); - animation-iteration-count: infinite; - opacity: 1; -} - -.active .spinner-layer.layer-1 { - -webkit-animation-name: fill-unfill-rotate, layer-1-fade-in-out; - animation-name: fill-unfill-rotate, layer-1-fade-in-out; -} - -.active .spinner-layer.layer-2 { - -webkit-animation-name: fill-unfill-rotate, layer-2-fade-in-out; - animation-name: fill-unfill-rotate, layer-2-fade-in-out; -} - -.active .spinner-layer.layer-3 { - -webkit-animation-name: fill-unfill-rotate, layer-3-fade-in-out; - animation-name: fill-unfill-rotate, layer-3-fade-in-out; -} - -.active .spinner-layer.layer-4 { - -webkit-animation-name: fill-unfill-rotate, layer-4-fade-in-out; - animation-name: fill-unfill-rotate, layer-4-fade-in-out; -} - -@-webkit-keyframes fill-unfill-rotate { -12.5% { - -webkit-transform: rotate(135deg) -} - -25% { - -webkit-transform: rotate(270deg) -} - -37.5% { - -webkit-transform: rotate(405deg) -} - -50% { - -webkit-transform: rotate(540deg) -} - -62.5% { - -webkit-transform: rotate(675deg) -} - -75% { - -webkit-transform: rotate(810deg) -} - -87.5% { - -webkit-transform: rotate(945deg) -} - -to { - -webkit-transform: rotate(1080deg) -} - -} - -@keyframes fill-unfill-rotate { -12.5% { - transform: rotate(135deg) -} - -25% { - transform: rotate(270deg) -} - -37.5% { - transform: rotate(405deg) -} - -50% { - transform: rotate(540deg) -} - -62.5% { - transform: rotate(675deg) -} - -75% { - transform: rotate(810deg) -} - -87.5% { - transform: rotate(945deg) -} - -to { - transform: rotate(1080deg) -} - -} - -@-webkit-keyframes layer-1-fade-in-out { -0% { - opacity: 1 -} - -25% { - opacity: 1 -} - -26% { - opacity: 0 -} - -89% { - opacity: 0 -} - -90% { - opacity: 1 -} - -to { - opacity: 1 -} - -} - -@keyframes layer-1-fade-in-out { -0% { - opacity: 1 -} - -25% { - opacity: 1 -} - -26% { - opacity: 0 -} - -89% { - opacity: 0 -} - -90% { - opacity: 1 -} - -to { - opacity: 1 -} - -} - -@-webkit-keyframes layer-2-fade-in-out { -0% { - opacity: 0 -} - -15% { - opacity: 0 -} - -25% { - opacity: 1 -} - -50% { - opacity: 1 -} - -51% { - opacity: 0 -} - -to { - opacity: 0 -} - -} - -@keyframes layer-2-fade-in-out { -0% { - opacity: 0 -} - -15% { - opacity: 0 -} - -25% { - opacity: 1 -} - -50% { - opacity: 1 -} - -51% { - opacity: 0 -} - -to { - opacity: 0 -} - -} - -@-webkit-keyframes layer-3-fade-in-out { -0% { - opacity: 0 -} - -40% { - opacity: 0 -} - -50% { - opacity: 1 -} - -75% { - opacity: 1 -} - -76% { - opacity: 0 -} - -to { - opacity: 0 -} - -} - -@keyframes layer-3-fade-in-out { -0% { - opacity: 0 -} - -40% { - opacity: 0 -} - -50% { - opacity: 1 -} - -75% { - opacity: 1 -} - -76% { - opacity: 0 -} - -to { - opacity: 0 -} - -} - -@-webkit-keyframes layer-4-fade-in-out { -0% { - opacity: 0 -} - -65% { - opacity: 0 -} - -75% { - opacity: 1 -} - -90% { - opacity: 1 -} - -to { - opacity: 0 -} - -} - -@keyframes layer-4-fade-in-out { -0% { - opacity: 0 -} - -65% { - opacity: 0 -} - -75% { - opacity: 1 -} - -90% { - opacity: 1 -} - -to { - opacity: 0 -} - -} - -.circle-clipper { - display: inline-block; - position: relative; - width: 50%; - height: 100%; - overflow: hidden; - border-color: inherit; -} - -.spinner-layer::after { - left: 45%; - width: 10%; - border-top-style: solid; -} - -.spinner-layer::after, .circle-clipper::after { - content: ''; - box-sizing: border-box; - position: absolute; - top: 0; - border-width: var(--paper-spinner-stroke-width, 3px); - border-color: inherit; - border-radius: 50%; -} - -.circle-clipper::after { - bottom: 0; - width: 200%; - border-style: solid; - border-bottom-color: transparent !important; -} - -.circle-clipper.left::after { - left: 0; - border-right-color: transparent !important; - -webkit-transform: rotate(129deg); - transform: rotate(129deg); -} - -.circle-clipper.right::after { - left: -100%; - border-left-color: transparent !important; - -webkit-transform: rotate(-129deg); - transform: rotate(-129deg); -} - -.active .gap-patch::after, .active .circle-clipper::after { - -webkit-animation-duration: var(--paper-spinner-expand-contract-duration); - -webkit-animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1); - -webkit-animation-iteration-count: infinite; - animation-duration: var(--paper-spinner-expand-contract-duration); - animation-timing-function: cubic-bezier(0.4, 0.0, 0.2, 1); - animation-iteration-count: infinite; -} - -.active .circle-clipper.left::after { - -webkit-animation-name: left-spin; - animation-name: left-spin; -} - -.active .circle-clipper.right::after { - -webkit-animation-name: right-spin; - animation-name: right-spin; -} - -@-webkit-keyframes left-spin { -0% { - -webkit-transform: rotate(130deg) -} - -50% { - -webkit-transform: rotate(-5deg) -} - -to { - -webkit-transform: rotate(130deg) -} - -} - -@keyframes left-spin { -0% { - transform: rotate(130deg) -} - -50% { - transform: rotate(-5deg) -} - -to { - transform: rotate(130deg) -} - -} - -@-webkit-keyframes right-spin { -0% { - -webkit-transform: rotate(-130deg) -} - -50% { - -webkit-transform: rotate(5deg) -} - -to { - -webkit-transform: rotate(-130deg) -} - -} - -@keyframes right-spin { -0% { - transform: rotate(-130deg) -} - -50% { - transform: rotate(5deg) -} - -to { - transform: rotate(-130deg) -} - -} - -#spinnerContainer.cooldown { - -webkit-animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite, fade-out var(--paper-spinner-cooldown-duration) cubic-bezier(0.4, 0.0, 0.2, 1); - animation: container-rotate var(--paper-spinner-container-rotation-duration) linear infinite, fade-out var(--paper-spinner-cooldown-duration) cubic-bezier(0.4, 0.0, 0.2, 1); -} - -@-webkit-keyframes fade-out { -0% { - opacity: 1 -} - -to { - opacity: 0 -} - -} - -@keyframes fade-out { -0% { - opacity: 1 -} - -to { - opacity: 0 -} - -} - -</style> - - <div id="spinnerContainer" class-name="[[__computeContainerClasses(active, __coolingDown)]]"> - <div class="spinner-layer"> - <div class="circle-clipper left"></div> - <div class="circle-clipper right"></div> - </div> - </div> - </template> - - </dom-module> -<iron-iconset-svg name="cr" size="24"> - <svg> - <defs> - - <g id="add"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"></path></g> - <g id="arrow-drop-up"><path d="M7 14l5-5 5 5z"></path></g> - <g id="arrow-drop-down"><path d="M7 10l5 5 5-5z"></path></g> - <g id="cancel"><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"></path></g> -<if expr="chromeos"> - <g id="check"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"></path></g> -</if> - <g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></g> - <g id="clear"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g> - <g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></g> - <g id="delete"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"></path></g> - <g id="domain"><path d="M12 7V3H2v18h20V7H12zM6 19H4v-2h2v2zm0-4H4v-2h2v2zm0-4H4V9h2v2zm0-4H4V5h2v2zm4 12H8v-2h2v2zm0-4H8v-2h2v2zm0-4H8V9h2v2zm0-4H8V5h2v2zm10 12h-8v-2h2v-2h-2v-2h2v-2h-2V9h8v10zm-2-8h-2v2h2v-2zm0 4h-2v2h2v-2z"></path></g> - <g id="expand-less"><path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"></path></g> - <g id="expand-more"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"></path></g> - <g id="extension"><path d="M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7 1.49 0 2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11z"></path></g> - <g id="file-download"><path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"></path></g> - <g id="folder"><path d="M10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-2-2z"></path></g> - <g id="fullscreen"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"></path></g> - <g id="group"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"></path></g> - <g id="menu"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></g> - <g id="more-vert"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"></path></g> - <g id="open-in-new"><path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"></path></g> - <g id="person"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"></path></g> - <g id="print"><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"></path></g> - <g id="search"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path></g> - <g id="settings"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"></path></g> - <g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path></g> - <g id="warning"><path d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"></path></g> - </defs> - </svg> -</iron-iconset-svg> -<dom-module id="cr-toolbar-search-field" assetpath="chrome://resources/cr_elements/cr_toolbar/" css-build="shadow"> - <template> - <style scope="cr-toolbar-search-field">:host { - align-items: center; - display: flex; - height: 40px; - transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1), - width 150ms cubic-bezier(0.4, 0, 0.2, 1); - width: 44px; -} - -[hidden] { - display: none !important; -} - -paper-icon-button { - height: 32px; - margin: 6px; - min-width: 32px; - padding: 6px; - width: 32px; -} - -#icon { - --paper-icon-button-ink-color: white; - transition: margin 150ms, opacity 200ms; -} - -#prompt { - opacity: 0; -} - -paper-spinner-lite { - ; - --paper-spinner-color: white; - margin: 0 6px; - opacity: 0; - padding: 6px; - position: absolute; -} - -paper-spinner-lite[active] { - opacity: 1; -} - -#prompt, paper-spinner-lite { - transition: opacity 200ms; -} - -#searchTerm { - -webkit-font-smoothing: antialiased; - -webkit-margin-start: 2px; - flex: 1; - line-height: 185%; - position: relative; -} - -label { - bottom: 0; - cursor: text; - left: 0; - overflow: hidden; - position: absolute; - right: 0; - top: 0; - white-space: nowrap; -} - -:host([has-search-text]) label { - visibility: hidden; -} - -input { - -webkit-appearance: none; - background: transparent; - border: none; - color: white; - font: inherit; - outline: none; - padding: 0; - position: relative; - width: 100%; -} - -input[type='search']::-webkit-search-decoration, input[type='search']::-webkit-search-cancel-button, input[type='search']::-webkit-search-results-button { - -webkit-appearance: none; -} - -:host(:not([narrow])) { - -webkit-padding-end: 0; - background: rgba(0, 0, 0, 0.22); - border-radius: 2px; - cursor: text; - width: var(--cr-toolbar-field-width); -} - -:host(:not([narrow]):not([showing-search])) #icon, :host(:not([narrow])) #prompt { - opacity: 0.7; -} - -:host([narrow]:not([showing-search])) #searchTerm { - display: none; -} - -:host([showing-search][spinner-active]) #icon { - opacity: 0; -} - -:host([narrow][showing-search]) { - width: 100%; -} - -:host([narrow][showing-search]) #icon, :host([narrow][showing-search]) paper-spinner-lite { - -webkit-margin-start: 18px; -} - -</style> - <template is="dom-if" if="[[isSpinnerShown_]]"> - <paper-spinner-lite active=""> - </paper-spinner-lite> - </template> - <paper-icon-button id="icon" icon="cr:search" title="[[label]]" tabindex$="[[computeIconTabIndex_(narrow)]]"> - </paper-icon-button> - <div id="searchTerm"> - <label id="prompt" for="searchInput">[[label]]</label> - <input id="searchInput" type="search" on-input="onSearchTermInput" on-search="onSearchTermSearch" on-keydown="onSearchTermKeydown_" on-focus="onInputFocus_" on-blur="onInputBlur_" incremental="" autofocus=""> - - </div> - <template is="dom-if" if="[[hasSearchText]]"> - <paper-icon-button icon="cr:cancel" id="clearSearch" title="[[clearLabel]]" on-tap="clearSearch_"> - </paper-icon-button> - </template> - </template> - </dom-module> -<dom-module id="cr-toolbar" assetpath="chrome://resources/cr_elements/cr_toolbar/" css-build="shadow"> - <template> - <style scope="cr-toolbar">:host { - --cr-toolbar-field-width: 580px; - --cr-toolbar-height: 56px; - align-items: center; - color: #fff; - display: flex; - height: var(--cr-toolbar-height); -} - -h1 { - -webkit-margin-start: 6px; - -webkit-padding-end: 12px; - flex: 1; - font-size: 123%; - font-weight: 400; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -#leftContent { - -webkit-margin-start: 12px; - position: relative; - transition: opacity 100ms; -} - -#leftSpacer { - -webkit-margin-start: 6px; - align-items: center; - display: flex; -} - -#menuButton { - height: 32px; - margin-bottom: 6px; - margin-top: 6px; - min-width: 32px; - padding: 6px; - width: 32px; -} - -#centeredContent { - display: flex; - flex: 1 1 0; - justify-content: center; -} - -#rightContent { - -webkit-margin-end: 12px; -} - -:host([narrow_]) #centeredContent { - justify-content: flex-end; -} - -:host([narrow_][showing-search_]) #leftContent { - position: absolute; - opacity: 0; -} - -:host(:not([narrow_])) #leftContent { - flex: 1 1 var(--cr-toolbar-field-margin, 0); -} - -:host(:not([narrow_])) #rightContent { - flex: 1 1 0; - text-align: end; -} - -#menuPromo { - -webkit-padding-end: 12px; - -webkit-padding-start: 8px; - align-items: center; - background: #616161; - border-radius: 2px; - color: white; - display: flex; - font-size: 92.3%; - font-weight: 500; - opacity: 0; - padding-bottom: 6px; - padding-top: 6px; - position: absolute; - top: var(--cr-toolbar-height); - white-space: nowrap; - z-index: 2; -} - -#menuPromo::before { - background: inherit; - - clip-path: polygon(0 105%, 100% 105%, 50% 0); - content: ''; - display: block; - left: 10px; - height: 6px; - position: absolute; - top: -6px; - width: 12px; -} - -:host-context([dir=rtl]) #menuPromo::before { - left: auto; - right: 10px; -} - -#closePromo { - -webkit-appearance: none; - -webkit-margin-start: 12px; - background: none; - border: none; - color: inherit; - font-size: 20px; - line-height: 20px; - padding: 0; - width: 20px; -} - -</style> - <div id="leftContent"> - <div id="leftSpacer"> - - <template is="dom-if" if="[[showMenu]]" restamp=""> - <paper-icon-button id="menuButton" icon="cr:menu" on-tap="onMenuTap_" title="[[titleIfNotShowMenuPromo_(menuLabel, showMenuPromo)]]" aria-label$="[[menuLabel]]"> - </paper-icon-button> - <template is="dom-if" if="[[showMenuPromo]]"> - <div id="menuPromo" role="tooltip"> - [[menuPromo]] - <button id="closePromo" on-tap="onClosePromoTap_" aria-label$="[[closeMenuPromo]]">✕</button> - - </div></template> - </template> - <h1>[[pageName]]</h1> - </div> - </div> - - <div id="centeredContent"> - <cr-toolbar-search-field id="search" narrow="[[narrow_]]" label="[[searchPrompt]]" clear-label="[[clearLabel]]" spinner-active="[[spinnerActive]]" showing-search="{{showingSearch_}}"> - </cr-toolbar-search-field> - <iron-media-query query="(max-width: 900px)" query-matches="{{narrow_}}"> - </iron-media-query> - </div> - - <div id="rightContent"> - <content select=".more-actions"></content> - </div> - </template> - </dom-module> -<dom-module id="downloads-toolbar" assetpath="chrome://downloads/" css-build="shadow"> - <template> - <style scope="downloads-toolbar">:host { - align-items: center; - background: var(--md-toolbar-color); - color: white; - display: flex; - min-height: 56px; -} - -[hidden] { - display: none !important; -} - -#toolbar { - --cr-toolbar-field-width: var(--downloads-card-width); - flex: 1; -} - -paper-icon-button { - --iron-icon-height: 20px; - --iron-icon-width: 20px; - --paper-icon-button_-_height: 32px; --paper-icon-button_-_padding: 6px; --paper-icon-button_-_width: 32px;; -} - -#more { - --paper-menu-button_-_padding: 6px;; -} - -paper-menu { - --paper-menu-selected-item_-_font-weight: normal;; -} - -paper-item { - -webkit-user-select: none; - cursor: pointer; - font: inherit; - min-height: 40px; - - white-space: nowrap; -} - -</style> - <cr-toolbar id="toolbar" page-name="$i18n{title}" search-prompt="$i18n{search}" clear-label="$i18n{clearSearch}" spinner-active="{{spinnerActive}}" on-search-changed="onSearchChanged_"> - <div class="more-actions"> - <paper-menu-button id="more" horizontal-align="right" allow-outside-scroll=""> - <paper-icon-button icon="cr:more-vert" title="$i18n{moreActions}" class="dropdown-trigger"></paper-icon-button> - <paper-menu class="dropdown-content"> - <paper-item class="clear-all" on-tap="onClearAllTap_" role="menuitem" on-blur="onItemBlur_"> - $i18n{clearAll} - </paper-item> - <paper-item on-tap="onOpenDownloadsFolderTap_" role="menuitem" on-blur="onItemBlur_"> - $i18n{openDownloadsFolder} - </paper-item> - </paper-menu> - </paper-menu-button> - </div> - </cr-toolbar> - </template> - </dom-module> -<style> -/* 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. */ - -:root { - /* This is a custom, Chrome-specific color that does not have a --paper or - * --google equivalent. */ - --md-background-color: #f1f1f1; - --md-loading-message-color: #6e6e6e; - /* This is --google-blue-700, rewritten as a native custom property for speed. - */ - --md-toolbar-color: rgb(51, 103, 214); -} - -</style><dom-module id="downloads-manager" assetpath="chrome://downloads/" css-build="shadow"> - <template> - <style scope="downloads-manager">:host { - display: flex; - flex: 1 0; - flex-direction: column; - height: 100%; - z-index: 0; -} - -[hidden] { - display: none !important; -} - -@media screen and (max-width: 1024px) { -:host { - flex-basis: calc( - var(--downloads-card-width) + 2 * var(--downloads-card-margin)); -} - -} - -#toolbar { - position: relative; - z-index: 1; -} - -#toolbar::after { - box-shadow: inset 0 5px 6px -3px rgba(0, 0, 0, 0.4); - content: ''; - display: block; - height: 6px; - opacity: 0; - position: absolute; - top: 100%; - transition: opacity 500ms; - width: 100%; -} - -:host([has-shadow_]) #toolbar::after { - opacity: 1; -} - -#downloads-list { - overflow-y: overlay !important; -} - -#no-downloads, #downloads-list { - flex: 1; -} - -:host([loading]) #no-downloads, :host([loading]) #downloads-list { - display: none; -} - -#no-downloads { - align-items: center; - color: #6e6e6e; - display: flex; - font-size: 123.1%; - font-weight: 500; - justify-content: center; - - min-height: min-content; -} - -#no-downloads .illustration { - background: -webkit-image-set( - url("chrome://downloads/1x/no_downloads.png") 1x, - url("chrome://downloads/2x/no_downloads.png") 2x) - no-repeat center center; - height: 144px; - margin-bottom: 32px; -} - -</style> - - <downloads-toolbar id="toolbar" spinner-active="{{spinnerActive_}}"> - </downloads-toolbar> - <iron-list id="downloads-list" items="{{items_}}" hidden="[[!hasDownloads_]]"> - <template> - <downloads-item data="[[item]]"></downloads-item> - </template> - </iron-list> - <div id="no-downloads" hidden="[[hasDownloads_]]"> - <div> - <div class="illustration"></div> - <span>[[noDownloadsText_(inSearchMode_)]]</span> - </div> - </div> - </template> - </dom-module> -</div><script src="crisper.js"></script></body></html> \ No newline at end of file
diff --git a/chrome/browser/resources/unpack_pak.py b/chrome/browser/resources/unpack_pak.py new file mode 100755 index 0000000..ce6a993 --- /dev/null +++ b/chrome/browser/resources/unpack_pak.py
@@ -0,0 +1,53 @@ +#!/usr/bin/env python +# 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. + +import os +import re +import sys + + +_HERE_PATH = os.path.join(os.path.dirname(__file__)) + + +_SRC_PATH = os.path.normpath(os.path.join(_HERE_PATH, '..', '..', '..')) +sys.path.append(os.path.join(_SRC_PATH, 'tools', 'grit')) +from grit.format import data_pack + + +def unpack(pak_path, out_path): + pak_dir = os.path.dirname(pak_path) + pak_id = os.path.splitext(os.path.basename(pak_path))[0] + + data = data_pack.DataPack.ReadDataPack(pak_path) + + # Associate numerical grit IDs to strings. + # For example 120045 -> 'IDR_SETTINGS_ABOUT_PAGE_HTML' + resource_ids = dict() + resources_path = os.path.join(pak_dir, 'grit', pak_id + '.h') + with open(resources_path) as resources_file: + for line in resources_file: + res = re.match('#define ([^ ]+) (\d+)', line) + if res: + resource_ids[int(res.group(2))] = res.group(1) + assert resource_ids + + # Associate numerical string IDs to files. + resource_filenames = dict() + resources_map_path = os.path.join(pak_dir, 'grit', pak_id + '_map.cc') + with open(resources_map_path) as resources_map: + for line in resources_map: + res = re.match(' {"([^"]+)", ([^}]+)', line) + if res: + resource_filenames[res.group(2)] = res.group(1) + assert resource_filenames + + # Extract packed files, while preserving directory structure. + for (resource_id, text) in data.resources.iteritems(): + filename = resource_filenames[resource_ids[resource_id]] + dirname = os.path.join(out_path, os.path.dirname(filename)) + if not os.path.exists(dirname): + os.makedirs(dirname) + with open(os.path.join(out_path, filename), 'w') as file: + file.write(text)
diff --git a/chrome/browser/resources/vulcanize.gni b/chrome/browser/resources/vulcanize.gni new file mode 100644 index 0000000..c9f9dbe --- /dev/null +++ b/chrome/browser/resources/vulcanize.gni
@@ -0,0 +1,54 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +template("vulcanize") { + action(target_name) { + script = "//chrome/browser/resources/vulcanize_gn.py" + + # Declare dependencies to all involved tools. + inputs = [ + "//chrome/browser/resources/unpack_pak.py", + "//third_party/node/node_modules.tar.gz.sha1", + ] + + if (is_linux) { + inputs += [ "//third_party/node/linux/node-linux-x64.tar.gz.sha1" ] + } + if (is_win) { + inputs += [ "//third_party/node/win/node.exe.sha1" ] + } + if (is_mac) { + inputs += [ "//third_party/node/mac/node-darwin-x64.tar.gz.sha1" ] + } + + depfile = "${target_gen_dir}/${target_name}.d" + + outputs = [ + "$target_gen_dir/${invoker.html_out_file}", + "$target_gen_dir/${invoker.js_out_file}", + ] + deps = invoker.deps + + # Note that we have to manually pass the sources to our script if the + # script needs them as inputs. + args = [ + "--host", + invoker.host, + "--html_in_file", + invoker.html_in_file, + "--html_out_file", + invoker.html_out_file, + "--js_out_file", + invoker.js_out_file, + "--input_type", + invoker.input_type, + "--input", + invoker.input, + "--out_folder", + rebase_path(target_gen_dir, root_build_dir), + "--depfile", + rebase_path(depfile, root_build_dir), + ] + } +}
diff --git a/chrome/browser/resources/vulcanize_gn.py b/chrome/browser/resources/vulcanize_gn.py new file mode 100755 index 0000000..0b2df59a --- /dev/null +++ b/chrome/browser/resources/vulcanize_gn.py
@@ -0,0 +1,216 @@ +#!/usr/bin/env python +# 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. + +import argparse +import itertools +import os +import platform +import re +import subprocess +import sys +import tempfile + + +_HERE_PATH = os.path.dirname(__file__) +_SRC_PATH = os.path.normpath(os.path.join(_HERE_PATH, '..', '..', '..')) +_CWD = os.getcwd() + +sys.path.append(os.path.join(_SRC_PATH, 'third_party', 'node')) +import node +import node_modules + + +_RESOURCES_PATH = os.path.join(_SRC_PATH, 'ui', 'webui', 'resources') + + +_CR_ELEMENTS_PATH = os.path.join(_RESOURCES_PATH, 'cr_elements') + + +_CSS_RESOURCES_PATH = os.path.join(_RESOURCES_PATH, 'css') + + +_HTML_RESOURCES_PATH = os.path.join(_RESOURCES_PATH, 'html') + + +_JS_RESOURCES_PATH = os.path.join(_RESOURCES_PATH, 'js') + + +_POLYMER_PATH = os.path.join( + _SRC_PATH, 'third_party', 'polymer', 'v1_0', 'components-chromium') + + +_VULCANIZE_BASE_ARGS = [ + '--exclude', 'crisper.js', + + # These files are already combined and minified. + '--exclude', 'chrome://resources/html/polymer.html', + '--exclude', 'web-animations-next-lite.min.js', + + # These files are dynamically created by C++. + '--exclude', 'load_time_data.js', + '--exclude', 'strings.js', + '--exclude', 'text_defaults.css', + '--exclude', 'text_defaults_md.css', + + '--inline-css', + '--inline-scripts', + '--strip-comments', +] + + +_URL_MAPPINGS = [ + ('chrome://resources/cr_elements/', _CR_ELEMENTS_PATH), + ('chrome://resources/css/', _CSS_RESOURCES_PATH), + ('chrome://resources/html/', _HTML_RESOURCES_PATH), + ('chrome://resources/js/', _JS_RESOURCES_PATH), + ('chrome://resources/polymer/v1_0/', _POLYMER_PATH) +] + + +_VULCANIZE_REDIRECT_ARGS = list(itertools.chain.from_iterable(map( + lambda m: ['--redirect', '"%s|%s"' % (m[0], m[1])], _URL_MAPPINGS))) + + +_REQUEST_LIST_FILE = 'request_list.txt' + + +_PAK_UNPACK_FOLDER = 'flattened' + + +def _run_node(cmd_parts, stdout=None): + cmd = " ".join([node.GetBinaryPath()] + cmd_parts) + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + stdout, stderr = process.communicate() + + if stderr: + print >> sys.stderr, '%s failed: %s' % (cmd, stderr) + raise + + return stdout + + +def _undo_mapping(mappings, url): + for (redirect_url, file_path) in mappings: + if url.startswith(redirect_url): + return url.replace(redirect_url, file_path + os.sep) + return url + + +# Get a list of all files that were bundled with Vulcanize and update the +# depfile accordingly such that Ninja knows when to trigger re-vulcanization. +def _update_dep_file(in_folder, args): + in_path = os.path.join(_CWD, in_folder) + out_path = os.path.join(_CWD, args.out_folder) + + # Prior call to vulcanize already generated the deps list, grab it from there. + request_list = open(os.path.join( + out_path, _REQUEST_LIST_FILE), 'r').read().splitlines() + + # Undo the URL mappings applied by vulcanize to get file paths relative to + # current working directory. + url_mappings = _URL_MAPPINGS + [ + ('/', os.path.relpath(in_path, _CWD)), + ('chrome://%s/' % args.host, os.path.relpath(in_path, _CWD)), + ] + + dependencies = map( + lambda url: _undo_mapping(url_mappings, url), request_list) + + # If the input was a .pak file, the generated depfile should not list files + # already in the .pak file. + filtered_dependencies = dependencies + if (args.input_type == 'PAK_FILE'): + filter_url = os.path.join(args.out_folder, _PAK_UNPACK_FOLDER) + filtered_dependencies = filter( + lambda url: not url.startswith(filter_url), dependencies) + + with open(os.path.join(_CWD, args.depfile), 'w') as f: + f.write(os.path.join( + args.out_folder, args.html_out_file) + ': ' + ' '.join( + filtered_dependencies)) + + +def _vulcanize(in_folder, out_folder, host, html_in_file, + html_out_file, js_out_file): + in_path = os.path.normpath(os.path.join(_CWD, in_folder)) + out_path = os.path.join(_CWD, out_folder) + + html_out_path = os.path.join(out_path, html_out_file) + js_out_path = os.path.join(out_path, js_out_file) + + output = _run_node( + [node_modules.PathToVulcanize()] + + _VULCANIZE_BASE_ARGS + _VULCANIZE_REDIRECT_ARGS + + ['--out-request-list', os.path.join(out_path, _REQUEST_LIST_FILE), + '--redirect', '"/|%s"' % in_path, + '--redirect', '"chrome://%s/|%s"' % (host, in_path), + # TODO(dpapad): Figure out why vulcanize treats the input path + # differently on Windows VS Linux/Mac. + os.path.join( + in_path if platform.system() == 'Windows' else os.sep, + html_in_file)]) + + with tempfile.NamedTemporaryFile(mode='wt+', delete=False) as tmp: + # Grit includes are not supported, use HTML imports instead. + tmp.write(output.replace( + '<include src="', '<include src-disabled="')) + + try: + _run_node([node_modules.PathToCrisper(), + '--source', tmp.name, + '--script-in-head', 'false', + '--html', html_out_path, + '--js', js_out_path]) + + # TODO(tsergeant): Remove when JS resources are minified by default: + # crbug.com/619091. + _run_node([node_modules.PathToUglifyJs(), js_out_path, + '--comments', '"/Copyright|license|LICENSE|\<\/?if/"', + '--output', js_out_path]) + finally: + os.remove(tmp.name) + + +def _css_build(out_folder, files): + out_path = os.path.join(_CWD, out_folder) + paths = map(lambda f: os.path.join(out_path, f), files) + + _run_node([node_modules.PathToPolymerCssBuild()] + paths) + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--depfile') + parser.add_argument('--host') + parser.add_argument('--html_in_file') + parser.add_argument('--html_out_file') + parser.add_argument('--input') + parser.add_argument('--input_type') + parser.add_argument('--js_out_file') + parser.add_argument('--out_folder') + args = parser.parse_args() + args.input = os.path.normpath(args.input) + + vulcanize_input_folder = args.input + + # If a .pak file was specified, unpack that file first and pass the output to + # vulcanize. + if (args.input_type == 'PAK_FILE'): + import unpack_pak + input_folder = os.path.join(_CWD, args.input) + output_folder = os.path.join(args.out_folder, _PAK_UNPACK_FOLDER) + unpack_pak.unpack(args.input, output_folder) + vulcanize_input_folder = output_folder + + _vulcanize(vulcanize_input_folder, args.out_folder, args.host, + args.html_in_file, args.html_out_file, args.js_out_file) + _css_build(args.out_folder, files=[args.html_out_file]) + + _update_dep_file(vulcanize_input_folder, args) + + +if __name__ == '__main__': + main()
diff --git a/chrome/browser/safe_browsing/local_database_manager.cc b/chrome/browser/safe_browsing/local_database_manager.cc index 615a7b6..7259e6b5 100644 --- a/chrome/browser/safe_browsing/local_database_manager.cc +++ b/chrome/browser/safe_browsing/local_database_manager.cc
@@ -271,7 +271,6 @@ const scoped_refptr<SafeBrowsingService>& service) : sb_service_(service), database_(NULL), - enabled_(false), enable_download_protection_(false), enable_csd_whitelist_(false), enable_download_whitelist_(false), @@ -692,12 +691,13 @@ void LocalSafeBrowsingDatabaseManager::StopOnIOThread(bool shutdown) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - SafeBrowsingDatabaseManager::StopOnIOThread(shutdown); DoStopOnIOThread(); if (shutdown) { sb_service_ = NULL; } + + SafeBrowsingDatabaseManager::StopOnIOThread(shutdown); } void LocalSafeBrowsingDatabaseManager::NotifyDatabaseUpdateFinished(
diff --git a/chrome/browser/safe_browsing/local_database_manager.h b/chrome/browser/safe_browsing/local_database_manager.h index 9a27a8e..c03fff31 100644 --- a/chrome/browser/safe_browsing/local_database_manager.h +++ b/chrome/browser/safe_browsing/local_database_manager.h
@@ -330,10 +330,6 @@ // Lock used to prevent possible data races due to compiler optimizations. mutable base::Lock database_lock_; - // Whether the service is running. 'enabled_' is used by the - // SafeBrowsingDatabaseManager on the IO thread during normal operations. - bool enabled_; - // Indicate if download_protection is enabled by command switch // so we allow this feature to be exercised. bool enable_download_protection_;
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc index 3554aed..5f51653 100644 --- a/chrome/browser/ui/views/find_bar_host.cc +++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -58,13 +58,11 @@ if (!contents) return false; - content::RenderViewHost* render_view_host = contents->GetRenderViewHost(); - // Make sure we don't have a text field element interfering with keyboard // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom". - render_view_host->ClearFocusedElement(); + contents->ClearFocusedElement(); NativeWebKeyboardEvent event(key_event); - render_view_host->GetWidget()->ForwardKeyboardEvent(event); + contents->GetRenderViewHost()->GetWidget()->ForwardKeyboardEvent(event); return true; }
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 73ece483..9ebe8c7 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1211,10 +1211,9 @@ translate::TranslateErrors::Type error_type, bool is_user_gesture) { if (contents_web_view_->HasFocus() && - !GetLocationBarView()->IsMouseHovered()) { - content::RenderViewHost* rvh = web_contents->GetRenderViewHost(); - if (rvh->IsFocusedElementEditable()) - return ShowTranslateBubbleResult::EDITABLE_FIELD_IS_ACTIVE; + !GetLocationBarView()->IsMouseHovered() && + web_contents->IsFocusedElementEditable()) { + return ShowTranslateBubbleResult::EDITABLE_FIELD_IS_ACTIVE; } translate::LanguageState& language_state =
diff --git a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc index b625633..27543b4e 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.cc
@@ -30,7 +30,7 @@ void LocationBarBubbleDelegateView::WebContentMouseHandler::OnKeyEvent( ui::KeyEvent* event) { if ((event->key_code() == ui::VKEY_ESCAPE || - web_contents_->GetRenderViewHost()->IsFocusedElementEditable()) && + web_contents_->IsFocusedElementEditable()) && event->type() == ui::ET_KEY_PRESSED) bubble_->CloseBubble(); }
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc index c37cf06..5bb18d38 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc
@@ -259,7 +259,7 @@ EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_TAB_CONTAINER)); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(web_contents->GetRenderViewHost()->IsFocusedElementEditable()); + EXPECT_TRUE(web_contents->IsFocusedElementEditable()); ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_K, false, false, false, false)); EXPECT_FALSE(IsBubbleShowing());
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index 02139e37..abd1edaf 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -24,6 +24,7 @@ #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/google/core/browser/google_util.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_ui.h" @@ -47,11 +48,10 @@ : content::WebContentsObserver(web_contents), is_md_(is_md) {} ~ExtensionWebUiTimer() override {} - void DidStartProvisionalLoadForFrame( - content::RenderFrameHost* render_frame_host, - const GURL& validated_url, - bool is_error_page) override { - timer_.reset(new base::ElapsedTimer()); + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override { + if (navigation_handle->IsInMainFrame() && !navigation_handle->IsSamePage()) + timer_.reset(new base::ElapsedTimer()); } void DocumentLoadedInFrame( @@ -70,12 +70,13 @@ } void DocumentOnLoadCompletedInMainFrame() override { - // Sometimes*, DidStartProvisionalLoadForFrame() isn't called before this - // or DocumentLoadedInFrame(). Don't log anything in those cases. - // *This appears to be for in-page navigations like hash changes. // TODO(devlin): The usefulness of these metrics remains to be seen. - if (!timer_) + if (!timer_) { + // This object could have been created for a child RenderFrameHost so it + // would never get a DidStartNavigation with the main frame. However it + // will receive this current callback. return; + } if (is_md_) { UMA_HISTOGRAM_TIMES("Extensions.WebUi.LoadCompletedInMainFrame.MD", timer_->Elapsed());
diff --git a/chrome/renderer/net/net_error_helper.cc b/chrome/renderer/net/net_error_helper.cc index 47316642..1c3d935 100644 --- a/chrome/renderer/net/net_error_helper.cc +++ b/chrome/renderer/net/net_error_helper.cc
@@ -320,9 +320,7 @@ void NetErrorHelper::LoadPageFromCache(const GURL& page_url) { blink::WebFrame* web_frame = render_frame()->GetWebFrame(); - DCHECK(!base::EqualsASCII( - base::StringPiece16(web_frame->dataSource()->getRequest().httpMethod()), - "POST")); + DCHECK_NE("POST", web_frame->dataSource()->getRequest().httpMethod().ascii()); blink::WebURLRequest request(page_url); request.setCachePolicy(blink::WebCachePolicy::ReturnCacheDataDontLoad);
diff --git a/chrome/renderer/safe_browsing/phishing_classifier.cc b/chrome/renderer/safe_browsing/phishing_classifier.cc index d5babf6..a2246d5 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier.cc +++ b/chrome/renderer/safe_browsing/phishing_classifier.cc
@@ -135,9 +135,7 @@ } blink::WebDataSource* ds = frame->dataSource(); - if (!ds || - !base::EqualsASCII(base::StringPiece16(ds->getRequest().httpMethod()), - "GET")) { + if (!ds || ds->getRequest().httpMethod().ascii() != "GET") { if (ds) RecordReasonForSkippingClassificationToUMA(SKIP_NONE_GET); RunFailureCallback();
diff --git a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc index a0ac57c..ad85540 100644 --- a/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc +++ b/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
@@ -93,14 +93,14 @@ // this issue. blink::WebURL CompleteURL(const blink::WebElement& element, const blink::WebString& partial_url) override { - GURL parsed_url(GURL(partial_url.utf8())); + GURL parsed_url = blink::WebStringToGURL(partial_url); GURL full_url; if (parsed_url.has_scheme()) { // This is already a complete URL. - full_url = GURL(blink::WebStringToGURL(partial_url)); + full_url = parsed_url; } else if (!base_domain_.empty()) { // This is a partial URL and only one frame in testing html. - full_url = GURL("http://" + base_domain_).Resolve(partial_url); + full_url = GURL("http://" + base_domain_).Resolve(partial_url.utf8()); } else { auto it = url_to_frame_domain_map_.find(partial_url.utf8()); if (it != url_to_frame_domain_map_.end()) {
diff --git a/chrome/test/data/webui/md_downloads/downloads_browsertest.js b/chrome/test/data/webui/md_downloads/downloads_browsertest.js index 7b793ab4..b0c6979 100644 --- a/chrome/test/data/webui/md_downloads/downloads_browsertest.js +++ b/chrome/test/data/webui/md_downloads/downloads_browsertest.js
@@ -15,10 +15,26 @@ * @constructor * @extends {PolymerTest} */ +function DownloadsTest() {} + +DownloadsTest.prototype = { + __proto__: PolymerTest.prototype, + + /** @override */ + setUp: function() { + PolymerTest.prototype.setUp.call(this); + this.accessibilityAuditConfig.ignoreSelectors('humanLangMissing', 'html'); + }, +}; + +/** + * @constructor + * @extends {DownloadsTest} + */ function DownloadsItemTest() {} DownloadsItemTest.prototype = { - __proto__: PolymerTest.prototype, + __proto__: DownloadsTest.prototype, /** @override */ browsePreload: 'chrome://downloads/item.html', @@ -33,18 +49,17 @@ mocha.run(); }); - /** * @constructor - * @extends {PolymerTest} + * @extends {DownloadsTest} */ function DownloadsLayoutTest() {} DownloadsLayoutTest.prototype = { - __proto__: PolymerTest.prototype, + __proto__: DownloadsTest.prototype, /** @override */ - browsePreload: 'chrome://downloads/manager.html', + browsePreload: 'chrome://downloads/', /** @override */ extraLibraries: PolymerTest.getLibraries(ROOT_PATH).concat([ @@ -58,12 +73,12 @@ /** * @constructor - * @extends {PolymerTest} + * @extends {DownloadsTest} */ function DownloadsToolbarTest() {} DownloadsToolbarTest.prototype = { - __proto__: PolymerTest.prototype, + __proto__: DownloadsTest.prototype, /** @override */ browsePreload: 'chrome://downloads/toolbar.html',
diff --git a/chrome/test/data/webui/md_downloads/toolbar_tests.js b/chrome/test/data/webui/md_downloads/toolbar_tests.js index 5729be5..7f287c3 100644 --- a/chrome/test/data/webui/md_downloads/toolbar_tests.js +++ b/chrome/test/data/webui/md_downloads/toolbar_tests.js
@@ -26,11 +26,11 @@ }); test('resize closes more options menu', function() { - MockInteractions.tap(toolbar.$$('paper-icon-button')); - assertTrue(toolbar.$.more.opened); + MockInteractions.tap(toolbar.$.moreActions); + assertTrue(toolbar.$.moreActionsMenu.open); window.dispatchEvent(new CustomEvent('resize')); - assertFalse(toolbar.$.more.opened); + assertFalse(toolbar.$.moreActionsMenu.open); }); test('search starts spinner', function() {
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index 9ffc7305..7f6700a 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -126,6 +126,7 @@ mojom("arc_bindings") { sources = [ + "common/accessibility_helper.mojom", "common/app.mojom", "common/arc_bridge.mojom", "common/audio.mojom",
diff --git a/components/arc/arc_bridge_host_impl.cc b/components/arc/arc_bridge_host_impl.cc index b22068e5..437aa1a4 100644 --- a/components/arc/arc_bridge_host_impl.cc +++ b/components/arc/arc_bridge_host_impl.cc
@@ -83,6 +83,12 @@ OnClosed(); } +void ArcBridgeHostImpl::OnAccessibilityHelperInstanceReady( + mojom::AccessibilityHelperInstancePtr accessibility_helper_ptr) { + OnInstanceReady(arc_bridge_service_->accessibility_helper(), + std::move(accessibility_helper_ptr)); +} + void ArcBridgeHostImpl::OnAppInstanceReady(mojom::AppInstancePtr app_ptr) { OnInstanceReady(arc_bridge_service_->app(), std::move(app_ptr)); }
diff --git a/components/arc/arc_bridge_host_impl.h b/components/arc/arc_bridge_host_impl.h index b420725..9ee3664 100644 --- a/components/arc/arc_bridge_host_impl.h +++ b/components/arc/arc_bridge_host_impl.h
@@ -38,6 +38,8 @@ ~ArcBridgeHostImpl() override; // ArcBridgeHost overrides. + void OnAccessibilityHelperInstanceReady( + mojom::AccessibilityHelperInstancePtr accessibility_helper_ptr) override; void OnAppInstanceReady(mojom::AppInstancePtr app_ptr) override; void OnAudioInstanceReady(mojom::AudioInstancePtr audio_ptr) override; void OnAuthInstanceReady(mojom::AuthInstancePtr auth_ptr) override;
diff --git a/components/arc/arc_bridge_service.h b/components/arc/arc_bridge_service.h index 3f4a5f5a3..b4b9fb1 100644 --- a/components/arc/arc_bridge_service.h +++ b/components/arc/arc_bridge_service.h
@@ -21,6 +21,7 @@ // Instead of including components/arc/common/arc_bridge.mojom.h, list all the // instance classes here for faster build. +class AccessibilityHelperInstance; class AppInstance; class AudioInstance; class AuthInstance; @@ -61,6 +62,9 @@ // Returns true if ARC is available on the current board. static bool GetAvailable(const base::CommandLine* command_line); + InstanceHolder<mojom::AccessibilityHelperInstance>* accessibility_helper() { + return &accessibility_helper_; + } InstanceHolder<mojom::AppInstance>* app() { return &app_; } InstanceHolder<mojom::AudioInstance>* audio() { return &audio_; } InstanceHolder<mojom::AuthInstance>* auth() { return &auth_; } @@ -103,6 +107,7 @@ InstanceHolder<mojom::WallpaperInstance>* wallpaper() { return &wallpaper_; } private: + InstanceHolder<mojom::AccessibilityHelperInstance> accessibility_helper_; InstanceHolder<mojom::AppInstance> app_; InstanceHolder<mojom::AudioInstance> audio_; InstanceHolder<mojom::AuthInstance> auth_;
diff --git a/components/arc/arc_session.cc b/components/arc/arc_session.cc index c3dc195..92940393 100644 --- a/components/arc/arc_session.cc +++ b/components/arc/arc_session.cc
@@ -9,6 +9,7 @@ #include <poll.h> #include <unistd.h> +#include <string> #include <utility> #include "base/files/file_path.h" @@ -221,10 +222,10 @@ // Synchronously accepts a connection on |socket_fd| and then processes the // connected socket's file descriptor. - static mojo::edk::ScopedPlatformHandle ConnectMojo( + static mojo::ScopedMessagePipeHandle ConnectMojo( mojo::edk::ScopedPlatformHandle socket_fd, base::ScopedFD cancel_fd); - void OnMojoConnected(mojo::edk::ScopedPlatformHandle fd); + void OnMojoConnected(mojo::ScopedMessagePipeHandle server_pipe); // Request to stop ARC instance via DBus. void StopArcInstance(); @@ -422,44 +423,52 @@ } // static -mojo::edk::ScopedPlatformHandle ArcSessionImpl::ConnectMojo( +mojo::ScopedMessagePipeHandle ArcSessionImpl::ConnectMojo( mojo::edk::ScopedPlatformHandle socket_fd, base::ScopedFD cancel_fd) { if (!WaitForSocketReadable(socket_fd.get().handle, cancel_fd.get())) { VLOG(1) << "Mojo connection was cancelled."; - return mojo::edk::ScopedPlatformHandle(); + return mojo::ScopedMessagePipeHandle(); } mojo::edk::ScopedPlatformHandle scoped_fd; if (!mojo::edk::ServerAcceptConnection(socket_fd.get(), &scoped_fd, /* check_peer_user = */ false) || !scoped_fd.is_valid()) { - return mojo::edk::ScopedPlatformHandle(); + return mojo::ScopedMessagePipeHandle(); } // Hardcode pid 0 since it is unused in mojo. const base::ProcessHandle kUnusedChildProcessHandle = 0; mojo::edk::PlatformChannelPair channel_pair; + std::string child_token = mojo::edk::GenerateRandomToken(); mojo::edk::ChildProcessLaunched(kUnusedChildProcessHandle, - channel_pair.PassServerHandle(), - mojo::edk::GenerateRandomToken()); + channel_pair.PassServerHandle(), child_token); mojo::edk::ScopedPlatformHandleVectorPtr handles( new mojo::edk::PlatformHandleVector{ channel_pair.PassClientHandle().release()}); - struct iovec iov = {const_cast<char*>(""), 1}; + std::string token = mojo::edk::GenerateRandomToken(); + // We need to send the length of the message as a single byte, so make sure it + // fits. + DCHECK_LT(token.size(), 256u); + uint8_t message_length = static_cast<uint8_t>(token.size()); + struct iovec iov[] = {{&message_length, sizeof(message_length)}, + {const_cast<char*>(token.c_str()), token.size()}}; ssize_t result = mojo::edk::PlatformChannelSendmsgWithHandles( - scoped_fd.get(), &iov, 1, handles->data(), handles->size()); + scoped_fd.get(), iov, sizeof(iov) / sizeof(iov[0]), handles->data(), + handles->size()); if (result == -1) { PLOG(ERROR) << "sendmsg"; - return mojo::edk::ScopedPlatformHandle(); + return mojo::ScopedMessagePipeHandle(); } - return scoped_fd; + return mojo::edk::CreateParentMessagePipe(token, child_token); } -void ArcSessionImpl::OnMojoConnected(mojo::edk::ScopedPlatformHandle fd) { +void ArcSessionImpl::OnMojoConnected( + mojo::ScopedMessagePipeHandle server_pipe) { DCHECK(thread_checker_.CalledOnValidThread()); if (state_ == State::STOPPED) { @@ -477,14 +486,6 @@ return; } - if (!fd.is_valid()) { - LOG(ERROR) << "Invalid handle"; - StopArcInstance(); - return; - } - - mojo::ScopedMessagePipeHandle server_pipe = - mojo::edk::CreateMessagePipe(std::move(fd)); if (!server_pipe.is_valid()) { LOG(ERROR) << "Invalid pipe"; StopArcInstance();
diff --git a/components/arc/common/accessibility_helper.mojom b/components/arc/common/accessibility_helper.mojom new file mode 100644 index 0000000..325006dc --- /dev/null +++ b/components/arc/common/accessibility_helper.mojom
@@ -0,0 +1,37 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Next MinVersion: 1 + +module arc.mojom; + +import "screen_rect.mojom"; + +// AccessibilityEventType is a enum which corresponds to event types of +// AccessibilityEvent in Android. +// https://developer.android.com/reference/android/view/accessibility/AccessibilityEvent.html +[Extensible] +enum AccessibilityEventType { + VIEW_FOCUSED, +}; + +// AccessibilityNodeInfoData is a struct to contain info of +// AccessibilityNodeInfo in Android. +// https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo.html +struct AccessibilityNodeInfoData { + ScreenRect boundsInScreen; +}; + +// Next method ID: 1 +interface AccessibilityHelperHost { + // OnAccessibilityEvent is called when a converted Android accessibility event + // is sent from Android. + OnAccessibilityEvent@0(AccessibilityEventType eventType, + AccessibilityNodeInfoData? eventSource); +}; + +// Next method ID: 1 +interface AccessibilityHelperInstance { + Init@0(AccessibilityHelperHost host); +};
diff --git a/components/arc/common/arc_bridge.mojom b/components/arc/common/arc_bridge.mojom index 94b0aa8..7b8a9c52 100644 --- a/components/arc/common/arc_bridge.mojom +++ b/components/arc/common/arc_bridge.mojom
@@ -4,6 +4,7 @@ module arc.mojom; +import "accessibility_helper.mojom"; import "app.mojom"; import "audio.mojom"; import "auth.mojom"; @@ -29,14 +30,18 @@ import "video.mojom"; import "wallpaper.mojom"; -// Next MinVersion: 21 +// Next MinVersion: 22 // Deprecated method IDs: 101, 105 -// Next method ID: 127 +// Next method ID: 128 interface ArcBridgeHost { // Keep the entries alphabetical. In order to do so without breaking // compatibility with the ARC instance, explicitly assign each interface a // unique ordinal. + // Notifies Chrome that the AccessibilityHelperInstance interface is ready. + [MinVersion=21] OnAccessibilityHelperInstanceReady@127( + AccessibilityHelperInstance instance_ptr); + // Notifies Chrome that the AppInstance interface is ready. OnAppInstanceReady@100(AppInstance instance_ptr);
diff --git a/components/safe_browsing_db/database_manager.cc b/components/safe_browsing_db/database_manager.cc index 91e4d7b6..0155efc 100644 --- a/components/safe_browsing_db/database_manager.cc +++ b/components/safe_browsing_db/database_manager.cc
@@ -15,7 +15,7 @@ namespace safe_browsing { -SafeBrowsingDatabaseManager::SafeBrowsingDatabaseManager() {} +SafeBrowsingDatabaseManager::SafeBrowsingDatabaseManager() : enabled_(false) {} SafeBrowsingDatabaseManager::~SafeBrowsingDatabaseManager() { DCHECK(!v4_get_hash_protocol_manager_); @@ -37,8 +37,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(v4_get_hash_protocol_manager_); - // Make sure we can check this url. - if (!(url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme))) { + // Make sure we can check this url and that the service is enabled. + if (!enabled_ || + !(url.SchemeIs(url::kHttpScheme) || url.SchemeIs(url::kHttpsScheme))) { return true; }
diff --git a/components/safe_browsing_db/database_manager.h b/components/safe_browsing_db/database_manager.h index 018bf15..9399f78 100644 --- a/components/safe_browsing_db/database_manager.h +++ b/components/safe_browsing_db/database_manager.h
@@ -196,12 +196,16 @@ // Called to initialize objects that are used on the io_thread, such as the // v4 protocol manager. This may be called multiple times during the life of - // the DatabaseManager. Must be called on IO thread. + // the DatabaseManager. Must be called on IO thread. All subclasses should + // override this method, set enabled_ to true and call the base class method + // at the top of it. virtual void StartOnIOThread( net::URLRequestContextGetter* request_context_getter, const V4ProtocolConfig& config); - // Called to stop or shutdown operations on the io_thread. + // Called to stop or shutdown operations on the io_thread. All subclasses + // should override this method, set enabled_ to false and call the base class + // method at the bottom of it. virtual void StopOnIOThread(bool shutdown); protected: @@ -262,6 +266,10 @@ // responsible for deleting them when removing from the set. ApiCheckSet api_checks_; + // Whether the service is running. 'enabled_' is used by the + // SafeBrowsingDatabaseManager on the IO thread during normal operations. + bool enabled_; + // Created and destroyed via StartOnIOThread/StopOnIOThread. std::unique_ptr<V4GetHashProtocolManager> v4_get_hash_protocol_manager_;
diff --git a/components/safe_browsing_db/remote_database_manager.cc b/components/safe_browsing_db/remote_database_manager.cc index 87f3c416..256c511 100644 --- a/components/safe_browsing_db/remote_database_manager.cc +++ b/components/safe_browsing_db/remote_database_manager.cc
@@ -98,8 +98,7 @@ // // TODO(nparker): Add more tests for this class -RemoteSafeBrowsingDatabaseManager::RemoteSafeBrowsingDatabaseManager() - : enabled_(false) { +RemoteSafeBrowsingDatabaseManager::RemoteSafeBrowsingDatabaseManager() { // Decide which resource types to check. These two are the minimum. resource_types_to_check_.insert(content::RESOURCE_TYPE_MAIN_FRAME); resource_types_to_check_.insert(content::RESOURCE_TYPE_SUB_FRAME);
diff --git a/components/safe_browsing_db/remote_database_manager.h b/components/safe_browsing_db/remote_database_manager.h index 8ae6663..3327081 100644 --- a/components/safe_browsing_db/remote_database_manager.h +++ b/components/safe_browsing_db/remote_database_manager.h
@@ -72,7 +72,6 @@ // Requests currently outstanding. This owns the ptrs. std::vector<ClientRequest*> current_requests_; - bool enabled_; std::set<content::ResourceType> resource_types_to_check_;
diff --git a/components/safe_browsing_db/test_database_manager.cc b/components/safe_browsing_db/test_database_manager.cc index 3209bb39..b6805ac0 100644 --- a/components/safe_browsing_db/test_database_manager.cc +++ b/components/safe_browsing_db/test_database_manager.cc
@@ -114,4 +114,16 @@ return false; } +void TestSafeBrowsingDatabaseManager::StartOnIOThread( + net::URLRequestContextGetter* request_context_getter, + const V4ProtocolConfig& config) { + SafeBrowsingDatabaseManager::StartOnIOThread(request_context_getter, config); + enabled_ = true; +} + +void TestSafeBrowsingDatabaseManager::StopOnIOThread(bool shutdown) { + enabled_ = false; + SafeBrowsingDatabaseManager::StopOnIOThread(shutdown); +} + } // namespace safe_browsing
diff --git a/components/safe_browsing_db/test_database_manager.h b/components/safe_browsing_db/test_database_manager.h index 3dbf275..870807f 100644 --- a/components/safe_browsing_db/test_database_manager.h +++ b/components/safe_browsing_db/test_database_manager.h
@@ -41,6 +41,9 @@ bool IsDownloadProtectionEnabled() const override; bool IsMalwareKillSwitchOn() override; bool IsSupported() const override; + void StartOnIOThread(net::URLRequestContextGetter* request_context_getter, + const V4ProtocolConfig& config) override; + void StopOnIOThread(bool shutdown) override; protected: ~TestSafeBrowsingDatabaseManager() override {};
diff --git a/components/safe_browsing_db/v4_get_hash_protocol_manager.cc b/components/safe_browsing_db/v4_get_hash_protocol_manager.cc index a1a640d..eba742b 100644 --- a/components/safe_browsing_db/v4_get_hash_protocol_manager.cc +++ b/components/safe_browsing_db/v4_get_hash_protocol_manager.cc
@@ -121,7 +121,7 @@ const char kPermission[] = "permission"; const char kPhaPatternType[] = "pha_pattern_type"; -const char kMalwarePatternType[] = "malware_pattern_type"; +const char kMalwareThreatType[] = "malware_threat_type"; const char kSePatternType[] = "se_pattern_type"; const char kLanding[] = "LANDING"; const char kDistribution[] = "DISTRIBUTION"; @@ -593,7 +593,7 @@ match.threat_type() == POTENTIALLY_HARMFUL_APPLICATION) { for (const ThreatEntryMetadata::MetadataEntry& m : match.threat_entry_metadata().entries()) { - if (m.key() == kPhaPatternType || m.key() == kMalwarePatternType) { + if (m.key() == kPhaPatternType || m.key() == kMalwareThreatType) { if (m.value() == kLanding) { metadata->threat_pattern_type = ThreatPatternType::MALWARE_LANDING; break;
diff --git a/components/safe_browsing_db/v4_local_database_manager.cc b/components/safe_browsing_db/v4_local_database_manager.cc index ffef84e..58f7ae8 100644 --- a/components/safe_browsing_db/v4_local_database_manager.cc +++ b/components/safe_browsing_db/v4_local_database_manager.cc
@@ -138,7 +138,6 @@ V4LocalDatabaseManager::V4LocalDatabaseManager(const base::FilePath& base_path) : base_path_(base_path), - enabled_(false), list_infos_(GetListInfos()), weak_factory_(this) { DCHECK(!base_path_.empty());
diff --git a/components/safe_browsing_db/v4_local_database_manager.h b/components/safe_browsing_db/v4_local_database_manager.h index 7db100dc..12d63a8 100644 --- a/components/safe_browsing_db/v4_local_database_manager.h +++ b/components/safe_browsing_db/v4_local_database_manager.h
@@ -265,9 +265,6 @@ // ready to process next update. DatabaseUpdatedCallback db_updated_callback_; - // Whether the service is running. - bool enabled_; - // The list of stores to manage (for hash prefixes and full hashes). Each // element contains the identifier for the store, the corresponding // SBThreatType, whether to fetch hash prefixes for that store, and the
diff --git a/components/ukm/ukm_service.cc b/components/ukm/ukm_service.cc index 823bff5..cbab848 100644 --- a/components/ukm/ukm_service.cc +++ b/components/ukm/ukm_service.cc
@@ -126,9 +126,6 @@ void UkmService::EnableReporting() { DCHECK(thread_checker_.CalledOnValidThread()); DVLOG(1) << "UkmService::EnableReporting"; -#if defined(OFFICIAL_BUILD) - CHECK(false); // Remove this once UKM checks sync state. -#endif if (!initialize_started_) Initialize(); scheduler_->Start();
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc index 9d870e3a..3da5b3b 100644 --- a/content/browser/presentation/presentation_service_impl.cc +++ b/content/browser/presentation/presentation_service_impl.cc
@@ -109,7 +109,9 @@ const PresentationServiceImpl::NewSessionCallback& callback) { callback.Run(blink::mojom::PresentationSessionInfoPtr(), blink::mojom::PresentationError::From(PresentationError( - PRESENTATION_ERROR_UNKNOWN, "Internal error"))); + PRESENTATION_ERROR_PREVIOUS_START_IN_PROGRESS, + "There is already an unsettled Promise from a previous call " + "to start."))); } } // namespace
diff --git a/content/browser/presentation/presentation_type_converters.cc b/content/browser/presentation/presentation_type_converters.cc index 827897cb..086ec7c 100644 --- a/content/browser/presentation/presentation_type_converters.cc +++ b/content/browser/presentation/presentation_type_converters.cc
@@ -17,6 +17,8 @@ return blink::mojom::PresentationErrorType::SESSION_REQUEST_CANCELLED; case content::PRESENTATION_ERROR_NO_PRESENTATION_FOUND: return blink::mojom::PresentationErrorType::NO_PRESENTATION_FOUND; + case content::PRESENTATION_ERROR_PREVIOUS_START_IN_PROGRESS: + return blink::mojom::PresentationErrorType::PREVIOUS_START_IN_PROGRESS; case content::PRESENTATION_ERROR_UNKNOWN: return blink::mojom::PresentationErrorType::UNKNOWN; }
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index ebd54ca..752f7234 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -43,7 +43,7 @@ #include "cc/surfaces/direct_compositor_frame_sink.h" #include "cc/surfaces/display.h" #include "cc/surfaces/display_scheduler.h" -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "components/display_compositor/compositor_overlay_candidate_validator_android.h" #include "components/display_compositor/gl_helper.h" @@ -435,13 +435,13 @@ animation_host_ = cc::AnimationHost::CreateMainInstance(); - cc::LayerTreeHostInProcess::InitParams params; + cc::LayerTreeHost::InitParams params; params.client = this; params.task_graph_runner = g_task_graph_runner.Pointer(); params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); params.settings = &settings; params.mutator_host = animation_host_.get(); - host_ = cc::LayerTreeHostInProcess::CreateSingleThreaded(this, ¶ms); + host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); DCHECK(!host_->IsVisible()); host_->GetLayerTree()->SetRootLayer(root_window_->GetLayer()); host_->SetFrameSinkId(frame_sink_id_);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 8fc8bde..6cfdebc 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1193,10 +1193,6 @@ auto registry = base::MakeUnique<service_manager::InterfaceRegistry>( service_manager::mojom::kServiceManager_ConnectorSpec); - channel_->AddAssociatedInterface( - base::Bind(&RenderProcessHostImpl::OnRouteProviderRequest, - base::Unretained(this))); - channel_->AddAssociatedInterfaceForIOThread( base::Bind(&IndexedDBDispatcherHost::AddBinding, indexed_db_factory_)); @@ -2065,6 +2061,21 @@ return listener->OnMessageReceived(msg); } +void RenderProcessHostImpl::OnAssociatedInterfaceRequest( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle handle) { + if (interface_name == mojom::RouteProvider::Name_) { + if (route_provider_binding_.is_bound()) + return; + mojom::RouteProviderAssociatedRequest request; + request.Bind(std::move(handle)); + route_provider_binding_.Bind(std::move(request)); + } else { + LOG(ERROR) << "Request for unknown Channel-associated interface: " + << interface_name; + } +} + void RenderProcessHostImpl::OnChannelConnected(int32_t peer_pid) { channel_connected_ = true; if (IsReady()) { @@ -2653,13 +2664,6 @@ shm_handle, metrics_allocator_->shared_memory()->mapped_size())); } -void RenderProcessHostImpl::OnRouteProviderRequest( - mojom::RouteProviderAssociatedRequest request) { - if (route_provider_binding_.is_bound()) - return; - route_provider_binding_.Bind(std::move(request)); -} - void RenderProcessHostImpl::ProcessDied(bool already_dead, RendererClosedDetails* known_details) { // Our child process has died. If we didn't expect it, it's a crash.
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 75895e1..dc269f2 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -186,6 +186,9 @@ // IPC::Listener via RenderProcessHost. bool OnMessageReceived(const IPC::Message& msg) override; + void OnAssociatedInterfaceRequest( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle handle) override; void OnChannelConnected(int32_t peer_pid) override; void OnChannelError() override; void OnBadMessageReceived(const IPC::Message& message) override; @@ -371,8 +374,6 @@ // Handle termination of our process. void ProcessDied(bool already_dead, RendererClosedDetails* known_details); - void OnRouteProviderRequest(mojom::RouteProviderAssociatedRequest request); - // GpuSwitchingObserver implementation. void OnGpuSwitched() override;
diff --git a/content/browser/renderer_host/render_view_host_browsertest.cc b/content/browser/renderer_host/render_view_host_browsertest.cc index 9b260626..6efcbf3 100644 --- a/content/browser/renderer_host/render_view_host_browsertest.cc +++ b/content/browser/renderer_host/render_view_host_browsertest.cc
@@ -120,10 +120,10 @@ GURL test_url = embedded_test_server()->GetURL("/touch_selection.html"); NavigateToURL(shell(), test_url); - RenderViewHost* rvh = shell()->web_contents()->GetRenderViewHost(); - EXPECT_FALSE(rvh->IsFocusedElementEditable()); + WebContents* contents = shell()->web_contents(); + EXPECT_FALSE(contents->IsFocusedElementEditable()); EXPECT_TRUE(ExecuteScript(shell(), "focus_textfield();")); - EXPECT_TRUE(rvh->IsFocusedElementEditable()); + EXPECT_TRUE(contents->IsFocusedElementEditable()); } // Flaky on Linux (https://crbug.com/559192).
diff --git a/content/browser/renderer_host/render_view_host_delegate.cc b/content/browser/renderer_host/render_view_host_delegate.cc index f202685c..3d5853c 100644 --- a/content/browser/renderer_host/render_view_host_delegate.cc +++ b/content/browser/renderer_host/render_view_host_delegate.cc
@@ -61,8 +61,4 @@ return false; } -bool RenderViewHostDelegate::IsFocusedElementEditable() { - return false; -} - } // namespace content
diff --git a/content/browser/renderer_host/render_view_host_delegate.h b/content/browser/renderer_host/render_view_host_delegate.h index a6864b4..2e1dda41 100644 --- a/content/browser/renderer_host/render_view_host_delegate.h +++ b/content/browser/renderer_host/render_view_host_delegate.h
@@ -190,14 +190,6 @@ // Whether download UI should be hidden. virtual bool HideDownloadUI() const; - // Whether the focused element on the page is editable. This returns true iff - // the focused frame has a focused editable element. - virtual bool IsFocusedElementEditable(); - - // Asks the delegate to clear the focused element. This will lead to an IPC to - // the focused RenderWidget. - virtual void ClearFocusedElement() {} - protected: virtual ~RenderViewHostDelegate() {} };
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 6be34a6c..6cca925 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -950,19 +950,6 @@ updating_web_preferences_ = false; } -void RenderViewHostImpl::ClearFocusedElement() { - // TODO(ekaramad): We should move this to WebContents instead - // (https://crbug.com/675975). - if (delegate_) - delegate_->ClearFocusedElement(); -} - -bool RenderViewHostImpl::IsFocusedElementEditable() { - // TODO(ekaramad): We should move this to WebContents instead - // (https://crbug.com/675975). - return delegate_ && delegate_->IsFocusedElementEditable(); -} - void RenderViewHostImpl::DisableScrollbarsForThreshold(const gfx::Size& size) { Send(new ViewMsg_DisableScrollbarsForSmallWindows(GetRoutingID(), size)); }
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index a2a0359..88b7ea9a 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -87,8 +87,6 @@ int GetRoutingID() const override; RenderFrameHost* GetMainFrame() override; void AllowBindings(int binding_flags) override; - void ClearFocusedElement() override; - bool IsFocusedElementEditable() override; void DirectoryEnumerationFinished( int request_id, const std::vector<base::FilePath>& files) override;
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc index af61d9c..76e9c2d 100644 --- a/content/browser/service_worker/service_worker_controllee_request_handler.cc +++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -380,10 +380,7 @@ DCHECK_EQ(original_registration->id(), registration_id); scoped_refptr<ServiceWorkerVersion> new_version = original_registration->installing_version(); - new_version->ReportError( - SERVICE_WORKER_OK, - "ServiceWorker was updated because \"Force update on page load\" was " - "checked in DevTools Source tab."); + new_version->ReportForceUpdateToDevTools(); new_version->set_skip_waiting(true); new_version->RegisterStatusChangeCallback(base::Bind( &self::OnUpdatedVersionStatusChanged, weak_factory_.GetWeakPtr(),
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 1cbb5348..d9fe5df 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -76,6 +76,9 @@ "Failed to claim clients due to Service Worker system shutdown."; const char kNotRespondingErrorMesage[] = "Service Worker is not responding."; +const char kForceUpdateInfoMessage[] = + "Service Worker was updated because \"Update on load\" was " + "checked in DevTools Service Workers toolbar."; void RunSoon(const base::Closure& callback) { if (!callback.is_null()) @@ -749,6 +752,11 @@ } } +void ServiceWorkerVersion::ReportForceUpdateToDevTools() { + embedded_worker_->AddMessageToConsole(blink::WebConsoleMessage::LevelWarning, + kForceUpdateInfoMessage); +} + void ServiceWorkerVersion::SetStartWorkerStatusCode( ServiceWorkerStatusCode status) { start_worker_status_ = status;
diff --git a/content/browser/service_worker/service_worker_version.h b/content/browser/service_worker/service_worker_version.h index a892ac6..f6b3e02 100644 --- a/content/browser/service_worker/service_worker_version.h +++ b/content/browser/service_worker/service_worker_version.h
@@ -354,6 +354,8 @@ void ReportError(ServiceWorkerStatusCode status, const std::string& status_message); + void ReportForceUpdateToDevTools(); + // Sets the status code to pass to StartWorker callbacks if start fails. void SetStartWorkerStatusCode(ServiceWorkerStatusCode status);
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index fce4361..fcd0937 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -410,6 +410,8 @@ void OnAllPasswordInputsHiddenOnHttp() override; void OnCreditCardInputShownOnHttp() override; void SetIsOverlayContent(bool is_overlay_content) override; + bool IsFocusedElementEditable() override; + void ClearFocusedElement() override; #if defined(OS_ANDROID) base::android::ScopedJavaLocalRef<jobject> GetJavaWebContents() override; @@ -557,8 +559,6 @@ bool IsOverridingUserAgent() override; bool IsJavaScriptDialogShowing() const override; bool HideDownloadUI() const override; - bool IsFocusedElementEditable() override; - void ClearFocusedElement() override; // NavigatorDelegate ---------------------------------------------------------
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index 2666ba2..dd7af71 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc
@@ -538,10 +538,6 @@ channel_->AddFilter(startup_filter); } - channel_->AddAssociatedInterface( - base::Bind(&ChildThreadImpl::OnRouteProviderRequest, - base::Unretained(this))); - ConnectChannel(); // This must always be done after ConnectChannel, because ConnectChannel() may @@ -754,6 +750,20 @@ return router_.OnMessageReceived(msg); } +void ChildThreadImpl::OnAssociatedInterfaceRequest( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle handle) { + if (interface_name == mojom::RouteProvider::Name_) { + DCHECK(!route_provider_binding_.is_bound()); + mojom::RouteProviderAssociatedRequest request; + request.Bind(std::move(handle)); + route_provider_binding_.Bind(std::move(request)); + } else { + LOG(ERROR) << "Request for unknown Channel-associated interface: " + << interface_name; + } +} + void ChildThreadImpl::StartServiceManagerConnection() { DCHECK(service_manager_connection_); service_manager_connection_->Start(); @@ -842,12 +852,6 @@ base::Process::Current().Terminate(0, false); } -void ChildThreadImpl::OnRouteProviderRequest( - mojom::RouteProviderAssociatedRequest request) { - DCHECK(!route_provider_binding_.is_bound()); - route_provider_binding_.Bind(std::move(request)); -} - void ChildThreadImpl::GetRoute( int32_t routing_id, mojom::AssociatedInterfaceProviderAssociatedRequest request) {
diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h index 6dc64263..a9ce450 100644 --- a/content/child/child_thread_impl.h +++ b/content/child/child_thread_impl.h
@@ -198,6 +198,9 @@ // IPC::Listener implementation: bool OnMessageReceived(const IPC::Message& msg) override; + void OnAssociatedInterfaceRequest( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle handle) override; void OnChannelConnected(int32_t peer_pid) override; void OnChannelError() override; @@ -235,8 +238,6 @@ void EnsureConnected(); - void OnRouteProviderRequest(mojom::RouteProviderAssociatedRequest request); - // mojom::RouteProvider: void GetRoute( int32_t routing_id,
diff --git a/content/common/associated_interface_registry_impl.cc b/content/common/associated_interface_registry_impl.cc index 67b5b0e..468dc9966 100644 --- a/content/common/associated_interface_registry_impl.cc +++ b/content/common/associated_interface_registry_impl.cc
@@ -14,6 +14,11 @@ AssociatedInterfaceRegistryImpl::~AssociatedInterfaceRegistryImpl() {} +bool AssociatedInterfaceRegistryImpl::CanBindRequest( + const std::string& interface_name) const { + return interfaces_.find(interface_name) != interfaces_.end(); +} + void AssociatedInterfaceRegistryImpl::BindRequest( const std::string& interface_name, mojo::ScopedInterfaceEndpointHandle handle) {
diff --git a/content/common/associated_interface_registry_impl.h b/content/common/associated_interface_registry_impl.h index 1f624a2f..4f7431c 100644 --- a/content/common/associated_interface_registry_impl.h +++ b/content/common/associated_interface_registry_impl.h
@@ -19,6 +19,7 @@ AssociatedInterfaceRegistryImpl(); ~AssociatedInterfaceRegistryImpl() override; + bool CanBindRequest(const std::string& interface_name) const; void BindRequest(const std::string& interface_name, mojo::ScopedInterfaceEndpointHandle handle);
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc index 9cfd41a..f392f276 100644 --- a/content/gpu/gpu_child_thread.cc +++ b/content/gpu/gpu_child_thread.cc
@@ -285,7 +285,10 @@ void GpuChildThread::OnAssociatedInterfaceRequest( const std::string& name, mojo::ScopedInterfaceEndpointHandle handle) { - associated_interfaces_.BindRequest(name, std::move(handle)); + if (associated_interfaces_.CanBindRequest(name)) + associated_interfaces_.BindRequest(name, std::move(handle)); + else + ChildThreadImpl::OnAssociatedInterfaceRequest(name, std::move(handle)); } void GpuChildThread::CreateGpuService(
diff --git a/content/public/browser/render_view_host.h b/content/public/browser/render_view_host.h index faa7ad0..04841375 100644 --- a/content/public/browser/render_view_host.h +++ b/content/public/browser/render_view_host.h
@@ -90,12 +90,6 @@ // should be a combination of values from BindingsPolicy. virtual void AllowBindings(int binding_flags) = 0; - // Tells the renderer to clear the focused element (if any). - virtual void ClearFocusedElement() = 0; - - // Returns true if the current focused element is editable. - virtual bool IsFocusedElementEditable() = 0; - // Notifies the listener that a directory enumeration is complete. virtual void DirectoryEnumerationFinished( int request_id,
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index a5e2535..98c79247 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -731,6 +731,12 @@ virtual int GetCurrentlyPlayingVideoCount() = 0; virtual bool IsFullscreen() = 0; + // Tells the renderer to clear the focused element (if any). + virtual void ClearFocusedElement() = 0; + + // Returns true if the current focused element is editable. + virtual bool IsFocusedElementEditable() = 0; + #if defined(OS_ANDROID) CONTENT_EXPORT static WebContents* FromJavaWebContents( const base::android::JavaRef<jobject>& jweb_contents_android);
diff --git a/content/public/common/presentation_session.h b/content/public/common/presentation_session.h index 87bafb4b..c57913a75 100644 --- a/content/public/common/presentation_session.h +++ b/content/public/common/presentation_session.h
@@ -44,6 +44,7 @@ PRESENTATION_ERROR_NO_AVAILABLE_SCREENS, PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED, PRESENTATION_ERROR_NO_PRESENTATION_FOUND, + PRESENTATION_ERROR_PREVIOUS_START_IN_PROGRESS, PRESENTATION_ERROR_UNKNOWN, };
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc index 8bf87802..8b17f64 100644 --- a/content/renderer/gpu/render_widget_compositor.cc +++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -44,7 +44,7 @@ #include "cc/resources/single_release_callback.h" #include "cc/scheduler/begin_frame_source.h" #include "cc/trees/latency_info_swap_promise_monitor.h" -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_mutator.h" #include "content/common/content_switches_internal.h" #include "content/common/layer_tree_settings_factory.h" @@ -236,7 +236,7 @@ std::unique_ptr<cc::LayerTreeHost> layer_tree_host; - cc::LayerTreeHostInProcess::InitParams params; + cc::LayerTreeHost::InitParams params; params.client = client; params.settings = &settings; params.task_graph_runner = deps->GetTaskGraphRunner(); @@ -251,10 +251,10 @@ } if (!is_threaded) { // Single-threaded layout tests. - layer_tree_host = cc::LayerTreeHostInProcess::CreateSingleThreaded( - single_thread_client, ¶ms); + layer_tree_host = + cc::LayerTreeHost::CreateSingleThreaded(single_thread_client, ¶ms); } else { - layer_tree_host = cc::LayerTreeHostInProcess::CreateThreaded( + layer_tree_host = cc::LayerTreeHost::CreateThreaded( deps->GetCompositorImplThreadTaskRunner(), ¶ms); }
diff --git a/content/renderer/presentation/presentation_dispatcher.cc b/content/renderer/presentation/presentation_dispatcher.cc index e5d3c51..594fdde 100644 --- a/content/renderer/presentation/presentation_dispatcher.cc +++ b/content/renderer/presentation/presentation_dispatcher.cc
@@ -54,6 +54,8 @@ return blink::WebPresentationError::ErrorTypeSessionRequestCancelled; case blink::mojom::PresentationErrorType::NO_PRESENTATION_FOUND: return blink::WebPresentationError::ErrorTypeNoPresentationFound; + case blink::mojom::PresentationErrorType::PREVIOUS_START_IN_PROGRESS: + return blink::WebPresentationError::ErrorTypePreviousStartInProgress; case blink::mojom::PresentationErrorType::UNKNOWN: default: return blink::WebPresentationError::ErrorTypeUnknown;
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 1dcaaa6f..e374de41 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1485,7 +1485,10 @@ void RenderThreadImpl::OnAssociatedInterfaceRequest( const std::string& name, mojo::ScopedInterfaceEndpointHandle handle) { - associated_interfaces_.BindRequest(name, std::move(handle)); + if (associated_interfaces_.CanBindRequest(name)) + associated_interfaces_.BindRequest(name, std::move(handle)); + else + ChildThreadImpl::OnAssociatedInterfaceRequest(name, std::move(handle)); } bool RenderThreadImpl::IsGpuRasterizationForced() {
diff --git a/extensions/browser/api/execute_code_function.cc b/extensions/browser/api/execute_code_function.cc index d1b1ee3..0f2dd5f 100644 --- a/extensions/browser/api/execute_code_function.cc +++ b/extensions/browser/api/execute_code_function.cc
@@ -163,7 +163,13 @@ } bool ExecuteCodeFunction::RunAsync() { - EXTENSION_FUNCTION_VALIDATE(Init()); + InitResult init_result = Init(); + EXTENSION_FUNCTION_VALIDATE(init_result != VALIDATION_FAILURE); + if (init_result == FAILURE) { + if (init_error_) + SetError(init_error_.value()); + return false; + } if (!details_->code.get() && !details_->file.get()) { error_ = kNoCodeOrFileToExecuteError;
diff --git a/extensions/browser/api/execute_code_function.h b/extensions/browser/api/execute_code_function.h index dbf8639..13df3dd 100644 --- a/extensions/browser/api/execute_code_function.h +++ b/extensions/browser/api/execute_code_function.h
@@ -6,6 +6,7 @@ #define EXTENSIONS_BROWSER_API_EXECUTE_CODE_FUNCTION_H_ #include "base/macros.h" +#include "base/optional.h" #include "extensions/browser/extension_function.h" #include "extensions/browser/script_executor.h" #include "extensions/common/api/extension_types.h" @@ -27,8 +28,23 @@ bool HasPermission() override; bool RunAsync() override; - // Initialize |details_| if it hasn't already been. - virtual bool Init() = 0; + enum InitResult { + // ExtensionFunction validation failure. + // Warning: Validation failures kill the renderer and should only be used + // for circumstances that should never happen. + VALIDATION_FAILURE, + // Failure other than validation. + // Failures return an error to the extension function and should be used + // when an error situation occurs: e.g. trying to execute script during + // browser shutdown. + FAILURE, + SUCCESS + }; + + // Initializes |details_| and other variables if they haven't already been. + // Returns whether or not it succeeded. Failure can be tolerable (FAILURE), or + // fatal (VALIDATION_FAILURE). + virtual InitResult Init() = 0; virtual bool ShouldInsertCSS() const = 0; virtual bool CanExecuteScriptOnPage() = 0; virtual ScriptExecutor* GetScriptExecutor() = 0; @@ -48,8 +64,20 @@ const HostID& host_id() const { return host_id_; } void set_host_id(const HostID& host_id) { host_id_ = host_id; } + InitResult set_init_result(InitResult init_result) { + init_result_ = init_result; + return init_result_.value(); + } + InitResult set_init_result_error(const std::string& error) { + init_error_ = error; + return set_init_result(FAILURE); + } + // The injection details. std::unique_ptr<api::extension_types::InjectDetails> details_; + base::Optional<InitResult> init_result_; + // Set iff |init_result_| == FAILURE, holds the error string. + base::Optional<std::string> init_error_; private: // Retrieves the file url for the given |extension_path| and optionally
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc index 790f767..179e68e 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -365,19 +365,16 @@ WebViewInternalExecuteCodeFunction::~WebViewInternalExecuteCodeFunction() { } -bool WebViewInternalExecuteCodeFunction::Init() { - if (details_.get()) - return true; +ExecuteCodeFunction::InitResult WebViewInternalExecuteCodeFunction::Init() { + if (init_result_) + return init_result_.value(); - if (!args_->GetInteger(0, &guest_instance_id_)) - return false; - - if (!guest_instance_id_) - return false; + if (!args_->GetInteger(0, &guest_instance_id_) || !guest_instance_id_) + return set_init_result(VALIDATION_FAILURE); std::string src; if (!args_->GetString(1, &src)) - return false; + return set_init_result(VALIDATION_FAILURE); // Set |guest_src_| here, but do not return false if it is invalid. // Instead, let it continue with the normal page load sequence, @@ -387,25 +384,25 @@ base::DictionaryValue* details_value = NULL; if (!args_->GetDictionary(2, &details_value)) - return false; + return set_init_result(VALIDATION_FAILURE); std::unique_ptr<InjectDetails> details(new InjectDetails()); if (!InjectDetails::Populate(*details_value, details.get())) - return false; + return set_init_result(VALIDATION_FAILURE); details_ = std::move(details); if (extension()) { set_host_id(HostID(HostID::EXTENSIONS, extension()->id())); - return true; + return set_init_result(SUCCESS); } WebContents* web_contents = GetSenderWebContents(); if (web_contents && web_contents->GetWebUI()) { const GURL& url = render_frame_host()->GetSiteInstance()->GetSiteURL(); set_host_id(HostID(HostID::WEBUI, url.spec())); - return true; + return set_init_result(SUCCESS); } - return false; + return set_init_result_error(""); // TODO(lazyboy): error? } bool WebViewInternalExecuteCodeFunction::ShouldInsertCSS() const {
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h index 3c5bf2aa..486bc03 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.h +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.h
@@ -97,7 +97,7 @@ ~WebViewInternalExecuteCodeFunction() override; // Initialize |details_| if it hasn't already been. - bool Init() override; + InitResult Init() override; bool ShouldInsertCSS() const override; bool CanExecuteScriptOnPage() override; // Guarded by a process ID check.
diff --git a/extensions/renderer/api/automation/automation_api_helper.cc b/extensions/renderer/api/automation/automation_api_helper.cc index 42a493b..8ffd54a7 100644 --- a/extensions/renderer/api/automation/automation_api_helper.cc +++ b/extensions/renderer/api/automation/automation_api_helper.cc
@@ -74,7 +74,7 @@ start_node = start_acc_obj.node(); } } - blink::WebString web_selector(selector); + blink::WebString web_selector = blink::WebString::fromUTF16(selector); blink::WebElement result_element = start_node.querySelector(web_selector); int result_acc_obj_id = 0; if (!result_element.isNull()) {
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 2a9986c..014d9f1 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -267,7 +267,7 @@ RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); // Register WebSecurityPolicy whitelists for the chrome-extension:// scheme. - WebString extension_scheme(base::ASCIIToUTF16(kExtensionScheme)); + WebString extension_scheme(WebString::fromASCII(kExtensionScheme)); // Resources should bypass Content Security Policy checks when included in // protected resources. TODO(kalman): What are "protected resources"?
diff --git a/extensions/renderer/dom_activity_logger.cc b/extensions/renderer/dom_activity_logger.cc index 13d960b..5f74d785 100644 --- a/extensions/renderer/dom_activity_logger.cc +++ b/extensions/renderer/dom_activity_logger.cc
@@ -63,7 +63,8 @@ void DOMActivityLogger::logGetter(const WebString& api_name, const WebURL& url, const WebString& title) { - SendDomActionMessage(api_name.utf8(), url, title, DomActionType::GETTER, + SendDomActionMessage(api_name.utf8(), url, title.utf16(), + DomActionType::GETTER, std::unique_ptr<base::ListValue>(new base::ListValue())); } @@ -84,7 +85,7 @@ AppendV8Value(api_name_utf8, new_value, args.get()); if (!old_value.IsEmpty()) AppendV8Value(api_name_utf8, old_value, args.get()); - SendDomActionMessage(api_name_utf8, url, title, DomActionType::SETTER, + SendDomActionMessage(api_name_utf8, url, title.utf16(), DomActionType::SETTER, std::move(args)); } @@ -97,7 +98,7 @@ std::string api_name_utf8 = api_name.utf8(); for (int i = 0; i < argc; ++i) AppendV8Value(api_name_utf8, argv[i], args.get()); - SendDomActionMessage(api_name_utf8, url, title, DomActionType::METHOD, + SendDomActionMessage(api_name_utf8, url, title.utf16(), DomActionType::METHOD, std::move(args)); } @@ -109,9 +110,9 @@ std::unique_ptr<base::ListValue> args(new base::ListValue); std::string event_name_utf8 = event_name.utf8(); for (int i = 0; i < argc; ++i) - args->AppendString(argv[i]); - SendDomActionMessage(event_name_utf8, url, title, DomActionType::METHOD, - std::move(args)); + args->AppendString(argv[i].utf16()); + SendDomActionMessage(event_name_utf8, url, title.utf16(), + DomActionType::METHOD, std::move(args)); } void DOMActivityLogger::SendDomActionMessage(
diff --git a/extensions/renderer/extension_frame_helper.cc b/extensions/renderer/extension_frame_helper.cc index 91d38c3..c737aa55 100644 --- a/extensions/renderer/extension_frame_helper.cc +++ b/extensions/renderer/extension_frame_helper.cc
@@ -50,10 +50,8 @@ blink::WebSecurityOrigin origin = frame_helper->render_frame()->GetWebFrame()->getSecurityOrigin(); if (origin.isUnique() || - !base::EqualsASCII(base::StringPiece16(origin.protocol()), - kExtensionScheme) || - !base::EqualsASCII(base::StringPiece16(origin.host()), - match_extension_id.c_str())) + !base::EqualsASCII(origin.protocol().utf16(), kExtensionScheme) || + !base::EqualsASCII(origin.host().utf16(), match_extension_id.c_str())) return false; if (match_window_id != extension_misc::kUnknownWindowId &&
diff --git a/ios/chrome/app/tests_fake_hook.mm b/ios/chrome/app/tests_fake_hook.mm index e4031757..c3125688 100644 --- a/ios/chrome/app/tests_fake_hook.mm +++ b/ios/chrome/app/tests_fake_hook.mm
@@ -12,6 +12,9 @@ bool DisableFirstRun() { return false; } +bool DisableGeolocation() { + return false; +} bool DisableSigninRecallPromo() { return false; }
diff --git a/ios/chrome/app/tests_hook.h b/ios/chrome/app/tests_hook.h index 3a63b93..7b39c521 100644 --- a/ios/chrome/app/tests_hook.h +++ b/ios/chrome/app/tests_hook.h
@@ -15,6 +15,10 @@ // run unimpeded. bool DisableFirstRun(); +// Returns true if the geolocation should be disabled to avoid the user location +// prompt displaying for the omnibox. +bool DisableGeolocation(); + // Returns true if the signin recall promo should be disabled to allow other // tests to run unimpeded. bool DisableSigninRecallPromo();
diff --git a/ios/chrome/browser/geolocation/BUILD.gn b/ios/chrome/browser/geolocation/BUILD.gn index 30306a6..b38a267 100644 --- a/ios/chrome/browser/geolocation/BUILD.gn +++ b/ios/chrome/browser/geolocation/BUILD.gn
@@ -23,6 +23,7 @@ "//base", "//components/prefs", "//components/strings", + "//ios/chrome/app:tests_hook", "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/browser/geolocation/location_manager.mm b/ios/chrome/browser/geolocation/location_manager.mm index e9daf6e..10c5ce0 100644 --- a/ios/chrome/browser/geolocation/location_manager.mm +++ b/ios/chrome/browser/geolocation/location_manager.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/geolocation/location_manager.h" +#include "ios/chrome/app/tests_hook.h" #import "ios/chrome/browser/geolocation/CLLocation+OmniboxGeolocation.h" #import "ios/chrome/browser/geolocation/location_manager+Testing.h" #import "ios/public/provider/chrome/browser/chrome_browser_provider.h" @@ -91,7 +92,8 @@ } - (BOOL)locationServicesEnabled { - return [CLLocationManager locationServicesEnabled]; + return !tests_hook::DisableGeolocation() && + [CLLocationManager locationServicesEnabled]; } - (void)startUpdatingLocation {
diff --git a/ios/chrome/test/earl_grey/eg_tests_hook.mm b/ios/chrome/test/earl_grey/eg_tests_hook.mm index 71ad274..5f98ad77 100644 --- a/ios/chrome/test/earl_grey/eg_tests_hook.mm +++ b/ios/chrome/test/earl_grey/eg_tests_hook.mm
@@ -14,6 +14,10 @@ return true; } +bool DisableGeolocation() { + return true; +} + bool DisableSigninRecallPromo() { return true; }
diff --git a/ipc/ipc_channel_mojo_unittest.cc b/ipc/ipc_channel_mojo_unittest.cc index 9b28e39..5e75fbd 100644 --- a/ipc/ipc_channel_mojo_unittest.cc +++ b/ipc/ipc_channel_mojo_unittest.cc
@@ -848,12 +848,17 @@ : driver_binding_(this), ping_receiver_binding_(this) {} ~ListenerWithIndirectProxyAssociatedInterface() override {} + // IPC::Listener: bool OnMessageReceived(const IPC::Message& message) override { return true; } - void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) { - proxy->AddAssociatedInterface( - base::Bind(&ListenerWithIndirectProxyAssociatedInterface::BindRequest, - base::Unretained(this))); + void OnAssociatedInterfaceRequest( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle handle) override { + DCHECK(!driver_binding_.is_bound()); + DCHECK_EQ(interface_name, IPC::mojom::IndirectTestDriver::Name_); + IPC::mojom::IndirectTestDriverAssociatedRequest request; + request.Bind(std::move(handle)); + driver_binding_.Bind(std::move(request)); } void set_ping_handler(const base::Closure& handler) { @@ -873,11 +878,6 @@ ping_handler_.Run(); } - void BindRequest(IPC::mojom::IndirectTestDriverAssociatedRequest request) { - DCHECK(!driver_binding_.is_bound()); - driver_binding_.Bind(std::move(request)); - } - mojo::AssociatedBinding<IPC::mojom::IndirectTestDriver> driver_binding_; mojo::AssociatedBinding<IPC::mojom::PingReceiver> ping_receiver_binding_; @@ -893,7 +893,6 @@ ListenerWithIndirectProxyAssociatedInterface listener; CreateProxy(&listener); - listener.RegisterInterfaceFactory(proxy()); RunProxy(); base::RunLoop loop; @@ -939,12 +938,6 @@ void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; } - void RegisterInterfaceFactory(IPC::ChannelProxy* proxy) { - proxy->AddAssociatedInterface( - base::Bind(&ListenerWithSyncAssociatedInterface::BindRequest, - base::Unretained(this))); - } - void RunUntilQuitRequested() { base::RunLoop loop; quit_closure_ = loop.QuitClosure(); @@ -989,6 +982,17 @@ return true; } + void OnAssociatedInterfaceRequest( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle handle) override { + DCHECK(!binding_.is_bound()); + DCHECK_EQ(interface_name, IPC::mojom::SimpleTestDriver::Name_); + + IPC::mojom::SimpleTestDriverAssociatedRequest request; + request.Bind(std::move(handle)); + binding_.Bind(std::move(request)); + } + void BindRequest(IPC::mojom::SimpleTestDriverAssociatedRequest request) { DCHECK(!binding_.is_bound()); binding_.Bind(std::move(request)); @@ -1027,7 +1031,6 @@ ListenerWithSyncAssociatedInterface listener; CreateProxy(&listener); listener.set_sync_sender(proxy()); - listener.RegisterInterfaceFactory(proxy()); RunProxy(); // Run the client's simple sanity check to completion. @@ -1071,11 +1074,6 @@ void set_driver(IPC::mojom::SimpleTestDriver* driver) { driver_ = driver; } void set_sync_sender(IPC::Sender* sync_sender) { sync_sender_ = sync_sender; } - void BindRequest(IPC::mojom::SimpleTestClientAssociatedRequest request) { - DCHECK(!binding_.is_bound()); - binding_.Bind(std::move(request)); - } - void WaitForValueRequest() { run_loop_.reset(new base::RunLoop); run_loop_->Run(); @@ -1119,6 +1117,17 @@ return true; } + void OnAssociatedInterfaceRequest( + const std::string& interface_name, + mojo::ScopedInterfaceEndpointHandle handle) override { + DCHECK(!binding_.is_bound()); + DCHECK_EQ(interface_name, IPC::mojom::SimpleTestClient::Name_); + + IPC::mojom::SimpleTestClientAssociatedRequest request; + request.Bind(std::move(handle)); + binding_.Bind(std::move(request)); + } + bool use_sync_sender_ = false; mojo::AssociatedBinding<IPC::mojom::SimpleTestClient> binding_; IPC::Sender* sync_sender_ = nullptr; @@ -1133,8 +1142,6 @@ SimpleTestClientImpl client_impl; CreateProxy(&client_impl); client_impl.set_sync_sender(proxy()); - proxy()->AddAssociatedInterface(base::Bind(&SimpleTestClientImpl::BindRequest, - base::Unretained(&client_impl))); RunProxy(); IPC::mojom::SimpleTestDriverAssociatedPtr driver;
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index 3365aef..91e8236 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc
@@ -27,17 +27,6 @@ namespace IPC { -namespace { - -void BindAssociatedInterfaceOnTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const ChannelProxy::GenericAssociatedInterfaceFactory& factory, - mojo::ScopedInterfaceEndpointHandle handle) { - task_runner->PostTask(FROM_HERE, base::Bind(factory, base::Passed(&handle))); -} - -} // namespace - //------------------------------------------------------------------------------ ChannelProxy::Context::Context( @@ -81,9 +70,9 @@ associated_group_ = *support->GetAssociatedGroup(); base::AutoLock l(pending_filters_lock_); - for (auto& entry : pending_interfaces_) + for (auto& entry : pending_io_thread_interfaces_) support->AddGenericAssociatedInterface(entry.first, entry.second); - pending_interfaces_.clear(); + pending_io_thread_interfaces_.clear(); } } @@ -388,21 +377,13 @@ associated_group_ = mojo::AssociatedGroup(); } -void ChannelProxy::Context::AddGenericAssociatedInterface( - const std::string& name, - const GenericAssociatedInterfaceFactory& factory) { - AddGenericAssociatedInterfaceForIOThread( - name, base::Bind(&BindAssociatedInterfaceOnTaskRunner, - listener_task_runner_, factory)); -} - void ChannelProxy::Context::AddGenericAssociatedInterfaceForIOThread( const std::string& name, const GenericAssociatedInterfaceFactory& factory) { base::AutoLock l(channel_lifetime_lock_); if (!channel_) { base::AutoLock l(pending_filters_lock_); - pending_interfaces_.emplace_back(name, factory); + pending_io_thread_interfaces_.emplace_back(name, factory); return; } Channel::AssociatedInterfaceSupport* support = @@ -585,12 +566,6 @@ base::RetainedRef(filter))); } -void ChannelProxy::AddGenericAssociatedInterface( - const std::string& name, - const GenericAssociatedInterfaceFactory& factory) { - context()->AddGenericAssociatedInterface(name, factory); -} - void ChannelProxy::AddGenericAssociatedInterfaceForIOThread( const std::string& name, const GenericAssociatedInterfaceFactory& factory) {
diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h index ade563e..bda83bb18 100644 --- a/ipc/ipc_channel_proxy.h +++ b/ipc/ipc_channel_proxy.h
@@ -169,14 +169,6 @@ const std::string& name, const GenericAssociatedInterfaceFactory& factory); - // Adds a generic associated interface factory to bind incoming interface - // requests on the ChannelProxy's thread. MUST be called before Init() or - // before the remote end of the Channel is able to send messages (e.g. before - // its process is launched.) - void AddGenericAssociatedInterface( - const std::string& name, - const GenericAssociatedInterfaceFactory& factory); - template <typename Interface> using AssociatedInterfaceFactory = base::Callback<void(mojo::AssociatedInterfaceRequest<Interface>)>; @@ -193,18 +185,6 @@ factory)); } - // Helper to bind a ChannelProxy-thread associated interface factory, - // inferring the interface name from the callback argument's type. MUST be - // called before Init(). - template <typename Interface> - void AddAssociatedInterface( - const AssociatedInterfaceFactory<Interface>& factory) { - AddGenericAssociatedInterface( - Interface::Name_, - base::Bind(&ChannelProxy::BindAssociatedInterfaceRequest<Interface>, - factory)); - } - // Gets the AssociatedGroup used to create new associated endpoints on this // ChannelProxy. mojo::AssociatedGroup* GetAssociatedGroup(); @@ -341,9 +321,6 @@ mojo::AssociatedGroup* associated_group() { return &associated_group_; } - void AddGenericAssociatedInterface( - const std::string& name, - const GenericAssociatedInterfaceFactory& factory); void AddGenericAssociatedInterfaceForIOThread( const std::string& name, const GenericAssociatedInterfaceFactory& factory); @@ -383,12 +360,12 @@ mojo::AssociatedGroup associated_group_; - // Holds associated interface binders added by AddGenericAssociatedInterface - // or AddGenericAssociatedInterfaceForIOThread until the underlying channel - // has been initialized. - base::Lock pending_interfaces_lock_; + // Holds associated interface binders added by + // AddGenericAssociatedInterfaceForIOThread until the underlying channel has + // been initialized. + base::Lock pending_io_thread_interfaces_lock_; std::vector<std::pair<std::string, GenericAssociatedInterfaceFactory>> - pending_interfaces_; + pending_io_thread_interfaces_; }; Context* context() { return context_.get(); }
diff --git a/net/http/disk_cache_based_quic_server_info.cc b/net/http/disk_cache_based_quic_server_info.cc index f305c18..2d4251b 100644 --- a/net/http/disk_cache_based_quic_server_info.cc +++ b/net/http/disk_cache_based_quic_server_info.cc
@@ -9,6 +9,7 @@ #include "base/callback_helpers.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" +#include "base/stl_util.h" #include "net/base/completion_callback.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -158,7 +159,7 @@ new_data_ = Serialize(); } else { new_data_ = pending_write_data_; - pending_write_data_.clear(); + base::STLClearObject(&pending_write_data_); } RecordQuicServerInfoStatus(QUIC_SERVER_INFO_PERSIST); @@ -392,7 +393,7 @@ if (entry_) entry_->Close(); entry_ = NULL; - new_data_.clear(); + base::STLClearObject(&new_data_); state_ = NONE; return OK; }
diff --git a/net/quic/quartc/quartc_session_test.cc b/net/quic/quartc/quartc_session_test.cc index f77e9a0..fc190057 100644 --- a/net/quic/quartc/quartc_session_test.cc +++ b/net/quic/quartc/quartc_session_test.cc
@@ -17,7 +17,6 @@ #include "net/quic/core/crypto/quic_random.h" #include "net/quic/core/quic_crypto_client_stream.h" #include "net/quic/core/quic_crypto_server_stream.h" -#include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_simple_buffer_allocator.h" #include "net/quic/platform/impl/quic_chromium_clock.h" #include "net/quic/quartc/quartc_alarm_factory.h" @@ -464,23 +463,20 @@ std::unique_ptr<QuartcSessionForTest> server_peer_; }; -TEST_F(QuartcSessionTest, StreamConnection) { - FLAGS_quic_reloadable_flag_enable_async_get_proof = false; +TEST_F(QuartcSessionTest, DISABLED_StreamConnection) { CreateClientAndServerSessions(); StartHandshake(); TestStreamConnection(); } -TEST_F(QuartcSessionTest, ClientRejection) { - FLAGS_quic_reloadable_flag_enable_async_get_proof = false; +TEST_F(QuartcSessionTest, DISABLED_ClientRejection) { CreateClientAndServerSessions(false /*client_handshake_success*/, true /*server_handshake_success*/); StartHandshake(); TestDisconnectAfterFailedHandshake(); } -TEST_F(QuartcSessionTest, ServerRejection) { - FLAGS_quic_reloadable_flag_enable_async_get_proof = false; +TEST_F(QuartcSessionTest, DISABLED_ServerRejection) { CreateClientAndServerSessions(true /*client_handshake_success*/, false /*server_handshake_success*/); StartHandshake(); @@ -494,8 +490,7 @@ EXPECT_EQ(nullptr, client_peer_->CreateOutgoingStream(kDefaultStreamParam)); } -TEST_F(QuartcSessionTest, CloseQuartcStream) { - FLAGS_quic_reloadable_flag_enable_async_get_proof = false; +TEST_F(QuartcSessionTest, DISABLED_CloseQuartcStream) { CreateClientAndServerSessions(); StartHandshake(); ASSERT_TRUE(client_peer_->IsCryptoHandshakeConfirmed() &&
diff --git a/services/ui/ws/display.cc b/services/ui/ws/display.cc index eee8a6c..e93c880 100644 --- a/services/ui/ws/display.cc +++ b/services/ui/ws/display.cc
@@ -270,13 +270,6 @@ return root_.get(); } -ServerWindow* Display::GetActiveRootWindow() { - WindowManagerDisplayRoot* display_root = GetActiveWindowManagerDisplayRoot(); - if (display_root) - return display_root->root(); - return nullptr; -} - void Display::OnAcceleratedWidgetAvailable() { display_manager()->OnDisplayAcceleratedWidgetAvailable(this); InitWindowManagerDisplayRoots(); @@ -313,6 +306,13 @@ pair.second->root()->SetBounds(new_bounds); } +ServerWindow* Display::GetActiveRootWindow() { + WindowManagerDisplayRoot* display_root = GetActiveWindowManagerDisplayRoot(); + if (display_root) + return display_root->root(); + return nullptr; +} + bool Display::CanHaveActiveChildren(ServerWindow* window) const { return window && activation_parents_.Contains(window); }
diff --git a/services/ui/ws/display.h b/services/ui/ws/display.h index 28bf83b..679a338 100644 --- a/services/ui/ws/display.h +++ b/services/ui/ws/display.h
@@ -143,6 +143,9 @@ // Updates the size of display root ServerWindow and WM root ServerWindow(s). void OnViewportMetricsChanged(const display::ViewportMetrics& metrics); + // Returns the root window of the active user. + ServerWindow* GetActiveRootWindow(); + private: friend class test::DisplayTestApi; @@ -166,7 +169,6 @@ // PlatformDisplayDelegate: display::Display GetDisplay() override; ServerWindow* GetRootWindow() override; - ServerWindow* GetActiveRootWindow() override; void OnAcceleratedWidgetAvailable() override; bool IsInHighContrastMode() override; void OnEvent(const ui::Event& event) override;
diff --git a/services/ui/ws/frame_generator.cc b/services/ui/ws/frame_generator.cc index ec6a3471..ba893e2 100644 --- a/services/ui/ws/frame_generator.cc +++ b/services/ui/ws/frame_generator.cc
@@ -31,6 +31,14 @@ DCHECK(delegate_); } +void FrameGenerator::SetDeviceScaleFactor(float device_scale_factor) { + if (device_scale_factor_ == device_scale_factor) + return; + device_scale_factor_ = device_scale_factor; + if (compositor_frame_sink_) + compositor_frame_sink_->SetNeedsBeginFrame(true); +} + FrameGenerator::~FrameGenerator() { // Invalidate WeakPtrs now to avoid callbacks back into the // FrameGenerator during destruction of |compositor_frame_sink_|. @@ -50,23 +58,17 @@ root_window_->CreateDisplayCompositorFrameSink( widget, std::move(sink_request), binding_.CreateInterfacePtrAndBind(), std::move(display_request)); - // TODO(fsamuel): This means we're always requesting a new BeginFrame signal - // even when we don't need it. Once surface ID propagation work is done, - // this will not be necessary because FrameGenerator will only need a - // BeginFrame if the window manager changes. - compositor_frame_sink_->SetNeedsBeginFrame(true); } -void FrameGenerator::OnSurfaceCreated(const cc::SurfaceId& surface_id, - ServerWindow* window) { - DCHECK(surface_id.is_valid()); +void FrameGenerator::OnSurfaceCreated(const cc::SurfaceInfo& surface_info) { + DCHECK(surface_info.id().is_valid()); // Only handle embedded surfaces changing here. The display root surface // changing is handled immediately after the CompositorFrame is submitted. - // TODO(samans): Only tell FrameGenerator about WM surface instead of all - // all surfaces. - if (window == delegate_->GetActiveRootWindow()) - window_manager_surface_id_ = surface_id; + if (surface_info != window_manager_surface_info_) { + window_manager_surface_info_ = surface_info; + compositor_frame_sink_->SetNeedsBeginFrame(true); + } } void FrameGenerator::DidReceiveCompositorFrameAck() {} @@ -91,6 +93,7 @@ compositor_frame_sink_->SubmitCompositorFrame(local_frame_id_, std::move(frame)); + compositor_frame_sink_->SetNeedsBeginFrame(false); last_submitted_frame_size_ = frame_size; } } @@ -112,7 +115,7 @@ render_pass->SetNew(render_pass_id, output_rect, output_rect, gfx::Transform()); - DrawWindow(render_pass.get(), delegate_->GetActiveRootWindow()); + DrawWindow(render_pass.get()); cc::CompositorFrame frame; frame.render_pass_list.push_back(std::move(render_pass)); @@ -121,7 +124,10 @@ invert_pass->SetNew(2, output_rect, output_rect, gfx::Transform()); cc::SharedQuadState* shared_state = invert_pass->CreateAndAppendSharedQuadState(); - shared_state->SetAll(gfx::Transform(), output_rect.size(), output_rect, + gfx::Size scaled_bounds = gfx::ScaleToCeiledSize( + output_rect.size(), window_manager_surface_info_.device_scale_factor(), + window_manager_surface_info_.device_scale_factor()); + shared_state->SetAll(gfx::Transform(), scaled_bounds, output_rect, output_rect, false, 1.f, SkBlendMode::kSrcOver, 0); auto* quad = invert_pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>(); render_pass->filters.Append(cc::FilterOperation::CreateInvertFilter(1.f)); @@ -134,48 +140,42 @@ } frame.metadata.device_scale_factor = device_scale_factor_; - if (window_manager_surface_id_.is_valid()) - frame.metadata.referenced_surfaces.push_back(window_manager_surface_id_); + if (window_manager_surface_info_.id().is_valid()) { + frame.metadata.referenced_surfaces.push_back( + window_manager_surface_info_.id()); + } return frame; } -void FrameGenerator::DrawWindow(cc::RenderPass* pass, ServerWindow* window) { - if (!window || !window->visible()) - return; +void FrameGenerator::DrawWindow(cc::RenderPass* pass) { + DCHECK(window_manager_surface_info_.id().is_valid()); - if (!window->compositor_frame_sink_manager()) - return; - - cc::SurfaceId default_surface_id = - window->compositor_frame_sink_manager()->GetLatestSurfaceId(); - - if (!default_surface_id.is_valid()) - return; + const gfx::Rect bounds_at_origin( + window_manager_surface_info_.size_in_pixels()); gfx::Transform quad_to_target_transform; - quad_to_target_transform.Translate(window->bounds().x(), - window->bounds().y()); + quad_to_target_transform.Translate(bounds_at_origin.x(), + bounds_at_origin.y()); cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); - const gfx::Rect bounds_at_origin(window->bounds().size()); + gfx::Size scaled_bounds = gfx::ScaleToCeiledSize( + bounds_at_origin.size(), + window_manager_surface_info_.device_scale_factor(), + window_manager_surface_info_.device_scale_factor()); + // TODO(fsamuel): These clipping and visible rects are incorrect. They need // to be populated from CompositorFrame structs. - sqs->SetAll( - quad_to_target_transform, bounds_at_origin.size() /* layer_bounds */, - bounds_at_origin /* visible_layer_bounds */, - bounds_at_origin /* clip_rect */, false /* is_clipped */, - 1.0f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting-context_id */); + sqs->SetAll(quad_to_target_transform, scaled_bounds /* layer_bounds */, + bounds_at_origin /* visible_layer_bounds */, + bounds_at_origin /* clip_rect */, false /* is_clipped */, + 1.0f /* opacity */, SkBlendMode::kSrcOver, + 0 /* sorting-context_id */); auto* quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>(); - quad->SetAll(sqs, bounds_at_origin /* rect */, - gfx::Rect() /* opaque_rect */, + quad->SetAll(sqs, bounds_at_origin /* rect */, gfx::Rect() /* opaque_rect */, bounds_at_origin /* visible_rect */, true /* needs_blending*/, - default_surface_id); -} - -void FrameGenerator::OnWindowDestroying(ServerWindow* window) { - Remove(window); + window_manager_surface_info_.id()); } } // namespace ws
diff --git a/services/ui/ws/frame_generator.h b/services/ui/ws/frame_generator.h index d5f5b75..9e5f943a 100644 --- a/services/ui/ws/frame_generator.h +++ b/services/ui/ws/frame_generator.h
@@ -23,7 +23,6 @@ namespace cc { class RenderPass; -class SurfaceId; } namespace ui { @@ -38,22 +37,18 @@ // Responsible for redrawing the display in response to the redraw requests by // submitting CompositorFrames to the owned CompositorFrameSink. -class FrameGenerator : public ServerWindowTracker, - public cc::mojom::MojoCompositorFrameSinkClient { +class FrameGenerator : public cc::mojom::MojoCompositorFrameSinkClient { public: FrameGenerator(FrameGeneratorDelegate* delegate, ServerWindow* root_window); ~FrameGenerator() override; - void set_device_scale_factor(float device_scale_factor) { - device_scale_factor_ = device_scale_factor; - } + void SetDeviceScaleFactor(float device_scale_factor); // Schedules a redraw for the provided region. void OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget); - // If |window| corresponds to the active WM for the display then update - // |window_manager_surface_id_|. - void OnSurfaceCreated(const cc::SurfaceId& surface_id, ServerWindow* window); + // Updates the WindowManager's SurfaceInfo. + void OnSurfaceCreated(const cc::SurfaceInfo& surface_info); private: friend class ui::ws::test::FrameGeneratorTest; @@ -67,12 +62,9 @@ // Generates the CompositorFrame. cc::CompositorFrame GenerateCompositorFrame(const gfx::Rect& output_rect); - // DrawWindow creates SurfaceDrawQuad for the provided ServerWindow and - // appends it to the provided cc::RenderPass. - void DrawWindow(cc::RenderPass* pass, ServerWindow* window); - - // ServerWindowObserver implementation. - void OnWindowDestroying(ServerWindow* window) override; + // DrawWindow creates SurfaceDrawQuad for the window manager and appends it to + // the provided cc::RenderPass. + void DrawWindow(cc::RenderPass* pass); FrameGeneratorDelegate* delegate_; ServerWindow* const root_window_; @@ -84,7 +76,7 @@ cc::mojom::MojoCompositorFrameSinkAssociatedPtr compositor_frame_sink_; cc::mojom::DisplayPrivateAssociatedPtr display_private_; - cc::SurfaceId window_manager_surface_id_; + cc::SurfaceInfo window_manager_surface_info_; mojo::Binding<cc::mojom::MojoCompositorFrameSinkClient> binding_;
diff --git a/services/ui/ws/frame_generator_delegate.h b/services/ui/ws/frame_generator_delegate.h index 88b2085..03fbcd04 100644 --- a/services/ui/ws/frame_generator_delegate.h +++ b/services/ui/ws/frame_generator_delegate.h
@@ -10,8 +10,6 @@ class FrameGeneratorDelegate { public: - // Returns the root window of the active user. - virtual ServerWindow* GetActiveRootWindow() = 0; virtual bool IsInHighContrastMode() = 0; protected:
diff --git a/services/ui/ws/frame_generator_unittest.cc b/services/ui/ws/frame_generator_unittest.cc index bb30aa8..27e2230 100644 --- a/services/ui/ws/frame_generator_unittest.cc +++ b/services/ui/ws/frame_generator_unittest.cc
@@ -71,17 +71,20 @@ }; void FrameGeneratorTest::DrawWindow(cc::RenderPass* pass) { - frame_generator_->DrawWindow(pass, root_window_.get()); + cc::SurfaceId surface_id(cc::FrameSinkId(5, 5), + cc::LocalFrameId(1u, kArbitraryToken)); + frame_generator_->window_manager_surface_info_ = + cc::SurfaceInfo(surface_id, 2, gfx::Size(2, 2)); + frame_generator_->DrawWindow(pass); } void FrameGeneratorTest::SetUp() { testing::Test::SetUp(); - frame_generator_delegate_ = - base::MakeUnique<TestFrameGeneratorDelegate>(root_window_.get()); + frame_generator_delegate_ = base::MakeUnique<TestFrameGeneratorDelegate>(); PlatformDisplayInitParams init_params; frame_generator_ = base::MakeUnique<FrameGenerator>( frame_generator_delegate_.get(), root_window_.get()); - frame_generator_->set_device_scale_factor( + frame_generator_->SetDeviceScaleFactor( init_params.metrics.device_scale_factor); InitWindow(root_window()); }
diff --git a/services/ui/ws/platform_display_default.cc b/services/ui/ws/platform_display_default.cc index ba50d30..c9f1b97 100644 --- a/services/ui/ws/platform_display_default.cc +++ b/services/ui/ws/platform_display_default.cc
@@ -38,7 +38,7 @@ frame_generator_(new FrameGenerator(this, init_params.root_window)), metrics_(init_params.metrics), widget_(gfx::kNullAcceleratedWidget) { - frame_generator_->set_device_scale_factor( + frame_generator_->SetDeviceScaleFactor( init_params.metrics.device_scale_factor); } @@ -149,7 +149,7 @@ } metrics_ = metrics; - frame_generator_->set_device_scale_factor(metrics_.device_scale_factor); + frame_generator_->SetDeviceScaleFactor(metrics_.device_scale_factor); return true; } @@ -255,10 +255,6 @@ void PlatformDisplayDefault::OnActivationChanged(bool active) {} -ServerWindow* PlatformDisplayDefault::GetActiveRootWindow() { - return delegate_->GetActiveRootWindow(); -} - bool PlatformDisplayDefault::IsInHighContrastMode() { return delegate_ ? delegate_->IsInHighContrastMode() : false; }
diff --git a/services/ui/ws/platform_display_default.h b/services/ui/ws/platform_display_default.h index f0f5326..ca1b7d5 100644 --- a/services/ui/ws/platform_display_default.h +++ b/services/ui/ws/platform_display_default.h
@@ -69,7 +69,6 @@ void OnActivationChanged(bool active) override; // FrameGeneratorDelegate: - ServerWindow* GetActiveRootWindow() override; bool IsInHighContrastMode() override; const int64_t display_id_;
diff --git a/services/ui/ws/platform_display_delegate.h b/services/ui/ws/platform_display_delegate.h index 808717bb..0358573 100644 --- a/services/ui/ws/platform_display_delegate.h +++ b/services/ui/ws/platform_display_delegate.h
@@ -28,9 +28,6 @@ // Returns the root window of this display. virtual ServerWindow* GetRootWindow() = 0; - // Returns the root window of the active user. - virtual ServerWindow* GetActiveRootWindow() = 0; - // Called once when the AcceleratedWidget is available for drawing. virtual void OnAcceleratedWidgetAvailable() = 0;
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc index c89d695..1506bdc 100644 --- a/services/ui/ws/test_utils.cc +++ b/services/ui/ws/test_utils.cc
@@ -154,16 +154,10 @@ // TestFrameGeneratorDelegate ------------------------------------------------- -TestFrameGeneratorDelegate::TestFrameGeneratorDelegate( - ServerWindow* root_window) - : root_window_(root_window) {} +TestFrameGeneratorDelegate::TestFrameGeneratorDelegate() {} TestFrameGeneratorDelegate::~TestFrameGeneratorDelegate() {} -ServerWindow* TestFrameGeneratorDelegate::GetActiveRootWindow() { - return root_window_; -} - bool TestFrameGeneratorDelegate::IsInHighContrastMode() { return false; }
diff --git a/services/ui/ws/test_utils.h b/services/ui/ws/test_utils.h index 0b323b9..43ce2a55 100644 --- a/services/ui/ws/test_utils.h +++ b/services/ui/ws/test_utils.h
@@ -285,16 +285,12 @@ // A stub implementation of FrameGeneratorDelegate. class TestFrameGeneratorDelegate : public FrameGeneratorDelegate { public: - TestFrameGeneratorDelegate(ServerWindow* root_window); + TestFrameGeneratorDelegate(); ~TestFrameGeneratorDelegate() override; // FrameGeneratorDelegate: - ServerWindow* GetActiveRootWindow() override; bool IsInHighContrastMode() override; - private: - ServerWindow* root_window_; - DISALLOW_COPY_AND_ASSIGN(TestFrameGeneratorDelegate); };
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index b41585f..c4758a5 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -787,10 +787,11 @@ // FrameGenerator will add an appropriate reference for the new surface. DCHECK(display_manager_->GetDisplayContaining(window)); - display_manager_->GetDisplayContaining(window) - ->platform_display() - ->GetFrameGenerator() - ->OnSurfaceCreated(surface_info.id(), window); + auto display = display_manager_->GetDisplayContaining(window); + if (window == display->GetActiveRootWindow()) { + display->platform_display()->GetFrameGenerator()->OnSurfaceCreated( + surface_info); + } // This is only used for testing to observe that a window has a // CompositorFrame.
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 7e7c20a..985e8e5f 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2247,17 +2247,9 @@ crbug.com/664844 media/track/track-cue-rendering-tree-is-removed-properly.html [ Pass Failure ] crbug.com/664844 media/track/track-default-attribute.html [ Pass Failure ] crbug.com/664844 media/track/track-kind-user-preference.html [ Pass Failure ] -crbug.com/664853 virtual/mojo-loading/webexposed/css-properties-as-js-properties.html [ Pass Failure ] -crbug.com/664853 virtual/mojo-loading/webexposed/web-animations-api.html [ Pass Failure ] crbug.com/664855 virtual/scroll_customization/fast/scroll-behavior/main-frame-interrupted-scroll.html [ Pass Failure ] crbug.com/664856 virtual/sharedarraybuffer/fast/workers/worker-gc.html [ Pass Failure ] -crbug.com/583193 inspector-protocol/debugger/stepping-with-blackboxed-ranges.html [ NeedsManualRebaseline ] -crbug.com/583193 inspector/sources/debugger-frameworks/frameworks-jquery.html [ NeedsManualRebaseline ] -crbug.com/583193 inspector/sources/debugger-frameworks/frameworks-steppings.html [ NeedsManualRebaseline ] -crbug.com/583193 inspector/sources/debugger-frameworks/frameworks-skip-step-in.html [ NeedsManualRebaseline ] -crbug.com/583193 inspector/sources/debugger-frameworks/frameworks-step-into-skips-setTimeout.html [ NeedsManualRebaseline ] - # Possible duplicate of crbug.com/665577 # crbug.com/664858 virtual/threaded/fast/scroll-behavior/overflow-scroll-animates.html [ Pass Failure ] # crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/horizontal-smooth-scroll-in-rtl.html [ Pass Failure ] @@ -2265,6 +2257,9 @@ # crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-anchors.html [ Pass Failure ] # crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-vertical-rl-anchors.html [ Pass Failure ] # crbug.com/664858 virtual/threaded/fast/scroll-behavior/smooth-scroll/scroll-during-selection.html [ Pass Failure ] + +crbug.com/684874 virtual/threaded/fast/scroll-behavior/smooth-scroll/scroll-during-selection.html [ Pass Failure ] + # ====== Random order flaky tests end here ====== # ====== Begin of display:contents tests ====== @@ -2338,3 +2333,6 @@ crbug.com/681471 virtual/stable/paint/invalidation/media-audio-no-spurious-repaints.html [ Failure Pass Timeout ] crbug.com/683800 [ Win7 Debug ] external/wpt/selection/ [ Failure Pass ] + +# CQ and Rebaseline-cl for crrev.com/2626973005 does not include this +crbug.com/680407 [ Mac ] fast/forms/select/menulist-appearance-basic.html [ NeedsManualRebaseline ]
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js index 685ab78e..4f7e8a7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
@@ -288,6 +288,16 @@ return InspectorTest.timelineModel().mainThreadEvents().filter(e => e.name === name)[index || 0]; } +InspectorTest.findChildEvent = function(events, parentIndex, name) +{ + var endTime = events[parentIndex].endTime; + for (var i = parentIndex + 1; i < events.length && (!events[i].endTime || events[i].endTime <= endTime); ++i) { + if (events[i].name === name) + return events[i]; + } + return null; +} + InspectorTest.FakeFileReader = function(input, delegate, callback) { this._delegate = delegate;
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-correct-suggestions-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-correct-suggestions-expected.txt index caceac4b..25022c43 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-correct-suggestions-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/console/console-correct-suggestions-expected.txt
@@ -71,18 +71,39 @@ Checking 'shou' Not Found: should not find this +Checking 'myMap.get(' +Found: "first") +Found: "second") +Found: "third") + +Checking 'myMap.get('' +Found: 'first') +Found: 'second') +Found: 'third') + +Checking 'myMap.set('firs' +Found: 'first', + +Checking 'myMap.set(should' +Found: shouldFindThisFunction +Not Found: shouldNotFindThis +Not Found: "shouldNotFindThis") + +Checking 'myMap.delete('' +Found: 'first') +Found: 'second') +Found: 'third') + Checking 'document. bo' Found: body Checking 'document. bo' Found: body -Checking 'document. -bo' +Checking 'document.\nbo' Found: body -Checking 'document. -bo' +Checking 'document.\r\nbo' Found: body Checking 'document [ 'bo'
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-correct-suggestions.html b/third_party/WebKit/LayoutTests/inspector/console/console-correct-suggestions.html index 2dd77ca2..20ee94f 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-correct-suggestions.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-correct-suggestions.html
@@ -12,9 +12,11 @@ } function shouldNotFindThisFunction() { } - +function shouldFindThisFunction() { } window["should not find this"] = true; +var myMap = new Map([['first', 1], ['second', 2], ['third', 3], ['shouldNotFindThis', 4]]); + function test() { var consoleEditor; @@ -31,7 +33,7 @@ function checkExpected(suggestions) { var completions = new Set(suggestions.map(suggestion => suggestion.title)); - var message = "Checking '" + text + "'"; + var message = "Checking '" + text.replace('\n', '\\n').replace('\r', '\\r') + "'"; if (force) message += " forcefully"; InspectorTest.addResult(message); @@ -72,6 +74,11 @@ () => testCompletions("// do", ["document"], false), () => testCompletions('["should', ["shouldNotFindThisFunction"]), () => testCompletions("shou", ["should not find this"]), + () => testCompletions('myMap.get(', ['"first")', '"second")', '"third")']), + () => testCompletions('myMap.get(\'', ['\'first\')', '\'second\')', '\'third\')']), + () => testCompletions('myMap.set(\'firs', ['\'first\', ']), + () => testCompletions('myMap.set(should', ['shouldFindThisFunction', 'shouldNotFindThis', '\"shouldNotFindThis\")']), + () => testCompletions('myMap.delete(\'', ['\'first\')', '\'second\')', '\'third\')']), () => testCompletions("document. bo", ["body"]), () => testCompletions("document.\tbo", ["body"]), () => testCompletions("document.\nbo", ["body"]),
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-fired-from-eval-call-site.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-fired-from-eval-call-site.html index d068362..e11b4e5 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-fired-from-eval-call-site.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-fired-from-eval-call-site.html
@@ -36,8 +36,8 @@ for (let i = 0; i < events.length; ++i) { if (events[i].name !== TimelineModel.TimelineModel.RecordType.TimerFire) continue; - var nextEvent = events[i + 1]; - var fnCallSite = nextEvent.args["data"]; + var functionCallChild = InspectorTest.findChildEvent(events, i, TimelineModel.TimelineModel.RecordType.FunctionCall); + var fnCallSite = functionCallChild.args["data"]; InspectorTest.addResult(`${events[i].name} ${fnCallSite.url}:${fnCallSite.lineNumber + 1}`); } InspectorTest.completeTest();
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-start-error.html b/third_party/WebKit/LayoutTests/presentation/presentation-start-error.html new file mode 100644 index 0000000..6cd746e --- /dev/null +++ b/third_party/WebKit/LayoutTests/presentation/presentation-start-error.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<body> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="../resources/mojo-helpers.js"></script> +<script src="resources/presentation-service-mock.js"></script> +<button>click me</button> +<script> + +var button = document.querySelector('button'); + +async_test(t => { + presentationServiceMock.then(service => { + service.startSession = urls => { + return Promise.resolve({ + sessionInfo: null, + error: { + error_type: 3 /* PresentationErrorType.PREVIOUS_START_IN_PROGRESS */, + message: 'Previous start in progress' + } + }); + }; + // This is receiving the user gesture and runs the callback. + waitForClick(() => { + var request = new PresentationRequest("http://example.com"); + request.start().catch(t.step_func_done(ex => { + assert_equals(ex.name, 'OperationError'); + })); + }, button); + }); +}, "Test that the PresentationRequest.start() rejects with OperationError if PresentationService reports PREVIOUS_START_IN_PROGRESS error"); + +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/presentation/presentation-start.html b/third_party/WebKit/LayoutTests/presentation/presentation-start.html index 1f824ea..f23de70 100644 --- a/third_party/WebKit/LayoutTests/presentation/presentation-start.html +++ b/third_party/WebKit/LayoutTests/presentation/presentation-start.html
@@ -11,15 +11,15 @@ var button = document.querySelector('button'); var testPresentationRequestStart = function(t, requestArgument, connectionUrl) { - presentationServiceMock.then(t.step_func(service => { + presentationServiceMock.then(service => { // This is receiving the user gesture and runs the callback. - waitForClick(t.step_func(_ => { + waitForClick(() => { new PresentationRequest(requestArgument).start().then( t.step_func_done(connection => { assert_equals(connection.url, connectionUrl); })); - }), button); - })); + }, button); + }); }; async_test(t => {
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn index cc40d0e..16517766f 100644 --- a/third_party/WebKit/Source/core/css/BUILD.gn +++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -378,6 +378,7 @@ "properties/CSSPropertyAPIPaintOrder.cpp", "properties/CSSPropertyAPIPaintStroke.cpp", "properties/CSSPropertyAPIQuotes.cpp", + "properties/CSSPropertyAPIRadius.cpp", "properties/CSSPropertyAPIRotate.cpp", "properties/CSSPropertyAPIScale.cpp", "properties/CSSPropertyAPIScrollSnapCoordinate.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.in b/third_party/WebKit/Source/core/css/CSSProperties.in index b621586..1866879 100644 --- a/third_party/WebKit/Source/core/css/CSSProperties.in +++ b/third_party/WebKit/Source/core/css/CSSProperties.in
@@ -346,8 +346,8 @@ resize custom_value right typedom_types=[Length], keywords=[auto], supports_percentage, interpolable, initial=initialOffset, converter=convertLengthOrAuto r interpolable, svg, converter=convertLength -rx interpolable, svg, converter=convertLengthOrAuto -ry interpolable, svg, converter=convertLengthOrAuto +rx interpolable, svg, converter=convertLengthOrAuto, api_class=CSSPropertyAPIRadius +ry interpolable, svg, converter=convertLengthOrAuto, api_class=CSSPropertyAPIRadius scroll-behavior runtime_flag=CSSOMSmoothScroll, type_name=ScrollBehavior scroll-snap-type runtime_flag=CSSScrollSnapPoints, type_name=ScrollSnapType scroll-snap-points-x runtime_flag=CSSScrollSnapPoints, converter=convertSnapPoints
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp index 1c6eb882..a757e70 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1163,13 +1163,6 @@ return consumeLengthOrPercent(range, SVGAttributeMode, ValueRangeAll); } -static CSSValue* consumeRxOrRy(CSSParserTokenRange& range) { - if (range.peek().id() == CSSValueAuto) - return consumeIdent(range); - return consumeLengthOrPercent(range, SVGAttributeMode, ValueRangeAll, - UnitlessQuirk::Forbid); -} - static CSSValue* consumePerspective(CSSParserTokenRange& range, const CSSParserContext* context, CSSPropertyID unresolvedProperty) { @@ -2275,9 +2268,6 @@ case CSSPropertyR: return consumeLengthOrPercent(m_range, SVGAttributeMode, ValueRangeAll, UnitlessQuirk::Forbid); - case CSSPropertyRx: - case CSSPropertyRy: - return consumeRxOrRy(m_range); case CSSPropertyPerspective: return consumePerspective(m_range, m_context, unresolvedProperty); case CSSPropertyScrollSnapPointsX:
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIRadius.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIRadius.cpp new file mode 100644 index 0000000..ce9b83e --- /dev/null +++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIRadius.cpp
@@ -0,0 +1,21 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "core/css/properties/CSSPropertyAPIRadius.h" + +#include "core/css/parser/CSSPropertyParserHelpers.h" + +namespace blink { + +const CSSValue* CSSPropertyAPIRadius::parseSingleValue( + CSSParserTokenRange& range, + const CSSParserContext* context) { + if (range.peek().id() == CSSValueAuto) + return CSSPropertyParserHelpers::consumeIdent(range); + return CSSPropertyParserHelpers::consumeLengthOrPercent( + range, SVGAttributeMode, ValueRangeAll, + CSSPropertyParserHelpers::UnitlessQuirk::Forbid); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/DocumentTest.cpp b/third_party/WebKit/Source/core/dom/DocumentTest.cpp index df59289..d9e2f2f 100644 --- a/third_party/WebKit/Source/core/dom/DocumentTest.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentTest.cpp
@@ -123,10 +123,6 @@ return m_contextDestroyedCalledCounter; } - const HeapVector<Member<const Element>>& attributeChangedElements() const { - return m_attributeChangedElements; - } - const HeapVector<Member<const ContainerNode>>& childrenChangedNodes() const { return m_childrenChangedNodes; } @@ -162,7 +158,6 @@ private: // Implement |SynchronousMutationObserver| member functions. void contextDestroyed(Document*) final; - void didChangeAttribute(const Element&) final; void didChangeChildren(const ContainerNode&) final; void didMergeTextNodes(const Text&, const NodeWithIndex&, unsigned) final; void didMoveTreeToNewDocument(const Node& root) final; @@ -175,7 +170,6 @@ void nodeWillBeRemoved(Node&) final; int m_contextDestroyedCalledCounter = 0; - HeapVector<Member<const Element>> m_attributeChangedElements; HeapVector<Member<const ContainerNode>> m_childrenChangedNodes; HeapVector<Member<MergeTextNodesRecord>> m_mergeTextNodesRecords; HeapVector<Member<const Node>> m_moveTreeToNewDocumentNodes; @@ -196,11 +190,6 @@ ++m_contextDestroyedCalledCounter; } -void TestSynchronousMutationObserver::didChangeAttribute( - const Element& element) { - m_attributeChangedElements.push_back(&element); -} - void TestSynchronousMutationObserver::didChangeChildren( const ContainerNode& container) { m_childrenChangedNodes.push_back(&container); @@ -242,7 +231,6 @@ } DEFINE_TRACE(TestSynchronousMutationObserver) { - visitor->trace(m_attributeChangedElements); visitor->trace(m_childrenChangedNodes); visitor->trace(m_mergeTextNodesRecords); visitor->trace(m_moveTreeToNewDocumentNodes); @@ -517,24 +505,6 @@ EXPECT_EQ(1, observer.countContextDestroyedCalled()); } -TEST_F(DocumentTest, SynchronousMutationNotifierChangeAttribute) { - auto& observer = *new TestSynchronousMutationObserver(document()); - Element* divNode = document().createElement("div"); - document().body()->appendChild(divNode); - divNode->setAttribute(HTMLNames::classAttr, "foo"); - - ASSERT_EQ(1u, observer.attributeChangedElements().size()); - EXPECT_EQ(divNode, observer.attributeChangedElements()[0]); - - divNode->setAttribute(HTMLNames::classAttr, "bar"); - ASSERT_EQ(2u, observer.attributeChangedElements().size()); - EXPECT_EQ(divNode, observer.attributeChangedElements()[1]); - - divNode->removeAttribute(HTMLNames::classAttr); - ASSERT_EQ(3u, observer.attributeChangedElements().size()); - EXPECT_EQ(divNode, observer.attributeChangedElements()[2]); -} - TEST_F(DocumentTest, SynchronousMutationNotifieAppendChild) { auto& observer = *new TestSynchronousMutationObserver(document()); document().body()->appendChild(document().createTextNode("a123456789"));
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index ee87d5e..77e51203 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -1297,7 +1297,6 @@ parseAttribute(params); document().incDOMTreeVersion(); - document().notifyChangeAttribute(*this); if (name == HTMLNames::idAttr) { AtomicString oldId = elementData()->idForStyleResolution();
diff --git a/third_party/WebKit/Source/core/dom/SynchronousMutationNotifier.cpp b/third_party/WebKit/Source/core/dom/SynchronousMutationNotifier.cpp index 59474ec..506cdb9 100644 --- a/third_party/WebKit/Source/core/dom/SynchronousMutationNotifier.cpp +++ b/third_party/WebKit/Source/core/dom/SynchronousMutationNotifier.cpp
@@ -11,12 +11,6 @@ SynchronousMutationNotifier::SynchronousMutationNotifier() = default; -void SynchronousMutationNotifier::notifyChangeAttribute( - const Element& element) { - for (SynchronousMutationObserver* observer : m_observers) - observer->didChangeAttribute(element); -} - void SynchronousMutationNotifier::notifyChangeChildren( const ContainerNode& container) { for (SynchronousMutationObserver* observer : m_observers)
diff --git a/third_party/WebKit/Source/core/dom/SynchronousMutationNotifier.h b/third_party/WebKit/Source/core/dom/SynchronousMutationNotifier.h index 2c1f4b2..813f209 100644 --- a/third_party/WebKit/Source/core/dom/SynchronousMutationNotifier.h +++ b/third_party/WebKit/Source/core/dom/SynchronousMutationNotifier.h
@@ -14,7 +14,6 @@ class CharacterData; class ContainerNode; class Document; -class Element; class Node; class NodeWithIndex; class SynchronousMutationObserver; @@ -23,7 +22,8 @@ class CORE_EXPORT SynchronousMutationNotifier : public LifecycleNotifier<Document, SynchronousMutationObserver> { public: - void notifyChangeAttribute(const Element&); + // TODO(yosin): We will have |notifyXXX()| functions defined in + // |SynchronousMutationObserver|. void notifyChangeChildren(const ContainerNode&); void notifyMergeTextNodes(const Text& mergedNode, const NodeWithIndex& nodeToBeRemovedWithIndex,
diff --git a/third_party/WebKit/Source/core/dom/SynchronousMutationObserver.cpp b/third_party/WebKit/Source/core/dom/SynchronousMutationObserver.cpp index 2ceae32..1840e8b 100644 --- a/third_party/WebKit/Source/core/dom/SynchronousMutationObserver.cpp +++ b/third_party/WebKit/Source/core/dom/SynchronousMutationObserver.cpp
@@ -12,7 +12,6 @@ SynchronousMutationObserver::SynchronousMutationObserver() : LifecycleObserver(nullptr) {} -void SynchronousMutationObserver::didChangeAttribute(const Element&) {} void SynchronousMutationObserver::didChangeChildren(const ContainerNode&) {} void SynchronousMutationObserver::didMergeTextNodes(const Text&, const NodeWithIndex&,
diff --git a/third_party/WebKit/Source/core/dom/SynchronousMutationObserver.h b/third_party/WebKit/Source/core/dom/SynchronousMutationObserver.h index 8d4d17f..ad0311ca 100644 --- a/third_party/WebKit/Source/core/dom/SynchronousMutationObserver.h +++ b/third_party/WebKit/Source/core/dom/SynchronousMutationObserver.h
@@ -14,7 +14,6 @@ class CharacterData; class ContainerNode; class Document; -class Element; class NodeWithIndex; class Text; @@ -41,9 +40,6 @@ // - didInsertText(Node*, unsigned offset, unsigned length); // - didRemoveText(Node*, unsigned offset, unsigned length); - // Called just after attribute is changed. - virtual void didChangeAttribute(const Element&); - // Called after child nodes changed. virtual void didChangeChildren(const ContainerNode&);
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp index d5e4f34..19c6471a 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -929,11 +929,6 @@ return nullptr; } -bool nodeIsUserSelectAll(const Node* node) { - return node && node->layoutObject() && - node->layoutObject()->style()->userSelect() == SELECT_ALL; -} - EUserSelect usedValueOfUserSelect(const Node& node) { if (node.isHTMLElement() && toHTMLElement(node).isTextControl()) return SELECT_TEXT;
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.h b/third_party/WebKit/Source/core/editing/EditingUtilities.h index 0b334ec5..563e02d 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.h +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.h
@@ -187,7 +187,6 @@ CORE_EXPORT bool areIdenticalElements(const Node&, const Node&); bool isNonTableCellHTMLBlockElement(const Node*); bool isBlockFlowElement(const Node&); -bool nodeIsUserSelectAll(const Node*); EUserSelect usedValueOfUserSelect(const Node&); bool isTextSecurityNode(const Node*); CORE_EXPORT TextDirection directionOfEnclosingBlock(const Position&);
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp index 6c84cce7..7366ca2 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -1743,6 +1743,11 @@ return honorEditingBoundaryAtOrAfter(next, c.deepEquivalent()); } +static bool nodeIsUserSelectAll(const Node* node) { + return node && node->layoutObject() && + node->layoutObject()->style()->userSelect() == SELECT_ALL; +} + template <typename Strategy> PositionTemplate<Strategy> startOfParagraphAlgorithm( const PositionTemplate<Strategy>& position,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc index a9880e4..bd10701 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -179,6 +179,7 @@ } // namespace NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( + LayoutObject* layout_object, PassRefPtr<const ComputedStyle> style, NGBlockNode* first_child, NGConstraintSpace* constraint_space, @@ -188,6 +189,8 @@ first_child_(first_child), constraint_space_(constraint_space), break_token_(break_token), + builder_(new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox, + layout_object)), is_fragment_margin_strut_block_start_updated_(false) { DCHECK(style_); } @@ -261,7 +264,6 @@ space_builder_->SetPercentageResolutionSize( NGLogicalSize(adjusted_inline_size, adjusted_block_size)); - builder_ = new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox); builder_->SetDirection(constraint_space_->Direction()); builder_->SetWritingMode(constraint_space_->WritingMode()); builder_->SetInlineSize(inline_size).SetBlockSize(block_size); @@ -306,8 +308,7 @@ ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_); builder_->SetBlockSize(block_size); - HeapLinkedHashSet<WeakMember<NGBlockNode>> positioned_out_of_flow_children = - LayoutOutOfFlowChildren(); + LayoutOutOfFlowChildren(); builder_->SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_); @@ -316,9 +317,6 @@ NGPhysicalFragment* fragment = builder_->ToBoxFragment(); - for (auto& node : positioned_out_of_flow_children) - node->PositionUpdated(); - return fragment; } @@ -341,8 +339,7 @@ builder_->AddChild(fragment, fragment_offset); } -HeapLinkedHashSet<WeakMember<NGBlockNode>> -NGBlockLayoutAlgorithm::LayoutOutOfFlowChildren() { +void NGBlockLayoutAlgorithm::LayoutOutOfFlowChildren() { HeapLinkedHashSet<WeakMember<NGBlockNode>> out_of_flow_candidates; Vector<NGStaticPosition> out_of_flow_candidate_positions; builder_->GetAndClearOutOfFlowDescendantCandidates( @@ -350,7 +347,6 @@ Member<NGOutOfFlowLayoutPart> out_of_flow_layout = new NGOutOfFlowLayoutPart(&Style(), builder_->Size()); - HeapLinkedHashSet<WeakMember<NGBlockNode>> positioned_children; size_t candidate_positions_index = 0; for (auto& child : out_of_flow_candidates) { @@ -362,13 +358,11 @@ NGLogicalOffset offset; out_of_flow_layout->Layout(*child, static_position, &fragment, &offset); // TODO(atotic) Need to adjust size of overflow rect per spec. - positioned_children.add(child); builder_->AddChild(fragment, offset); } else { builder_->AddOutOfFlowDescendant(child, static_position); } } - return positioned_children; } bool NGBlockLayoutAlgorithm::ProceedToNextUnfinishedSibling(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h index 1524af04..b0599801 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -29,12 +29,14 @@ class CORE_EXPORT NGBlockLayoutAlgorithm : public NGLayoutAlgorithm { public: // Default constructor. + // @param layout_object The layout object associated with this block. // @param style Style reference of the block that is being laid out. // @param first_child Our first child; the algorithm will use its NextSibling // method to access all the children. // @param space The constraint space which the algorithm should generate a // fragment within. - NGBlockLayoutAlgorithm(PassRefPtr<const ComputedStyle>, + NGBlockLayoutAlgorithm(LayoutObject* layout_object, + PassRefPtr<const ComputedStyle> style, NGBlockNode* first_child, NGConstraintSpace* space, NGBreakToken* break_token = nullptr); @@ -51,7 +53,7 @@ // Creates a new constraint space for the current child. NGConstraintSpace* CreateConstraintSpaceForCurrentChild(); void FinishCurrentChildLayout(NGFragment* fragment); - HeapLinkedHashSet<WeakMember<NGBlockNode>> LayoutOutOfFlowChildren(); + void LayoutOutOfFlowChildren(); // Proceed to the next sibling that still needs layout. //
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc index d5189a5..ff60378 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -4,20 +4,28 @@ #include "core/layout/ng/ng_block_layout_algorithm.h" +#include "core/dom/NodeComputedStyle.h" +#include "core/dom/TagCollection.h" +#include "core/layout/ng/layout_ng_block_flow.h" #include "core/layout/ng/ng_block_node.h" #include "core/layout/ng/ng_constraint_space.h" #include "core/layout/ng/ng_constraint_space_builder.h" +#include "core/layout/ng/ng_floating_object.h" #include "core/layout/ng/ng_length_utils.h" +#include "core/layout/LayoutTestHelper.h" #include "core/layout/ng/ng_physical_box_fragment.h" #include "core/layout/ng/ng_physical_fragment.h" #include "core/layout/ng/ng_units.h" -#include "core/layout/LayoutTestHelper.h" +#include "testing/gmock/include/gmock/gmock.h" #include "core/style/ComputedStyle.h" #include "testing/gtest/include/gtest/gtest.h" namespace blink { namespace { +using testing::ElementsAre; +using testing::Pointee; + NGConstraintSpace* ConstructConstraintSpace(NGWritingMode writing_mode, TextDirection direction, NGLogicalSize size, @@ -50,19 +58,32 @@ NGBlockNode parent(style_.get()); parent.SetFirstChild(first_child); - NGBlockLayoutAlgorithm algorithm(style_.get(), first_child, space); + NGBlockLayoutAlgorithm algorithm(/* layout_object */ nullptr, style_.get(), + first_child, space); NGPhysicalFragment* fragment = algorithm.Layout(); return toNGPhysicalBoxFragment(fragment); } + std::pair<NGPhysicalBoxFragment*, NGConstraintSpace*> + RunBlockLayoutAlgorithmForElement(Element* element) { + LayoutNGBlockFlow* block_flow = + toLayoutNGBlockFlow(element->layoutObject()); + NGConstraintSpace* space = + NGConstraintSpace::CreateFromLayoutObject(*block_flow); + NGPhysicalBoxFragment* fragment = RunBlockLayoutAlgorithm( + space, new NGBlockNode(element->layoutObject()->slowFirstChild())); + return std::make_pair(fragment, space); + } + MinAndMaxContentSizes RunComputeMinAndMax(NGBlockNode* first_child) { // The constraint space is not used for min/max computation, but we need // it to create the algorithm. NGConstraintSpace* space = ConstructConstraintSpace(kHorizontalTopBottom, TextDirection::kLtr, NGLogicalSize(LayoutUnit(), LayoutUnit())); - NGBlockLayoutAlgorithm algorithm(style_.get(), first_child, space); + NGBlockLayoutAlgorithm algorithm(/* layout_object */ nullptr, style_.get(), + first_child, space); MinAndMaxContentSizes sizes; EXPECT_TRUE(algorithm.ComputeMinAndMaxContentSizes(&sizes)); return sizes; @@ -167,237 +188,352 @@ // Verifies the collapsing margins case for the next pair: // - top margin of a box and top margin of its first in-flow child. -// -// Test case's HTML representation: -// <div style="margin-top: 20px; height: 50px;"> <!-- DIV1 --> -// <div style="margin-top: 10px"></div> <!-- DIV2 --> -// </div> -// -// Expected: -// - Empty margin strut of the fragment that establishes new formatting context -// - Margins are collapsed resulting a single margin 20px = max(20px, 10px) -// - The top offset of DIV2 == 20px -TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase1) { - const int kHeight = 50; - const int kDiv1MarginTop = 20; - const int kDiv2MarginTop = 10; +// Verifies that floats are positioned at the top of the first child that can +// determine its position after margins collapsed. +// TODO(glebl): Enable with new the float/margins collapsing algorithm. +TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_CollapsingMarginsCase1WithFloats) { + setBodyInnerHTML( + "<style>" + " #container {" + " height: 200px;" + " width: 200px;" + " margin-top: 10px;" + " padding: 0 7px;" + " background-color: red;" + " }" + " #first-child {" + " margin-top: 20px;" + " height: 10px;" + " background-color: blue;" + " }" + " #float-child-left {" + " float: left;" + " height: 10px;" + " width: 10px;" + " padding: 10px;" + " margin: 10px;" + " background-color: green;" + " }" + " #float-child-right {" + " float: right;" + " height: 30px;" + " width: 30px;" + " background-color: pink;" + " }" + "</style>" + "<div id='container'>" + " <div id='float-child-left'></div>" + " <div id='float-child-right'></div>" + " <div id='first-child'></div>" + "</div>"); - // DIV1 - RefPtr<ComputedStyle> div1_style = ComputedStyle::create(); - div1_style->setHeight(Length(kHeight, Fixed)); - div1_style->setMarginTop(Length(kDiv1MarginTop, Fixed)); - NGBlockNode* div1 = new NGBlockNode(div1_style.get()); + // ** Run LayoutNG algorithm ** + NGConstraintSpace* space; + NGPhysicalBoxFragment* fragment; + std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( + document().getElementsByTagName("html")->item(0)); + ASSERT_EQ(fragment->Children().size(), 1UL); + auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0]); + // 20 = max(first child's margin top, containers's margin top) + int body_top_offset = 20; + EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->TopOffset()); + // 8 = body's margin + int body_left_offset = 8; + EXPECT_THAT(LayoutUnit(body_left_offset), body_fragment->LeftOffset()); + ASSERT_EQ(1UL, body_fragment->Children().size()); + auto* container_fragment = + toNGPhysicalBoxFragment(body_fragment->Children()[0]); + // 0 = collapsed with body's margin + EXPECT_THAT(LayoutUnit(0), container_fragment->TopOffset()); + ASSERT_EQ(1UL, container_fragment->Children().size()); + auto* first_child_fragment = + toNGPhysicalBoxFragment(container_fragment->Children()[0]); + // 0 = collapsed with container's margin + EXPECT_THAT(LayoutUnit(0), first_child_fragment->TopOffset()); - // DIV2 - RefPtr<ComputedStyle> div2_style = ComputedStyle::create(); - div2_style->setMarginTop(Length(kDiv2MarginTop, Fixed)); - NGBlockNode* div2 = new NGBlockNode(div2_style.get()); + // ** Verify layout tree ** + Element* first_child = document().getElementById("first-child"); + int first_child_block_offset = body_top_offset; + EXPECT_EQ(first_child_block_offset, first_child->offsetTop()); - div1->SetFirstChild(div2); + // float-child-left is positioned at the top edge of the container padding box + Element* float_child_left = document().getElementById("float-child-left"); + // 30 = std::max(first-child's margin 20, container's margin 10, + // body's margin 8) + float-child-left's margin 10 + int float_child_left_block_offset = 30; + EXPECT_EQ(float_child_left_block_offset, float_child_left->offsetTop()); - auto* space = - NGConstraintSpaceBuilder(kHorizontalTopBottom) - .SetAvailableSize(NGLogicalSize(LayoutUnit(100), NGSizeIndefinite)) - .SetPercentageResolutionSize( - NGLogicalSize(LayoutUnit(100), NGSizeIndefinite)) - .SetTextDirection(TextDirection::kLtr) - .SetIsNewFormattingContext(true) - .ToConstraintSpace(); - NGPhysicalBoxFragment* frag = RunBlockLayoutAlgorithm(space, div1); + // float-child-right is positioned at the top edge of container padding box + Element* float_child_right = document().getElementById("float-child-right"); + // Should be equal to first_child_block_offset + // 20 = std::max(first-child's margin 20, container's margin 10, + // body's margin 8) + int float_child_right_block_offset = 20; + EXPECT_EQ(float_child_right_block_offset, float_child_right->offsetTop()); - EXPECT_TRUE(frag->MarginStrut().IsEmpty()); - ASSERT_EQ(frag->Children().size(), 1UL); - const NGPhysicalBoxFragment* div2_fragment = - static_cast<const NGPhysicalBoxFragment*>(frag->Children()[0].get()); - EXPECT_EQ(NGDeprecatedMarginStrut({LayoutUnit(kDiv2MarginTop)}), - div2_fragment->MarginStrut()); - EXPECT_EQ(kDiv1MarginTop, div2_fragment->TopOffset()); + // ** Verify exclusions ** + // float-child-left's height(10) + padding(2x10) + margin(2x10) = 50px + NGLogicalSize exclusion1_size = {LayoutUnit(50), LayoutUnit(50)}; + // float-child-left's inline offset + // 15 = body's margin(8) + container's inline padding(7) + NGLogicalOffset exclusion1_offset = {LayoutUnit(15), + LayoutUnit(first_child_block_offset)}; + NGLogicalRect exclusion1_rect = {exclusion1_offset, exclusion1_size}; + NGExclusion expected_exclusion1 = {exclusion1_rect, NGExclusion::kFloatLeft}; + + NGLogicalSize exclusion2_size = {LayoutUnit(30), LayoutUnit(30)}; + // float-child-right's inline offset + // right_float_offset = 200 container's width - right float width 30 = 170 + // 185 = body's margin(8) + right_float_offset(170) + container's padding(7) + NGLogicalOffset exclusion2_offset = {LayoutUnit(185), + LayoutUnit(first_child_block_offset)}; + NGLogicalRect exclusion2_rect = {exclusion2_offset, exclusion2_size}; + NGExclusion expected_exclusion2 = {exclusion2_rect, NGExclusion::kFloatRight}; + + EXPECT_THAT(space->Exclusions()->storage, + (ElementsAre(Pointee(expected_exclusion1), + Pointee(expected_exclusion2)))); } // Verifies the collapsing margins case for the next pair: // - bottom margin of box and top margin of its next in-flow following sibling. -// -// Test case's HTML representation: -// <div style="margin-bottom: 20px; height: 50px;"> <!-- DIV1 --> -// <div style="margin-bottom: -15px"></div> <!-- DIV2 --> -// <div></div> <!-- DIV3 --> -// </div> -// <div></div> <!-- DIV4 --> -// <div style="margin-top: 10px; height: 50px;"> <!-- DIV5 --> -// <div></div> <!-- DIV6 --> -// <div style="margin-top: -30px"></div> <!-- DIV7 --> -// </div> -// -// Expected: -// Margins are collapsed resulting an overlap -// -10px = max(20px, 10px) - max(abs(-15px), abs(-30px)) -// between DIV2 and DIV3. Zero-height blocks are ignored. -TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase2) { - const int kHeight = 50; - const int kDiv1MarginBottom = 20; - const int kDiv2MarginBottom = -15; - const int kDiv5MarginTop = 10; - const int kDiv7MarginTop = -30; - const int kExpectedCollapsedMargin = -10; +// - top and bottom margins of a box that does not establish a new block +// formatting context and that has zero computed 'min-height', zero or 'auto' +// computed 'height', and no in-flow children +// TODO(glebl): Enable with new the float/margins collapsing algorithm. +TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_CollapsingMarginsCase2WithFloats) { + setBodyInnerHTML( + "<style>" + "#first-child {" + " background-color: red;" + " height: 50px;" + " margin-bottom: 20px;" + "}" + "#float-between-empties {" + " background-color: green;" + " float: left;" + " height: 30px;" + " width: 30px;" + "}" + "#float-between-nonempties {" + " background-color: lightgreen;" + " float: left;" + " height: 40px;" + " width: 40px;" + "}" + "#float-top-align {" + " background-color: seagreen;" + " float: left;" + " height: 50px;" + " width: 50px;" + "}" + "#second-child {" + " background-color: blue;" + " height: 50px;" + " margin-top: 10px;" + "}" + "</style>" + "<div id='first-child'>" + " <div id='empty1' style='margin-bottom: -15px'></div>" + " <div id='float-between-empties'></div>" + " <div id='empty2'></div>" + "</div>" + "<div id='float-between-nonempties'></div>" + "<div id='second-child'>" + " <div id='float-top-align'></div>" + " <div id='empty3'></div>" + " <div id='empty4' style='margin-top: -30px'></div>" + "</div>" + "<div id='empty5'></div>"); - // DIV1 - RefPtr<ComputedStyle> div1_style = ComputedStyle::create(); - div1_style->setHeight(Length(kHeight, Fixed)); - div1_style->setMarginBottom(Length(kDiv1MarginBottom, Fixed)); - NGBlockNode* div1 = new NGBlockNode(div1_style.get()); + // ** Run LayoutNG algorithm ** + NGConstraintSpace* space; + NGPhysicalBoxFragment* fragment; + std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( + document().getElementsByTagName("html")->item(0)); - // DIV2 - RefPtr<ComputedStyle> div2_style = ComputedStyle::create(); - div2_style->setMarginBottom(Length(kDiv2MarginBottom, Fixed)); - NGBlockNode* div2 = new NGBlockNode(div2_style.get()); + auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0]); + // -7 = empty1's margin(-15) + body's margin(8) + int body_top_offset = -7; + EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->TopOffset()); + int body_left_offset = 8; + EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->TopOffset()); + ASSERT_EQ(3UL, body_fragment->Children().size()); - // Empty DIVs: DIV3, DIV4, DIV6 - NGBlockNode* div3 = new NGBlockNode(ComputedStyle::create().get()); - NGBlockNode* div4 = new NGBlockNode(ComputedStyle::create().get()); - NGBlockNode* div6 = new NGBlockNode(ComputedStyle::create().get()); + auto* first_child_fragment = + toNGPhysicalBoxFragment(body_fragment->Children()[0]); + EXPECT_THAT(LayoutUnit(), first_child_fragment->TopOffset()); - // DIV5 - RefPtr<ComputedStyle> div5_style = ComputedStyle::create(); - div5_style->setHeight(Length(kHeight, Fixed)); - div5_style->setMarginTop(Length(kDiv5MarginTop, Fixed)); - NGBlockNode* div5 = new NGBlockNode(div5_style.get()); + auto* second_child_fragment = + toNGPhysicalBoxFragment(body_fragment->Children()[1]); + // 40 = first_child's height(50) - margin's collapsing result(10) + int second_child_block_offset = 40; + EXPECT_THAT(LayoutUnit(second_child_block_offset), + second_child_fragment->TopOffset()); - // DIV7 - RefPtr<ComputedStyle> div7_style = ComputedStyle::create(); - div7_style->setMarginTop(Length(kDiv7MarginTop, Fixed)); - NGBlockNode* div7 = new NGBlockNode(div7_style.get()); + auto* empty5_fragment = toNGPhysicalBoxFragment(body_fragment->Children()[2]); + // 90 = first_child's height(50) + collapsed margins(-10) + + // second child's height(50) + int empty5_fragment_block_offset = 90; + EXPECT_THAT(LayoutUnit(empty5_fragment_block_offset), + empty5_fragment->TopOffset()); - div1->SetFirstChild(div2); - div2->SetNextSibling(div3); - div1->SetNextSibling(div4); - div4->SetNextSibling(div5); - div5->SetFirstChild(div6); - div6->SetNextSibling(div7); + ASSERT_EQ(3UL, body_fragment->PositionedFloats().size()); + auto float_nonempties_fragment = + body_fragment->PositionedFloats().at(1)->fragment; + // 70 = first_child's height(50) + first child's margin-bottom(20) + EXPECT_THAT(LayoutUnit(70), float_nonempties_fragment->TopOffset()); + EXPECT_THAT(LayoutUnit(0), float_nonempties_fragment->LeftOffset()); - auto* space = ConstructConstraintSpace( - kHorizontalTopBottom, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(100), NGSizeIndefinite)); - NGPhysicalBoxFragment* frag = RunBlockLayoutAlgorithm(space, div1); + // ** Verify layout tree ** + Element* first_child = document().getElementById("first-child"); + // -7 = body_top_offset + EXPECT_EQ(body_top_offset, first_child->offsetTop()); - ASSERT_EQ(frag->Children().size(), 3UL); + NGLogicalSize float_empties_exclusion_size = {LayoutUnit(30), LayoutUnit(30)}; + NGLogicalOffset float_empties_exclusion_offset = { + LayoutUnit(body_left_offset), LayoutUnit(body_top_offset)}; + NGLogicalRect float_empties_exclusion_rect = {float_empties_exclusion_offset, + float_empties_exclusion_size}; + NGExclusion float_empties_exclusion = {float_empties_exclusion_rect, + NGExclusion::kFloatLeft}; - // DIV1 - const NGPhysicalFragment* child = frag->Children()[0]; - EXPECT_EQ(kHeight, child->Height()); - EXPECT_EQ(0, child->TopOffset()); + NGLogicalSize float_nonempties_exclusion_size = {LayoutUnit(40), + LayoutUnit(40)}; + // 63 = first_child_margin_strut(20) + first-child's height(50) + + // body_top_offset(-7) + NGLogicalOffset float_nonempties_exclusion_offset = { + LayoutUnit(body_left_offset), LayoutUnit(63)}; + NGLogicalRect float_nonempties_exclusion_rect = { + float_nonempties_exclusion_offset, float_nonempties_exclusion_size}; + NGExclusion float_nonempties_exclusion = {float_nonempties_exclusion_rect, + NGExclusion::kFloatLeft}; - // DIV5 - child = frag->Children()[2]; - EXPECT_EQ(kHeight, child->Height()); - EXPECT_EQ(kHeight + kExpectedCollapsedMargin, child->TopOffset()); + NGLogicalSize float_top_align_exclusion_size = {LayoutUnit(50), + LayoutUnit(50)}; + // 63 = float_nonempties_exclusion_offset because of the top edge alignment + // rule. + // 48 = body's margin + float_nonempties_exclusion_size + NGLogicalOffset float_top_align_exclusion_offset = {LayoutUnit(48), + LayoutUnit(63)}; + NGLogicalRect float_top_align_exclusion_rect = { + float_top_align_exclusion_offset, float_top_align_exclusion_size}; + NGExclusion float_top_align_exclusion = {float_top_align_exclusion_rect, + NGExclusion::kFloatLeft}; + + EXPECT_THAT(space->Exclusions()->storage, + (ElementsAre(Pointee(float_empties_exclusion), + Pointee(float_nonempties_exclusion), + Pointee(float_top_align_exclusion)))); } // Verifies the collapsing margins case for the next pair: // - bottom margin of a last in-flow child and bottom margin of its parent if // the parent has 'auto' computed height -// -// Test case's HTML representation: -// <div style="margin-bottom: 20px; height: 50px;"> <!-- DIV1 --> -// <div style="margin-bottom: 200px; height: 50px;"/> <!-- DIV2 --> -// </div> -// -// Expected: -// 1) Margins are collapsed with the result = std::max(20, 200) -// if DIV1.height == auto -// 2) Margins are NOT collapsed if DIV1.height != auto -TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase3) { - const int kHeight = 50; - const int kDiv1MarginBottom = 20; - const int kDiv2MarginBottom = 200; +// TODO(glebl): Enable with new the float/margins collapsing algorithm. +TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_CollapsingMarginsCase3) { + setBodyInnerHTML( + "<style>" + " #container {" + " margin-bottom: 20px;" + " }" + " #child {" + " margin-bottom: 200px;" + " height: 50px;" + " }" + "</style>" + "<div id='container'>" + " <div id='child'></div>" + "</div>"); - // DIV1 - RefPtr<ComputedStyle> div1_style = ComputedStyle::create(); - div1_style->setMarginBottom(Length(kDiv1MarginBottom, Fixed)); - NGBlockNode* div1 = new NGBlockNode(div1_style.get()); + const NGPhysicalBoxFragment* body_fragment; + const NGPhysicalBoxFragment* container_fragment; + const NGPhysicalBoxFragment* child_fragment; + const NGPhysicalBoxFragment* fragment; + auto run_test = [&](const Length& container_height) { + Element* container = document().getElementById("container"); + container->mutableComputedStyle()->setHeight(container_height); + std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( + document().getElementsByTagName("html")->item(0)); + ASSERT_EQ(1UL, fragment->Children().size()); + body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0]); + container_fragment = toNGPhysicalBoxFragment(body_fragment->Children()[0]); + ASSERT_EQ(1UL, container_fragment->Children().size()); + child_fragment = toNGPhysicalBoxFragment(container_fragment->Children()[0]); + }; - // DIV2 - RefPtr<ComputedStyle> div2_style = ComputedStyle::create(); - div2_style->setHeight(Length(kHeight, Fixed)); - div2_style->setMarginBottom(Length(kDiv2MarginBottom, Fixed)); - NGBlockNode* div2 = new NGBlockNode(div2_style.get()); + // height == auto + run_test(Length(Auto)); + // Margins are collapsed with the result 200 = std::max(20, 200) + // The fragment size 258 == body's margin 8 + child's height 50 + 200 + EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(258)), fragment->Size()); + // EXPECT_EQ(NGMarginStrut({LayoutUnit(200)}), + // container_fragment->EndMarginStrut()); - div1->SetFirstChild(div2); - - auto* space = ConstructConstraintSpace( - kHorizontalTopBottom, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(100), NGSizeIndefinite)); - NGPhysicalBoxFragment* frag = RunBlockLayoutAlgorithm(space, div1); - - // Verify that margins are collapsed. - EXPECT_EQ( - NGDeprecatedMarginStrut({LayoutUnit(0), LayoutUnit(kDiv2MarginBottom)}), - frag->MarginStrut()); - - // Verify that margins are NOT collapsed. - div1_style->setHeight(Length(kHeight, Fixed)); - frag = RunBlockLayoutAlgorithm(space, div1); - EXPECT_EQ( - NGDeprecatedMarginStrut({LayoutUnit(0), LayoutUnit(kDiv1MarginBottom)}), - frag->MarginStrut()); + // height == fixed + run_test(Length(50, Fixed)); + // Margins are not collapsed, so fragment still has margins == 20. + // The fragment size 78 == body's margin 8 + child's height 50 + 20 + // EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(78)), + // fragment->Size()); + // EXPECT_EQ(NGMarginStrut(), container_fragment->EndMarginStrut()); } // Verifies that 2 adjoining margins are not collapsed if there is padding or // border that separates them. -// -// Test case's HTML representation: -// <div style="margin: 30px 0px; padding: 20px 0px;"> <!-- DIV1 --> -// <div style="margin: 200px 0px; height: 50px;"/> <!-- DIV2 --> -// </div> -// -// Expected: -// Margins do NOT collapse if there is an interfering padding or border. -TEST_F(NGBlockLayoutAlgorithmTest, CollapsingMarginsCase4) { - const int kHeight = 50; - const int kDiv1Margin = 30; - const int kDiv1Padding = 20; - const int kDiv2Margin = 200; +// TODO(glebl): Enable with new the float/margins collapsing algorithm. +TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_CollapsingMarginsCase4) { + setBodyInnerHTML( + "<style>" + " #container {" + " margin: 30px 0px;" + " width: 200px;" + " }" + " #child {" + " margin: 200px 0px;" + " height: 50px;" + " background-color: blue;" + " }" + "</style>" + "<div id='container'>" + " <div id='child'></div>" + "</div>"); - // DIV1 - RefPtr<ComputedStyle> div1_style = ComputedStyle::create(); - div1_style->setMarginTop(Length(kDiv1Margin, Fixed)); - div1_style->setMarginBottom(Length(kDiv1Margin, Fixed)); - div1_style->setPaddingTop(Length(kDiv1Padding, Fixed)); - div1_style->setPaddingBottom(Length(kDiv1Padding, Fixed)); - NGBlockNode* div1 = new NGBlockNode(div1_style.get()); + const NGPhysicalBoxFragment* body_fragment; + const NGPhysicalBoxFragment* container_fragment; + const NGPhysicalBoxFragment* child_fragment; + const NGPhysicalBoxFragment* fragment; + auto run_test = [&](const Length& container_padding_top) { + Element* container = document().getElementById("container"); + container->mutableComputedStyle()->setPaddingTop(container_padding_top); + std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( + document().getElementsByTagName("html")->item(0)); + ASSERT_EQ(1UL, fragment->Children().size()); + body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0]); + container_fragment = toNGPhysicalBoxFragment(body_fragment->Children()[0]); + ASSERT_EQ(1UL, container_fragment->Children().size()); + child_fragment = toNGPhysicalBoxFragment(container_fragment->Children()[0]); + }; - // DIV2 - RefPtr<ComputedStyle> div2_style = ComputedStyle::create(); - div2_style->setHeight(Length(kHeight, Fixed)); - div2_style->setMarginTop(Length(kDiv2Margin, Fixed)); - div2_style->setMarginBottom(Length(kDiv2Margin, Fixed)); - NGBlockNode* div2 = new NGBlockNode(div2_style.get()); + // with padding + run_test(Length(20, Fixed)); + // 500 = child's height 50 + 2xmargin 400 + paddint-top 20 + + // container's margin 30 + EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(500)), fragment->Size()); + // 30 = max(body's margin 8, container margin 30) + EXPECT_EQ(LayoutUnit(30), body_fragment->TopOffset()); + // 220 = container's padding top 20 + child's margin + EXPECT_EQ(LayoutUnit(220), child_fragment->TopOffset()); - div1->SetFirstChild(div2); - - auto* space = ConstructConstraintSpace( - kHorizontalTopBottom, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(100), NGSizeIndefinite)); - NGPhysicalBoxFragment* frag = RunBlockLayoutAlgorithm(space, div1); - - // Verify that margins do NOT collapse. - frag = RunBlockLayoutAlgorithm(space, div1); - EXPECT_EQ(NGDeprecatedMarginStrut( - {LayoutUnit(kDiv1Margin), LayoutUnit(kDiv1Margin)}), - frag->MarginStrut()); - ASSERT_EQ(frag->Children().size(), 1UL); - - EXPECT_EQ(NGDeprecatedMarginStrut( - {LayoutUnit(kDiv2Margin), LayoutUnit(kDiv2Margin)}), - static_cast<const NGPhysicalBoxFragment*>(frag->Children()[0].get()) - ->MarginStrut()); - - // Reset padding and verify that margins DO collapse. - div1_style->setPaddingTop(Length(0, Fixed)); - div1_style->setPaddingBottom(Length(0, Fixed)); - frag = RunBlockLayoutAlgorithm(space, div1); - EXPECT_EQ(NGDeprecatedMarginStrut( - {LayoutUnit(kDiv2Margin), LayoutUnit(kDiv2Margin)}), - frag->MarginStrut()); + // without padding + run_test(Length(0, Fixed)); + // 450 = 2xmax(body's margin 8, container's margin 30, child's margin 200) + + // child's height 50 + EXPECT_EQ(NGPhysicalSize(LayoutUnit(800), LayoutUnit(450)), fragment->Size()); + // 200 = (body's margin 8, container's margin 30, child's margin 200) + EXPECT_EQ(LayoutUnit(200), body_fragment->TopOffset()); + // 0 = collapsed margins + EXPECT_EQ(LayoutUnit(0), child_fragment->TopOffset()); } // Verifies that margins of 2 adjoining blocks with different writing modes @@ -632,175 +768,404 @@ EXPECT_EQ(LayoutUnit(0), child->TopOffset()); } -// Verifies that 3 Left/Right float fragments and one regular block fragment -// are correctly positioned by the algorithm. -// -// Test case's HTML representation: -// <div id="parent" style="width: 200px; height: 200px;"> -// <div style="float:left; width: 30px; height: 30px; -// margin-top: 10px;"/> <!-- DIV1 --> -// <div style="width: 30px; height: 30px;"/> <!-- DIV2 --> -// <div style="float:right; width: 50px; height: 50px;"/> <!-- DIV3 --> -// <div style="float:left; width: 120px; height: 120px; -// margin-left: 30px;"/> <!-- DIV4 --> -// </div> -// -// Expected: -// - Left float(DIV1) is positioned at the left. -// - Regular block (DIV2) is positioned behind DIV1. -// - Right float(DIV3) is positioned at the right below DIV2 -// - Left float(DIV4) is positioned at the left below DIV3. -TEST_F(NGBlockLayoutAlgorithmTest, PositionFloatFragments) { - const int kParentLeftPadding = 10; - const int kDiv1TopMargin = 10; - const int kParentSize = 200; - const int kDiv1Size = 30; - const int kDiv2Size = 30; - const int kDiv3Size = 50; - const int kDiv4Size = kParentSize - kDiv3Size; - const int kDiv4LeftMargin = kDiv1Size; +// Verifies that floats can be correctly positioned if they are inside of nested +// empty blocks. +// TODO(glebl): Enable with new the float/margins collapsing algorithm. +TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_PositionFloatInsideEmptyBlocks) { + setBodyInnerHTML( + "<!DOCTYPE html>" + "<style>" + " #container {" + " height: 200px;" + " width: 200px;" + " }" + " #empty1 {" + " margin: 20px;" + " padding: 0 20px;" + " }" + " #empty2 {" + " margin: 15px;" + " padding: 0 15px;" + " }" + " #float {" + " float: left;" + " height: 5px;" + " width: 5px;" + " padding: 10px;" + " margin: 10px;" + " background-color: green;" + " }" + "</style>" + "<div id='container'>" + " <div id='empty1'>" + " <div id='empty2'>" + " <div id='float'></div>" + " </div>" + " </div>" + "</div>"); - style_->setHeight(Length(kParentSize, Fixed)); - style_->setWidth(Length(kParentSize, Fixed)); - style_->setPaddingLeft(Length(kParentLeftPadding, Fixed)); + // ** Run LayoutNG algorithm ** + NGConstraintSpace* space; + NGPhysicalBoxFragment* fragment; + std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( + document().getElementsByTagName("html")->item(0)); - // DIV1 - RefPtr<ComputedStyle> div1_style = ComputedStyle::create(); - div1_style->setWidth(Length(kDiv1Size, Fixed)); - div1_style->setHeight(Length(kDiv1Size, Fixed)); - div1_style->setFloating(EFloat::kLeft); - div1_style->setMarginTop(Length(kDiv1TopMargin, Fixed)); - NGBlockNode* div1 = new NGBlockNode(div1_style.get()); + auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0]); + // 20 = std::max(empty1's margin, empty2's margin, body's margin) + int body_top_offset = 20; + EXPECT_THAT(LayoutUnit(body_top_offset), body_fragment->TopOffset()); + ASSERT_EQ(1UL, body_fragment->Children().size()); + auto* container_fragment = + toNGPhysicalBoxFragment(body_fragment->Children()[0]); + ASSERT_EQ(1UL, container_fragment->Children().size()); - // DIV2 - RefPtr<ComputedStyle> div2_style = ComputedStyle::create(); - div2_style->setWidth(Length(kDiv2Size, Fixed)); - div2_style->setHeight(Length(kDiv2Size, Fixed)); - NGBlockNode* div2 = new NGBlockNode(div2_style.get()); + auto* empty1_fragment = + toNGPhysicalBoxFragment(container_fragment->Children()[0]); + // 0, vertical margins got collapsed + EXPECT_THAT(LayoutUnit(), empty1_fragment->TopOffset()); + // 20 empty1's margin + int empty1_inline_offset = 20; + EXPECT_THAT(LayoutUnit(empty1_inline_offset), empty1_fragment->LeftOffset()); + ASSERT_EQ(empty1_fragment->Children().size(), 1UL); - // DIV3 - RefPtr<ComputedStyle> div3_style = ComputedStyle::create(); - div3_style->setWidth(Length(kDiv3Size, Fixed)); - div3_style->setHeight(Length(kDiv3Size, Fixed)); - div3_style->setFloating(EFloat::kRight); - NGBlockNode* div3 = new NGBlockNode(div3_style.get()); + auto* empty2_fragment = + toNGPhysicalBoxFragment(empty1_fragment->Children()[0]); + // 0, vertical margins got collapsed + EXPECT_THAT(LayoutUnit(), empty2_fragment->TopOffset()); + // 35 = empty1's padding(20) + empty2's padding(15) + int empty2_inline_offset = 35; + EXPECT_THAT(LayoutUnit(empty2_inline_offset), empty2_fragment->LeftOffset()); - // DIV4 - RefPtr<ComputedStyle> div4_style = ComputedStyle::create(); - div4_style->setWidth(Length(kDiv4Size, Fixed)); - div4_style->setHeight(Length(kDiv4Size, Fixed)); - div4_style->setMarginLeft(Length(kDiv4LeftMargin, Fixed)); - div4_style->setFloating(EFloat::kLeft); - NGBlockNode* div4 = new NGBlockNode(div4_style.get()); + ASSERT_EQ(1UL, body_fragment->PositionedFloats().size()); + auto float_fragment = body_fragment->PositionedFloats().at(0)->fragment; + // 10 = float's padding + EXPECT_THAT(LayoutUnit(10), float_fragment->TopOffset()); + // 25 = empty2's padding(15) + float's padding(10) + int float_inline_offset = 25; + EXPECT_THAT(float_fragment->LeftOffset(), LayoutUnit(float_inline_offset)); - div1->SetNextSibling(div2); - div2->SetNextSibling(div3); - div3->SetNextSibling(div4); + // ** Verify layout tree ** + Element* left_float = document().getElementById("float"); + // 88 = body's margin(8) + + // empty1's padding and margin + empty2's padding and margins + float's + // padding + EXPECT_THAT(left_float->offsetLeft(), 88); + // 30 = body_top_offset(collapsed margins result) + float's padding + EXPECT_THAT(body_top_offset + 10, left_float->offsetTop()); - auto* space = ConstructConstraintSpace( - kHorizontalTopBottom, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(kParentSize), LayoutUnit(kParentSize))); - NGPhysicalBoxFragment* frag = RunBlockLayoutAlgorithm(space, div1); - ASSERT_EQ(frag->Children().size(), 4UL); + // ** Legacy Floating objects ** + Element* body = document().getElementsByTagName("body")->item(0); + auto& floating_objects = + const_cast<FloatingObjects*>( + toLayoutBlockFlow(body->layoutObject())->floatingObjects()) + ->mutableSet(); + ASSERT_EQ(1UL, floating_objects.size()); + auto floating_object = floating_objects.takeFirst(); + ASSERT_TRUE(floating_object->isPlaced()); + // 80 = float_inline_offset(25) + accumulative offset of empty blocks(35 + 20) + EXPECT_THAT(LayoutUnit(80), floating_object->x()); + // 10 = float's padding + EXPECT_THAT(LayoutUnit(10), floating_object->y()); +} - // DIV1 - const NGPhysicalFragment* child1 = frag->Children()[0]; - EXPECT_EQ(kDiv1TopMargin, child1->TopOffset()); - EXPECT_EQ(kParentLeftPadding, child1->LeftOffset()); +// Verifies that left/right floating and regular blocks can be positioned +// correctly by the algorithm. +// TODO(glebl): Enable with new the float/margins collapsing algorithm. +TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_PositionFloatFragments) { + setBodyInnerHTML( + "<style>" + " #container {" + " height: 200px;" + " width: 200px;" + " }" + " #left-float {" + " background-color: red;" + " float:left;" + " height: 30px;" + " width: 30px;" + " }" + " #left-wide-float {" + " background-color: greenyellow;" + " float:left;" + " height: 30px;" + " width: 180px;" + " }" + " #regular {" + " width: 40px;" + " height: 40px;" + " background-color: green;" + " }" + " #right-float {" + " background-color: cyan;" + " float:right;" + " width: 50px;" + " height: 50px;" + " }" + " #left-float-with-margin {" + " background-color: black;" + " float:left;" + " height: 120px;" + " margin: 10px;" + " width: 120px;" + " }" + "</style>" + "<div id='container'>" + " <div id='left-float'></div>" + " <div id='left-wide-float'></div>" + " <div id='regular'></div>" + " <div id='right-float'></div>" + " <div id='left-float-with-margin'></div>" + "</div>"); - // DIV2 - const NGPhysicalFragment* child2 = frag->Children()[1]; - EXPECT_EQ(0, child2->TopOffset()); - EXPECT_EQ(kParentLeftPadding, child2->LeftOffset()); + // ** Run LayoutNG algorithm ** + NGConstraintSpace* space; + NGPhysicalBoxFragment* fragment; + std::tie(fragment, space) = RunBlockLayoutAlgorithmForElement( + document().getElementsByTagName("html")->item(0)); - // DIV3 - const NGPhysicalFragment* child3 = frag->Children()[2]; - EXPECT_EQ(kDiv2Size, child3->TopOffset()); - EXPECT_EQ(kParentLeftPadding + kParentSize - kDiv3Size, child3->LeftOffset()); + // ** Verify LayoutNG fragments and the list of positioned floats ** + EXPECT_THAT(LayoutUnit(), fragment->TopOffset()); + ASSERT_EQ(1UL, fragment->Children().size()); + auto* body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0]); + EXPECT_THAT(LayoutUnit(8), body_fragment->TopOffset()); + auto* container_fragment = + toNGPhysicalBoxFragment(body_fragment->Children()[0]); + ASSERT_EQ(1UL, container_fragment->Children().size()); + ASSERT_EQ(4UL, container_fragment->PositionedFloats().size()); - // DIV4 - const NGPhysicalFragment* child4 = frag->Children()[3]; - EXPECT_EQ(kDiv2Size + kDiv3Size, child4->TopOffset()); - EXPECT_EQ(kParentLeftPadding + kDiv4LeftMargin, child4->LeftOffset()); + // ** Verify layout tree ** + Element* left_float = document().getElementById("left-float"); + // 8 = body's margin-top + int left_float_block_offset = 8; + EXPECT_EQ(left_float_block_offset, left_float->offsetTop()); + auto left_float_fragment = + container_fragment->PositionedFloats().at(0)->fragment; + EXPECT_THAT(LayoutUnit(), left_float_fragment->TopOffset()); + + Element* left_wide_float = document().getElementById("left-wide-float"); + // left-wide-float is positioned right below left-float as it's too wide. + // 38 = left_float_block_offset + + // left-float's height 30 + int left_wide_float_block_offset = 38; + EXPECT_EQ(left_wide_float_block_offset, left_wide_float->offsetTop()); + auto left_wide_float_fragment = + container_fragment->PositionedFloats().at(1)->fragment; + // 30 = left-float's height. + EXPECT_THAT(LayoutUnit(30), left_wide_float_fragment->TopOffset()); + + Element* regular = document().getElementById("regular"); + // regular_block_offset = body's margin-top 8 + int regular_block_offset = 8; + EXPECT_EQ(regular_block_offset, regular->offsetTop()); + auto* regular_block_fragment = + toNGPhysicalBoxFragment(container_fragment->Children()[0]); + EXPECT_THAT(LayoutUnit(), regular_block_fragment->TopOffset()); + + Element* right_float = document().getElementById("right-float"); + // 158 = body's margin-left 8 + container's width 200 - right_float's width 50 + int right_float_inline_offset = 158; + // it's positioned right after our left_wide_float + // 68 = left_wide_float_block_offset 38 + left-wide-float's height 30 + int right_float_block_offset = left_wide_float_block_offset + 30; + EXPECT_EQ(right_float_inline_offset, right_float->offsetLeft()); + EXPECT_EQ(right_float_block_offset, right_float->offsetTop()); + auto right_float_fragment = + container_fragment->PositionedFloats().at(2)->fragment; + // 60 = right_float_block_offset(68) - body's margin(8) + EXPECT_THAT(LayoutUnit(right_float_block_offset - 8), + right_float_fragment->TopOffset()); + // 150 = right_float_inline_offset(158) - body's margin(8) + EXPECT_THAT(LayoutUnit(right_float_inline_offset - 8), + right_float_fragment->LeftOffset()); + + Element* left_float_with_margin = + document().getElementById("left-float-with-margin"); + // 18 = body's margin(8) + left-float-with-margin's margin(10) + int left_float_with_margin_inline_offset = 18; + EXPECT_EQ(left_float_with_margin_inline_offset, + left_float_with_margin->offsetLeft()); + // 78 = left_wide_float_block_offset 38 + left-wide-float's height 30 + + // left-float-with-margin's margin(10) + int left_float_with_margin_block_offset = 78; + EXPECT_EQ(left_float_with_margin_block_offset, + left_float_with_margin->offsetTop()); + auto left_float_with_margin_fragment = + container_fragment->PositionedFloats().at(3)->fragment; + // 70 = left_float_with_margin_block_offset(78) - body's margin(8) + EXPECT_THAT(LayoutUnit(left_float_with_margin_block_offset - 8), + left_float_with_margin_fragment->TopOffset()); + // 10 = left_float_with_margin_inline_offset(18) - body's margin(8) + EXPECT_THAT(LayoutUnit(left_float_with_margin_inline_offset - 8), + left_float_with_margin_fragment->LeftOffset()); + + // ** Verify exclusions ** + NGLogicalSize left_float_exclusion_size = {LayoutUnit(30), LayoutUnit(30)}; + // this should be equal to body's margin(8) + NGLogicalOffset left_float_exclusion_offset = {LayoutUnit(8), LayoutUnit(8)}; + NGLogicalRect left_float_exclusion_rect = {left_float_exclusion_offset, + left_float_exclusion_size}; + NGExclusion left_float_exclusion = {left_float_exclusion_rect, + NGExclusion::kFloatLeft}; + + NGLogicalSize left_wide_exclusion_size = {LayoutUnit(180), LayoutUnit(30)}; + NGLogicalOffset left_wide_exclusion_offset = { + LayoutUnit(8), LayoutUnit(left_wide_float_block_offset)}; + NGLogicalRect left_wide_exclusion_rect = {left_wide_exclusion_offset, + left_wide_exclusion_size}; + NGExclusion left_wide_exclusion = {left_wide_exclusion_rect, + NGExclusion::kFloatLeft}; + + NGLogicalSize right_float_exclusion_size = {LayoutUnit(50), LayoutUnit(50)}; + NGLogicalOffset right_float_exclusion_offset = { + LayoutUnit(right_float_inline_offset), + LayoutUnit(right_float_block_offset)}; + NGLogicalRect right_float_exclusion_rect = {right_float_exclusion_offset, + right_float_exclusion_size}; + NGExclusion right_float_exclusion = {right_float_exclusion_rect, + NGExclusion::kFloatRight}; + + // left-float-with-margin's size(120) + margin(2x10) + NGLogicalSize left_float_with_margin_exclusion_size = {LayoutUnit(140), + LayoutUnit(140)}; + // Exclusion starts from the right_float_block_offset position. + NGLogicalOffset left_float_with_margin_exclusion_offset = { + LayoutUnit(8), LayoutUnit(right_float_block_offset)}; + NGLogicalRect left_float_with_margin_exclusion_rect = { + left_float_with_margin_exclusion_offset, + left_float_with_margin_exclusion_size}; + NGExclusion left_float_with_margin_exclusion = { + left_float_with_margin_exclusion_rect, NGExclusion::kFloatLeft}; + + EXPECT_THAT( + space->Exclusions()->storage, + (ElementsAre(Pointee(left_float_exclusion), Pointee(left_wide_exclusion), + Pointee(right_float_exclusion), + Pointee(left_float_with_margin_exclusion)))); } // Verifies that NG block layout algorithm respects "clear" CSS property. -// -// Test case's HTML representation: -// <div id="parent" style="width: 200px; height: 200px;"> -// <div style="float: left; width: 30px; height: 30px;"/> <!-- DIV1 --> -// <div style="float: right; width: 40px; height: 40px; -// clear: left;"/> <!-- DIV2 --> -// <div style="clear: ...; width: 50px; height: 50px;"/> <!-- DIV3 --> -// </div> -// -// Expected: -// - DIV2 is positioned below DIV1 because it has clear: left; -// - DIV3 is positioned below DIV1 if clear: left; -// - DIV3 is positioned below DIV2 if clear: right; -// - DIV3 is positioned below DIV2 if clear: both; -TEST_F(NGBlockLayoutAlgorithmTest, PositionFragmentsWithClear) { - const int kParentSize = 200; - const int kDiv1Size = 30; - const int kDiv2Size = 40; - const int kDiv3Size = 50; +// TODO(glebl): Enable with new the float/margins collapsing algorithm. +TEST_F(NGBlockLayoutAlgorithmTest, DISABLED_PositionFragmentsWithClear) { + setBodyInnerHTML( + "<style>" + " #container {" + " height: 200px;" + " width: 200px;" + " }" + " #float-left {" + " background-color: red;" + " float: left;" + " height: 30px;" + " width: 30px;" + " }" + " #float-right {" + " background-color: blue;" + " float: right;" + " height: 170px;" + " width: 40px;" + " }" + " #clearance {" + " background-color: yellow;" + " height: 60px;" + " width: 60px;" + " margin: 20px;" + " }" + " #block {" + " margin: 40px;" + " background-color: black;" + " height: 60px;" + " width: 60px;" + " }" + " #adjoining-clearance {" + " background-color: green;" + " clear: left;" + " height: 20px;" + " width: 20px;" + " margin: 30px;" + " }" + "</style>" + "<div id='container'>" + " <div id='float-left'></div>" + " <div id='float-right'></div>" + " <div id='clearance'></div>" + " <div id='block'></div>" + " <div id='adjoining-clearance'></div>" + "</div>"); - style_->setHeight(Length(kParentSize, Fixed)); - style_->setWidth(Length(kParentSize, Fixed)); + const NGPhysicalBoxFragment* clerance_fragment; + const NGPhysicalBoxFragment* body_fragment; + const NGPhysicalBoxFragment* container_fragment; + const NGPhysicalBoxFragment* block_fragment; + const NGPhysicalBoxFragment* adjoining_clearance_fragment; + auto run_with_clearance = [&](EClear clear_value) { + NGPhysicalBoxFragment* fragment; + Element* el_with_clear = document().getElementById("clearance"); + el_with_clear->mutableComputedStyle()->setClear(clear_value); + std::tie(fragment, std::ignore) = RunBlockLayoutAlgorithmForElement( + document().getElementsByTagName("html")->item(0)); + ASSERT_EQ(1UL, fragment->Children().size()); + body_fragment = toNGPhysicalBoxFragment(fragment->Children()[0]); + container_fragment = toNGPhysicalBoxFragment(body_fragment->Children()[0]); + ASSERT_EQ(3UL, container_fragment->Children().size()); + clerance_fragment = + toNGPhysicalBoxFragment(container_fragment->Children()[0]); + block_fragment = toNGPhysicalBoxFragment(container_fragment->Children()[1]); + adjoining_clearance_fragment = + toNGPhysicalBoxFragment(container_fragment->Children()[2]); + }; - // DIV1 - RefPtr<ComputedStyle> div1_style = ComputedStyle::create(); - div1_style->setWidth(Length(kDiv1Size, Fixed)); - div1_style->setHeight(Length(kDiv1Size, Fixed)); - div1_style->setFloating(EFloat::kLeft); - NGBlockNode* div1 = new NGBlockNode(div1_style.get()); + // clear: none + run_with_clearance(EClear::ClearNone); + // 20 = std::max(body's margin 8, clearance's margins 20) + EXPECT_EQ(LayoutUnit(20), body_fragment->TopOffset()); + EXPECT_EQ(LayoutUnit(0), container_fragment->TopOffset()); + // 0 = collapsed margins + EXPECT_EQ(LayoutUnit(0), clerance_fragment->TopOffset()); + // 100 = clearance's height 60 + + // std::max(clearance's margins 20, block's margins 40) + EXPECT_EQ(LayoutUnit(100), block_fragment->TopOffset()); + // 200 = 100 + block's height 60 + max(adjoining_clearance's margins 30, + // block's margins 40) + EXPECT_EQ(LayoutUnit(200), adjoining_clearance_fragment->TopOffset()); - // DIV2 - RefPtr<ComputedStyle> div2_style = ComputedStyle::create(); - div2_style->setWidth(Length(kDiv2Size, Fixed)); - div2_style->setHeight(Length(kDiv2Size, Fixed)); - div2_style->setClear(EClear::ClearLeft); - div2_style->setFloating(EFloat::kRight); - NGBlockNode* div2 = new NGBlockNode(div2_style.get()); + // clear: right + run_with_clearance(EClear::ClearRight); + // 8 = body's margin. This doesn't collapse its margins with 'clearance' block + // as it's not an adjoining block to body. + EXPECT_EQ(LayoutUnit(8), body_fragment->TopOffset()); + EXPECT_EQ(LayoutUnit(0), container_fragment->TopOffset()); + // 170 = float-right's height + EXPECT_EQ(LayoutUnit(170), clerance_fragment->TopOffset()); + // 270 = float-right's height + clearance's height 60 + + // max(clearance's margin 20, block margin 40) + EXPECT_EQ(LayoutUnit(270), block_fragment->TopOffset()); + // 370 = block's offset 270 + block's height 60 + + // std::max(block's margin 40, adjoining_clearance's margin 30) + EXPECT_EQ(LayoutUnit(370), adjoining_clearance_fragment->TopOffset()); - // DIV3 - RefPtr<ComputedStyle> div3_style = ComputedStyle::create(); - div3_style->setWidth(Length(kDiv3Size, Fixed)); - div3_style->setHeight(Length(kDiv3Size, Fixed)); - NGBlockNode* div3 = new NGBlockNode(div3_style.get()); + // clear: left + run_with_clearance(EClear::ClearLeft); + // 8 = body's margin. This doesn't collapse its margins with 'clearance' block + // as it's not an adjoining block to body. + EXPECT_EQ(LayoutUnit(8), body_fragment->TopOffset()); + EXPECT_EQ(LayoutUnit(0), container_fragment->TopOffset()); + // 30 = float_left's height + EXPECT_EQ(LayoutUnit(30), clerance_fragment->TopOffset()); + // 130 = float_left's height + clearance's height 60 + + // max(clearance's margin 20, block margin 40) + EXPECT_EQ(LayoutUnit(130), block_fragment->TopOffset()); + // 230 = block's offset 130 + block's height 60 + + // std::max(block's margin 40, adjoining_clearance's margin 30) + EXPECT_EQ(LayoutUnit(230), adjoining_clearance_fragment->TopOffset()); - div1->SetNextSibling(div2); - div2->SetNextSibling(div3); - - // clear: left; - div3_style->setClear(EClear::ClearLeft); - auto* space = ConstructConstraintSpace( - kHorizontalTopBottom, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(kParentSize), LayoutUnit(kParentSize))); - NGPhysicalBoxFragment* frag = RunBlockLayoutAlgorithm(space, div1); - const NGPhysicalFragment* child3 = frag->Children()[2]; - EXPECT_EQ(kDiv1Size, child3->TopOffset()); - - // clear: right; - div3_style->setClear(EClear::ClearRight); - space = ConstructConstraintSpace( - kHorizontalTopBottom, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(kParentSize), LayoutUnit(kParentSize))); - frag = RunBlockLayoutAlgorithm(space, div1); - child3 = frag->Children()[2]; - EXPECT_EQ(kDiv1Size + kDiv2Size, child3->TopOffset()); - - // clear: both; - div3_style->setClear(EClear::ClearBoth); - space = ConstructConstraintSpace( - kHorizontalTopBottom, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(kParentSize), LayoutUnit(kParentSize))); - frag = RunBlockLayoutAlgorithm(space, div1); - space = ConstructConstraintSpace( - kHorizontalTopBottom, TextDirection::kLtr, - NGLogicalSize(LayoutUnit(kParentSize), LayoutUnit(kParentSize))); - child3 = frag->Children()[2]; - EXPECT_EQ(kDiv1Size + kDiv2Size, child3->TopOffset()); + // clear: both + // same as clear: right + run_with_clearance(EClear::ClearBoth); + EXPECT_EQ(LayoutUnit(8), body_fragment->TopOffset()); + EXPECT_EQ(LayoutUnit(0), container_fragment->TopOffset()); + EXPECT_EQ(LayoutUnit(170), clerance_fragment->TopOffset()); + EXPECT_EQ(LayoutUnit(270), block_fragment->TopOffset()); + EXPECT_EQ(LayoutUnit(370), adjoining_clearance_fragment->TopOffset()); } // Verifies that we compute the right min and max-content size.
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc index 09a93eb8..882d9c3 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -21,6 +21,45 @@ namespace blink { +namespace { + +// Copies data back to the legacy layout tree for a given child fragment. +void FragmentPositionUpdated(const NGPhysicalBoxFragment& box_fragment) { + LayoutBox* layout_box = toLayoutBox(box_fragment.GetLayoutObject()); + if (!layout_box) + return; + + DCHECK(layout_box->parent()) << "Should be called on children only."; + + layout_box->setX(box_fragment.LeftOffset()); + layout_box->setY(box_fragment.TopOffset()); +} + +// Similar to FragmentPositionUpdated but for floats. +// - Updates layout object's geometric information. +// - Creates legacy FloatingObject and attached it to the provided parent. +void FloatingObjectPositionedUpdated(NGFloatingObject& floating_object, + LayoutBox* parent) { + NGPhysicalBoxFragment* box_fragment = + toNGPhysicalBoxFragment(floating_object.fragment); + FragmentPositionUpdated(*box_fragment); + + LayoutBox* layout_box = toLayoutBox(box_fragment->GetLayoutObject()); + DCHECK(layout_box->isFloating()); + + if (parent && parent->isLayoutBlockFlow()) { + FloatingObject* floating_object = + toLayoutBlockFlow(parent)->insertFloatingObject(*layout_box); + // TODO(glebl): Fix floating_object's inline offset if it's attached to + // parent != layout_box_->parent + floating_object->setX(box_fragment->LeftOffset()); + floating_object->setY(box_fragment->TopOffset()); + floating_object->setIsPlaced(true); + } +} + +} // namespace + NGBlockNode::NGBlockNode(LayoutObject* layout_object) : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyBlock), layout_box_(toLayoutBox(layout_object)) { @@ -88,8 +127,8 @@ .ToConstraintSpace(); // TODO(cbiesinger): For orthogonal children, we need to always synthesize. - NGBlockLayoutAlgorithm minmax_algorithm(Style(), toNGBlockNode(FirstChild()), - constraint_space); + NGBlockLayoutAlgorithm minmax_algorithm( + layout_box_, Style(), toNGBlockNode(FirstChild()), constraint_space); if (minmax_algorithm.ComputeMinAndMaxContentSizes(sizes)) return true; @@ -142,6 +181,10 @@ return next_sibling_; } +LayoutObject* NGBlockNode::GetLayoutObject() { + return layout_box_; +} + NGLayoutInputNode* NGBlockNode::FirstChild() { if (!first_child_) { LayoutObject* child = layout_box_ ? layout_box_->slowFirstChild() : nullptr; @@ -175,29 +218,6 @@ NGLayoutInputNode::trace(visitor); } -void NGBlockNode::PositionUpdated() { - if (!layout_box_) - return; - DCHECK(layout_box_->parent()) << "Should be called on children only."; - - layout_box_->setX(fragment_->LeftOffset()); - layout_box_->setY(fragment_->TopOffset()); -} - -void NGBlockNode::FloatPositionUpdated(LayoutObject* parent) { - PositionUpdated(); - - if (layout_box_->isFloating() && parent && parent->isLayoutBlockFlow()) { - FloatingObject* floating_object = - toLayoutBlockFlow(parent)->insertFloatingObject(*layout_box_); - // TODO(glebl): Fix floating_object's inline offset if it's attached to - // parent != layout_box_->parent - floating_object->setX(fragment_->LeftOffset()); - floating_object->setY(fragment_->TopOffset()); - floating_object->setIsPlaced(true); - } -} - bool NGBlockNode::CanUseNewLayout() { if (!layout_box_) return true; @@ -255,13 +275,12 @@ // Ensure the position of the children are copied across to the // LayoutObject tree. } else { - for (NGBlockNode* box = toNGBlockNode(FirstChild()); box; - box = box->NextSibling()) { - if (box->fragment_ && box->fragment_->IsPlaced()) - box->PositionUpdated(); + for (const auto& child_fragment : fragment_->Children()) { + if (child_fragment->IsPlaced()) + FragmentPositionUpdated(toNGPhysicalBoxFragment(*child_fragment)); - for (const auto& floating_object : box->fragment_->PositionedFloats()) { - floating_object->node->FloatPositionUpdated(box->layout_box_); + for (const auto& floating_object : child_fragment->PositionedFloats()) { + FloatingObjectPositionedUpdated(*floating_object, layout_box_); } } } @@ -301,7 +320,7 @@ LayoutRect overflow = layout_box_->layoutOverflowRect(); // TODO(layout-ng): This does not handle writing modes correctly (for // overflow) - NGFragmentBuilder builder(NGPhysicalFragment::kFragmentBox); + NGFragmentBuilder builder(NGPhysicalFragment::kFragmentBox, layout_box_); builder.SetInlineSize(layout_box_->logicalWidth()) .SetBlockSize(layout_box_->logicalHeight()) .SetDirection(layout_box_->styleRef().direction())
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h index dbf5213..088fdaf 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.h
@@ -34,8 +34,8 @@ ~NGBlockNode() override; NGPhysicalFragment* Layout(NGConstraintSpace* constraint_space) override; - NGBlockNode* NextSibling() override; + LayoutObject* GetLayoutObject() override; // Computes the value of min-content and max-content for this box. // The return value has the same meaning as for Layout. @@ -75,17 +75,7 @@ // Save static position for legacy AbsPos layout. void SaveStaticOffsetForLegacy(const NGLogicalOffset&); - - // This is necessary for interop between old and new trees -- after our parent - // positions us, it calls this function so we can store the position on the - // underlying LayoutBox. - void PositionUpdated(); - private: - // Similar to PositionUpdated but for floats. - // - Updates layout object's geometric information. - // - Creates legacy FloatingObject and attached it to the provided parent. - void FloatPositionUpdated(LayoutObject* parent); bool CanUseNewLayout(); bool HasInlineChildren();
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc index 8491651..45eaca4 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -12,10 +12,13 @@ namespace blink { -NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type) +// TODO(ikilpatrick): Make writing mode and direction be in the constructor. +NGFragmentBuilder::NGFragmentBuilder(NGPhysicalFragment::NGFragmentType type, + LayoutObject* layout_object) : type_(type), writing_mode_(kHorizontalTopBottom), - direction_(TextDirection::kLtr) {} + direction_(TextDirection::kLtr), + layout_object_(layout_object) {} NGFragmentBuilder& NGFragmentBuilder::SetWritingMode( NGWritingMode writing_mode) { @@ -156,7 +159,7 @@ break_token_ = nullptr; NGPhysicalSize physical_size = size_.ConvertToPhysical(writing_mode_); - HeapVector<Member<const NGPhysicalFragment>> children; + HeapVector<Member<NGPhysicalFragment>> children; children.reserveCapacity(children_.size()); for (size_t i = 0; i < children_.size(); ++i) { @@ -178,8 +181,8 @@ } return new NGPhysicalBoxFragment( - physical_size, overflow_.ConvertToPhysical(writing_mode_), children, - out_of_flow_descendants_, out_of_flow_positions_, margin_strut_, + layout_object_, physical_size, overflow_.ConvertToPhysical(writing_mode_), + children, out_of_flow_descendants_, out_of_flow_positions_, margin_strut_, unpositioned_floats_, positioned_floats_, break_token); } @@ -194,7 +197,8 @@ HeapVector<Member<NGFloatingObject>> empty_positioned_floats; return new NGPhysicalTextFragment( - node, start_index, end_index, size_.ConvertToPhysical(writing_mode_), + layout_object_, node, start_index, end_index, + size_.ConvertToPhysical(writing_mode_), overflow_.ConvertToPhysical(writing_mode_), out_of_flow_descendants_, out_of_flow_positions_, empty_unpositioned_floats, empty_positioned_floats);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h index 29e39de..d1a7301 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -20,7 +20,7 @@ class CORE_EXPORT NGFragmentBuilder final : public GarbageCollectedFinalized<NGFragmentBuilder> { public: - NGFragmentBuilder(NGPhysicalFragment::NGFragmentType); + NGFragmentBuilder(NGPhysicalFragment::NGFragmentType, LayoutObject*); using WeakBoxList = HeapLinkedHashSet<WeakMember<NGBlockNode>>; @@ -137,6 +137,8 @@ NGWritingMode writing_mode_; TextDirection direction_; + LayoutObject* layout_object_; + NGLogicalSize size_; NGLogicalSize overflow_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc index bc36849..a6cd530 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.cc
@@ -18,6 +18,7 @@ namespace blink { NGInlineLayoutAlgorithm::NGInlineLayoutAlgorithm( + LayoutObject* layout_object, PassRefPtr<const ComputedStyle> style, NGInlineNode* first_child, NGConstraintSpace* constraint_space, @@ -26,14 +27,15 @@ style_(style), first_child_(first_child), constraint_space_(constraint_space), - break_token_(break_token) { + break_token_(break_token), + builder_(new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox, + layout_object)) { DCHECK(style_); } NGPhysicalFragment* NGInlineLayoutAlgorithm::Layout() { // TODO(kojii): Implement sizing and child constraint spaces. Share common // logic with NGBlockLayoutAlgorithm using composition. - builder_ = new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox); builder_->SetWritingMode(constraint_space_->WritingMode()); builder_->SetDirection(constraint_space_->Direction()); NGInlineNode* current_child = first_child_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h index 760531e..e37ba0d 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_layout_algorithm.h
@@ -12,6 +12,7 @@ namespace blink { class ComputedStyle; +class LayoutObject; class NGBreakToken; class NGConstraintSpace; class NGFragmentBuilder; @@ -26,12 +27,14 @@ class CORE_EXPORT NGInlineLayoutAlgorithm : public NGLayoutAlgorithm { public: // Default constructor. + // @param layout_object The LayoutObject associated with this anonymous block. // @param style Style reference of the block that is being laid out. // @param first_child Our first child; the algorithm will use its NextSibling // method to access all the children. // @param space The constraint space which the algorithm should generate a // fragment within. - NGInlineLayoutAlgorithm(PassRefPtr<const ComputedStyle>, + NGInlineLayoutAlgorithm(LayoutObject* layout_object, + PassRefPtr<const ComputedStyle> style, NGInlineNode* first_child, NGConstraintSpace* space, NGBreakToken* break_token = nullptr);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc index 76940e5f..34f3f3f 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.cc
@@ -25,7 +25,7 @@ namespace blink { NGInlineNode::NGInlineNode(LayoutObject* start_inline, - ComputedStyle* block_style) + const ComputedStyle* block_style) : NGLayoutInputNode(NGLayoutInputNodeType::kLegacyInline), start_inline_(start_inline), last_inline_(nullptr), @@ -246,6 +246,10 @@ return next_sibling_; } +LayoutObject* NGInlineNode::GetLayoutObject() { + return GetLayoutBlockFlow(); +} + // Find the first LayoutBlockFlow in the ancestor chain of |start_inilne_|. LayoutBlockFlow* NGInlineNode::GetLayoutBlockFlow() const { for (LayoutObject* layout_object = start_inline_->parent(); layout_object;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h index 1aaaec5..e01d502 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node.h
@@ -31,12 +31,13 @@ // Represents an inline node to be laid out. class CORE_EXPORT NGInlineNode : public NGLayoutInputNode { public: - NGInlineNode(LayoutObject* start_inline, ComputedStyle* block_style); + NGInlineNode(LayoutObject* start_inline, const ComputedStyle* block_style); ~NGInlineNode() override; NGPhysicalFragment* Layout(NGConstraintSpace*) override; void LayoutInline(NGConstraintSpace*, NGLineBuilder*); NGInlineNode* NextSibling() override; + LayoutObject* GetLayoutObject() override; // Prepare inline and text content for layout. Must be called before // calling the Layout method. @@ -67,7 +68,7 @@ LayoutObject* start_inline_; LayoutObject* last_inline_; - RefPtr<ComputedStyle> block_style_; + RefPtr<const ComputedStyle> block_style_; Member<NGInlineNode> next_sibling_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc index 7f51d7b..8a797d9 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_inline_node_test.cc
@@ -24,6 +24,8 @@ } using NGInlineNode::NGInlineNode; + LayoutObject* GetLayoutObject() override { return nullptr; } + String& Text() { return text_content_; } Vector<NGLayoutInlineItem>& Items() { return items_; } @@ -71,7 +73,8 @@ new NGTextLayoutAlgorithm(node, constraint_space); algorithm->LayoutInline(&line_builder); - NGFragmentBuilder fragment_builder(NGPhysicalFragment::kFragmentBox); + NGFragmentBuilder fragment_builder(NGPhysicalFragment::kFragmentBox, + /* layout_object */ nullptr); line_builder.CreateFragments(&fragment_builder); NGPhysicalBoxFragment* fragment = fragment_builder.ToBoxFragment(); for (const NGPhysicalFragment* child : fragment->Children()) {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc index 1050b23..89996db 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.cc
@@ -26,14 +26,17 @@ if (!block->CanUseNewLayout()) return new NGLegacyBlockLayoutAlgorithm(block, constraint_space); const ComputedStyle* style = block->Style(); + LayoutObject* layout_object = input_node->GetLayoutObject(); if (block->HasInlineChildren()) { NGInlineNode* child = toNGInlineNode(block->FirstChild()); - return new NGInlineLayoutAlgorithm(style, child, constraint_space); + return new NGInlineLayoutAlgorithm(layout_object, style, child, + constraint_space); } NGBlockNode* child = toNGBlockNode(block->FirstChild()); // TODO(layout-ng): The break token should be passed as an argument to this // method instead of getting it from the NGBlockNode NGBreakToken* token = block->CurrentBreakToken(); - return new NGBlockLayoutAlgorithm(style, child, constraint_space, token); + return new NGBlockLayoutAlgorithm(layout_object, style, child, + constraint_space, token); } }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.h index 91022a0..6e502df 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_node.h
@@ -10,6 +10,7 @@ namespace blink { +class LayoutObject; class NGConstraintSpace; class NGPhysicalFragment; class NGLayoutAlgorithm; @@ -30,6 +31,9 @@ // Returns the next sibling. virtual NGLayoutInputNode* NextSibling() = 0; + // Returns the LayoutObject which is associated with this node. + virtual LayoutObject* GetLayoutObject() = 0; + NGLayoutInputNodeType Type() const { return static_cast<NGLayoutInputNodeType>(type_); }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc index 7b85379..be0f9ab1 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_line_builder.cc
@@ -42,7 +42,8 @@ if (inline_box_->IsBidiEnabled()) BidiReorder(); - NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText); + NGFragmentBuilder text_builder(NGPhysicalFragment::kFragmentText, + inline_box_->GetLayoutObject()); text_builder.SetWritingMode(constraint_space_->WritingMode()); LayoutUnit inline_offset; const Vector<NGLayoutInlineItem>& items = inline_box_->Items();
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc index ee1b8d8a..8efd4f9 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.cc
@@ -7,16 +7,18 @@ namespace blink { NGPhysicalBoxFragment::NGPhysicalBoxFragment( + LayoutObject* layout_object, NGPhysicalSize size, NGPhysicalSize overflow, - HeapVector<Member<const NGPhysicalFragment>>& children, + HeapVector<Member<NGPhysicalFragment>>& children, HeapLinkedHashSet<WeakMember<NGBlockNode>>& out_of_flow_descendants, Vector<NGStaticPosition>& out_of_flow_positions, NGDeprecatedMarginStrut margin_strut, HeapVector<Member<NGFloatingObject>>& unpositioned_floats, HeapVector<Member<NGFloatingObject>>& positioned_floats, NGBreakToken* break_token) - : NGPhysicalFragment(size, + : NGPhysicalFragment(layout_object, + size, overflow, kFragmentBox, out_of_flow_descendants,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h index 0a9edc2..e9b2a171 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_box_fragment.h
@@ -19,9 +19,10 @@ public: // This modifies the passed-in children vector. NGPhysicalBoxFragment( + LayoutObject* layout_object, NGPhysicalSize size, NGPhysicalSize overflow, - HeapVector<Member<const NGPhysicalFragment>>& children, + HeapVector<Member<NGPhysicalFragment>>& children, HeapLinkedHashSet<WeakMember<NGBlockNode>>& out_of_flow_descendants, Vector<NGStaticPosition>& out_of_flow_positions, NGDeprecatedMarginStrut margin_strut, @@ -29,7 +30,7 @@ HeapVector<Member<NGFloatingObject>>& positioned_floats, NGBreakToken* break_token = nullptr); - const HeapVector<Member<const NGPhysicalFragment>>& Children() const { + const HeapVector<Member<NGPhysicalFragment>>& Children() const { return children_; } @@ -38,7 +39,7 @@ DECLARE_TRACE_AFTER_DISPATCH(); private: - HeapVector<Member<const NGPhysicalFragment>> children_; + HeapVector<Member<NGPhysicalFragment>> children_; NGDeprecatedMarginStrut margin_strut_; };
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc index f08f1c5b..147049b 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.cc
@@ -11,6 +11,7 @@ namespace blink { NGPhysicalFragment::NGPhysicalFragment( + LayoutObject* layout_object, NGPhysicalSize size, NGPhysicalSize overflow, NGFragmentType type, @@ -19,7 +20,8 @@ HeapVector<Member<NGFloatingObject>>& unpositioned_floats, HeapVector<Member<NGFloatingObject>>& positioned_floats, NGBreakToken* break_token) - : size_(size), + : layout_object_(layout_object), + size_(size), overflow_(overflow), break_token_(break_token), type_(type),
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h index a222834..bb69c7f 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_fragment.h
@@ -13,6 +13,7 @@ namespace blink { +class LayoutObject; class NGBlockNode; class NGBreakToken; struct NGFloatingObject; @@ -21,6 +22,10 @@ // fragment stores all of its information in the physical coordinate system for // use by paint, hit-testing etc. // +// The fragment keeps a pointer back to the LayoutObject which generated it. +// Once we have transitioned fully to LayoutNG it should be a const pointer +// such that paint/hit-testing/etc don't modify it. +// // Layout code should only access output layout information through the // NGFragmentBase classes which transforms information into the logical // coordinate system. @@ -64,6 +69,8 @@ NGBreakToken* BreakToken() const { return break_token_; } + LayoutObject* GetLayoutObject() const { return layout_object_; } + const HeapLinkedHashSet<WeakMember<NGBlockNode>>& OutOfFlowDescendants() const { return out_of_flow_descendants_; @@ -101,6 +108,7 @@ protected: NGPhysicalFragment( + LayoutObject* layout_object, NGPhysicalSize size, NGPhysicalSize overflow, NGFragmentType type, @@ -110,6 +118,7 @@ HeapVector<Member<NGFloatingObject>>& positioned_floats, NGBreakToken* break_token = nullptr); + LayoutObject* layout_object_; NGPhysicalSize size_; NGPhysicalSize overflow_; NGPhysicalOffset offset_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h index 7de145b..7bdfffb 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_physical_text_fragment.h
@@ -17,6 +17,7 @@ class CORE_EXPORT NGPhysicalTextFragment final : public NGPhysicalFragment { public: NGPhysicalTextFragment( + LayoutObject* layout_object, const NGInlineNode* node, unsigned start_index, unsigned end_index, @@ -26,7 +27,8 @@ Vector<NGStaticPosition> out_of_flow_positions, HeapVector<Member<NGFloatingObject>>& unpositioned_floats, HeapVector<Member<NGFloatingObject>>& positioned_floats) - : NGPhysicalFragment(size, + : NGPhysicalFragment(layout_object, + size, overflow, kFragmentText, out_of_flow_descendants,
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units.h b/third_party/WebKit/Source/core/layout/ng/ng_units.h index d5b98d1..f2a5972a 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_units.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_units.h
@@ -44,13 +44,6 @@ bool IsEmpty() const { return inline_size == LayoutUnit() || block_size == LayoutUnit(); } - - private: - friend class NGBlockLayoutAlgorithmTest; - // Used in tests. - NGLogicalSize(int inline_size, int block_size) - : inline_size(LayoutUnit(inline_size)), - block_size(LayoutUnit(block_size)) {} }; inline std::ostream& operator<<(std::ostream& stream, @@ -96,13 +89,6 @@ bool operator<=(const NGLogicalOffset& other) const; String ToString() const; - - private: - friend class NGBlockLayoutAlgorithmTest; - // Used in tests. - NGLogicalOffset(int inline_offset, int block_offset) - : inline_offset(LayoutUnit(inline_offset)), - block_offset(LayoutUnit(block_offset)) {} }; CORE_EXPORT inline std::ostream& operator<<(std::ostream& os, @@ -130,7 +116,7 @@ } }; -struct NGPhysicalSize { +struct CORE_EXPORT NGPhysicalSize { NGPhysicalSize() {} NGPhysicalSize(LayoutUnit width, LayoutUnit height) : width(width), height(height) {}
diff --git a/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp b/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp index c5c2ac2..276b3bc 100644 --- a/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp +++ b/third_party/WebKit/Source/core/loader/resource/ImageResourceTest.cpp
@@ -853,13 +853,53 @@ ResourceFetcher::create(ImageResourceTestMockFetchContext::create()); FetchRequest request(testURL, FetchInitiatorInfo()); ImageResource* imageResource = ImageResource::fetch(request, fetcher); + std::unique_ptr<MockImageResourceObserver> observer = + MockImageResourceObserver::create(imageResource->getContent()); imageResource->loader()->didReceiveResponse( WrappedResourceResponse( ResourceResponse(testURL, "image/jpeg", 18, nullAtom, String())), nullptr); + + EXPECT_EQ(0, observer->imageChangedCount()); + imageResource->loader()->didReceiveData("notactuallyanimage", 18); + EXPECT_EQ(ResourceStatus::DecodeError, imageResource->getStatus()); + EXPECT_TRUE(observer->imageNotifyFinishedCalled()); + EXPECT_EQ(ResourceStatus::DecodeError, + observer->statusOnImageNotifyFinished()); + EXPECT_EQ(2, observer->imageChangedCount()); + EXPECT_FALSE(imageResource->isLoading()); +} + +TEST(ImageResourceTest, DecodeErrorWithEmptyBody) { + KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.html"); + ScopedRegisteredURL scopedRegisteredURL(testURL); + + ResourceFetcher* fetcher = + ResourceFetcher::create(ImageResourceTestMockFetchContext::create()); + FetchRequest request(testURL, FetchInitiatorInfo()); + ImageResource* imageResource = ImageResource::fetch(request, fetcher); + std::unique_ptr<MockImageResourceObserver> observer = + MockImageResourceObserver::create(imageResource->getContent()); + + imageResource->loader()->didReceiveResponse( + WrappedResourceResponse( + ResourceResponse(testURL, "image/jpeg", 0, nullAtom, String())), + nullptr); + + EXPECT_EQ(ResourceStatus::Pending, imageResource->getStatus()); + EXPECT_FALSE(observer->imageNotifyFinishedCalled()); + EXPECT_EQ(0, observer->imageChangedCount()); + + imageResource->loader()->didFinishLoading(0.0, 0, 0); + + EXPECT_EQ(ResourceStatus::DecodeError, imageResource->getStatus()); + EXPECT_TRUE(observer->imageNotifyFinishedCalled()); + EXPECT_EQ(ResourceStatus::DecodeError, + observer->statusOnImageNotifyFinished()); + EXPECT_EQ(1, observer->imageChangedCount()); EXPECT_FALSE(imageResource->isLoading()); } @@ -1027,6 +1067,9 @@ imageResource->loader()->didReceiveResponse( WrappedResourceResponse(ResourceResponse( testURL, "image/jpeg", sizeof(kBadData), nullAtom, String()))); + + EXPECT_EQ(0, observer->imageChangedCount()); + imageResource->loader()->didReceiveData(kBadData, sizeof(kBadData)); // The dimensions could not be extracted, so the full original image should be @@ -1039,6 +1082,7 @@ static_cast<int>(WebCachePolicy::BypassingCache), static_cast<int>(imageResource->resourceRequest().getCachePolicy())); EXPECT_FALSE(observer->imageNotifyFinishedCalled()); + EXPECT_EQ(3, observer->imageChangedCount()); imageResource->loader()->didReceiveResponse( WrappedResourceResponse(ResourceResponse( @@ -1051,7 +1095,7 @@ EXPECT_EQ(ResourceStatus::Cached, imageResource->getStatus()); EXPECT_EQ(sizeof(kJpegImage), imageResource->encodedSize()); EXPECT_FALSE(imageResource->isPlaceholder()); - EXPECT_LT(0, observer->imageChangedCount()); + EXPECT_LT(3, observer->imageChangedCount()); EXPECT_EQ(kJpegImageWidth, observer->imageWidthOnLastImageChanged()); EXPECT_TRUE(observer->imageNotifyFinishedCalled()); EXPECT_EQ(kJpegImageWidth, observer->imageWidthOnImageNotifyFinished());
diff --git a/third_party/WebKit/Source/core/loader/resource/MockImageResourceObserver.cpp b/third_party/WebKit/Source/core/loader/resource/MockImageResourceObserver.cpp index 504ee10a..0432687 100644 --- a/third_party/WebKit/Source/core/loader/resource/MockImageResourceObserver.cpp +++ b/third_party/WebKit/Source/core/loader/resource/MockImageResourceObserver.cpp
@@ -44,6 +44,7 @@ m_imageNotifyFinishedCount++; m_imageWidthOnImageNotifyFinished = m_content->hasImage() ? m_content->getImage()->width() : 0; + m_statusOnImageNotifyFinished = m_content->getStatus(); } bool MockImageResourceObserver::imageNotifyFinishedCalled() const {
diff --git a/third_party/WebKit/Source/core/loader/resource/MockImageResourceObserver.h b/third_party/WebKit/Source/core/loader/resource/MockImageResourceObserver.h index 0fdabb11..44028471 100644 --- a/third_party/WebKit/Source/core/loader/resource/MockImageResourceObserver.h +++ b/third_party/WebKit/Source/core/loader/resource/MockImageResourceObserver.h
@@ -8,6 +8,7 @@ #include "core/loader/resource/ImageResource.h" #include "core/loader/resource/ImageResourceContent.h" #include "core/loader/resource/ImageResourceObserver.h" +#include "platform/loader/fetch/ResourceStatus.h" #include <memory> namespace blink { @@ -31,6 +32,9 @@ int imageWidthOnImageNotifyFinished() const { return m_imageWidthOnImageNotifyFinished; } + ResourceStatus statusOnImageNotifyFinished() const { + return m_statusOnImageNotifyFinished; + } private: explicit MockImageResourceObserver(ImageResourceContent*); @@ -45,6 +49,7 @@ int m_imageWidthOnLastImageChanged; int m_imageNotifyFinishedCount; int m_imageWidthOnImageNotifyFinished; + ResourceStatus m_statusOnImageNotifyFinished = ResourceStatus::NotStarted; }; } // namespace blink
diff --git a/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js b/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js index 379e79a..79463a2 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js +++ b/third_party/WebKit/Source/devtools/front_end/components/JavaScriptAutocomplete.js
@@ -14,13 +14,24 @@ * @return {!Promise<!UI.SuggestBox.Suggestions>} */ Components.JavaScriptAutocomplete.completionsForTextInCurrentContext = function(text, query, force) { + var clippedExpression = Components.JavaScriptAutocomplete._clipExpression(text, true); + var mapCompletionsPromise = Components.JavaScriptAutocomplete._mapCompletions(text, query); + return Components.JavaScriptAutocomplete.completionsForExpression(clippedExpression, query, force) + .then(completions => mapCompletionsPromise.then(mapCompletions => mapCompletions.concat(completions))); +}; + +/** + * @param {string} text + * @param {boolean=} allowEndingBracket + * @return {string} + */ +Components.JavaScriptAutocomplete._clipExpression = function(text, allowEndingBracket) { var index; var stopChars = new Set('=:({;,!+-*/&|^<>`'.split('')); var whiteSpaceChars = new Set(' \r\n\t'.split('')); var continueChars = new Set('[. \r\n\t'.split('')); for (index = text.length - 1; index >= 0; index--) { - // Pass less stop characters to rangeOfWord so the range will be a more complete expression. if (stopChars.has(text.charAt(index))) break; if (whiteSpaceChars.has(text.charAt(index)) && !continueChars.has(text.charAt(index - 1))) @@ -35,16 +46,112 @@ if (character === ']') bracketCount++; // Allow an open bracket at the end for property completion. - if (character === '[' && index < clippedExpression.length - 1) { + if (character === '[' && (index < clippedExpression.length - 1 || !allowEndingBracket)) { bracketCount--; if (bracketCount < 0) break; } index--; } - clippedExpression = clippedExpression.substring(index + 1).trim(); + return clippedExpression.substring(index + 1).trim(); +}; - return Components.JavaScriptAutocomplete.completionsForExpression(clippedExpression, query, force); +/** + * @param {string} text + * @param {string} query + * @return {!Promise<!UI.SuggestBox.Suggestions>} + */ +Components.JavaScriptAutocomplete._mapCompletions = function(text, query) { + var mapMatch = text.match(/\.\s*(get|set|delete)\s*\(\s*$/); + var executionContext = UI.context.flavor(SDK.ExecutionContext); + if (!executionContext || !mapMatch) + return Promise.resolve([]); + + var clippedExpression = Components.JavaScriptAutocomplete._clipExpression(text.substring(0, mapMatch.index)); + var fulfill; + var promise = new Promise(x => fulfill = x); + executionContext.evaluate(clippedExpression, 'completion', true, true, false, false, false, evaluated); + return promise; + + /** + * @param {?SDK.RemoteObject} result + * @param {!Protocol.Runtime.ExceptionDetails=} exceptionDetails + */ + function evaluated(result, exceptionDetails) { + if (!result || !!exceptionDetails || result.subtype !== 'map') { + fulfill([]); + return; + } + result.getOwnPropertiesPromise(false).then(extractEntriesProperty); + } + + /** + * @param {!{properties: ?Array<!SDK.RemoteObjectProperty>, internalProperties: ?Array<!SDK.RemoteObjectProperty>}} properties + */ + function extractEntriesProperty(properties) { + var internalProperties = properties.internalProperties || []; + var entriesProperty = internalProperties.find(property => property.name === '[[Entries]]'); + if (!entriesProperty) { + fulfill([]); + return; + } + entriesProperty.value.callFunctionJSONPromise(getEntries).then(keysObj => gotKeys(Object.keys(keysObj))); + } + + /** + * @suppressReceiverCheck + * @this {!Array<{key:?, value:?}>} + * @return {!Object} + */ + function getEntries() { + var result = {__proto__: null}; + for (var i = 0; i < this.length; i++) { + if (typeof this[i].key === 'string') + result[this[i].key] = true; + } + return result; + } + + /** + * @param {!Array<string>} rawKeys + */ + function gotKeys(rawKeys) { + var caseSensitivePrefix = []; + var caseInsensitivePrefix = []; + var caseSensitiveAnywhere = []; + var caseInsensitiveAnywhere = []; + var quoteChar = '"'; + if (query.startsWith('\'')) + quoteChar = '\''; + var endChar = ')'; + if (mapMatch[0].indexOf('set') !== -1) + endChar = ', '; + + var sorter = rawKeys.length < 1000 ? String.naturalOrderComparator : undefined; + var keys = rawKeys.sort(sorter).map(key => quoteChar + key + quoteChar + endChar); + + for (var key of keys) { + if (key.length < query.length) + continue; + if (query.length && key.toLowerCase().indexOf(query.toLowerCase()) === -1) + continue; + // Substitute actual newlines with newline characters. @see crbug.com/498421 + var title = key.split('\n').join('\\n'); + + if (key.startsWith(query)) + caseSensitivePrefix.push({title: title, priority: 4}); + else if (key.toLowerCase().startsWith(query.toLowerCase())) + caseInsensitivePrefix.push({title: title, priority: 3}); + else if (key.indexOf(query) !== -1) + caseSensitiveAnywhere.push({title: title, priority: 2}); + else + caseInsensitiveAnywhere.push({title: title, priority: 1}); + } + var suggestions = caseSensitivePrefix.concat(caseInsensitivePrefix, caseSensitiveAnywhere, caseInsensitiveAnywhere); + if (suggestions.length) + suggestions[0].subtitle = Common.UIString('Keys'); + fulfill(suggestions); + } }; /** @@ -76,8 +183,8 @@ if (!query && !expressionString && !force) return Promise.resolve([]); - var fufill; - var promise = new Promise(x => fufill = x); + var fulfill; + var promise = new Promise(x => fulfill = x); var selectedFrame = executionContext.debuggerModel.selectedCallFrame(); if (!expressionString && selectedFrame) variableNamesInScopes(selectedFrame, receivedPropertyNames); @@ -91,7 +198,7 @@ */ function evaluated(result, exceptionDetails) { if (!result || !!exceptionDetails) { - fufill([]); + fulfill([]); return; } @@ -223,7 +330,7 @@ if (result && !exceptionDetails) receivedPropertyNames(/** @type {!Object} */ (result.value)); else - fufill([]); + fulfill([]); } /** @@ -232,7 +339,7 @@ function receivedPropertyNames(object) { executionContext.target().runtimeAgent().releaseObjectGroup('completion'); if (!object) { - fufill([]); + fulfill([]); return; } var propertyGroups = /** @type {!Array<!Components.JavaScriptAutocomplete.CompletionGroup>} */ (object); @@ -262,7 +369,7 @@ ]; propertyGroups.push({items: commandLineAPI}); } - fufill(Components.JavaScriptAutocomplete._completionsForQuery( + fulfill(Components.JavaScriptAutocomplete._completionsForQuery( dotNotation, bracketNotation, expressionString, query, propertyGroups)); } }; @@ -296,7 +403,7 @@ var result = []; var lastGroupTitle; for (var group of propertyGroups) { - group.items.sort(itemComparator); + group.items.sort(itemComparator.bind(null, group.items.length > 1000)); var caseSensitivePrefix = []; var caseInsensitivePrefix = []; var caseSensitiveAnywhere = []; @@ -340,17 +447,18 @@ return result; /** + * @param {boolean} naturalOrder * @param {string} a * @param {string} b * @return {number} */ - function itemComparator(a, b) { + function itemComparator(naturalOrder, a, b) { var aStartsWithUnderscore = a.startsWith('_'); var bStartsWithUnderscore = b.startsWith('_'); if (aStartsWithUnderscore && !bStartsWithUnderscore) return 1; if (bStartsWithUnderscore && !aStartsWithUnderscore) return -1; - return String.naturalOrderComparator(a, b); + return naturalOrder ? String.naturalOrderComparator(a, b) : a.localeCompare(b); } };
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js b/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js index 5351fa7..11d9e33 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsolePrompt.js
@@ -264,7 +264,7 @@ var excludedTokens = new Set(['js-comment', 'js-string-2', 'js-def']); var trimmedBefore = before.trim(); - if (!trimmedBefore.endsWith('[')) + if (!trimmedBefore.endsWith('[') && !trimmedBefore.match(/\.\s*(get|set|delete)\s*\(\s*$/)) excludedTokens.add('js-string'); if (!trimmedBefore.endsWith('.')) excludedTokens.add('js-property');
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogViewColumns.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogViewColumns.js index 7dc4d44a2..37a7b2f2 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogViewColumns.js +++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogViewColumns.js
@@ -263,9 +263,9 @@ var columnId = this._dataGrid.sortColumnId(); this._networkLogView.removeAllNodeHighlights(); this._waterfallRequestsAreStale = true; - if (columnId === 'waterfall') { - this._waterfallColumnSortIcon.classList.remove('sort-ascending', 'sort-descending'); + this._waterfallColumnSortIcon.classList.remove('sort-ascending', 'sort-descending'); + if (columnId === 'waterfall') { if (this._dataGrid.sortOrder() === DataGrid.DataGrid.Order.Ascending) this._waterfallColumnSortIcon.classList.add('sort-ascending'); else
diff --git a/third_party/WebKit/Source/devtools/front_end/network/networkLogView.css b/third_party/WebKit/Source/devtools/front_end/network/networkLogView.css index 73a9653..a434b65 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/networkLogView.css +++ b/third_party/WebKit/Source/devtools/front_end/network/networkLogView.css
@@ -389,6 +389,12 @@ display: none; } +@media (-webkit-min-device-pixel-ratio: 1.1) { +.network-waterfall-header .sort-order-icon { + background-image: url(Images/toolbarButtonGlyphs_2x.png); +} +} /* media */ + .network-waterfall-header .sort-ascending.sort-order-icon { display: block; background-position: -4px -111px;
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp index 8737ae9..5c3b653 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
@@ -32,6 +32,7 @@ #include "core/dom/DOMException.h" #include "core/dom/ExceptionCode.h" #include "core/dom/ExecutionContext.h" +#include "core/dom/TaskRunnerHelper.h" #include "core/html/HTMLMediaElement.h" #include "modules/encryptedmedia/ContentDecryptionModuleResultPromise.h" #include "modules/encryptedmedia/EncryptedMediaUtils.h" @@ -142,7 +143,9 @@ m_cdm(std::move(cdm)), m_mediaElement(nullptr), m_reservedForMediaElement(false), - m_timer(this, &MediaKeys::timerFired) { + m_timer(TaskRunnerHelper::get(TaskType::MiscPlatformAPI, context), + this, + &MediaKeys::timerFired) { DVLOG(MEDIA_KEYS_LOG_LEVEL) << __func__ << "(" << this << ")"; InstanceCounters::incrementCounter(InstanceCounters::MediaKeysCounter); }
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.h b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.h index 9d69dd78..edb874e 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.h +++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.h
@@ -128,7 +128,7 @@ bool m_reservedForMediaElement; HeapDeque<Member<PendingAction>> m_pendingActions; - Timer<MediaKeys> m_timer; + TaskRunnerTimer<MediaKeys> m_timer; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/presentation/PresentationError.cpp b/third_party/WebKit/Source/modules/presentation/PresentationError.cpp index f238e04..3b1aca0 100644 --- a/third_party/WebKit/Source/modules/presentation/PresentationError.cpp +++ b/third_party/WebKit/Source/modules/presentation/PresentationError.cpp
@@ -24,6 +24,9 @@ case WebPresentationError::ErrorTypeAvailabilityNotSupported: code = NotSupportedError; break; + case WebPresentationError::ErrorTypePreviousStartInProgress: + code = OperationError; + break; case WebPresentationError::ErrorTypeUnknown: code = UnknownError; break;
diff --git a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp index fb749cad..0a4e6e6 100644 --- a/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp +++ b/third_party/WebKit/Source/platform/testing/WebLayerTreeViewImplForTesting.cpp
@@ -9,7 +9,7 @@ #include "cc/animation/animation_timeline.h" #include "cc/blink/web_layer_impl.h" #include "cc/layers/layer.h" -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "public/platform/Platform.h" #include "public/platform/WebLayer.h" @@ -24,14 +24,13 @@ WebLayerTreeViewImplForTesting::WebLayerTreeViewImplForTesting( const cc::LayerTreeSettings& settings) { m_animationHost = cc::AnimationHost::CreateMainInstance(); - cc::LayerTreeHostInProcess::InitParams params; + cc::LayerTreeHost::InitParams params; params.client = this; params.settings = &settings; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); params.task_graph_runner = &m_taskGraphRunner; params.mutator_host = m_animationHost.get(); - m_layerTreeHost = - cc::LayerTreeHostInProcess::CreateSingleThreaded(this, ¶ms); + m_layerTreeHost = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); ASSERT(m_layerTreeHost); }
diff --git a/third_party/WebKit/Source/web/tests/NGInlineLayoutTest.cpp b/third_party/WebKit/Source/web/tests/NGInlineLayoutTest.cpp index 1645943..897ffa5 100644 --- a/third_party/WebKit/Source/web/tests/NGInlineLayoutTest.cpp +++ b/third_party/WebKit/Source/web/tests/NGInlineLayoutTest.cpp
@@ -49,7 +49,8 @@ NGInlineNode* inlineBox = new NGInlineNode(blockFlow->firstChild(), blockFlow->mutableStyle()); NGPhysicalFragment* fragment = - NGInlineLayoutAlgorithm(blockFlow->style(), inlineBox, constraintSpace) + NGInlineLayoutAlgorithm(blockFlow, blockFlow->style(), inlineBox, + constraintSpace) .Layout(); EXPECT_TRUE(fragment); @@ -75,7 +76,8 @@ NGInlineNode* inlineBox = new NGInlineNode(blockFlow->firstChild(), blockFlow->mutableStyle()); NGPhysicalFragment* fragment = - NGInlineLayoutAlgorithm(blockFlow->style(), inlineBox, constraintSpace) + NGInlineLayoutAlgorithm(blockFlow, blockFlow->style(), inlineBox, + constraintSpace) .Layout(); EXPECT_TRUE(fragment);
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py index a1d3d966..5ee9604 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater.py
@@ -342,6 +342,7 @@ description += 'TBR=qyearsley@chromium.org\n' # Move any NOEXPORT tag to the end of the description. description = description.replace('NOEXPORT=true', '') + description = description.replace('\n\n\n\n', '\n\n') description += 'NOEXPORT=true' return description
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py index 2cd16a9..a590744 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/deps_updater_unittest.py
@@ -81,12 +81,12 @@ def test_cl_description_with_empty_environ(self): host = MockHost() - host.executive = MockExecutive(output='Last commit message\n') + host.executive = MockExecutive(output='Last commit message\n\n') updater = DepsUpdater(host) description = updater._cl_description() self.assertEqual( description, - ('Last commit message\n' + ('Last commit message\n\n' 'TBR=qyearsley@chromium.org\n' 'NOEXPORT=true')) self.assertEqual(host.executive.calls, [['git', 'log', '-1', '--format=%B']]) @@ -109,7 +109,7 @@ def test_cl_description_moves_noexport_tag(self): host = MockHost() - host.executive = MockExecutive(output='Summary\n\nNOEXPORT=true') + host.executive = MockExecutive(output='Summary\n\nNOEXPORT=true\n\n') updater = DepsUpdater(host) description = updater._cl_description() self.assertEqual(
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py index ceb7387..e053170 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
@@ -70,7 +70,7 @@ def all_branches(self): """Returns a list of local and remote branches.""" - return self.run(['git', 'branch', '-a']).splitlines() + return [s.strip() for s in self.run(['git', 'branch', '-a']).splitlines()] def create_branch_with_patch(self, message, patch, author): """Commits the given patch and pushes to the upstream repo. @@ -95,6 +95,7 @@ # TODO(jeffcarp): Use git am -p<n> where n is len(CHROMIUM_WPT_DIR.split(/')) # or something not off-by-one. self.run(['git', 'apply', '-'], input=patch) + self.run(['git', 'add', '.']) self.run(['git', 'commit', '--author', author, '-am', message]) self.run(['git', 'push', REMOTE_NAME, self.branch_name])
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py index f90c772..8591941 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
@@ -96,5 +96,6 @@ ['git', 'branch', '-a'], ['git', 'checkout', '-b', 'chromium-export-try'], ['git', 'apply', '-'], + ['git', 'add', '.'], ['git', 'commit', '--author', 'author', '-am', 'message'], ['git', 'push', 'github', 'chromium-export-try']])
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_github.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_github.py index e3f6b73a..4cc6fb8 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_github.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_github.py
@@ -96,11 +96,12 @@ raise Exception('PR could not be merged: %d' % pull_request_number) def delete_remote_branch(self, remote_branch_name): + # TODO(jeffcarp): Unit test this method path = '/repos/w3c/web-platform-tests/git/refs/heads/%s' % remote_branch_name data, status_code = self.request(path, method='DELETE') - if status_code != 200: + if status_code != 204: # TODO(jeffcarp): Raise more specific exception (create MergeError class?) - raise Exception('PR could not be merged') + raise Exception('Received non-204 status code attempting to delete remote branch: {}'.format(status_code)) return data
diff --git a/third_party/WebKit/public/platform/modules/presentation/WebPresentationError.h b/third_party/WebKit/public/platform/modules/presentation/WebPresentationError.h index f12792ef..ed01d8d84 100644 --- a/third_party/WebKit/public/platform/modules/presentation/WebPresentationError.h +++ b/third_party/WebKit/public/platform/modules/presentation/WebPresentationError.h
@@ -15,6 +15,7 @@ ErrorTypeSessionRequestCancelled, ErrorTypeNoPresentationFound, ErrorTypeAvailabilityNotSupported, + ErrorTypePreviousStartInProgress, ErrorTypeUnknown, ErrorTypeLast = ErrorTypeUnknown };
diff --git a/third_party/WebKit/public/platform/modules/presentation/presentation.mojom b/third_party/WebKit/public/platform/modules/presentation/presentation.mojom index 96aea0c7..7af9140 100644 --- a/third_party/WebKit/public/platform/modules/presentation/presentation.mojom +++ b/third_party/WebKit/public/platform/modules/presentation/presentation.mojom
@@ -30,6 +30,7 @@ NO_AVAILABLE_SCREENS, SESSION_REQUEST_CANCELLED, NO_PRESENTATION_FOUND, + PREVIOUS_START_IN_PROGRESS, UNKNOWN, };
diff --git a/tools/perf/PRESUBMIT.py b/tools/perf/PRESUBMIT.py index ec698c42..25fe5f4 100644 --- a/tools/perf/PRESUBMIT.py +++ b/tools/perf/PRESUBMIT.py
@@ -9,7 +9,6 @@ """ import os -import re import sys @@ -96,50 +95,3 @@ report = [] report.extend(_CommonChecks(input_api, output_api)) return report - - -def _AreBenchmarksModified(change): - """Checks whether CL contains any modification to Telemetry benchmarks.""" - for affected_file in change.AffectedFiles(): - file_path = affected_file.LocalPath() - # Changes to unittest files should not count. - if file_path.endswith('test.py'): - continue - if (os.path.join('tools', 'perf', 'benchmarks') in file_path or - os.path.join('tools', 'perf', 'measurements') in file_path): - return True - return False - - -def PostUploadHook(cl, change, output_api): - """git cl upload will call this hook after the issue is created/modified. - - This hook adds extra try bots list to the CL description in order to run - Telemetry benchmarks on Perf trybots in addition to CQ trybots if the CL - contains any changes to Telemetry benchmarks. - """ - benchmarks_modified = _AreBenchmarksModified(change) - rietveld_obj = cl.RpcServer() - issue = cl.issue - original_description = rietveld_obj.get_description(issue) - if not benchmarks_modified or re.search( - r'^CQ_INCLUDE_TRYBOTS=.*', original_description, re.M | re.I): - return [] - - results = [] - bots = [ - 'linux_perf_cq', - 'mac_retina_perf_cq', - 'winx64_10_perf_cq' - ] - bots = ['master.tryserver.chromium.perf:%s' % s for s in bots] - bots_string = ';'.join(bots) - description = original_description - description += '\nCQ_INCLUDE_TRYBOTS=%s' % bots_string - results.append(output_api.PresubmitNotifyResult( - 'Automatically added Perf trybots to run Telemetry benchmarks on CQ.')) - - if description != original_description: - rietveld_obj.update_description(issue, description) - - return results
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index fb0fe72..236560d 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -30,7 +30,7 @@ #include "cc/scheduler/begin_frame_source.h" #include "cc/surfaces/surface_id_allocator.h" #include "cc/surfaces/surface_manager.h" -#include "cc/trees/layer_tree_host_in_process.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/compositor/compositor_observer.h" @@ -193,13 +193,13 @@ animation_host_ = cc::AnimationHost::CreateMainInstance(); - cc::LayerTreeHostInProcess::InitParams params; + cc::LayerTreeHost::InitParams params; params.client = this; params.task_graph_runner = context_factory_->GetTaskGraphRunner(); params.settings = &settings; params.main_task_runner = task_runner_; params.mutator_host = animation_host_.get(); - host_ = cc::LayerTreeHostInProcess::CreateSingleThreaded(this, ¶ms); + host_ = cc::LayerTreeHost::CreateSingleThreaded(this, ¶ms); UMA_HISTOGRAM_TIMES("GPU.CreateBrowserCompositor", base::TimeTicks::Now() - before_create);
diff --git a/ui/views/corewm/tooltip_controller.cc b/ui/views/corewm/tooltip_controller.cc index cd1792f..a52c806 100644 --- a/ui/views/corewm/tooltip_controller.cc +++ b/ui/views/corewm/tooltip_controller.cc
@@ -25,12 +25,13 @@ #include "ui/gfx/text_elider.h" #include "ui/views/corewm/tooltip.h" #include "ui/views/widget/tooltip_manager.h" +#include "ui/wm/public/tooltip_client.h" namespace views { namespace corewm { namespace { -const int kTooltipTimeoutMs = 500; +const int kDelayForTooltipUpdateInMs = 500; const int kDefaultTooltipShownTimeoutMs = 10000; #if defined(OS_WIN) // Drawing a long word in tooltip is very slow on Windows. crbug.com/513693 @@ -129,11 +130,8 @@ tooltip_id_(NULL), tooltip_window_at_mouse_press_(NULL), tooltip_(std::move(tooltip)), - tooltips_enabled_(true) { - tooltip_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs), - this, &TooltipController::TooltipTimerFired); -} + tooltips_enabled_(true), + tooltip_show_delayed_(true) {} TooltipController::~TooltipController() { if (tooltip_window_) @@ -150,9 +148,7 @@ UpdateIfRequired(); // Reset |tooltip_window_at_mouse_press_| if the moving within the same window - // but over a region that has different tooltip text. By resetting - // |tooltip_window_at_mouse_press_| we ensure the next time the timer fires - // we'll requery for the tooltip text. + // but over a region that has different tooltip text. // This handles the case of clicking on a view, moving within the same window // but over a different view, than back to the original. if (tooltip_window_at_mouse_press_ && @@ -160,17 +156,6 @@ aura::client::GetTooltipText(target) != tooltip_text_at_mouse_press_) { tooltip_window_at_mouse_press_ = NULL; } - - // If we had stopped the tooltip timer for some reason, we must restart it if - // there is a change in the tooltip. - if (!tooltip_timer_.IsRunning()) { - if (tooltip_window_ != target || (tooltip_window_ && - tooltip_text_ != aura::client::GetTooltipText(tooltip_window_))) { - tooltip_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(kTooltipTimeoutMs), - this, &TooltipController::TooltipTimerFired); - } - } } void TooltipController::SetTooltipShownTimeout(aura::Window* target, @@ -211,10 +196,10 @@ target = GetTooltipTarget(*event, &curr_mouse_loc_); } SetTooltipWindow(target); - if (tooltip_timer_.IsRunning()) - tooltip_timer_.Reset(); - if (tooltip_->IsVisible()) + if (tooltip_->IsVisible() || + (tooltip_window_ && + tooltip_text_ != aura::client::GetTooltipText(tooltip_window_))) UpdateIfRequired(); break; } @@ -232,10 +217,6 @@ // Hide the tooltip for click, release, drag, wheel events. if (tooltip_->IsVisible()) tooltip_->Hide(); - - // Don't reshow the tooltip during scroll. - if (tooltip_timer_.IsRunning()) - tooltip_timer_.Reset(); break; default: break; @@ -255,6 +236,10 @@ SetTooltipWindow(NULL); } +void TooltipController::OnCursorVisibilityChanged(bool is_visible) { + UpdateIfRequired(); +} + void TooltipController::OnWindowDestroyed(aura::Window* window) { if (tooltip_window_ == window) { tooltip_->Hide(); @@ -263,25 +248,26 @@ } } +void TooltipController::OnWindowPropertyChanged(aura::Window* window, + const void* key, + intptr_t old) { + if ((key == aura::client::kTooltipIdKey || + key == aura::client::kTooltipTextKey) && + aura::client::GetTooltipText(window) != base::string16() && + (tooltip_text_ != aura::client::GetTooltipText(window) || + tooltip_id_ != aura::client::GetTooltipId(window))) + UpdateIfRequired(); +} + //////////////////////////////////////////////////////////////////////////////// // TooltipController private: -void TooltipController::TooltipTimerFired() { - UpdateIfRequired(); -} - void TooltipController::TooltipShownTimerFired() { tooltip_->Hide(); - - // Since the user presumably no longer needs the tooltip, we also stop the - // tooltip timer so that tooltip does not pop back up. We will restart this - // timer if the tooltip changes (see UpdateTooltip()). - tooltip_timer_.Stop(); } void TooltipController::UpdateIfRequired() { - if (!tooltips_enabled_ || - aura::Env::GetInstance()->IsMouseButtonDown() || + if (!tooltips_enabled_ || aura::Env::GetInstance()->IsMouseButtonDown() || IsDragDropInProgress() || !IsCursorVisible()) { tooltip_->Hide(); return; @@ -309,9 +295,6 @@ ids_differ = tooltip_id_ != tooltip_id; tooltip_id_ = tooltip_id; - // We add the !tooltip_->IsVisible() below because when we come here from - // TooltipTimerFired(), the tooltip_text may not have changed but we still - // want to update the tooltip because the timer has fired. // If we come here from UpdateTooltip(), we have already checked for tooltip // visibility and this check below will have no effect. if (tooltip_text_ != tooltip_text || !tooltip_->IsVisible() || ids_differ) { @@ -321,26 +304,44 @@ gfx::TruncateString(tooltip_text_, kMaxTooltipLength, gfx::WORD_BREAK); // If the string consists entirely of whitespace, then don't both showing it // (an empty tooltip is useless). - base::string16 whitespace_removed_text; base::TrimWhitespace(trimmed_text, base::TRIM_ALL, - &whitespace_removed_text); - if (whitespace_removed_text.empty()) { + &tooltip_text_whitespace_trimmed_); + if (tooltip_text_whitespace_trimmed_.empty()) { tooltip_->Hide(); - } else { - gfx::Point widget_loc = curr_mouse_loc_ + - tooltip_window_->GetBoundsInScreen().OffsetFromOrigin(); - tooltip_->SetText(tooltip_window_, whitespace_removed_text, widget_loc); - tooltip_->Show(); - int timeout = GetTooltipShownTimeout(); - if (timeout > 0) { - tooltip_shown_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(timeout), - this, &TooltipController::TooltipShownTimerFired); + } else if (tooltip_show_delayed_) { + // Initialize the one-shot timer to show the tooltip in a while. + // If there is already a request queued then cancel it and post the new + // request. This ensures that tooltip won't show up too early. + // The delayed appearance of a tooltip is by default. + if (tooltip_defer_timer_.IsRunning()) { + tooltip_defer_timer_.Reset(); + } else { + tooltip_defer_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( + kDelayForTooltipUpdateInMs), + this, &TooltipController::ShowTooltip); } + } else { + ShowTooltip(); // Allow tooltip to show up without delay for unit tests. } } } +void TooltipController::ShowTooltip() { + if (!tooltip_window_) + return; + gfx::Point widget_loc = + curr_mouse_loc_ + tooltip_window_->GetBoundsInScreen().OffsetFromOrigin(); + tooltip_->SetText(tooltip_window_, tooltip_text_whitespace_trimmed_, + widget_loc); + tooltip_->Show(); + int timeout = GetTooltipShownTimeout(); + if (timeout > 0) { + tooltip_shown_timer_.Start(FROM_HERE, + base::TimeDelta::FromMilliseconds(timeout), this, + &TooltipController::TooltipShownTimerFired); + } +} + bool TooltipController::IsTooltipVisible() { return tooltip_->IsVisible(); }
diff --git a/ui/views/corewm/tooltip_controller.h b/ui/views/corewm/tooltip_controller.h index 5a274e3..630df74 100644 --- a/ui/views/corewm/tooltip_controller.h +++ b/ui/views/corewm/tooltip_controller.h
@@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "base/timer/timer.h" +#include "ui/aura/client/cursor_client_observer.h" #include "ui/aura/window_observer.h" #include "ui/events/event_handler.h" #include "ui/gfx/geometry/point.h" @@ -31,9 +32,11 @@ } // namespace test // TooltipController provides tooltip functionality for aura. -class VIEWS_EXPORT TooltipController : public aura::client::TooltipClient, - public ui::EventHandler, - public aura::WindowObserver { +class VIEWS_EXPORT TooltipController + : public aura::client::TooltipClient, + public ui::EventHandler, + public aura::client::CursorClientObserver, + public aura::WindowObserver { public: explicit TooltipController(std::unique_ptr<Tooltip> tooltip); ~TooltipController() override; @@ -50,17 +53,25 @@ void OnTouchEvent(ui::TouchEvent* event) override; void OnCancelMode(ui::CancelModeEvent* event) override; + // Overridden from aura::client::CursorClientObserver. + void OnCursorVisibilityChanged(bool is_visible) override; + // Overridden from aura::WindowObserver. void OnWindowDestroyed(aura::Window* window) override; + void OnWindowPropertyChanged(aura::Window* window, + const void* key, + intptr_t old) override; const gfx::Point& mouse_location() const { return curr_mouse_loc_; } private: friend class test::TooltipControllerTestHelper; - void TooltipTimerFired(); void TooltipShownTimerFired(); + // Show the tooltip. + void ShowTooltip(); + // Updates the tooltip if required (if there is any change in the tooltip // text, tooltip id or the aura::Window). void UpdateIfRequired(); @@ -80,8 +91,11 @@ // Calls AddObserver on the new window if it is not NULL. void SetTooltipWindow(aura::Window* target); + void DisableTooltipShowDelay() { tooltip_show_delayed_ = false; } + aura::Window* tooltip_window_; base::string16 tooltip_text_; + base::string16 tooltip_text_whitespace_trimmed_; const void* tooltip_id_; // These fields are for tracking state when the user presses a mouse button. @@ -90,7 +104,8 @@ std::unique_ptr<Tooltip> tooltip_; - base::RepeatingTimer tooltip_timer_; + // Timer for requesting delayed updates of the tooltip. + base::OneShotTimer tooltip_defer_timer_; // Timer to timeout the life of an on-screen tooltip. We hide the tooltip when // this timer fires. @@ -101,6 +116,11 @@ bool tooltips_enabled_; + // An indicator of whether tooltip appears with delay or not. + // If the flag is true, tooltip shows up with delay; + // otherwise there is no delay, which is used in unit tests only. + bool tooltip_show_delayed_; + std::map<aura::Window*, int> tooltip_shown_timeout_map_; DISALLOW_COPY_AND_ASSIGN(TooltipController);
diff --git a/ui/views/corewm/tooltip_controller_test_helper.cc b/ui/views/corewm/tooltip_controller_test_helper.cc index f96b08d..45d940f 100644 --- a/ui/views/corewm/tooltip_controller_test_helper.cc +++ b/ui/views/corewm/tooltip_controller_test_helper.cc
@@ -14,6 +14,7 @@ TooltipControllerTestHelper::TooltipControllerTestHelper( TooltipController* controller) : controller_(controller) { + controller_->DisableTooltipShowDelay(); } TooltipControllerTestHelper::~TooltipControllerTestHelper() { @@ -27,12 +28,8 @@ return controller_->tooltip_window_; } -void TooltipControllerTestHelper::FireTooltipTimer() { - controller_->TooltipTimerFired(); -} - -bool TooltipControllerTestHelper::IsTooltipTimerRunning() { - return controller_->tooltip_timer_.IsRunning(); +void TooltipControllerTestHelper::UpdateIfRequired() { + controller_->UpdateIfRequired(); } void TooltipControllerTestHelper::FireTooltipShownTimer() {
diff --git a/ui/views/corewm/tooltip_controller_test_helper.h b/ui/views/corewm/tooltip_controller_test_helper.h index af1bcb8..9a710f0 100644 --- a/ui/views/corewm/tooltip_controller_test_helper.h +++ b/ui/views/corewm/tooltip_controller_test_helper.h
@@ -34,8 +34,7 @@ // These are mostly cover methods for TooltipController private methods. base::string16 GetTooltipText(); aura::Window* GetTooltipWindow(); - void FireTooltipTimer(); - bool IsTooltipTimerRunning(); + void UpdateIfRequired(); void FireTooltipShownTimer(); bool IsTooltipShownTimerRunning(); bool IsTooltipVisible();
diff --git a/ui/views/corewm/tooltip_controller_unittest.cc b/ui/views/corewm/tooltip_controller_unittest.cc index 72209dd..97a3351 100644 --- a/ui/views/corewm/tooltip_controller_unittest.cc +++ b/ui/views/corewm/tooltip_controller_unittest.cc
@@ -187,18 +187,16 @@ view_->set_tooltip_text(ASCIIToUTF16("Tooltip Text")); EXPECT_EQ(base::string16(), helper_->GetTooltipText()); EXPECT_EQ(NULL, helper_->GetTooltipWindow()); + generator_->MoveMouseToCenterOf(GetWindow()); EXPECT_EQ(GetWindow(), GetRootWindow()->GetEventHandlerForPoint( generator_->current_location())); base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text"); EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(GetWindow())); - EXPECT_EQ(base::string16(), helper_->GetTooltipText()); + EXPECT_EQ(expected_tooltip, helper_->GetTooltipText()); EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow()); - // Fire tooltip timer so tooltip becomes visible. - helper_->FireTooltipTimer(); - EXPECT_TRUE(helper_->IsTooltipVisible()); generator_->MoveMouseBy(1, 0); @@ -221,10 +219,8 @@ "width"); view_->set_tooltip_text(text); gfx::Point center = GetWindow()->bounds().CenterPoint(); - generator_->MoveMouseTo(center); - // Fire tooltip timer so tooltip becomes visible. - helper_->FireTooltipTimer(); + generator_->MoveMouseTo(center); EXPECT_TRUE(helper_->IsTooltipVisible()); gfx::RenderText* render_text = @@ -249,9 +245,7 @@ aura::Window* window = GetWindow(); aura::Window* root_window = GetRootWindow(); - // Fire tooltip timer so tooltip becomes visible. generator_->MoveMouseRelativeTo(window, view_->bounds().CenterPoint()); - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); for (int i = 0; i < 49; ++i) { generator_->MoveMouseBy(1, 0); @@ -286,22 +280,18 @@ EXPECT_EQ(NULL, helper_->GetTooltipWindow()); generator_->MoveMouseRelativeTo(GetWindow(), view_->bounds().CenterPoint()); - base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text"); - - // Fire tooltip timer so tooltip becomes visible. - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); // Disable tooltips and check again. helper_->controller()->SetTooltipsEnabled(false); EXPECT_FALSE(helper_->IsTooltipVisible()); - helper_->FireTooltipTimer(); + helper_->UpdateIfRequired(); EXPECT_FALSE(helper_->IsTooltipVisible()); // Enable tooltips back and check again. helper_->controller()->SetTooltipsEnabled(true); EXPECT_FALSE(helper_->IsTooltipVisible()); - helper_->FireTooltipTimer(); + helper_->UpdateIfRequired(); EXPECT_TRUE(helper_->IsTooltipVisible()); } @@ -317,8 +307,6 @@ EXPECT_EQ(NULL, helper_->GetTooltipWindow()); generator_->MoveMouseRelativeTo(GetWindow(), view_->bounds().CenterPoint()); - - helper_->FireTooltipTimer(); EXPECT_FALSE(helper_->IsTooltipVisible()); } @@ -337,15 +325,12 @@ aura::Window* window = GetWindow(); - // Fire tooltip timer so tooltip becomes visible. generator_->MoveMouseRelativeTo(window, view_->bounds().CenterPoint()); - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); EXPECT_TRUE(helper_->IsTooltipShownTimerRunning()); generator_->PressKey(ui::VKEY_1, 0); EXPECT_FALSE(helper_->IsTooltipVisible()); - EXPECT_FALSE(helper_->IsTooltipTimerRunning()); EXPECT_FALSE(helper_->IsTooltipShownTimerRunning()); // Moving the mouse inside |view1| should not change the state of the tooltip @@ -353,7 +338,6 @@ for (int i = 0; i < 49; i++) { generator_->MoveMouseBy(1, 0); EXPECT_FALSE(helper_->IsTooltipVisible()); - EXPECT_FALSE(helper_->IsTooltipTimerRunning()); EXPECT_FALSE(helper_->IsTooltipShownTimerRunning()); EXPECT_EQ(window, GetRootWindow()->GetEventHandlerForPoint( @@ -364,10 +348,9 @@ EXPECT_EQ(window, helper_->GetTooltipWindow()); } - // Now we move the mouse on to |view2|. It should re-start the tooltip timer. + // Now we move the mouse on to |view2|. It should update the tooltip. generator_->MoveMouseBy(1, 0); - EXPECT_TRUE(helper_->IsTooltipTimerRunning()); - helper_->FireTooltipTimer(); + EXPECT_TRUE(helper_->IsTooltipVisible()); EXPECT_TRUE(helper_->IsTooltipShownTimerRunning()); base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text for view 2"); @@ -391,15 +374,13 @@ aura::Window* window = GetWindow(); - // Fire tooltip timer so tooltip becomes visible. + // Update tooltip so tooltip becomes visible. generator_->MoveMouseRelativeTo(window, view_->bounds().CenterPoint()); - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); EXPECT_TRUE(helper_->IsTooltipShownTimerRunning()); helper_->FireTooltipShownTimer(); EXPECT_FALSE(helper_->IsTooltipVisible()); - EXPECT_FALSE(helper_->IsTooltipTimerRunning()); EXPECT_FALSE(helper_->IsTooltipShownTimerRunning()); // Moving the mouse inside |view1| should not change the state of the tooltip @@ -407,7 +388,6 @@ for (int i = 0; i < 49; ++i) { generator_->MoveMouseBy(1, 0); EXPECT_FALSE(helper_->IsTooltipVisible()); - EXPECT_FALSE(helper_->IsTooltipTimerRunning()); EXPECT_FALSE(helper_->IsTooltipShownTimerRunning()); EXPECT_EQ(window, GetRootWindow()->GetEventHandlerForPoint( generator_->current_location())); @@ -417,10 +397,9 @@ EXPECT_EQ(window, helper_->GetTooltipWindow()); } - // Now we move the mouse on to |view2|. It should re-start the tooltip timer. + // Now we move the mouse on to |view2|. It should update the tooltip. generator_->MoveMouseBy(1, 0); - EXPECT_TRUE(helper_->IsTooltipTimerRunning()); - helper_->FireTooltipTimer(); + EXPECT_TRUE(helper_->IsTooltipVisible()); EXPECT_TRUE(helper_->IsTooltipShownTimerRunning()); base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text for view 2"); @@ -440,12 +419,9 @@ generator_->MoveMouseToCenterOf(GetWindow()); base::string16 expected_tooltip = ASCIIToUTF16("Tooltip Text"); EXPECT_EQ(expected_tooltip, aura::client::GetTooltipText(GetWindow())); - EXPECT_EQ(base::string16(), helper_->GetTooltipText()); + EXPECT_EQ(expected_tooltip, helper_->GetTooltipText()); EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow()); - // Fire tooltip timer so tooltip becomes visible. - helper_->FireTooltipTimer(); - EXPECT_TRUE(helper_->IsTooltipVisible()); generator_->SendMouseExit(); EXPECT_FALSE(helper_->IsTooltipVisible()); @@ -476,8 +452,6 @@ View::ConvertPointToWidget(v1, &v1_point); generator_->MoveMouseRelativeTo(GetWindow(), v1_point); - // Fire tooltip timer so tooltip becomes visible. - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); EXPECT_EQ(v1_tt, helper_->GetTooltipText()); @@ -489,7 +463,6 @@ generator_->MoveMouseRelativeTo(GetWindow(), v2_point); generator_->MoveMouseRelativeTo(GetWindow(), v1_point); - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); EXPECT_EQ(v1_tt, helper_->GetTooltipText()); } @@ -554,9 +527,6 @@ EXPECT_EQ(base::string16(), helper_->GetTooltipText()); EXPECT_EQ(GetWindow(), helper_->GetTooltipWindow()); - // Fire tooltip timer so tooltip becomes visible. - helper_->FireTooltipTimer(); - EXPECT_TRUE(helper_->IsTooltipVisible()); view_->GetWidget()->ReleaseCapture(); EXPECT_FALSE(helper_->IsTooltipVisible()); @@ -602,8 +572,6 @@ generator_->MoveMouseRelativeTo(widget_->GetNativeWindow(), view_->bounds().CenterPoint()); - EXPECT_TRUE(helper_->IsTooltipTimerRunning()); - helper_->FireTooltipTimer(); // Even though the mouse is over a window with a tooltip it shouldn't be // picked up because the windows don't have the same value for // |TooltipManager::kGroupingPropertyKey|. @@ -618,8 +586,6 @@ widget2->SetNativeWindowProperty(TooltipManager::kGroupingPropertyKey, reinterpret_cast<void*>(grouping_key)); generator_->MoveMouseBy(1, 10); - EXPECT_TRUE(helper_->IsTooltipTimerRunning()); - helper_->FireTooltipTimer(); EXPECT_EQ(tooltip_text2, helper_->GetTooltipText()); widget2.reset(); @@ -704,8 +670,8 @@ window->SetBounds(gfx::Rect(0, 0, 300, 300)); base::string16 tooltip_text(ASCIIToUTF16(" \nx ")); aura::client::SetTooltipText(window.get(), &tooltip_text); + EXPECT_FALSE(helper_->IsTooltipVisible()); generator_->MoveMouseToCenterOf(window.get()); - helper_->FireTooltipTimer(); EXPECT_EQ(ASCIIToUTF16("x"), test_tooltip_->tooltip_text()); } @@ -717,10 +683,9 @@ window->SetBounds(gfx::Rect(0, 0, 300, 300)); base::string16 tooltip_text(ASCIIToUTF16("Tooltip Text")); aura::client::SetTooltipText(window.get(), &tooltip_text); + EXPECT_FALSE(helper_->IsTooltipVisible()); generator_->MoveMouseToCenterOf(window.get()); - // Fire tooltip timer so tooltip becomes visible. - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); // Send OnCancelMode event and verify that tooltip becomes invisible and @@ -849,7 +814,6 @@ // Test whether a toolbar appears on v1 gfx::Point center = v1->bounds().CenterPoint(); generator_->MoveMouseRelativeTo(GetWindow(), center); - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); EXPECT_EQ(reference_string, helper_->GetTooltipText()); gfx::Point tooltip_bounds1 = test_tooltip_->location(); @@ -857,7 +821,6 @@ // Test whether the toolbar changes position on mouse over v2 center = v2->bounds().CenterPoint(); generator_->MoveMouseRelativeTo(GetWindow(), center); - helper_->FireTooltipTimer(); EXPECT_TRUE(helper_->IsTooltipVisible()); EXPECT_EQ(reference_string, helper_->GetTooltipText()); gfx::Point tooltip_bounds2 = test_tooltip_->location(); @@ -871,7 +834,6 @@ center = v2_1->GetLocalBounds().CenterPoint(); views::View::ConvertPointToTarget(v2_1, view_, ¢er); generator_->MoveMouseRelativeTo(GetWindow(), center); - helper_->FireTooltipTimer(); gfx::Point tooltip_bounds2_1 = test_tooltip_->location(); EXPECT_NE(tooltip_bounds2, tooltip_bounds2_1); @@ -883,7 +845,6 @@ center = v2_2->GetLocalBounds().CenterPoint(); views::View::ConvertPointToTarget(v2_2, view_, ¢er); generator_->MoveMouseRelativeTo(GetWindow(), center); - helper_->FireTooltipTimer(); gfx::Point tooltip_bounds2_2 = test_tooltip_->location(); EXPECT_NE(tooltip_bounds2_1, tooltip_bounds2_2); @@ -895,7 +856,6 @@ center = v1_1->GetLocalBounds().CenterPoint(); views::View::ConvertPointToTarget(v1_1, view_, ¢er); generator_->MoveMouseRelativeTo(GetWindow(), center); - helper_->FireTooltipTimer(); gfx::Point tooltip_bounds1_1 = test_tooltip_->location(); EXPECT_TRUE(helper_->IsTooltipVisible()); @@ -903,7 +863,6 @@ center = v1->bounds().CenterPoint(); generator_->MoveMouseRelativeTo(GetWindow(), center); - helper_->FireTooltipTimer(); tooltip_bounds1 = test_tooltip_->location(); EXPECT_NE(tooltip_bounds1_1, tooltip_bounds1);
diff --git a/ui/wm/public/tooltip_client.cc b/ui/wm/public/tooltip_client.cc index 5dd446c..c9fd6f8 100644 --- a/ui/wm/public/tooltip_client.cc +++ b/ui/wm/public/tooltip_client.cc
@@ -4,19 +4,17 @@ #include "ui/wm/public/tooltip_client.h" -#include "ui/aura/window.h" #include "ui/aura/window_property.h" -DECLARE_WINDOW_PROPERTY_TYPE(aura::client::TooltipClient*) -DECLARE_WINDOW_PROPERTY_TYPE(void**) +DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(AURA_EXPORT, aura::client::TooltipClient*) +DECLARE_EXPORTED_WINDOW_PROPERTY_TYPE(AURA_EXPORT, void**) namespace aura { namespace client { -DEFINE_LOCAL_WINDOW_PROPERTY_KEY( - TooltipClient*, kRootWindowTooltipClientKey, NULL); -DEFINE_LOCAL_WINDOW_PROPERTY_KEY(base::string16*, kTooltipTextKey, NULL); -DEFINE_LOCAL_WINDOW_PROPERTY_KEY(void*, kTooltipIdKey, NULL); +DEFINE_WINDOW_PROPERTY_KEY(TooltipClient*, kRootWindowTooltipClientKey, NULL); +DEFINE_WINDOW_PROPERTY_KEY(base::string16*, kTooltipTextKey, NULL); +DEFINE_WINDOW_PROPERTY_KEY(void*, kTooltipIdKey, NULL); void SetTooltipClient(Window* root_window, TooltipClient* client) { DCHECK_EQ(root_window->GetRootWindow(), root_window);
diff --git a/ui/wm/public/tooltip_client.h b/ui/wm/public/tooltip_client.h index 7709515..2b0ebcf 100644 --- a/ui/wm/public/tooltip_client.h +++ b/ui/wm/public/tooltip_client.h
@@ -6,6 +6,7 @@ #define UI_WM_PUBLIC_TOOLTIP_CLIENT_H_ #include "ui/aura/aura_export.h" +#include "ui/aura/window.h" #include "ui/gfx/font.h" namespace gfx { @@ -52,6 +53,10 @@ AURA_EXPORT const base::string16 GetTooltipText(Window* window); AURA_EXPORT const void* GetTooltipId(Window* window); +AURA_EXPORT extern const aura::WindowProperty<void*>* const kTooltipIdKey; +AURA_EXPORT extern const aura::WindowProperty<base::string16*>* const + kTooltipTextKey; + } // namespace client } // namespace aura