This is not simply an inversion of the Slightly Smiling Face emoji.
The facial features were flipped vertically but the underlying "face"
was kept the same, because for both emojis the top is lighter than the
bottom.
Many properties can now have percentage values that get resolved in
layout. The reference value (what is this a percentage *of*?) differs
per property, so I've added a helper where you provide a reference
value as an added parameter to the existing length_or_fallback().
Step one of moving DesktopServices::open handling out of process. This
makes it easier to do things like read in associations for which program
opens which files or protocols. This gives users the ability to modify
the associations without having to rebuild :^)
This implements only one of the two forms of this function,
ctx.fill(winding_rule).
Also tweaks the quadratic curve demo to have a nice looking filled
shape.
This display type is implemented using a LayoutBlock that is_inline().
Basically it behaves like a block internally, and its children are laid
out in the normal block layout fashion. Externally however, it behaves
like an atomic inline-level box.
Layout of inline-block boxes happens in three stages:
1. The outer dimensions of the block are computed during the recursive
normal layout pass. We skip positioning, but lay out children.
2. Later on, during line layout in the *containing block*, the inline
block now contributes a linebox fragment. When linebox fragments are
positioned, we learn the final position of the inline block. That's
when we set the inline block's position.
3. We re-layout the inline block's children once again. This is done to
make sure they end up in the right position. The layout tree doesn't
use relative offsets, so after we position the inline block in (2),
its children will not have its positions updated. Relayout moves
all children of inline blocks to the right place.
This is a rather naive approach but it does get the basic behavior into
place so we can iterate on it. :^)
When dealing with png data that has less than 8 bits per pixel, round
up to the next byte when allocating per row buffers and streamers. This
fixes decoding odd sized PNGs with less than 8 bits per pixel.
Also added a test page with some odd sized palleted PNGs.
The HackStudio debugger integrates with LibDebug to provide
source-level debugging.
The user can set breakpoints at various positions in the source code,
and then run the program in debug mode.
When the program is stopped, the current execution position is
displayed, and the user can insert/remove breakpoints, continue
execution, or single step the program.
This patch adds the following methods to CanvasRenderingContext2D:
- beginPath()
- moveTo(x, y)
- lineTo(x, y)
- closePath()
- stroke()
We also add the lineWidth property. :^)
Add an implementation of CanvasRenderingContext2DWrapper.strokeRect().
While implementing this I fixed fillRect() and the new strokeRect() to
honor the .scale() and .translate() values that had previously been plumbed.
Also enhance the canvas.html demo to utilize strokeRect(), scale(), and translate().
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 adds:
- A global Date object (with `length` property and `now` function)
- The Date constructor (no arguments yet)
- The Date prototype (with `get*` functions)
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.
This patchset adds a bookmark bar that is backed by a json file backend.
The json file is loaded and checked for the format. According to the
format, the bookmarks bar is populated with the bookmark items.
If the bookmarks do not fit into one line, an expader button is shown
that brings up a menu containing the missing bookmark items.
There is currently no way to add or remove bookmarks. A hover over a
bookmark is also not yet showing the url in the statusbar.
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! :^)
You can now throw an expression to the nearest catcher! :^)
To support throwing arbitrary values, I added an Exception class that
sits as a wrapper around whatever is thrown. In the future it will be
a logical place to store a call stack.
You can now throw exceptions by calling Interpreter::throw_exception().
Anyone who calls ASTNode::execute() needs to check afterwards if the
Interpreter now has an exception(), and if so, stop what they're doing
and simply return.
When catching an exception, we'll first execute the CatchClause node
if present. After that, we'll execute the finalizer block if present.
This is unlikely to be completely correct, but it's a start! :^)
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.