Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/vaev-engine/css/lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export struct Token {
}

void repr(Io::Emit& e) const {
if (not *this) {
if (not*this) {
e("nil");
return;
}
Expand Down Expand Up @@ -207,19 +207,21 @@ static auto const RE_NUMBER = Re::chain(

export struct Lexer {
Io::SScan _scan;
Token _curr;

Lexer(Str text) : _scan(text) {
_curr = _next(_scan);
}

Lexer(Io::SScan const& scan)
: _scan(scan) {
_curr = _next(_scan);
}

Token peek() const {
return _curr;
Token peek(usize offset = 1) const {
Io::SScan scan = _scan;
Token res = Token::NIL;
for (auto _ : range(offset)) {
res = _next(scan);
}
return res;
}

Token _nextIdent(Io::SScan& s) const {
Expand Down Expand Up @@ -392,9 +394,7 @@ export struct Lexer {
}

Token next() {
auto res = _curr;
_curr = _next(_scan);
return res;
return _next(_scan);
}

bool ended() const {
Expand Down
56 changes: 50 additions & 6 deletions src/vaev-engine/css/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ export struct Sst;

export using Content = Vec<Sst>;

export enum struct Important {
UNSET,
YES,
};

#define FOREACH_SST(SST) \
SST(RULE) \
SST(FUNC) \
Expand All @@ -40,13 +45,19 @@ export struct Sst {
Token token = Token(Token::NIL);
Opt<Box<Sst>> prefix{};
Content content{};
Important important = Important::UNSET;

Sst(Type type) : type(type) {}

Sst(Token token) : type(TOKEN), token(token) {}

Sst(Content content) : type(LIST), content(content) {}

// https://drafts.csswg.org/css-variables-2/#guaranteed-invalid
static Sst guaranteedInvalid() {
return Token::badString("");
}

void repr(Io::Emit& e) const {
if (type == TOKEN) {
e("{}", token);
Expand Down Expand Up @@ -200,18 +211,48 @@ Sst consumeAtRule(Lexer& lex) {
}
}

export Content consumeDeclarationValue(Lexer& lex) {
Important consumeImportant(Lexer& lex) {
if (lex.peek() != Css::Token::delim("!"))
return Important::UNSET;
lex.next();

auto copy = lex;
eatWhitespace(copy);
if (copy.next() != Css::Token::ident("important"))
return Important::UNSET;
lex = copy;
return Important::YES;
}

export bool endedDeclarationValue(Lexer& lex) {
return lex.peek() == Token::END_OF_FILE or
lex.peek() == Token::SEMICOLON or
lex.peek() == Token::RIGHT_CURLY_BRACKET;
}

export Tuple<Content, Important> consumeDeclarationValue(Lexer& lex) {
Content value;

// 3. While the next input token is a <whitespace-token>, consume the next input token.
eatWhitespace(lex);

// 4. As long as the next input token is anything other than an <EOF-token>,
// consume a component value and append it to the declaration’s value.
while ((lex.peek() != Token::END_OF_FILE and lex.peek() != Token::SEMICOLON and lex.peek() != Token::RIGHT_CURLY_BRACKET)) {
value.pushBack(consumeComponentValue(lex));
eatWhitespace(lex);
while (endedDeclarationValue(lex)) {
// 5. If the last two non-<whitespace-token>s in the declaration’s
// value are a <delim-token> with the value "!" followed by an
// <ident-token> with a value that is an ASCII case-insensitive match
// for "important", remove them from the declaration’s value
// and set the declaration’s important flag to true.
if (consumeImportant(lex) == Important::YES) {
eatWhitespace(lex);
return {std::move(value), Important::UNSET};
} else {
value.pushBack(consumeComponentValue(lex));
eatWhitespace(lex);
}
}
return value;
return {std::move(value), Important::UNSET};
}

// https://www.w3.org/TR/css-syntax-3/#consume-style-block
Expand Down Expand Up @@ -286,6 +327,7 @@ Content consumeDeclarationBlock(Lexer& lex) {
return res;
}

// https://www.w3.org/TR/css-syntax-3/#consume-declaration
export Opt<Sst> consumeDeclaration(Lexer& lex) {
Sst decl{Sst::DECL};
decl.token = lex.next();
Expand All @@ -303,7 +345,9 @@ export Opt<Sst> consumeDeclaration(Lexer& lex) {
lex.next();

// Parse the declaration’s value.
decl.content = consumeDeclarationValue(lex);
auto [content, important] = consumeDeclarationValue(lex);
decl.content = std::move(content);
decl.important = important;

return decl;
}
Expand Down
9 changes: 9 additions & 0 deletions src/vaev-engine/dom/document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import Karm.Ref;
import Karm.Font;
import :dom.node;
import :dom.element;
import :props.base;
import :props.registry;

namespace Vaev::Style {
export struct StyleSheetList;
} // namespace Vaev::Style

namespace Vaev::Dom {

export struct Window;

export enum struct QuirkMode {
NO,
LIMITED,
Expand All @@ -29,7 +33,12 @@ export struct Document : Node {
String xmlEncoding;
String xmlStandalone = "no"s; // https://www.w3.org/TR/xml/#NT-SDDecl

// https://drafts.csswg.org/cssom/#dom-documentorshadowroot-stylesheets
Gc::Ptr<Style::StyleSheetList> styleSheets;

// https://drafts.css-houdini.org/css-properties-values-api/#dom-window-registeredpropertyset-slot
Style::PropertyRegistry registeredPropertySet = Style::defaultRegistry();

Opt<Rc<Font::Database>> fontDatabase;

Document(Ref::Url url)
Expand Down
1 change: 1 addition & 0 deletions src/vaev-engine/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"layout/base",
"layout/builder",
"loader",
"props",
"style",
"values",
"xml"
Expand Down
Loading
Loading