diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc new file mode 100644 index 00000000000..0a17d3656ef --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc @@ -0,0 +1,123 @@ +// Copyright 2021 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/html/custom/custom_state_set.h" + +#include "third_party/blink/renderer/core/css/css_selector.h" +#include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h" +#include "third_party/blink/renderer/core/dom/element.h" + +namespace blink { + +CustomStateSet::CustomStateSet(Element& element) : element_(element) {} + +void CustomStateSet::Trace(Visitor* visitor) const { + visitor->Trace(element_); + ScriptWrappable::Trace(visitor); +} + +void CustomStateSet::add(const String& value, ExceptionState& exception_state) { + // https://wicg.github.io/custom-state-pseudo-class/#dom-customstateset-add + + // 1. If value does not match to <dashed-ident>, then throw a "SyntaxError" + // DOMException. + if (!value.StartsWith("--")) { + exception_state.ThrowDOMException( + DOMExceptionCode::kSyntaxError, + "The specified value '" + value + "' must start with '--'."); + return; + } + for (wtf_size_t i = 2; i < value.length(); ++i) { + if (IsNameCodePoint(value[i])) + continue; + exception_state.ThrowDOMException( + DOMExceptionCode::kSyntaxError, + "The specified value '" + value + + "' must match to <dashed-ident> production. '" + value[i] + + "' is invalid."); + return; + } + + // 2. Invoke the default add operation, which the setlike<DOMString> would + // have if CustomStateSet interface had no add(value) operation, with value + // argument. + set_.insert(value); + + InvalidateStyle(); +} + +uint32_t CustomStateSet::size() const { + return set_.size(); +} + +void CustomStateSet::clearForBinding(ScriptState*, ExceptionState&) { + set_.clear(); + InvalidateStyle(); +} + +bool CustomStateSet::deleteForBinding(ScriptState*, + const String& value, + ExceptionState&) { + auto iter = set_.find(value); + if (iter == set_.cend()) + return false; + set_.erase(iter); + InvalidateStyle(); + return true; +} + +bool CustomStateSet::hasForBinding(ScriptState*, + const String& value, + ExceptionState&) const { + return Has(value); +} + +bool CustomStateSet::Has(const String& value) const { + return set_.Contains(value); +} + +class CustomStateIterationSource : public CustomStateSet::IterationSource { + public: + explicit CustomStateIterationSource(CustomStateSet& states) + : states_(states), iterator_(states.set_.begin()) {} + + void Trace(Visitor* visitor) const override { + visitor->Trace(states_); + CustomStateSet::IterationSource::Trace(visitor); + } + + bool Next(ScriptState*, + String& out_key, + String& out_value, + ExceptionState&) override { + if (iterator_ == states_->set_.end()) + return false; + String value = *iterator_; + ++iterator_; + out_key = value; + out_value = value; + return true; + } + + private: + Member<CustomStateSet> states_; + LinkedHashSet<String>::const_iterator iterator_; +}; + +CustomStateSet::IterationSource* CustomStateSet::StartIteration( + ScriptState*, + ExceptionState&) { + return MakeGarbageCollected<CustomStateIterationSource>(*this); +} + +void CustomStateSet::InvalidateStyle() const { + // TOOD(tkent): The following line invalidates all of rulesets with any + // custom state pseudo classes though we should invalidate only rulesets + // with the updated state ideally. We can improve style resolution + // performance in documents with various custom state pseudo classes by + // having blink::InvalidationSet for each of states. + element_->PseudoStateChanged(CSSSelector::kPseudoState); +} + +} // namespace blink |