blob: 4679fe253adafc31d0641115f8fa9b8190677e7b [file] [log] [blame]
// Copyright 2018 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 "third_party/blink/renderer/core/frame/link_highlights.h"
#include <memory>
#include "cc/animation/animation_host.h"
#include "cc/layers/picture_layer.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_layer_tree_view.h"
#include "third_party/blink/renderer/core/dom/node.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/layout/layout_object.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/paint/link_highlight_impl.h"
#include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h"
namespace blink {
LinkHighlights::LinkHighlights(Page& owner) : page_(&owner) {}
LinkHighlights::~LinkHighlights() {
RemoveAllHighlights();
}
void LinkHighlights::Trace(blink::Visitor* visitor) {
visitor->Trace(page_);
}
void LinkHighlights::RemoveAllHighlights() {
for (auto& highlight : link_highlights_) {
if (timeline_)
timeline_->AnimationDestroyed(*highlight);
if (auto* node = highlight->GetNode()) {
if (auto* layout_object = node->GetLayoutObject())
layout_object->SetNeedsPaintPropertyUpdate();
}
}
link_highlights_.clear();
}
void LinkHighlights::ResetForPageNavigation() {
RemoveAllHighlights();
}
void LinkHighlights::SetTapHighlights(
HeapVector<Member<Node>>& highlight_nodes) {
// Always clear any existing highlight when this is invoked, even if we
// don't get a new target to highlight.
RemoveAllHighlights();
for (wtf_size_t i = 0; i < highlight_nodes.size(); ++i) {
Node* node = highlight_nodes[i];
if (!node || !node->GetLayoutObject())
continue;
Color highlight_color =
node->GetLayoutObject()->StyleRef().TapHighlightColor();
// Safari documentation for -webkit-tap-highlight-color says if the
// specified color has 0 alpha, then tap highlighting is disabled.
// http://developer.apple.com/library/safari/#documentation/appleapplications/reference/safaricssref/articles/standardcssproperties.html
if (!highlight_color.Alpha())
continue;
link_highlights_.push_back(std::make_unique<LinkHighlightImpl>(node));
if (timeline_)
timeline_->AnimationAttached(*link_highlights_.back());
node->GetLayoutObject()->SetNeedsPaintPropertyUpdate();
}
}
void LinkHighlights::UpdateGeometry() {
for (auto& highlight : link_highlights_)
highlight->UpdateGeometry();
}
LocalFrame* LinkHighlights::MainFrame() const {
return GetPage().MainFrame() && GetPage().MainFrame()->IsLocalFrame()
? GetPage().DeprecatedLocalMainFrame()
: nullptr;
}
void LinkHighlights::StartHighlightAnimationIfNeeded() {
for (auto& highlight : link_highlights_)
highlight->StartHighlightAnimationIfNeeded();
if (auto* local_frame = MainFrame())
GetPage().GetChromeClient().ScheduleAnimation(local_frame->View());
}
void LinkHighlights::LayerTreeViewInitialized(
WebLayerTreeView& layer_tree_view,
cc::AnimationHost& animation_host) {
animation_host_ = &animation_host;
if (Platform::Current()->IsThreadedAnimationEnabled()) {
timeline_ = std::make_unique<CompositorAnimationTimeline>();
animation_host_->AddAnimationTimeline(timeline_->GetAnimationTimeline());
}
}
void LinkHighlights::WillCloseLayerTreeView(WebLayerTreeView& layer_tree_view) {
RemoveAllHighlights();
if (timeline_) {
animation_host_->RemoveAnimationTimeline(timeline_->GetAnimationTimeline());
timeline_.reset();
}
animation_host_ = nullptr;
}
bool LinkHighlights::NeedsHighlightEffectInternal(
const LayoutObject& object) const {
for (auto& highlight : link_highlights_) {
if (auto* node = highlight->GetNode()) {
if (node->GetLayoutObject() == &object)
return true;
}
}
return false;
}
void LinkHighlights::Paint(GraphicsContext& context) const {
DCHECK(RuntimeEnabledFeatures::CompositeAfterPaintEnabled());
for (const auto& highlight : link_highlights_)
highlight->Paint(context);
}
} // namespace blink