We don't want to descend into inline-block containers when iterating
inline-level items, since that would make the inline-level children of
the inline-block bubble up to the containing block of the inline-block.
This resolves a long-standing architectural problem in LibWeb that made
it unable to place CSS floating objects correctly due to not having
final vertical position information when computing the amount of
available horizontal space for each line.
This patch adds a new mechanism that allows InlineFormattingContext to
build line boxes incrementally instead of all-in-one go.
Incremental build will eventually allow much better support for CSS
floating objects.
This moves LibWeb to using the list of hidden elements from the spec.
Concretely, the following things are now explicitly marked
`display: none` in addition to before:
- elements with the `hidden` attribute
- area
- base
- basefont
- datalist
- param
- rp
The spec also wants `noframes` and `noembed` to be `display: none`,
but since support for frames and embeds doesn't exist yet, these
are omitted for now.
With this, everyone's favorite website http://45.33.8.238/ no longer
displays spans with attribute hidden. (Whitespace handling still
looks a bit off though.)
This also refactors interpreter creation to follow
InitializeHostDefinedRealm, but I couldn't fit it in the title :^)
This allows us to follow the spec much more closely rather than being
completely ad-hoc with just the parse node instead of having all the
surrounding data such as the realm of the parse node.
The interpreter creation refactor creates the global execution context
once and doesn't take it off the stack. This allows LibWeb to take the
global execution context and manually handle it, following the HTML
spec. The HTML spec calls this the "realm execution context" of the
environment settings object.
It also allows us to specify the globalThis type, as it can be
different from the global object type. For example, on the web, Window
global objects use a WindowProxy global this value to enforce the same
origin policy on operations like [[GetOwnProperty]].
Finally, it allows us to directly call Program::execute in perform_eval
and perform_shadow_realm_eval as this moves
global_declaration_instantiation into Interpreter::run
(ScriptEvaluation) as per the spec.
Note that this doesn't evalulate Source Text Modules yet or refactor
the bytecode interpreter, that's work for future us :^)
This patch was originally build by Luke for the environment settings
object change but was also needed for modules. So I (davidot) have
modified it with the new completion changes and setup for that.
Co-authored-by: davidot <davidot@serenityos.org>
In querySelector(All)'s use of "Match a Selector Against a Tree", it
passes in the node the function was called on as the "optional scoping
root", which causes it and the nodes which aren't descendants of it
to be excluded from the list of possible nodes to match against.
For us, this is the equivalent of using the non-inclusive variant of
`for_each_in_subtree_of_type`.
This was tripping up the node re-ordering logic of d3 and would cause
it to try and reinsert nodes into their parent, causing an exception
to be thrown.
Note that this should be shadow-including, but we don't currently have
shadow-including tree traversal as per https://dom.spec.whatwg.org/#concept-shadow-including-tree-orderhttps://drafts.csswg.org/selectors-4/#match-a-selector-against-a-treehttps://dom.spec.whatwg.org/#scope-match-a-selectors-string
Despite looking like it was still needed, it was only used for passing
to other calls to Length::resolved() recursively. This makes the
various `foo.resolved().resolved()` calls a lot less awkward.
(Though, still quite awkward.)
I think we'd need to separate calculated lengths out to properly tidy
these calls up, but one yak at a time. :^)
A lot of this is quite ugly, but it should only be so until I remove
Length::Type::Percentage entirely. (Which should happen later in this
PR, otherwise, yell at me!) For now, a lot of things have to be
resolved twice, first from a LengthPercentage to a Length, and then
from a Length to a pixel one.
The flexbox logic confuses me so regressions are possible, though our
test page looks the same as before so it should be fine.
Renamed FlexBasis::Length -> LengthPercentage too, for clarity.
This does undo the changes in 88c32836d8,
which accounted for our bitmap fonts being a different size than the
`font-size` property requests. I think this would be better handled
inside Length::to_px(), which would then apply to all font-size-relative
lengths (eg, em and rem) instead of only for the line-height property.
Layout::Node still treats border radii as having a single value instead
of horizontal and vertical, but one less hack is nice, and helps with
conversion to LengthPercentage. :^)
This is in a slightly weird state, where Percentages are sometimes
Lengths and sometimes not, which I will be cleaning up in subsequent
commits, in an attempt not to change all of LibWeb in one go. :^)
Length and Percentage are different types, and sometimes only one or the
other is allowed in a given CSS property. This is a first step towards
separating them.
This is in line with this recent change to Conditional-3:
> Removed the “unknown” value in CSS feature queries’ boolean logic,
> defining unrecognized syntaxes as “false” instead.
> https://github.com/w3c/csswg-drafts/issues/6175
This change unfortunately cannot be atomically made without a single
commit changing everything.
Most of the important changes are in LibIPC/Connection.cpp,
LibIPC/ServerConnection.cpp and LibCore/LocalServer.cpp.
The notable changes are:
- IPCCompiler now generates the decode and decode_message functions such
that they take a Core::Stream::LocalSocket instead of the socket fd.
- IPC::Decoder now uses the receive_fd method of LocalSocket instead of
doing system calls directly on the fd.
- IPC::ConnectionBase and related classes now use the Stream API
functions.
- IPC::ServerConnection no longer constructs the socket itself; instead,
a convenience macro, IPC_CLIENT_CONNECTION, is used in place of
C_OBJECT and will generate a static try_create factory function for
the ServerConnection subclass. The subclass is now responsible for
passing the socket constructed in this function to its
ServerConnection base; the socket is passed as the first argument to
the constructor (as a NonnullOwnPtr<Core::Stream::LocalServer>) before
any other arguments.
- The functionality regarding taking over sockets from SystemServer has
been moved to LibIPC/SystemServerTakeover.cpp. The Core::LocalSocket
implementation of this functionality hasn't been deleted due to my
intention of removing this class in the near future and to reduce
noise on this (already quite noisy) PR.
Instead of making it a void function, checking for an exception, and
then receiving the relevant result via VM::last_value(), we can
consolidate all of this by using completions.
This allows us to remove more uses of VM::exception(), and all uses of
VM::last_value().
This includes:
- Parsing proper LabelledStatements with try_parse_labelled_statement()
- Removing LabelableStatement
- Implementing the LoopEvaluation semantics via loop_evaluation() in
each IterationStatement subclass; and IterationStatement evaluation
via {For,ForIn,ForOf,ForAwaitOf,While,DoWhile}Statement::execute()
- Updating ReturnStatement, BreakStatement and ContinueStatement to
return the appropriate completion types
- Basically reimplementing TryStatement and SwitchStatement according to
the spec, using completions
- Honoring result completion types in AsyncBlockStart and
OrdinaryCallEvaluateBody
- Removing any uses of the VM unwind mechanism - most importantly,
VM::throw_exception() now exclusively sets an exception and no longer
triggers any unwinding mechanism.
However, we already did a good job updating all of LibWeb and userland
applications to not use it, and the few remaining uses elsewhere don't
rely on unwinding AFAICT.
This requires an implementation of the "text preparation algorithm" as
specified here:
html.spec.whatwg.org/multipage/canvas.html#text-preparation-algorithm
However, we're missing a lot of things such as the
CanvasTextDrawingStyles interface, so most of the algorithm was not
implemented. Additionally, we also are not able to use a LineBox like
the algorithm suggests, because our layouting infra is not up to the
task yet. The prepare_text function does nothing other than figuring out
the width of the given text and return glyphs with offsets at the
moment.
In the end this is a nicer API than having separate has_{value,target}()
and having to check those first, and then making another Optional from
the unwrapped value:
completion.has_value() ? completion.value() : Optional<Value> {}
// ^^^^^^^^^^^^^^^^^^
// Implicit creation of non-empty Optional<Value>
This way we need to unwrap the optional ourselves, but can easily pass
it to something else as well.
This is in anticipation of the AST using completions :^)
This means you can now do queries like:
```css
@media (400px <= width < 800px) { }
```
Chromium and Firefox which I tested with both don't support this yet, so
that's cool. :^)
Past me decided that the grammar was overly verbose and I could do it
better myself. Which seemed fine until the spec changed and I didn't
know how to integrate the changes. Lesson learned! :^)
Rather than have a function for every single part of the grammar, I have
written some as lambdas, and combned `<media-condition>` and
`<media-condition-without-or>` into one function. But otherwise it's
close to the spec, with comments listing the part of the grammar being
parsed, so hopefully it will be easier to make future adjustments!
This does not add any new functionality.
Web::CSS::MediaQuery::MediaFeature::Type was getting a bit ridiculous!
Also, this moves the detection of "min-" and "max-" media-features into
the MediaFeature itself, since this is an implementation detail, not
part of the spec.
Having these in here was a hack to support the other hack of making
media-queries use StyleValues. Now they don't do that, so we can remove
these again and keep things hygienic.
Previously, we were using StyleValues for this, which was a bit of a
hack and was brittle, breaking when I modified how custom properties
were parsed. This is better and also lets us limit the kinds of value
that can be used here, to match the spec.