blob: 49332075b1be6c4cb3d1a8cf813619baa63b15ab [file] [log] [blame]
// Copyright 2020 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/css/resolver/cascade_resolver.h"
#include "third_party/blink/renderer/core/animation/css/css_animations.h"
#include "third_party/blink/renderer/core/css/css_variable_data.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"
#include "third_party/blink/renderer/core/css/properties/longhands/custom_property.h"
#include "third_party/blink/renderer/core/css/resolver/cascade_priority.h"
namespace blink {
bool CascadeResolver::IsLocked(const CSSProperty& property) const {
return Find(property) != kNotFound;
}
bool CascadeResolver::AllowSubstitution(CSSVariableData* data) const {
if (data && data->IsAnimationTainted() && stack_.size()) {
const CSSProperty* property = CurrentProperty();
if (IsA<CustomProperty>(*property))
return true;
return !CSSAnimations::IsAnimationAffectingProperty(*property);
}
return true;
}
void CascadeResolver::MarkUnapplied(CascadePriority* priority) const {
DCHECK(priority);
*priority = CascadePriority(*priority, 0);
}
void CascadeResolver::MarkApplied(CascadePriority* priority) const {
DCHECK(priority);
*priority = CascadePriority(*priority, generation_);
}
bool CascadeResolver::DetectCycle(const CSSProperty& property) {
wtf_size_t index = Find(property);
if (index == kNotFound)
return false;
cycle_depth_ = std::min(cycle_depth_, index);
return true;
}
bool CascadeResolver::InCycle() const {
return cycle_depth_ != kNotFound;
}
wtf_size_t CascadeResolver::Find(const CSSProperty& property) const {
wtf_size_t index = 0;
for (const CSSProperty* p : stack_) {
if (p->GetCSSPropertyName() == property.GetCSSPropertyName())
return index;
++index;
}
return kNotFound;
}
CascadeResolver::AutoLock::AutoLock(const CSSProperty& property,
CascadeResolver& resolver)
: resolver_(resolver) {
DCHECK(!resolver.IsLocked(property));
resolver_.stack_.push_back(&property);
}
CascadeResolver::AutoLock::~AutoLock() {
resolver_.stack_.pop_back();
if (resolver_.stack_.size() <= resolver_.cycle_depth_)
resolver_.cycle_depth_ = kNotFound;
}
} // namespace blink