mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:07:35 +00:00
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.
This commit is contained in:
parent
04d67d0239
commit
54617e1a91
8 changed files with 248 additions and 24 deletions
|
@ -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
|
||||
|
|
42
Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp
Normal file
42
Userland/Libraries/LibWeb/CSS/CSSImportRule.cpp
Normal file
|
@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
57
Userland/Libraries/LibWeb/CSS/CSSImportRule.h
Normal file
57
Userland/Libraries/LibWeb/CSS/CSSImportRule.h
Normal file
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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&);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
namespace Web::CSS {
|
||||
class CSSRule;
|
||||
class CSSImportRule;
|
||||
class Length;
|
||||
class Selector;
|
||||
class StyleDeclaration;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue