diff options
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r-- | Userland/Libraries/LibWeb/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp | 42 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/CSSImportRule.h | 57 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp | 158 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/CSS/Parser/CSSParser.h | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Dump.cpp | 9 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Dump.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Forward.h | 1 |
8 files changed, 248 insertions, 24 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 61ed208ca5..d9590baf0f 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -9,6 +9,7 @@ set(SOURCES Bindings/ScriptExecutionContext.cpp Bindings/WindowObject.cpp Bindings/Wrappable.cpp + CSS/CSSImportRule.cpp CSS/CSSRule.cpp CSS/DefaultStyleSheetSource.cpp CSS/Length.cpp diff --git a/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp b/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp new file mode 100644 index 0000000000..0bdf55000d --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * 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 <AK/URL.h> +#include <LibWeb/CSS/CSSImportRule.h> +#include <LibWeb/CSS/StyleSheet.h> + +namespace Web::CSS { + +CSSImportRule::CSSImportRule(URL url) + : m_url(move(url)) +{ +} + +CSSImportRule::~CSSImportRule() +{ +} + +} diff --git a/Userland/Libraries/LibWeb/CSS/CSSImportRule.h b/Userland/Libraries/LibWeb/CSS/CSSImportRule.h new file mode 100644 index 0000000000..7607239528 --- /dev/null +++ b/Userland/Libraries/LibWeb/CSS/CSSImportRule.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021, the SerenityOS developers. + * 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/URL.h> +#include <LibWeb/CSS/CSSRule.h> + +namespace Web::CSS { + +class CSSImportRule : public CSSRule { + AK_MAKE_NONCOPYABLE(CSSImportRule); + AK_MAKE_NONMOVABLE(CSSImportRule); + +public: + static NonnullRefPtr<CSSImportRule> create(URL url) + { + return adopt(*new CSSImportRule(move(url))); + } + + ~CSSImportRule(); + + const URL& url() const { return m_url; } + + virtual StringView class_name() const { return "CSSImportRule"; }; + virtual Type type() const { return Type::Import; }; + +private: + CSSImportRule(URL); + + URL m_url; +}; + +} diff --git a/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp index b83b21c238..e8ed789d61 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp +++ b/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp @@ -25,6 +25,7 @@ */ #include <AK/HashMap.h> +#include <LibWeb/CSS/CSSImportRule.h> #include <LibWeb/CSS/CSSRule.h> #include <LibWeb/CSS/Parser/CSSParser.h> #include <LibWeb/CSS/PropertyID.h> @@ -70,6 +71,11 @@ bool ParsingContext::in_quirks_mode() const return m_document ? m_document->in_quirks_mode() : false; } +URL ParsingContext::complete_url(const String& addr) const +{ + return m_document ? m_document->url().complete_url(addr) : URL::create_with_url_or_path(addr); +} + } static Optional<Color> parse_css_color(const CSS::ParsingContext&, const StringView& view) @@ -664,6 +670,11 @@ public: return ch && ch != '!' && ch != ';' && ch != '}'; } + bool is_valid_string_quotes_char(char ch) const + { + return ch == '\'' || ch == '\"'; + } + struct ValueAndImportant { String value; bool important { false }; @@ -785,31 +796,8 @@ public: } } - void parse_rule() + void parse_style_rule() { - consume_whitespace_or_comments(); - if (!peek()) - return; - - // FIXME: We ignore @-rules for now. - if (peek() == '@') { - while (peek() != '{') - consume_one(); - int level = 0; - for (;;) { - auto ch = consume_one(); - if (ch == '{') { - ++level; - } else if (ch == '}') { - --level; - if (level == 0) - break; - } - } - consume_whitespace_or_comments(); - return; - } - parse_selector_list(); if (!consume_specific('{')) { PARSE_ERROR(); @@ -820,7 +808,129 @@ public: PARSE_ERROR(); return; } + rules.append(CSS::StyleRule::create(move(current_rule.selectors), CSS::StyleDeclaration::create(move(current_rule.properties)))); + } + + Optional<String> parse_string() + { + if (!is_valid_string_quotes_char(peek())) { + PARSE_ERROR(); + return {}; + } + + char end_char = consume_one(); + buffer.clear(); + while (peek() && peek() != end_char) { + if (peek() == '\\') { + consume_specific('\\'); + if (peek() == 0) + break; + } + buffer.append(consume_one()); + } + + String string_value(String::copy(buffer)); + buffer.clear(); + + if (consume_specific(end_char)) { + return { string_value }; + } + return {}; + } + + Optional<String> parse_url() + { + if (is_valid_string_quotes_char(peek())) + return parse_string(); + + buffer.clear(); + while (peek() && peek() != ')') + buffer.append(consume_one()); + + String url_value(String::copy(buffer)); + buffer.clear(); + + if (peek() == ')') + return { url_value }; + return {}; + } + + void parse_at_import_rule() + { + consume_whitespace_or_comments(); + Optional<String> imported_address; + if (is_valid_string_quotes_char(peek())) { + imported_address = parse_string(); + } else if (next_is("url")) { + consume_specific('u'); + consume_specific('r'); + consume_specific('l'); + + consume_whitespace_or_comments(); + + if (!consume_specific('(')) + return; + imported_address = parse_url(); + if (!consume_specific(')')) + return; + } else { + PARSE_ERROR(); + return; + } + + if (imported_address.has_value()) + rules.append(CSS::CSSImportRule::create(m_context.complete_url(imported_address.value()))); + + // FIXME: We ignore possilbe media query list + while (peek() && peek() != ';') + consume_one(); + + consume_specific(';'); + } + + void parse_at_rule() + { + HashMap<String, void (CSSParser::*)()> at_rules_parsers({ { "@import", &CSSParser::parse_at_import_rule } }); + + for (const auto& rule_parser_pair : at_rules_parsers) { + if (next_is(rule_parser_pair.key.characters())) { + for (char c : rule_parser_pair.key) { + consume_specific(c); + } + (this->*(rule_parser_pair.value))(); + return; + } + } + + // FIXME: We ignore other @-rules completely for now. + while (peek() != 0 && peek() != '{') + consume_one(); + int level = 0; + for (;;) { + auto ch = consume_one(); + if (ch == '{') { + ++level; + } else if (ch == '}') { + --level; + if (level == 0) + break; + } + } + } + + void parse_rule() + { + consume_whitespace_or_comments(); + if (!peek()) + return; + + if (peek() == '@') { + parse_at_rule(); + } else { + parse_style_rule(); + } + consume_whitespace_or_comments(); } diff --git a/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.h b/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.h index ca9a4688e2..80421fce8e 100644 --- a/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.h +++ b/Userland/Libraries/LibWeb/CSS/Parser/CSSParser.h @@ -27,6 +27,7 @@ #pragma once #include <AK/NonnullRefPtr.h> +#include <AK/String.h> #include <LibWeb/CSS/StyleSheet.h> namespace Web::CSS { @@ -38,6 +39,8 @@ public: bool in_quirks_mode() const; + URL complete_url(const String&) const; + private: const DOM::Document* m_document { nullptr }; }; diff --git a/Userland/Libraries/LibWeb/Dump.cpp b/Userland/Libraries/LibWeb/Dump.cpp index 2ce412a23a..0a2d2f8d36 100644 --- a/Userland/Libraries/LibWeb/Dump.cpp +++ b/Userland/Libraries/LibWeb/Dump.cpp @@ -28,6 +28,7 @@ #include <AK/QuickSort.h> #include <AK/StringBuilder.h> #include <AK/Utf8View.h> +#include <LibWeb/CSS/CSSImportRule.h> #include <LibWeb/CSS/CSSRule.h> #include <LibWeb/CSS/PropertyID.h> #include <LibWeb/CSS/StyleRule.h> @@ -406,11 +407,19 @@ void dump_rule(StringBuilder& builder, const CSS::CSSRule& rule) case CSS::CSSRule::Type::Style: dump_style_rule(builder, downcast<const CSS::StyleRule>(rule)); break; + case CSS::CSSRule::Type::Import: + dump_import_rule(builder, downcast<const CSS::CSSImportRule>(rule)); + break; default: VERIFY_NOT_REACHED(); } } +void dump_import_rule(StringBuilder& builder, const CSS::CSSImportRule& rule) +{ + builder.appendff(" Document URL: {}\n", rule.url()); +} + void dump_style_rule(StringBuilder& builder, const CSS::StyleRule& rule) { for (auto& selector : rule.selectors()) { diff --git a/Userland/Libraries/LibWeb/Dump.h b/Userland/Libraries/LibWeb/Dump.h index 78ba4a46bd..48f7166bcd 100644 --- a/Userland/Libraries/LibWeb/Dump.h +++ b/Userland/Libraries/LibWeb/Dump.h @@ -41,6 +41,7 @@ void dump_sheet(const CSS::StyleSheet&); void dump_rule(StringBuilder&, const CSS::CSSRule&); void dump_rule(const CSS::CSSRule&); void dump_style_rule(StringBuilder&, const CSS::StyleRule&); +void dump_import_rule(StringBuilder&, const CSS::CSSImportRule&); void dump_selector(StringBuilder&, const CSS::Selector&); void dump_selector(const CSS::Selector&); diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index f7a9b71fc0..84e704edb1 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -29,6 +29,7 @@ namespace Web::CSS { class CSSRule; +class CSSImportRule; class Length; class Selector; class StyleDeclaration; |