This patch implements the "create a new browsing context" function from
the HTML spec and replaces our existing logic with it.
The big difference is that browsing contexts now initially navigate to
"about:blank" instead of starting out in a strange "empty" state.
This makes it possible for websites to create a new iframe and start
scripting inside it right away, without having to load an URL into it.
The way we've been creating DOM::Document has been pretty far from what
the spec tells us to do, and this is a first big step towards getting us
closer to spec.
The new Document::create_and_initialize() is called by FrameLoader after
loading a "text/html" resource.
We create the JS Realm and the Window object when creating the Document
(previously, we'd do it on first access to Document::interpreter().)
The realm execution context is owned by the Environment Settings Object.
This disables this system progress bar, and instead creates one
out of pseudo elements, that can be selected and styled with the
::-webkit-progress-bar/value selectors.
This prevents us from needing a sv suffix, and potentially reduces the
need to run generic code for a single character (as contains,
starts_with, ends_with etc. for a char will be just a length and
equality check).
No functional changes.
Each of these strings would previously rely on StringView's char const*
constructor overload, which would call __builtin_strlen on the string.
Since we now have operator ""sv, we can replace these with much simpler
versions. This opens the door to being able to remove
StringView(char const*).
No functional changes.
The main thing that is missing is validating certain pieces of data
against XML productions in well-formed mode, but nothing uses
well-formed mode right now.
Required by Closure Library for sanitising HTML.
e687b3d8ab/closure/goog/html/sanitizer/safedomtreeprocessor.js (L117)
Previously we forwarded all event handler attributes to Window from
these two elements, however, we are only supposed to forward blur,
error, focus, load, resize and scroll.
This allows HTMLCanvasElement and CRC2D to share their lifetime, as JS
allows them to arbitrarily access them at any time and CRC2D.canvas
expects a non-null return value.
Used by Google seemingly almost all around account sign in and
management. The modern sign in page has this near the beginning:
```html
<base href="https://accounts.google.com">
```
All of the XHRs performed by sign in are relative URLs to this
base URL. Previously we ignored this and did it relative to the
current URL, causing the XHRs to 404 and sign in to fall apart.
I presume they do this because you can access the sign in page
from multiple endpoints, such as `/ServiceLogin` and
`/o/oauth2/auth/identifier`
After this change, LibWeb now expects Web::ImageDecoding::Decoder to be
pre-initialized with a concrete implementation before using the webpage.
The previous implementation, based on the ImageDecoder service, has been
provided directly through an adapter in LibWebClient, and is now used as
the default value by WebContent.
Previously requestAnimationFrame() callbacks were registered with a
static global RequestAnimationFrameDriver shared between all windows.
This led to callbacks still running after navigating away from a page
(This could be seen with the WASM GoL demo).
This commit moves the RequestAnimationFrameDriver (now
AnimationFrameCallbackDriver) to be a member of the HTML::Window
object, then uses the 'active document' parameter of
run_animation_frame_callbacks() to run only the active callbacks.
Using a Vector<Value> is unsafe as GC cannot see the stored values.
This is then vended to outside users of ConsoleClient, e.g. LibWeb and
WebContent, which is then outside of LibJS's control.
An example issue is if the client stores it for later use and forgets
to visit the stored values, meaning they can be destroyed at any time.
We can save the client from this by vending a MarkedVector<Value> to
them.
- Don't add multiple numbers to nested steps, just the innermost one
(as rendered in the HTML document)
- "Otherwise" comments go before the else, not after it
- "FIXME:" goes before step number, not between it and the comment text
- Always add a period between number and comment text
The majority of these were introduced in #13756, but some unrelated ones
have been updated as well.
The goal here is to move the parser-internal classes into this namespace
so they can have more convenient names without causing collisions. The
Parser itself won't collide, and would be more convenient to just
remain `CSS::Parser`, but having a namespace and a class with the same
name makes C++ unhappy.
When a favicon has been loaded, trigger a favicon update on
document level. Of all the link tags in the header, the last
favicon that is load should be shown.
When the favicon could not be loaded, load the next icon in reverse tree
order.
Previously, we only remapped the destination rect through the context's
affine transform, but didn't actually paint through it.
This patch fixes that by implementing a very inefficient algorithm for
rasterizing a transformed bitmap. When the context has a plain identity
transform, we bypass this algorithm in favor of calling Gfx::Painter
directly as we did before.
This makes the player character in "Biolab Disaster" able to turn left!
BrowsingContext shouldn't be scrolling itself, instead it has to update
the layout (to ensure that we have current document metrics, and then
ask the PageClient nicely to scroll it.
This fixes an issue where BrowsingContext sometimes believed itself to
be scrolled, but OOPWV had a different idea.
If the document is not attached to a browsing context we can't create
a new nested browsing context.
This can happen when the resource load for the <object> finishes after
the user navigated away from the current document, for example by
reloading ACID 3 while it's running.
The storage inspector now has a new tab for local storage. The next step
would be to persist local storage and receive real-time notifications
for changes to update the table view.
This is now the source of truth for 'user enabled/disabled scripting',
but it has to ask the window's page, which actually stores the setting.
Also use this new functionality in two places where it was previously
marked as a FIXME.
From the HTML spec:
Modulo platform conventions, it is suggested that the following
elements should be considered as focusable areas and be sequentially
focusable:
...
- button elements
- select elements
- textarea elements
...
Also add a spec link to the existing HTMLAnchorElement::is_focusable().
Note that this still doesn't allow triggering keyboard-focused buttons,
checkboxes, or radio buttons - we don't seem to run the expected
activation behavior for any of them.
From the HTML spec:
Modulo platform conventions, it is suggested that the following
elements should be considered as focusable areas and be sequentially
focusable:
...
- input elements whose type attribute are not in the Hidden state
...
This commit moves the regular handling of links to the anchor elements'
activation behavior, and implements a few auxiliary algorithms as
defined by the HTML specification.
Note that certain things such as javascript links, fragments and opening
a new tab are still handled directly in EventHandler, but they have been
moved to handle_mouseup so that it behaves closer to how it would if it
was entirely up-to-spec.
Specifically HTMLIFrameElement and HTMLObjectElement. HTMLEmbedElement
will gain it automatically once it's also converted to inherit from
BrowsingContextContainer.
The HTMLObjectElement spec is set up to ignore application/octet-stream
MIME types only. For this to work, we need to implement the MIME type
sniffing algorithm so that all unknown MIME types become mapped to the
application/octet-stream type. Until then, ignore all application/ MIME
types as we won't be able to display them anyways.
We were using the literal string "unknown" as the unknown MIME type,
which caused us to treat the object as a nested browsing context (as
"unknown" does not start with "image/"). Use an Optional instead to
prevent this mishap.
We currently only supported loading image data from an HTMLObjectElement
node. This adds (some) support for non-image data. A big FIXME is to
actually paint that data. We will need to make FrameBox and
NestedBrowsingContextPaintable work with HTMLObjectElement for this
(they currently only work with HTMLIFrameElement).
We will soon have two DOM nodes which contain nested browsing contexts:
HTMLIFrameElement and HTMLObjectElement. Only HTMLIFrameElement should
have its nested context created automatically upon insertion, so move
the invocation of that logic to HTMLIFrameElement.
HTMLObjectElement will need to be both a FormAssociatedElement and a
BrowsingContextContainer. Currently, both of these classes inherit from
HTMLElement. This can work in C++, but is generally frowned upon, and
doesn't play particularly well with the rest of LibWeb.
Instead, we can essentially revert commit 3bb5c62 to remove HTMLElement
from FormAssociatedElement's hierarchy. This means that objects such as
HTMLObjectElement individually inherit from FormAssociatedElement and
HTMLElement now.
Some caveats are:
* FormAssociatedElement still needs to know when the HTMLElement is
inserted into and removed from the DOM. This hook is automatically
injected via a macro now, while still allowing classes like
HTMLInputElement to also know when the element is inserted.
* Casting from a DOM::Element to a FormAssociatedElement is now a
sideways cast, rather than directly following an inheritance chain.
This means static_cast cannot be used here; but we can safely use
dynamic_cast since the only 2 instances of this already use RTTI to
verify the cast.
This is another event upon which the task to determine an object's
respresentation must be queued:
* one of the element's ancestor object elements changes to or from
showing its fallback content
For example, on Acid2, the image for the eyes is nested below an object
that is designed to fail to load. This ensures the eyes will render as
the fallback of the failed parent object.
There are a long list of conditions under which the HTMLObjectElement is
to queue an element task to load / determine an object's representation.
This handles the case where the data attribute has changed.
Much of the spec for determining the object's representation is not
implemented here. Namely, anything to do with XML documents or browser
plugins are left as FIXMEs.
This replaces the usage of `rounded_int_rect`, whose name did not
accurately reflect the rounding operation happening. For example, the
position of the rect was not rounded but floored, and the size was
pulled through `roundf` before casting to `int` which could result in
inadvertent flooring if the resulting floating point could not exactly
represent the rounded value.
We should not set the 'value' attribute when an input element's value is
changed (by the user or programmatically). Instead, we should track the
value internally and mark it with a dirty flag when it is changed.
The HTML Specification is quite tricky in this case.
Usually "have a particular element in <x> scope" mentions
"consisting of the following element types:", but in this case it's
"consisting of all element types except the following:"
Thanks to @AtkinsSJ for spotting this difference
Instead of choking on the VERIFY(document), let's just return null if
there's no active document for now. This is incorrect, but sidesteps
a frequent crash that happens on content with iframes.
I've left a FIXME about removing the hack once it's no longer needed.
We shouldn't delay the load event for scripts that we're completely
refusing to run anyway. Also, for scripts that have inline text content,
we don't need to delay them either, as they will become ready before
returning from "prepare script".
This makes the "load" event finally fire on lots of websites, including
Wikipedia. :^)
If we try loading a link element but it's reject for whatever reason
(broken URL, content filtering, etc.) make sure we don't mark that link
element as delaying the document load event.
We previously had a bug where markup with unclosed script tags caused
the document load event to be delayed indefinitely. Fix this by only
marking script elements as delaying the load event once we encounter
the script end tag.
It makes no sense to require passing a global object and doing a stack
space check in some cases where running out of stack is highly unlikely,
we can't recover from errors, and currently ignore the result anyway.
This is most commonly in constructors and when setting things up, rather
than regular function calls.
Right now the only functionality supported is getting/setting via JS
and resetting when browsing cross origin.
The HTML Specification (7.11 Browsing the web) also specifies how the
name should be restored from history entries, but we don't have those
yet.