Scripts loaded in this way will block the parser until they finish
executing. This means that they see the DOM before the whole document
has been fully parsed. This is all normal, of course.
To make this work, I changed the way we notify DOM nodes about tree
insertion. The inserted_into() callbacks are now incrementally invoked
during parse, as each node is appended to its parent.
To accomodate inline scripts and inline style sheets, we now also have
a children_changed() callback which is invoked on any parent when it
has children added/removed.
This function creates a nested event loop and runs a load() operation
inside it, returning only once the load has either succeeded or failed.
This will be used to implement blocking loads (ew!)
The Help application was hooking HtmlView::on_link_click, which would
get invoked before DOM event dispatch. Since we were holding on to the
clicked node with a Node*, the DOM node was gone after returning from
the on_link_click callback.
Fix this by keeping DOM nodes in RefPtrs in the event management code.
Also move DOM event dispatch before widget hook invocation, to try and
keep things sane on the LibWeb side of things.
Fixes#1605.
Let's move towards using references over pointers in LibJS as well.
I had originally steered away from it because that's how I've seen
things done in other engines. But this is not the other engines. :^)
LibWeb now creates a WindowObject which inherits from GlobalObject.
Allocation of the global object is moved out of the Interpreter ctor
to allow for specialized construction.
The existing Window interfaces are moved to WindowObject with their
implementation code in the new Window class.
I made some mistakes in the selector parsing code. It's now able to
parse selectors composed of multiple complex selectors, instead of just
one complex selector.
This currently returns a JS::Array of elements matching a selector.
The more correct behavior would be to return a static NodeList, but as
we don't have NodeLists right now, that'll be a task for the future.
Instead of implementing every native function as a lambda function,
use static member functions instead.
This makes it easier to navigate the code + backtraces look nicer. :^)
Native functions now only get the Interpreter& as an argument. They can
then extract |this| along with any indexed arguments it wants from it.
This forces functions that want |this| to actually deal with calling
interpreter.this_value().to_object(), and dealing with the possibility
of a non-object |this|.
This is still not great but let's keep massaging it forward.
Getting the innerHTML property will recurse through the subtree inside
the element and serialize it into a string as it goes.
Setting it will parse the set value as an HTML fragment. It will then
remove all current children of the element and replace them with all
the children inside the parsed fragment.
Setting element.innerHTML will currently force a complete rebuild of
the document's layout tree.
This is pretty neat! :^)
This function allows you to throw away the entire layout tree if that's
something you want to do.
It's certainly not super cheap to reconstruct, but hey, who am I to
tell you what to do? :^)
This momentarily handles the CSS property "position: absolute;" in
combination with the properties "top" and "left", so that elements can
be placed anywhere on the page independently from their parents.
Statically positioned elements ignore absolute positioned elements when
calculating their position as they don't take up space.
We now support rAF, driven by GUI::DisplayLink callbacks. It's a bit
strange how we keep registering new callbacks over and over.
That's something we can definitely optimize.
This allows you to update animations/whatever without doing it more
often than the browser can display.
FlyString is a flyweight string class that wraps a RefPtr<StringImpl>
known to be unique among the set of FlyStrings. The class is very
unoptimized at the moment.
When to use FlyString:
- When you want O(1) string comparison
- When you want to deduplicate a lot of identical strings
When not to use FlyString:
- For strings that don't need either of the above features
- For strings that are likely to be unique
This patch adds the Event base class, along with a MouseEvent subclass.
We now dispatch MouseEvent objects for mousedown, mouseup and mousemove
and these objects have the .offsetX and .offsetY properties.
Both of those properties are hard-coded at the moment. This will be
fixed in the next patch. :^)
This makes it possible to write shorter CSS. Instead of writing
.foo {
border-width: 3px;
border-style: solid;
border-color: blue;
}
it is now possible to write
.foo {
border: 3px solid blue;
}
while the order of values is irrelevant.
Currently only the basic values are supported. More values should be
added in the future.
Three more value specific parse functions were added:
parse_line_width, parse_color, and parse_line_style
Additionally a few test cases were added to borders.html.