Matching the behaviour of the other big three browser engines,
also tested by WPT, but does not appear to be explicitly specified.
I also noticed when investigating that browser engines disagree
about whether a child mutation should trigger script execution.
For this, I've just gone with the behaviour of Webkit/Chromium of
not running script.
The m_result Variant can hold a GC::Ref<ImportMapParseResult> when the
script element has type="importmap", but visit_edges only traced the
GC::Ref<Script> arm. This left the ImportMapParseResult unvisited,
allowing the GC to collect it while the element still held a reference.
ImportMapParseResult inherited from JS::Script::HostDefined, but no
JS::Script or JS::Module ever stored it as host_defined data, so
visit_host_defined_self was dead code. This removes the HostDefined
inheritance entirely and switches m_result visitation to Variant::visit
with a lambda that catches all GC::Ref arms.
Issue #6294 describes an edge case where the browser crash if the same
module is loaded three times in a document, but all attempts fail.
Failure scenario:
1. Module load 1 set the state to "Fetching"
2. Module load 2 registers a callback to `on_complete` since the
current state is "Fetching"
3. Module load 1 finish with a failure, invoking the callback for load
number 2
4. Module load 3 cause a crash. The state is neither "Fetching" or
"ModuleScript", so we'll reset the state to "Fetching". This invokes
the callback for module load 2 again, now with an unexpected state
which will cause an assert violation.
Proposed fix is to remove the condition that invokes `on_complete`
immediately for successfully loaded modules only, the callback should
be invoked regardless of whether the fetch succeeded or failed.
This reveals a separate bug in HTMLScriptElement, where
`mark_as_ready()` can be invoked before
`m_steps_to_run_when_the_result_is_ready` is assigned.
This appears to be a spec bug, reported as
https://github.com/whatwg/html/issues/12073 and addressed by delaying
the callback by a task, similar to the issue was resolved for inline
scripts.
Prevents observably calling Trusted Types, which can run arbitrary JS,
cause crashes due to use of MUST and allow arbitrary JS to modify
internal elements.
Otherwise we'll try to use the Utf16String that has already been
through Trusted Types and put it through again. That can also fail if
there's no default policy and there's a `require-trusted-types-for
'script'` directive.
Fixes Outlook failing to load.
The src IDL attribute was previously implemented as an inline getter
that returned the raw attribute value. This broke spec semantics and
sites like Telegram Web that rely on document.currentScript.src to
compute Webpack’s publicPath.
According to the HTML Standard:
https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes
For URL-reflecting attributes:
1. If contentAttributeValue is null, then return the empty string.
2. Let urlString be the result of encoding-parsing-and-serializing
a URL given contentAttributeValue,
relative to element’s node document.
3. If urlString is not failure, then return urlString.
This patch moves the getter to HTMLScriptElement.cpp and implements
these steps.
Which has an optmization if both size of the string being passed
through are FlyStrings, which actually ends up being the case
in some places during selector matching comparing attribute names.
Instead of maintaining more overloads of
Infra::is_ascii_case_insensitive_match, switch
everything over to equals_ignoring_ascii_case instead.
Before this change, we were going through the chain of base classes for
each IDL interface object and having them set the prototype to their
prototype.
Instead of doing that, reorder things so that we set the right prototype
immediately in Foo::initialize(), and then don't bother in all the base
class overrides.
This knocks off a ~1% profile item on Speedometer 3.
Currently, this metadata is only provided on the insertion steps,
though I believe it would be useful to extend to the other cases
as well. This metadata can aid in making optimizations for these
steps by providing extra context into the type of change which
was made on the child.
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:
* JS::NonnullGCPtr -> GC::Ref
* JS::GCPtr -> GC::Ptr
* JS::HeapFunction -> GC::Function
* JS::CellImpl -> GC::Cell
* JS::Handle -> GC::Root
We currently have 2 virtual methods to inform DOM::Element subclasses
when an attribute has changed, one of which is spec-compliant. This
patch removes the non-compliant variant.
This patchset makes ProtocolServer stream the downloads to its client
(LibProtocol), and as such changes the download API; a possible
download lifecycle could be as such:
notation = client->server:'>', server->client:'<', pipe activity:'*'
```
> StartDownload(GET, url, headers, {})
< Response(0, fd 8)
* {data, 1024b}
< HeadersBecameAvailable(0, response_headers, 200)
< DownloadProgress(0, 4K, 1024)
* {data, 1024b}
* {data, 1024b}
< DownloadProgress(0, 4K, 2048)
* {data, 1024b}
< DownloadProgress(0, 4K, 1024)
< DownloadFinished(0, true, 4K)
```
Since managing the received file descriptor is a pain, LibProtocol
implements `Download::stream_into(OutputStream)`, which can be used to
stream the download into any given output stream (be it a file, or
memory, or writing stuff with a delay, etc.).
Also, as some of the users of this API require all the downloaded data
upfront, LibProtocol also implements `set_should_buffer_all_input()`,
which causes the download instance to buffer all the data until the
download is complete, and to call the `on_buffered_download_finish`
hook.
This makes most operations thread safe, especially so that they
can safely be used in the Kernel. This includes obtaining a strong
reference from a weak reference, which now requires an explicit
call to WeakPtr::strong_ref(). Another major change is that
Weakable::make_weak_ref() may require the explicit target type.
Previously we used reinterpret_cast in WeakPtr, assuming that it
can be properly converted. But WeakPtr does not necessarily have
the knowledge to be able to do this. Instead, we now ask the class
itself to deliver a WeakPtr to the type that we want.
Also, WeakLink is no longer specific to a target type. The reason
for this is that we want to be able to safely convert e.g. WeakPtr<T>
to WeakPtr<U>, and before this we just reinterpret_cast the internal
WeakLink<T> to WeakLink<U>, which is a bold assumption that it would
actually produce the correct code. Instead, WeakLink now operates
on just a raw pointer and we only make those constructors/operators
available if we can verify that it can be safely cast.
In order to guarantee thread safety, we now use the least significant
bit in the pointer for locking purposes. This also means that only
properly aligned pointers can be used.
LibWeb keeps growing and the Web namespace is filling up fast.
Let's put DOM stuff into Web::DOM, just like we already started doing
with SVG stuff in Web::SVG.