Serenity Operating System
at master 102 lines 2.9 kB view raw
1/* 2 * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/QuickSort.h> 8#include <LibWeb/Bindings/Intrinsics.h> 9#include <LibWeb/Bindings/StyleSheetListPrototype.h> 10#include <LibWeb/CSS/StyleSheetList.h> 11#include <LibWeb/DOM/Document.h> 12 13namespace Web::CSS { 14 15void StyleSheetList::add_sheet(CSSStyleSheet& sheet) 16{ 17 sheet.set_style_sheet_list({}, this); 18 m_sheets.append(sheet); 19 20 sort_sheets(); 21 22 if (sheet.rules().length() == 0) { 23 // NOTE: If the added sheet has no rules, we don't have to invalidate anything. 24 return; 25 } 26 27 m_document.style_computer().invalidate_rule_cache(); 28 m_document.style_computer().load_fonts_from_sheet(sheet); 29 m_document.invalidate_style(); 30} 31 32void StyleSheetList::remove_sheet(CSSStyleSheet& sheet) 33{ 34 sheet.set_style_sheet_list({}, nullptr); 35 m_sheets.remove_first_matching([&](auto& entry) { return entry.ptr() == &sheet; }); 36 37 if (sheet.rules().length() == 0) { 38 // NOTE: If the removed sheet had no rules, we don't have to invalidate anything. 39 return; 40 } 41 42 sort_sheets(); 43 44 m_document.style_computer().invalidate_rule_cache(); 45 m_document.invalidate_style(); 46} 47 48WebIDL::ExceptionOr<JS::NonnullGCPtr<StyleSheetList>> StyleSheetList::create(DOM::Document& document) 49{ 50 auto& realm = document.realm(); 51 return MUST_OR_THROW_OOM(realm.heap().allocate<StyleSheetList>(realm, document)); 52} 53 54StyleSheetList::StyleSheetList(DOM::Document& document) 55 : Bindings::LegacyPlatformObject(document.realm()) 56 , m_document(document) 57{ 58} 59 60JS::ThrowCompletionOr<void> StyleSheetList::initialize(JS::Realm& realm) 61{ 62 MUST_OR_THROW_OOM(Base::initialize(realm)); 63 set_prototype(&Bindings::ensure_web_prototype<Bindings::StyleSheetListPrototype>(realm, "StyleSheetList")); 64 65 return {}; 66} 67 68void StyleSheetList::visit_edges(Cell::Visitor& visitor) 69{ 70 Base::visit_edges(visitor); 71 visitor.visit(m_document); 72 for (auto sheet : m_sheets) 73 visitor.visit(sheet.ptr()); 74} 75 76// https://www.w3.org/TR/cssom/#ref-for-dfn-supported-property-indices%E2%91%A1 77bool StyleSheetList::is_supported_property_index(u32 index) const 78{ 79 // The object’s supported property indices are the numbers in the range zero to one less than the number of CSS style sheets represented by the collection. 80 // If there are no such CSS style sheets, then there are no supported property indices. 81 if (m_sheets.is_empty()) 82 return false; 83 84 return index < m_sheets.size(); 85} 86 87WebIDL::ExceptionOr<JS::Value> StyleSheetList::item_value(size_t index) const 88{ 89 if (index >= m_sheets.size()) 90 return JS::js_undefined(); 91 92 return m_sheets[index].ptr(); 93} 94 95void StyleSheetList::sort_sheets() 96{ 97 quick_sort(m_sheets, [](JS::NonnullGCPtr<StyleSheet> a, JS::NonnullGCPtr<StyleSheet> b) { 98 return a->owner_node()->is_before(*b->owner_node()); 99 }); 100} 101 102}