diff options
author | Andreas Kling <kling@serenityos.org> | 2020-06-04 16:06:32 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-06-04 16:06:32 +0200 |
commit | 959de19418c831e1384f6d65a45971dd1d6a4287 (patch) | |
tree | 11799bded8de162b37feab50fd098aeb0b6a0a71 | |
parent | ec1891837fd2aeec9b644ca1b70caf6f026e305a (diff) | |
download | serenity-959de19418c831e1384f6d65a45971dd1d6a4287.zip |
LibWeb: Process style sheets in document order
Until now we would simply apply stylesheets in the order they finished
loading. This patch adds a StyleSheetList object that hangs off of each
Document and contains all the style sheets in document order.
There's still a lot of work to do for a proper cascade, but at least
this makes us consistently wrong every time. :^)
-rw-r--r-- | Applications/Browser/Tab.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/StyleResolver.cpp | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/StyleSheet.h | 1 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/StyleSheetList.cpp | 43 | ||||
-rw-r--r-- | Libraries/LibWeb/CSS/StyleSheetList.h | 54 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/Document.cpp | 1 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/Document.h | 7 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/HTMLLinkElement.cpp | 10 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/HTMLLinkElement.h | 2 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/HTMLStyleElement.cpp | 4 |
11 files changed, 120 insertions, 7 deletions
diff --git a/Applications/Browser/Tab.cpp b/Applications/Browser/Tab.cpp index e26d2bb99a..4028612c15 100644 --- a/Applications/Browser/Tab.cpp +++ b/Applications/Browser/Tab.cpp @@ -322,7 +322,7 @@ Tab::Tab() this)); debug_menu.add_action(GUI::Action::create( "Dump Style sheets", [this](auto&) { - for (auto& sheet : m_page_view->document()->stylesheets()) { + for (auto& sheet : m_page_view->document()->style_sheets().sheets()) { dump_sheet(sheet); } }, diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 023a60be8b..02b98b3133 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -24,6 +24,7 @@ set(SOURCES CSS/StyleResolver.cpp CSS/StyleRule.cpp CSS/StyleSheet.cpp + CSS/StyleSheetList.cpp CSS/StyleValue.cpp DOM/AttributeNames.cpp DOM/CanvasRenderingContext2D.cpp diff --git a/Libraries/LibWeb/CSS/StyleResolver.cpp b/Libraries/LibWeb/CSS/StyleResolver.cpp index 6a0f14b88d..dc6bfe7ea0 100644 --- a/Libraries/LibWeb/CSS/StyleResolver.cpp +++ b/Libraries/LibWeb/CSS/StyleResolver.cpp @@ -60,7 +60,7 @@ template<typename Callback> void StyleResolver::for_each_stylesheet(Callback callback) const { callback(default_stylesheet()); - for (auto& sheet : document().stylesheets()) { + for (auto& sheet : document().style_sheets().sheets()) { callback(sheet); } } diff --git a/Libraries/LibWeb/CSS/StyleSheet.h b/Libraries/LibWeb/CSS/StyleSheet.h index 4acd446038..496260d76a 100644 --- a/Libraries/LibWeb/CSS/StyleSheet.h +++ b/Libraries/LibWeb/CSS/StyleSheet.h @@ -41,6 +41,7 @@ public: ~StyleSheet(); const NonnullRefPtrVector<StyleRule>& rules() const { return m_rules; } + NonnullRefPtrVector<StyleRule>& rules() { return m_rules; } private: explicit StyleSheet(NonnullRefPtrVector<StyleRule>&&); diff --git a/Libraries/LibWeb/CSS/StyleSheetList.cpp b/Libraries/LibWeb/CSS/StyleSheetList.cpp new file mode 100644 index 0000000000..bbda79757c --- /dev/null +++ b/Libraries/LibWeb/CSS/StyleSheetList.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibWeb/CSS/StyleSheetList.h> + +namespace Web { +namespace CSS { + +void StyleSheetList::add_sheet(NonnullRefPtr<StyleSheet> sheet) +{ + m_sheets.append(move(sheet)); +} + +StyleSheetList::StyleSheetList(Document& document) + : m_document(document) +{ +} + +} +} diff --git a/Libraries/LibWeb/CSS/StyleSheetList.h b/Libraries/LibWeb/CSS/StyleSheetList.h new file mode 100644 index 0000000000..ebccf4dccb --- /dev/null +++ b/Libraries/LibWeb/CSS/StyleSheetList.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <AK/RefCounted.h> +#include <LibWeb/CSS/StyleSheet.h> + +namespace Web { +namespace CSS { + +class StyleSheetList : public RefCounted<StyleSheetList> { +public: + static NonnullRefPtr<StyleSheetList> create(Document& document) + { + return adopt(*new StyleSheetList(document)); + } + + void add_sheet(NonnullRefPtr<StyleSheet>); + + const NonnullRefPtrVector<StyleSheet>& sheets() const { return m_sheets; } + +private: + explicit StyleSheetList(Document&); + + Document& m_document; + NonnullRefPtrVector<StyleSheet> m_sheets; +}; + +} +} diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 48acc74d8a..529be4f88e 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -63,6 +63,7 @@ namespace Web { Document::Document(const URL& url) : ParentNode(*this, NodeType::DOCUMENT_NODE) , m_style_resolver(make<StyleResolver>(*this)) + , m_style_sheets(CSS::StyleSheetList::create(*this)) , m_url(url) , m_window(Window::create_with_document(*this)) { diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index 37db176127..6679e46e23 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -37,6 +37,7 @@ #include <LibJS/Forward.h> #include <LibWeb/CSS/StyleResolver.h> #include <LibWeb/CSS/StyleSheet.h> +#include <LibWeb/CSS/StyleSheetList.h> #include <LibWeb/DOM/NonElementParentNode.h> #include <LibWeb/DOM/ParentNode.h> @@ -63,8 +64,8 @@ public: StyleResolver& style_resolver() { return *m_style_resolver; } const StyleResolver& style_resolver() const { return *m_style_resolver; } - void add_sheet(const StyleSheet& sheet) { m_sheets.append(sheet); } - const NonnullRefPtrVector<StyleSheet>& stylesheets() const { return m_sheets; } + CSS::StyleSheetList& style_sheets() { return *m_style_sheets; } + const CSS::StyleSheetList& style_sheets() const { return *m_style_sheets; } virtual FlyString tag_name() const override { return "#document"; } @@ -146,7 +147,7 @@ private: virtual RefPtr<LayoutNode> create_layout_node(const StyleProperties* parent_style) const override; OwnPtr<StyleResolver> m_style_resolver; - NonnullRefPtrVector<StyleSheet> m_sheets; + RefPtr<CSS::StyleSheetList> m_style_sheets; RefPtr<Node> m_hovered_node; RefPtr<Node> m_inspected_node; WeakPtr<Frame> m_frame; diff --git a/Libraries/LibWeb/DOM/HTMLLinkElement.cpp b/Libraries/LibWeb/DOM/HTMLLinkElement.cpp index 4ccc36bc5b..30e08f0010 100644 --- a/Libraries/LibWeb/DOM/HTMLLinkElement.cpp +++ b/Libraries/LibWeb/DOM/HTMLLinkElement.cpp @@ -68,12 +68,20 @@ void HTMLLinkElement::resource_did_load() dbg() << "HTMLLinkElement: Failed to parse stylesheet: " << href(); return; } - document().add_sheet(*sheet); + + // Transfer the rules from the successfully parsed sheet into the sheet we've already inserted. + m_style_sheet->rules() = sheet->rules(); + document().update_style(); } void HTMLLinkElement::load_stylesheet(const URL& url) { + // First insert an empty style sheet in the document sheet list. + // There's probably a nicer way to do this, but this ensures that sheets are in document order. + m_style_sheet = StyleSheet::create({}); + document().style_sheets().add_sheet(*m_style_sheet); + LoadRequest request; request.set_url(url); set_resource(ResourceLoader::the().load_resource(Resource::Type::Generic, request)); diff --git a/Libraries/LibWeb/DOM/HTMLLinkElement.h b/Libraries/LibWeb/DOM/HTMLLinkElement.h index b0a85c0195..bae7d8d9f0 100644 --- a/Libraries/LibWeb/DOM/HTMLLinkElement.h +++ b/Libraries/LibWeb/DOM/HTMLLinkElement.h @@ -50,6 +50,8 @@ private: virtual void resource_did_load() override; void load_stylesheet(const URL&); + + RefPtr<StyleSheet> m_style_sheet; }; template<> diff --git a/Libraries/LibWeb/DOM/HTMLStyleElement.cpp b/Libraries/LibWeb/DOM/HTMLStyleElement.cpp index 83ae31b148..e2e2ec4a27 100644 --- a/Libraries/LibWeb/DOM/HTMLStyleElement.cpp +++ b/Libraries/LibWeb/DOM/HTMLStyleElement.cpp @@ -50,7 +50,9 @@ void HTMLStyleElement::children_changed() }); m_stylesheet = parse_css(builder.to_string()); if (m_stylesheet) - document().add_sheet(*m_stylesheet); + document().style_sheets().add_sheet(*m_stylesheet); + else + document().style_sheets().add_sheet(StyleSheet::create({})); HTMLElement::children_changed(); } |