Skip to content

Commit 21741e5

Browse files
committed
(wip) vaev-style: Added support for dynamic property registration.
1 parent b81bee4 commit 21741e5

39 files changed

+7086
-4213
lines changed

src/vaev-engine/css/lexer.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export struct Token {
6565
}
6666

6767
void repr(Io::Emit& e) const {
68-
if (not *this) {
68+
if (not*this) {
6969
e("nil");
7070
return;
7171
}
@@ -207,19 +207,21 @@ static auto const RE_NUMBER = Re::chain(
207207

208208
export struct Lexer {
209209
Io::SScan _scan;
210-
Token _curr;
211210

212211
Lexer(Str text) : _scan(text) {
213-
_curr = _next(_scan);
214212
}
215213

216214
Lexer(Io::SScan const& scan)
217215
: _scan(scan) {
218-
_curr = _next(_scan);
219216
}
220217

221-
Token peek() const {
222-
return _curr;
218+
Token peek(usize offset = 1) const {
219+
Io::SScan scan = _scan;
220+
Token res = Token::NIL;
221+
for (auto _ : range(offset)) {
222+
res = _next(scan);
223+
}
224+
return res;
223225
}
224226

225227
Token _nextIdent(Io::SScan& s) const {
@@ -392,9 +394,7 @@ export struct Lexer {
392394
}
393395

394396
Token next() {
395-
auto res = _curr;
396-
_curr = _next(_scan);
397-
return res;
397+
return _next(_scan);
398398
}
399399

400400
bool ended() const {

src/vaev-engine/css/parser.cpp

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ export struct Sst;
1717

1818
export using Content = Vec<Sst>;
1919

20+
export enum struct Important {
21+
UNSET,
22+
YES,
23+
};
24+
2025
#define FOREACH_SST(SST) \
2126
SST(RULE) \
2227
SST(FUNC) \
@@ -40,13 +45,19 @@ export struct Sst {
4045
Token token = Token(Token::NIL);
4146
Opt<Box<Sst>> prefix{};
4247
Content content{};
48+
Important important = Important::UNSET;
4349

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

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

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

56+
// https://drafts.csswg.org/css-variables-2/#guaranteed-invalid
57+
static Sst guaranteedInvalid() {
58+
return Token::badString("");
59+
}
60+
5061
void repr(Io::Emit& e) const {
5162
if (type == TOKEN) {
5263
e("{}", token);
@@ -200,18 +211,48 @@ Sst consumeAtRule(Lexer& lex) {
200211
}
201212
}
202213

203-
export Content consumeDeclarationValue(Lexer& lex) {
214+
Important consumeImportant(Lexer& lex) {
215+
if (lex.peek() != Css::Token::delim("!"))
216+
return Important::UNSET;
217+
lex.next();
218+
219+
auto copy = lex;
220+
eatWhitespace(copy);
221+
if (copy.next() != Css::Token::ident("important"))
222+
return Important::UNSET;
223+
lex = copy;
224+
return Important::YES;
225+
}
226+
227+
export bool endedDeclarationValue(Lexer& lex) {
228+
return lex.peek() == Token::END_OF_FILE or
229+
lex.peek() == Token::SEMICOLON or
230+
lex.peek() == Token::RIGHT_CURLY_BRACKET;
231+
}
232+
233+
export Tuple<Content, Important> consumeDeclarationValue(Lexer& lex) {
204234
Content value;
235+
205236
// 3. While the next input token is a <whitespace-token>, consume the next input token.
206237
eatWhitespace(lex);
207238

208239
// 4. As long as the next input token is anything other than an <EOF-token>,
209240
// consume a component value and append it to the declaration’s value.
210-
while ((lex.peek() != Token::END_OF_FILE and lex.peek() != Token::SEMICOLON and lex.peek() != Token::RIGHT_CURLY_BRACKET)) {
211-
value.pushBack(consumeComponentValue(lex));
212-
eatWhitespace(lex);
241+
while (endedDeclarationValue(lex)) {
242+
// 5. If the last two non-<whitespace-token>s in the declaration’s
243+
// value are a <delim-token> with the value "!" followed by an
244+
// <ident-token> with a value that is an ASCII case-insensitive match
245+
// for "important", remove them from the declaration’s value
246+
// and set the declaration’s important flag to true.
247+
if (consumeImportant(lex) == Important::YES) {
248+
eatWhitespace(lex);
249+
return {std::move(value), Important::UNSET};
250+
} else {
251+
value.pushBack(consumeComponentValue(lex));
252+
eatWhitespace(lex);
253+
}
213254
}
214-
return value;
255+
return {std::move(value), Important::UNSET};
215256
}
216257

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

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

305347
// Parse the declaration’s value.
306-
decl.content = consumeDeclarationValue(lex);
348+
auto [content, important] = consumeDeclarationValue(lex);
349+
decl.content = std::move(content);
350+
decl.important = important;
307351

308352
return decl;
309353
}

src/vaev-engine/manifest.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"layout/base",
1313
"layout/builder",
1414
"loader",
15+
"props",
1516
"style",
1617
"values",
1718
"xml"

0 commit comments

Comments
 (0)