summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibWeb')
-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;