Files
serenity/Userland/Libraries/LibWeb/DOM/AdoptedStyleSheets.cpp
Andreas Kling 1b73445f55 LibWeb: Note what's causing a style invalidation to happen
You can now build with STYLE_INVALIDATION_DEBUG and get a debug stream
of reasons why style invalidations are happening and where.

I've rewritten this code many times, so instead of throwing it away once
again, I figured we should at least have it behind a flag.

(cherry picked from commit ddbfac38b0074819470766846fca08fd78630eb0;
minorly amended for conflicts in AK/Debug.h.in and
Meta/CMake/all_the_debug_macros.cmake due to us having more debug
macros. Also, downstream got alphabetical order for
STYLE_INVALIDATION_DEBUG wrong.)
2024-10-20 01:32:53 -04:00

48 lines
2.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/CSS/StyleComputer.h>
#include <LibWeb/DOM/AdoptedStyleSheets.h>
#include <LibWeb/DOM/Document.h>
namespace Web::DOM {
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 values 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(DOM::StyleInvalidationReason::AdoptedStyleSheetsList);
return {};
});
adopted_style_sheets->set_on_delete_an_indexed_value_callback([&document]() -> WebIDL::ExceptionOr<void> {
document.style_computer().invalidate_rule_cache();
document.invalidate_style(DOM::StyleInvalidationReason::AdoptedStyleSheetsList);
return {};
});
return adopted_style_sheets;
}
}