Age | Commit message (Collapse) | Author |
|
|
|
Using split() creates a new String object for each of the split tokens.
Use split_view() instead to avoid these unnecessary heap allocations.
|
|
Rather than parsing the selector every time we want to check it, we
now parse it once at the beginning.
A bonus effect of this is that we now support a selector list in
:not(), instead of just a single selector, though only when using
the new parser.
|
|
The end goal is to make the PseudoClass::not_selector be a Selector
instead of a String that is repeatedly re-parsed. But since Selector
contains a Vector of ComplexSelectors, which each have a Vector of
SimpleSelectors, it's probably a good idea to not be passing them
around by value anyway. :^)
|
|
Same reasoning again! This is the last one.
While I was at it, I added the two remaining CSS2.2 pseudo-elements,
::first-line and ::first-letter. All 4 are handled in the new CSS
parser, including with the compatibility single-colon syntax. I have
not added support to the old parser.
|
|
Same reasoning as the previous commit.
|
|
Previously, SimpleSelectors optionally had Attribute-selector data
as well as their main type. Now, they're either one or the other,
which better matches the spec, and makes parsing and matching more
straightforward.
|
|
|
|
We were only discarding at most one token when a declaration is
invalid, when we should discard all until we see a ; or EOF.
|
|
Calling is_valid_escape_sequence() with no arguments hides what it
is operating on, so I have removed that, so that you must explicitly
tell it what you are testing.
The call from consume_a_token() was using the wrong tokens, so it
returned false incorrectly. This was resulting in corrupted output
when faced with this code from Acid2. (Abbreviated)
```css
.parser { error: \}; }
.parser { }
```
|
|
|
|
This is a modified copy of the code from Selector.cpp, to work on a
TokenStream instead of a String.
|
|
The input is ComponentValues, and the output is too, so storing as
a String in the middle was inefficient and unnecessary.
|
|
Had to adjust some places that were using Token.to_string() for
non-debug-logging purposes. Changed its name to to_debug_string()
to make the usage clearer.
|
|
There were several crashes here from out-of-bounds memory access.
|
|
|
|
Whitespace marks the end of a compound-selector, no matter where
it occurs. `check_for_eof_or_whitespace()` reconsumes the whitespace
token for convenience.
|
|
|
|
|
|
A lot of this is not spec-compliant and copied from the old parser.
In future PRs, we can revise it.
|
|
It's feeling unwieldy having it everywhere.
|
|
|
|
|
|
Each method can either be called with a TokenStream, or with no
arguments to replicate the previous behaviour.
|
|
The entry points for CSS parsing in the spec are defined as accepting
any of a stream of Tokens, or a stream of ComponentValues, or a String.
TokenStream is an attempt to reduce the duplication of code for that.
|
|
The end goal here is to make the two classes mostly interchangeable, as
the CSS spec requires that the various parser algorithms can take a
stream of either class, and we want to have that functionality without
needing to duplicate all of the code.
|
|
|
|
Rather than passing a ComponentType, and then manually modifying the
data fields, we now create them initialized.
The constructor that takes a Token is intentionally left implicit,
so that we can automatically convert when using the TokenStream later.
|
|
AtStyleRule being a subclass of QualifiedStyleRule was causing
problems when trying to distinguish between them. Combining them
and then distinguishing between them with a Type enum makes that
check simpler, and is in line with how similar checks are done
elsewhere in the parser.
|
|
They're still using the same parsing code, so there's a lot of room
for improvement, but it's good for now.
|
|
The new one is the same as the old one, just in the new Parser's
source files. This isn't the most elegant solution but it seemed
like the best option. And it's all temporary, after all.
|
|
Previous implementation was returning everything in a single Vector,
when what we really want is a Vector of Vectors, one for each comma-
separated part of the list.
|
|
Optional seems like a good idea, but in many places we were not
checking if it had a value, which was causing crashes when the
Tokenizer was given malformed input. Using an EOF value along with
is_eof() makes things a lot simpler.
|
|
This is very much stubbed out for now. Most notably is
Parser::convert_rule() where most of the conversion will happen
from the parser's internal rule classes to CSSRule and its children.
|
|
A single DELIM token is only one character long, so the check for
a "||" DELIM didn't work. We now just do the check inline.
|
|
Whitespace parsing was too greedy, consuming the first non-
whitespace character after it.
|
|
|
|
|
|
|
|
This adds:
- ContainsString [att*=val]
- StartsWithSegment [att|=val]
- StartsWithString [att^=val]
- EndsWithString [att$=val]
Renamed AttributeMatchType::Contains to ::ContainsWord for clarity.
|
|
Noticed while doing this that attribute selectors have two different
ways of saying "starts with", and so AttributeMatchType::StartsWith
needs a better name. But I'll change that when I add the missing
types.
These class names are a mouthful to fit in a commit message. :^)
|
|
Previously these were all passed around by value, but some of them
(StyleComponentValueRule and StyleBlockRule) want to include each
other as fields, so this had to change.
|
|
Also added some pseudo-classes that were handled in the deprecated
parser:
- :disabled
- :enabled
- :checked
- :nth-child
- :nth-last-child
- :not
|
|
Some of these will be removed later, when we move to using is()
exclusively.
|
|
|
|
We already do this in most places, so the style should be consistent.
Also, Clang does not like it, as this could cause an unexpected compile
error if some statements are added to the default label or a new label
is added above it.
|
|
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.
This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.
What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.
Key changes include:
- 1:1 matching function names and parameters of all object-related
functions, to avoid ambiguity. Previously we had things like put(),
which the spec doesn't have - as a result it wasn't always clear which
need to be used.
- Better separation between object abstract operations and internal
methods - the former are always the same, the latter can be overridden
(and are therefore virtual). The internal methods (i.e. [[Foo]] in the
spec) are now prefixed with 'internal_' for clarity - again, it was
previously not always clear which AO a certain method represents,
get() could've been both Get and [[Get]] (I don't know which one it
was closer to right now).
Note that some of the old names have been kept until all code relying
on them is updated, but they are now simple wrappers around the
closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
storage are now prefixed with 'storage_' to make their purpose clear,
and as they are not part of the spec they should not contain any steps
specified by it. Much functionality is now covered by the layers above
it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
by PropertyDescriptor - a concept similar to the current
implementation, but more aligned with the actual spec. See the commit
message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
introduced more inline comments with the exact steps from the spec -
this makes it super easy to verify correctness.
- East-const all the things.
As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.
Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)
Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
|
|
This patch adds support for the identifiers upper-roman and lower-roman
of the list-style property.
|
|
This implements StringUtils::find_any_of() and uses it in
String::find_any_of() and StringView::find_any_of(). All uses of
find_{first,last}_of have been replaced with find_any_of(), find() or
find_last(). find_{first,last}_of have subsequently been removed.
|
|
Adds support for the :active pseudo-class for hyperlinks (<a> tags
only).
Also, since it was very similar to :focus and an element having a
focused state was already implemented, I went ahead and implemented
that pseudo-class too, although I cannot come up with a working
example to validate it.
|