summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorSviatoslav Peleshko <speles@mail.ua>2021-02-21 18:36:34 +0200
committerAndreas Kling <kling@serenityos.org>2021-02-28 10:27:32 +0100
commit54617e1a9109b28b00599a247de2f9607152c129 (patch)
tree8fb5856a0e667fd83354af750f9a9b80c99c020e /Userland/Libraries
parent04d67d023945ebfc8375a67212b690619916ef2a (diff)
downloadserenity-54617e1a9109b28b00599a247de2f9607152c129.zip
LibWeb: Added simple parsing for (at)import rules
For now, the parsing is very crude, and parses only the document url. The meta queries for the import are ignored.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibWeb/CMakeLists.txt1
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp42
-rw-r--r--Userland/Libraries/LibWeb/CSS/CSSImportRule.h57
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/CSSParser.cpp158
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/CSSParser.h3
-rw-r--r--Userland/Libraries/LibWeb/Dump.cpp9
-rw-r--r--Userland/Libraries/LibWeb/Dump.h1
-rw-r--r--Userland/Libraries/LibWeb/Forward.h1
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;