Before this change, we would wake up on every event loop iteration to
drive animations in single-frame images. This was a complete waste of
time and caused 100% CPU usage on our main GitHub repo page.
With this change, CPU usage is ~1% when idle on the same page. :^)
This commit introduces a WEB_SET_PROTOTYPE_FOR_INTERFACE macro that
caches the interface name in a local static FlyString. This means that
we only pay for FlyString-from-literal lookup once per browser lifetime
instead of every time the interface is instantiated.
Document::navigable() can be unpleasantly slow, since we don't have a
direct link between documents and navigables at the moment. So let's not
call it twice when once is enough.
This allows us to skip evaluating selectors like "[foo=bar]" for any
element that doesn't have a "foo" attribute.
Note that the bucket is case-insensitively keyed on the attribute name
since case sensitivity is depending on evaluation context. This ensures
we may get some false positives but no false negatives.
Reduces the number of selectors evaluated by 36% when loading our GitHub
repo at https://github.com/SerenityOS/serenity
We already grow the "rules to run" vector before appending to it, so we
can actually use unchecked_append() here and avoid the "needs to grow"
checks every time we append to it.
This takes appending from 3% to <1% when loading our GitHub repo.
When matching a CSS attribute selector against an HTML element, the
attribute name is case-insensitive. Before this change, that meant we
had to call equals_ignoring_ascii_case() on all the attribute names.
We now cache the attribute name lowercased on each Attr node, which
allows us to do FlyString-to-FlyString comparison (simple pointer
comparison).
This brings attribute selector matching from 6% to <1% when loading our
GitHub repo at https://github.com/SerenityOS/serenity
The API value of a <textarea> element is its raw value with normalized
newlines. This should be used in a couple of places where we currently
use the raw value.
Patch up existing style properties instead of using the regular style
invalidation path, which requires rule matching for each element in the
invalidated subtree.
- !important properties: this change introduces a flag used to skip the
update of animated properties overridden by !important.
- inherited animated properties: for now, these are invalidated by
traversing animated element's subtree to propagate the update.
- StyleProperties has a separate array for animated properties that
allows the removal animated properties after animation has ended,
without requiring full style invalidation.
The behavior of Crypto::UnsignedBigInt::export_data unexpectedly
does not actually remove leading zero bytes when the corresponding
parameter is passed. The caller must manually adjust for the location
of the zero bytes.
By following the spec more closely, we can actually make this function
a bit more efficient (by comparing the parent against the document
instead of looking for the first element child of the document).
If a selector must match a pseudo element, or must match the root
element, we now cache that information in the MatchingRule struct.
We also introduce separate buckets for these rules, so we can avoid
running them altogether if the current element can't possibly match.
This cuts the number of selectors evaluated by 32% when loading our
GitHub repo page https://github.com/SerenityOS/serenity
We frequently end up matching hundreds or even thousands of rules. By
giving this vector some inline capacity, we avoid a lot of the
repetitive churn from dynamically growing it all the way from 0
capacity.
This is required to upload files to GitHub. Unfortunately, this is not
currently testable with our test infrastructure. This path is only hit
from HTTP/S uploads, whereas all of our tests are limited to file://.
We were unconditionally creating new File objects for all Blob-type
values passed to `FormData.append`. We should only do so if the value is
not already a File object (or if the `filename` attribute is present).
We must also carry MIME type information forward from the underlying
Blob object.
This does not implement any of the IDL methods, but GitHub requires the
interface exists to upload files via an <input type="file"> element.
Their JS handles uploads via this element and via drag-and-drop in one
function, and check if the uploaded file is `instanceof DataTransfer` to
decide how to handle it.
This patch implements and tests window.crypto.sublte.generateKey with
an RSA-OAEP algorithm. In order for the types to be happy, the
KeyAlgorithms objects are moved to their own .h/.cpp pair, and the new
KeyAlgorithms for RSA are added there.