|
@@ -483,6 +483,8 @@ void Document::visit_edges(Cell::Visitor& visitor)
|
|
visitor.visit(event.event);
|
|
visitor.visit(event.event);
|
|
visitor.visit(event.target);
|
|
visitor.visit(event.target);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ visitor.visit(m_adopted_style_sheets);
|
|
}
|
|
}
|
|
|
|
|
|
// https://w3c.github.io/selection-api/#dom-document-getselection
|
|
// https://w3c.github.io/selection-api/#dom-document-getselection
|
|
@@ -4562,4 +4564,78 @@ bool Document::has_skipped_resize_observations()
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static JS::NonnullGCPtr<WebIDL::ObservableArray> create_adopted_style_sheets_list(Document& document)
|
|
|
|
+{
|
|
|
|
+ auto adopted_style_sheets = WebIDL::ObservableArray::create(document.realm());
|
|
|
|
+ adopted_style_sheets->set_on_set_an_indexed_value_callback([&document](JS::Value& value) -> WebIDL::ExceptionOr<void> {
|
|
|
|
+ auto& vm = document.vm();
|
|
|
|
+ if (!value.is_object())
|
|
|
|
+ return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "CSSStyleSheet");
|
|
|
|
+ auto& object = value.as_object();
|
|
|
|
+ if (!is<CSS::CSSStyleSheet>(object))
|
|
|
|
+ return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "CSSStyleSheet");
|
|
|
|
+ auto& style_sheet = static_cast<CSS::CSSStyleSheet&>(object);
|
|
|
|
+
|
|
|
|
+ // The set an indexed value algorithm for adoptedStyleSheets, given value and index, is the following:
|
|
|
|
+ // 1. If value’s constructed flag is not set, or its constructor document is not equal to this
|
|
|
|
+ // DocumentOrShadowRoot's node document, throw a "NotAllowedError" DOMException.
|
|
|
|
+ if (!style_sheet.constructed())
|
|
|
|
+ return WebIDL::NotAllowedError::create(document.realm(), "StyleSheet's constructed flag is not set."_fly_string);
|
|
|
|
+ if (!style_sheet.constructed() || style_sheet.constructor_document().ptr() != &document)
|
|
|
|
+ return WebIDL::NotAllowedError::create(document.realm(), "Sharing a StyleSheet between documents is not allowed."_fly_string);
|
|
|
|
+
|
|
|
|
+ document.style_computer().load_fonts_from_sheet(style_sheet);
|
|
|
|
+ document.style_computer().invalidate_rule_cache();
|
|
|
|
+ document.invalidate_style();
|
|
|
|
+ return {};
|
|
|
|
+ });
|
|
|
|
+ adopted_style_sheets->set_on_delete_an_indexed_value_callback([&document]() -> WebIDL::ExceptionOr<void> {
|
|
|
|
+ document.style_computer().invalidate_rule_cache();
|
|
|
|
+ document.invalidate_style();
|
|
|
|
+ return {};
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return adopted_style_sheets;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+JS::NonnullGCPtr<WebIDL::ObservableArray> Document::adopted_style_sheets() const
|
|
|
|
+{
|
|
|
|
+ if (!m_adopted_style_sheets)
|
|
|
|
+ m_adopted_style_sheets = create_adopted_style_sheets_list(const_cast<Document&>(*this));
|
|
|
|
+ return *m_adopted_style_sheets;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+WebIDL::ExceptionOr<void> Document::set_adopted_style_sheets(JS::Value new_value)
|
|
|
|
+{
|
|
|
|
+ if (!m_adopted_style_sheets)
|
|
|
|
+ m_adopted_style_sheets = create_adopted_style_sheets_list(const_cast<Document&>(*this));
|
|
|
|
+
|
|
|
|
+ m_adopted_style_sheets->clear();
|
|
|
|
+ auto iterator_record = TRY(get_iterator(vm(), new_value, JS::IteratorHint::Sync));
|
|
|
|
+ while (true) {
|
|
|
|
+ auto next = TRY(iterator_step_value(vm(), iterator_record));
|
|
|
|
+ if (!next.has_value())
|
|
|
|
+ break;
|
|
|
|
+ TRY(m_adopted_style_sheets->append(*next));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return {};
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void Document::for_each_css_style_sheet(Function<void(CSS::CSSStyleSheet&)>&& callback) const
|
|
|
|
+{
|
|
|
|
+ for (auto& style_sheet : m_style_sheets->sheets())
|
|
|
|
+ callback(*style_sheet);
|
|
|
|
+
|
|
|
|
+ if (m_adopted_style_sheets) {
|
|
|
|
+ for (auto& entry : m_adopted_style_sheets->indexed_properties()) {
|
|
|
|
+ auto value_and_attributes = m_adopted_style_sheets->indexed_properties().storage()->get(entry.index());
|
|
|
|
+ if (value_and_attributes.has_value()) {
|
|
|
|
+ auto& style_sheet = verify_cast<CSS::CSSStyleSheet>(value_and_attributes->value.as_object());
|
|
|
|
+ callback(style_sheet);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
}
|
|
}
|