We now create a flex container inside the input element's UA shadow tree
and add the placeholder and non-placeholder text as flex items (wrapped
in elements whose style we can manipulate).
This fixes the visual glitch where the placeholder would appear below
the bounding box of the input element. It also allows us to align the
text vertically inside the input element (like we're supposed to).
In order to achieve this, I had to make two small architectural changes
to layout tree building:
- Elements can now report that they represent a given pseudo element.
This allows us to instantiate the ::placeholder pseudo element as an
actual DOM element inside the input element's UA shadow tree.
- We no longer create a separate layout node for the shadow root itself.
Instead, children of the shadow root are treated as if they were
children of the DOM element itself for the purpose of layout tree
building.
We know what types and identifiers a property can accept, so we can use
that information to only parse things that can be accepted. This solves
some awkward ambiguity problems that we have now or will face in the
future, including:
- Is `0` a number or a length with no unit?
- Is `3.5` a number or a ratio?
- Is `bottom` an identifier, or a custom-ident?
Two CSS Parser methods are introduced here:
`parse_css_value_for_property()` attempts to parse a StyleValue that the
property can accept, skipping any types that it doesn't want.
`parse_css_value_for_properties()` does the same, but takes multiple
PropertyIDs and additionally returns which one the parsed StyleValue is
for. This is intended for parsing shorthands, so you can give it a list
of longhands you haven't yet parsed.
Subsequent commits will actually use these new methods.
We don't yet have generic parsing support for `<filter-value-list>` or
`<paint>`, so listing them here confuses the new StyleValue parsing code
I'm working on. For now, let's skip `<filter-value-list>` since it's
only used in one pkace which manually parses it, and list the parts of
`<paint>` instead which are taken from here:
https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint
This is a clear sign that they want to use a UnixDateTime instead.
This also adds support for placing durations and date times into SQL
databases via their millisecond offset to UTC.
That's what this class really is; in fact that's what the first line of
the comment says it is.
This commit does not rename the main files, since those will contain
other time-related classes in a little bit.
This fixes the issue where max margin is used to find offset of
floating box although horizonal margins do not collapse so they need
to be summed instead.
This fixes a plethora of rounding problems on many websites.
In the future, we may want to replace this with fixed-point arithmetic
(bug #18566) for performance (and consistency with other engines),
but in the meantime this makes the web look a bit better. :^)
There's a lot more things that could be converted to doubles, which
would reduce the amount of casting necessary in this patch.
We can do that incrementally, however.
Introduce optimization that determines if one node is preceding,
following, ancestor or descdendant of another node by comparing
ancestors chains of both nodes which is much cheaper than using
Node::is_before() that can walk whole subtree in the worst case.
SVG presentation attributes are parsed as CSS values, so we also need to
handle CSS variable expansion when handling them.
This (roughly) matches the behavior of other engines. It's also used on
the web, for example on https://stripe.com/ :^)
If we finish parsing a calculation tree and it still contains
UnparsedCalculationNodes, then it's not valid, and we shouldn't create
a StyleValue from it.
This avoids a ton of work when painting large documents. Even though it
would eventually get clipped by the painter anyway, by bailing out
earlier, we avoid a lot more work (UTF-8 iteration, OpenType lookups,
etc).
It would be even nicer if we could skip entire line boxes, but we don't
have a fast way to get the bounding rect of a line box at the moment.
Some of the live HTMLCollection only ever contain children of their root
node. When we know that's the case, we can avoid doing a full subtree
traversal of all descendants and only visit children.
This cuts the ECMA262 spec loading time by over 10 seconds. :^)
Previously, calling `.right()` on a `Gfx::Rect` would return the last
column's coordinate still inside the rectangle, or `left + width - 1`.
This is called 'endpoint inclusive' and does not make a lot of sense for
`Gfx::Rect<float>` where a rectangle of width 5 at position (0, 0) would
return 4 as its right side. This same problem exists for `.bottom()`.
This changes `Gfx::Rect` to be endpoint exclusive, which gives us the
nice property that `width = right - left` and `height = bottom - top`.
It enables us to treat `Gfx::Rect<int>` and `Gfx::Rect<float>` exactly
the same.
All users of `Gfx::Rect` have been updated accordingly.
Before this change, LayoutState essentially had a Vector<UsedValues*>
resized to the exact number of layout nodes in the current document.
When a nested layout is performed (to calculate the intrinsic size of
something), we make a new LayoutState with its own Vector. If an entry
is missing in a nested LayoutState, we check the parent chain all the
way up to the root.
Because each nested LayoutState had to allocate a new Vector with space
for all layout nodes, this could get really nasty on very large pages
(such as the ECMA262 specification).
This patch replaces the Vector with a HashMap. There's now a small cost
to lookups, but what we get in return is the ability to handle huge
layout trees without spending eternity in page faults.