summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc
diff options
context:
space:
mode:
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.cc123
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