StyleSheetList.cpp 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/QuickSort.h>
  7. #include <LibWeb/Bindings/Intrinsics.h>
  8. #include <LibWeb/Bindings/StyleSheetListPrototype.h>
  9. #include <LibWeb/CSS/StyleSheetList.h>
  10. #include <LibWeb/DOM/Document.h>
  11. namespace Web::CSS {
  12. void StyleSheetList::add_sheet(CSSStyleSheet& sheet)
  13. {
  14. sheet.set_style_sheet_list({}, this);
  15. m_sheets.append(sheet);
  16. sort_sheets();
  17. if (sheet.rules().length() == 0) {
  18. // NOTE: If the added sheet has no rules, we don't have to invalidate anything.
  19. return;
  20. }
  21. m_document.style_computer().invalidate_rule_cache();
  22. m_document.style_computer().load_fonts_from_sheet(sheet);
  23. m_document.invalidate_style();
  24. }
  25. void StyleSheetList::remove_sheet(CSSStyleSheet& sheet)
  26. {
  27. sheet.set_style_sheet_list({}, nullptr);
  28. m_sheets.remove_first_matching([&](auto& entry) { return entry.ptr() == &sheet; });
  29. if (sheet.rules().length() == 0) {
  30. // NOTE: If the removed sheet had no rules, we don't have to invalidate anything.
  31. return;
  32. }
  33. sort_sheets();
  34. m_document.style_computer().invalidate_rule_cache();
  35. m_document.invalidate_style();
  36. }
  37. StyleSheetList* StyleSheetList::create(DOM::Document& document)
  38. {
  39. auto& realm = document.realm();
  40. return realm.heap().allocate<StyleSheetList>(realm, document);
  41. }
  42. StyleSheetList::StyleSheetList(DOM::Document& document)
  43. : Bindings::LegacyPlatformObject(Bindings::ensure_web_prototype<Bindings::StyleSheetListPrototype>(document.realm(), "StyleSheetList"))
  44. , m_document(document)
  45. {
  46. }
  47. void StyleSheetList::visit_edges(Cell::Visitor& visitor)
  48. {
  49. Base::visit_edges(visitor);
  50. visitor.visit(m_document);
  51. for (auto sheet : m_sheets)
  52. visitor.visit(sheet.ptr());
  53. }
  54. // https://www.w3.org/TR/cssom/#ref-for-dfn-supported-property-indices%E2%91%A1
  55. bool StyleSheetList::is_supported_property_index(u32 index) const
  56. {
  57. // 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.
  58. // If there are no such CSS style sheets, then there are no supported property indices.
  59. if (m_sheets.is_empty())
  60. return false;
  61. return index < m_sheets.size();
  62. }
  63. JS::Value StyleSheetList::item_value(size_t index) const
  64. {
  65. if (index >= m_sheets.size())
  66. return JS::js_undefined();
  67. return m_sheets[index].ptr();
  68. }
  69. void StyleSheetList::sort_sheets()
  70. {
  71. quick_sort(m_sheets, [](JS::NonnullGCPtr<StyleSheet> a, JS::NonnullGCPtr<StyleSheet> b) {
  72. return a->owner_node()->is_before(*b->owner_node());
  73. });
  74. }
  75. }