This patch adds the "has a rendering opportunity" concept from the spec
to BrowsingContext and uses it to filter out contexts that are unable
to render right now when doing the event loop's rendering updates.
Note that we actually consider all contexts to have a rendering
opportunity at all times right now. Coming up with reasons to avoid
rendering is left as a FIXME. :^)
We now invoke DOM timer callbacks via HTML tasks. This brings callback
sequencing closer to the spec, although there are still many
imperfections in this area.
This particularly implements these two points:
- "If the adjusted current node is an HTML integration point and the
token is a start tag"
- "If the adjusted current node is an HTML integration point and the
token is a character token"
This also adds spec comments to the tree constructor.
When parsing a CSS value in the context of a CSSStyleDeclaration
camelCase property setter, we don't necessarily have a Document to
provide the CSS parser for context.
So the parser can't go assuming that there's always a Document in the
ParsingContext. And ImageStyleValue can't go assuming that there's
always a Document either. This will require some more work to get things
right, I'm just patching up the null dereference for now.
We now follow the "update a style block" algorithm from the HTML spec
instead of using the ad-hoc CSSLoader mechanism.
This necessitated improving our StyleSheet and CSSStyleSheet classes as
well, so that's baked into this commit.
If a page is nice enough to give us some preload hints, we can tell
RequestServer to get started on downloading the resources right away,
instead of waiting until discovering them later on during parsing.
We now fire "pageshow" events at the appropriate time during document
loading (done by the parser.)
Note that there are no corresponding "pagehide" events yet.
This will be used to determine whether "pageshow" and "pagehide" events
are appropriate. We won't actually make use of it until we implement
more of history traversal and document unloading.
The only difference from what we were already doing is that setting the
same ready state twice no longer fires a "readystatechange" event.
I don't think that could happen in practice though.
We will now spin in "the end" until there are no more "things delaying
the load event". Of course, nothing actually uses this yet, and there
are a lot of things that need to.
The ideal solution here is to implement a more spec-compliant event
loop, but while we get all the pieces in place for that, this at least
makes the HTML event loop a bit more responsive since it never has to
wait for a 16ms timer to fire.
The old name is the result of the perhaps somewhat confusingly named
abstract operation OrdinaryFunctionCreate(), which creates an "ordinary
object" (https://tc39.es/ecma262/#ordinary-object) in contrast to an
"exotic object" (https://tc39.es/ecma262/#exotic-object).
However, the term "Ordinary Function" is not used anywhere in the spec,
instead the created object is referred to as an "ECMAScript Function
Object" (https://tc39.es/ecma262/#sec-ecmascript-function-objects), so
let's call it that.
The "ordinary" vs. "exotic" distinction is important because there are
also "Built-in Function Objects", which can be either implemented as
ordinary ECMAScript function objects, or as exotic objects (our
NativeFunction).
More work needs to be done to move a lot of infrastructure to
ECMAScriptFunctionObject in order to make FunctionObject nothing more
than an interface for objects that implement [[Call]] and optionally
[[Construct]].
Resolved style is a spec concept that refers to the weird mix of
computed style and used style reflected by getComputedStyle().
The purpose of this class is to produce the *computed* style for a given
element, so let's call it StyleComputer.
This fixes the issue where an `<img>` set to its native size would
sometimes still appear blurry, because it had a fractional position,
causing `enclosing_int_rect()` to expand by 1px.
Instead of firing up a network request and synchronously blocking for it
to finish via a nested event loop, we now start an asynchronous request
when encountering <script src>.
Once the script load finishes (or fails), it gets executed at one of the
synchronization points in the HTML parser.
This solves some long-standing issues with random unexpected events
getting dispatched in the middle of parsing.