mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-19 07:33:20 +00:00
Compare commits
3 commits
92c0cbc453
...
d4df0e1db9
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d4df0e1db9 | ||
![]() |
373b2838db | ||
![]() |
980e715668 |
19 changed files with 122 additions and 36 deletions
25
.github/workflows/js-and-wasm-benchmarks.yml
vendored
25
.github/workflows/js-and-wasm-benchmarks.yml
vendored
|
@ -53,7 +53,6 @@ jobs:
|
||||||
sudo apt-get install -y python3-venv
|
sudo apt-get install -y python3-venv
|
||||||
|
|
||||||
- name: 'Download JS repl artifact'
|
- name: 'Download JS repl artifact'
|
||||||
id: download-js-artifact
|
|
||||||
uses: dawidd6/action-download-artifact@v11
|
uses: dawidd6/action-download-artifact@v11
|
||||||
with:
|
with:
|
||||||
run_id: ${{ github.event.workflow_run.id }}
|
run_id: ${{ github.event.workflow_run.id }}
|
||||||
|
@ -73,15 +72,16 @@ jobs:
|
||||||
commit_hash=$(cat js-repl/COMMIT)
|
commit_hash=$(cat js-repl/COMMIT)
|
||||||
echo "sha=${commit_hash}" >> "${GITHUB_OUTPUT}"
|
echo "sha=${commit_hash}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
- name: 'Download Wasm repl artifact'
|
- name: 'Download wasm repl artifact'
|
||||||
id: download-wasm-artifact
|
|
||||||
uses: dawidd6/action-download-artifact@v11
|
uses: dawidd6/action-download-artifact@v11
|
||||||
with:
|
with:
|
||||||
run_id: ${{ github.event.workflow_run.id }}
|
run_id: ${{ github.event.workflow_run.id }}
|
||||||
name: ladybird-wasm-${{ matrix.package_type }}
|
name: ladybird-wasm-${{ matrix.package_type }}
|
||||||
path: wasm-repl
|
path: wasm-repl
|
||||||
|
if_no_artifact_found: warn
|
||||||
|
|
||||||
- name: 'Extract Wasm repl'
|
- name: 'Extract wasm repl'
|
||||||
|
if: ${{ hashFiles('wasm-repl/*.tar.gz') != '' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
cd wasm-repl
|
cd wasm-repl
|
||||||
|
@ -95,17 +95,24 @@ jobs:
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
python3 -m pip install -r requirements.txt
|
python3 -m pip install -r requirements.txt
|
||||||
|
|
||||||
run_options="--iterations=5"
|
run_options='--iterations=5'
|
||||||
|
|
||||||
|
js_path="${{ github.workspace }}/js-repl/bin/js"
|
||||||
|
run_options="${run_options} --executable=${js_path}"
|
||||||
|
|
||||||
|
wasm_path="${{ github.workspace }}/wasm-repl/bin/wasm"
|
||||||
|
if [ -x "${wasm_path}" ]; then
|
||||||
|
run_options="${run_options} --wasm-executable=${wasm_path}"
|
||||||
|
else
|
||||||
|
echo "Wasm repl not found; skipping wasm benchmarks."
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${{ github.event.workflow_run.event }}" = "workflow_dispatch" ]; then
|
if [ "${{ github.event.workflow_run.event }}" = "workflow_dispatch" ]; then
|
||||||
# Upstream was run manually; we might run into failing benchmarks as a result of older builds.
|
# Upstream was run manually; we might run into failing benchmarks as a result of older builds.
|
||||||
run_options="${run_options} --continue-on-failure"
|
run_options="${run_options} --continue-on-failure"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
./run.py \
|
./run.py ${run_options}
|
||||||
--executable=${{ github.workspace }}/js-repl/bin/js \
|
|
||||||
--wasm-executable=${{ github.workspace }}/wasm-repl/bin/wasm \
|
|
||||||
${run_options}
|
|
||||||
|
|
||||||
- name: 'Save results as an artifact'
|
- name: 'Save results as an artifact'
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|
3
.github/workflows/merge-conflict-labeler.yml
vendored
3
.github/workflows/merge-conflict-labeler.yml
vendored
|
@ -13,9 +13,12 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
auto-labeler:
|
auto-labeler:
|
||||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||||
|
if: github.repository == 'LadybirdBrowser/ladybird'
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: eps1lon/actions-label-merge-conflict@v3
|
- uses: eps1lon/actions-label-merge-conflict@v3
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
#include <LibWeb/DOM/Event.h>
|
#include <LibWeb/DOM/Event.h>
|
||||||
#include <LibWeb/DOM/Node.h>
|
#include <LibWeb/DOM/Node.h>
|
||||||
#include <LibWeb/DOM/ShadowRoot.h>
|
#include <LibWeb/DOM/ShadowRoot.h>
|
||||||
|
#include <LibWeb/HTML/Window.h>
|
||||||
|
#include <LibWeb/HTML/WindowProxy.h>
|
||||||
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
|
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
|
||||||
|
|
||||||
namespace Web::DOM {
|
namespace Web::DOM {
|
||||||
|
@ -263,4 +265,13 @@ Vector<GC::Root<EventTarget>> Event::composed_path() const
|
||||||
return composed_path;
|
return composed_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AD-HOC: Needed to return a WindowProxy when the current target is a Window,
|
||||||
|
// ensuring that JavaScript sees the correct global object instead of the internal Window.
|
||||||
|
GC::Ptr<EventTarget> Event::current_target_for_bindings() const
|
||||||
|
{
|
||||||
|
if (auto* window = as_if<HTML::Window>(m_current_target.ptr()))
|
||||||
|
return window->window();
|
||||||
|
return m_current_target;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,6 +101,8 @@ public:
|
||||||
GC::Ptr<EventTarget> current_target() const { return m_current_target; }
|
GC::Ptr<EventTarget> current_target() const { return m_current_target; }
|
||||||
void set_current_target(EventTarget* current_target) { m_current_target = current_target; }
|
void set_current_target(EventTarget* current_target) { m_current_target = current_target; }
|
||||||
|
|
||||||
|
GC::Ptr<EventTarget> current_target_for_bindings() const;
|
||||||
|
|
||||||
bool return_value() const { return !m_cancelled; }
|
bool return_value() const { return !m_cancelled; }
|
||||||
void set_return_value(bool return_value)
|
void set_return_value(bool return_value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@ interface Event {
|
||||||
readonly attribute DOMString type;
|
readonly attribute DOMString type;
|
||||||
readonly attribute EventTarget? target;
|
readonly attribute EventTarget? target;
|
||||||
readonly attribute EventTarget? srcElement; // legacy
|
readonly attribute EventTarget? srcElement; // legacy
|
||||||
readonly attribute EventTarget? currentTarget;
|
[ImplementedAs=current_target_for_bindings] readonly attribute EventTarget? currentTarget;
|
||||||
sequence<EventTarget> composedPath();
|
sequence<EventTarget> composedPath();
|
||||||
|
|
||||||
const unsigned short NONE = 0;
|
const unsigned short NONE = 0;
|
||||||
|
|
|
@ -89,7 +89,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventLi
|
||||||
|
|
||||||
// 11. Call a user object’s operation with listener’s callback, "handleEvent", « event », and event’s currentTarget attribute value.
|
// 11. Call a user object’s operation with listener’s callback, "handleEvent", « event », and event’s currentTarget attribute value.
|
||||||
// FIXME: These should be wrapped for us in call_user_object_operation, but it currently doesn't do that.
|
// FIXME: These should be wrapped for us in call_user_object_operation, but it currently doesn't do that.
|
||||||
auto* this_value = event.current_target().ptr();
|
auto* this_value = event.current_target_for_bindings().ptr();
|
||||||
auto* wrapped_event = &event;
|
auto* wrapped_event = &event;
|
||||||
auto result = WebIDL::call_user_object_operation(callback, "handleEvent"_utf16_fly_string, this_value, { { wrapped_event } });
|
auto result = WebIDL::call_user_object_operation(callback, "handleEvent"_utf16_fly_string, this_value, { { wrapped_event } });
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <LibJS/Runtime/PropertyDescriptor.h>
|
#include <LibJS/Runtime/PropertyDescriptor.h>
|
||||||
#include <LibJS/Runtime/PropertyKey.h>
|
#include <LibJS/Runtime/PropertyKey.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
|
#include <LibWeb/DOM/EventTarget.h>
|
||||||
#include <LibWeb/HTML/CrossOrigin/AbstractOperations.h>
|
#include <LibWeb/HTML/CrossOrigin/AbstractOperations.h>
|
||||||
#include <LibWeb/HTML/CrossOrigin/Reporting.h>
|
#include <LibWeb/HTML/CrossOrigin/Reporting.h>
|
||||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||||
|
@ -24,7 +25,7 @@ GC_DEFINE_ALLOCATOR(WindowProxy);
|
||||||
|
|
||||||
// 7.4 The WindowProxy exotic object, https://html.spec.whatwg.org/multipage/window-object.html#the-windowproxy-exotic-object
|
// 7.4 The WindowProxy exotic object, https://html.spec.whatwg.org/multipage/window-object.html#the-windowproxy-exotic-object
|
||||||
WindowProxy::WindowProxy(JS::Realm& realm)
|
WindowProxy::WindowProxy(JS::Realm& realm)
|
||||||
: JS::Object(realm, nullptr, MayInterfereWithIndexedPropertyAccess::Yes)
|
: DOM::EventTarget(realm, MayInterfereWithIndexedPropertyAccess::Yes)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,14 @@
|
||||||
#include <LibGC/Ptr.h>
|
#include <LibGC/Ptr.h>
|
||||||
#include <LibJS/Forward.h>
|
#include <LibJS/Forward.h>
|
||||||
#include <LibJS/Runtime/Object.h>
|
#include <LibJS/Runtime/Object.h>
|
||||||
|
#include <LibWeb/DOM/EventTarget.h>
|
||||||
#include <LibWeb/Export.h>
|
#include <LibWeb/Export.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
class WEB_API WindowProxy final : public JS::Object {
|
class WEB_API WindowProxy final : public DOM::EventTarget {
|
||||||
JS_OBJECT(WindowProxy, JS::Object);
|
WEB_PLATFORM_OBJECT(WindowProxy, DOM::EventTarget)
|
||||||
GC_DECLARE_ALLOCATOR(WindowProxy);
|
GC_DECLARE_ALLOCATOR(WindowProxy);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -33,8 +34,6 @@ public:
|
||||||
virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override;
|
virtual JS::ThrowCompletionOr<bool> internal_delete(JS::PropertyKey const&) override;
|
||||||
virtual JS::ThrowCompletionOr<GC::RootVector<JS::Value>> internal_own_property_keys() const override;
|
virtual JS::ThrowCompletionOr<GC::RootVector<JS::Value>> internal_own_property_keys() const override;
|
||||||
|
|
||||||
virtual bool eligible_for_own_property_enumeration_fast_path() const override final { return false; }
|
|
||||||
|
|
||||||
GC::Ptr<Window> window() const { return m_window; }
|
GC::Ptr<Window> window() const { return m_window; }
|
||||||
void set_window(GC::Ref<Window>);
|
void set_window(GC::Ref<Window>);
|
||||||
|
|
||||||
|
@ -43,6 +42,8 @@ public:
|
||||||
private:
|
private:
|
||||||
explicit WindowProxy(JS::Realm&);
|
explicit WindowProxy(JS::Realm&);
|
||||||
|
|
||||||
|
virtual bool is_window_or_worker_global_scope_mixin() const final { return true; }
|
||||||
|
|
||||||
virtual bool is_html_window_proxy() const override { return true; }
|
virtual bool is_html_window_proxy() const override { return true; }
|
||||||
virtual void visit_edges(JS::Cell::Visitor&) override;
|
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,8 @@ Harness status: OK
|
||||||
|
|
||||||
Found 5 tests
|
Found 5 tests
|
||||||
|
|
||||||
4 Pass
|
5 Pass
|
||||||
1 Fail
|
Pass In window.document with click event
|
||||||
Fail In window.document with click event
|
|
||||||
Pass In window.document with load event
|
Pass In window.document with load event
|
||||||
Pass In window.document.cloneNode(true)
|
Pass In window.document.cloneNode(true)
|
||||||
Pass In new Document()
|
Pass In new Document()
|
||||||
|
|
|
@ -2,9 +2,8 @@ Harness status: OK
|
||||||
|
|
||||||
Found 5 tests
|
Found 5 tests
|
||||||
|
|
||||||
4 Pass
|
5 Pass
|
||||||
1 Fail
|
Pass In window.document with click event
|
||||||
Fail In window.document with click event
|
|
||||||
Pass In window.document with load event
|
Pass In window.document with load event
|
||||||
Pass In window.document.cloneNode(true)
|
Pass In window.document.cloneNode(true)
|
||||||
Pass In new Document()
|
Pass In new Document()
|
||||||
|
|
|
@ -2,5 +2,5 @@ Harness status: OK
|
||||||
|
|
||||||
Found 1 tests
|
Found 1 tests
|
||||||
|
|
||||||
1 Fail
|
1 Pass
|
||||||
Fail Dispatch additional events inside an event listener
|
Pass Dispatch additional events inside an event listener
|
|
@ -2,5 +2,5 @@ Harness status: OK
|
||||||
|
|
||||||
Found 1 tests
|
Found 1 tests
|
||||||
|
|
||||||
1 Fail
|
1 Pass
|
||||||
Fail Multiple dispatchEvent() and cancelBubble
|
Pass Multiple dispatchEvent() and cancelBubble
|
|
@ -2,5 +2,5 @@ Harness status: OK
|
||||||
|
|
||||||
Found 1 tests
|
Found 1 tests
|
||||||
|
|
||||||
1 Fail
|
1 Pass
|
||||||
Fail Multiple dispatchEvent() and stopPropagation()
|
Pass Multiple dispatchEvent() and stopPropagation()
|
|
@ -2,5 +2,5 @@ Harness status: OK
|
||||||
|
|
||||||
Found 1 tests
|
Found 1 tests
|
||||||
|
|
||||||
1 Fail
|
1 Pass
|
||||||
Fail EventTarget.addEventListener with the capture argument omitted
|
Pass EventTarget.addEventListener with the capture argument omitted
|
|
@ -2,5 +2,5 @@ Harness status: OK
|
||||||
|
|
||||||
Found 1 tests
|
Found 1 tests
|
||||||
|
|
||||||
1 Fail
|
1 Pass
|
||||||
Fail Dispatch additional events inside an event listener
|
Pass Dispatch additional events inside an event listener
|
|
@ -2,5 +2,5 @@ Harness status: OK
|
||||||
|
|
||||||
Found 1 tests
|
Found 1 tests
|
||||||
|
|
||||||
1 Fail
|
1 Pass
|
||||||
Fail Event propagation path when an element in it is moved within the DOM
|
Pass Event propagation path when an element in it is moved within the DOM
|
|
@ -2,5 +2,5 @@ Harness status: OK
|
||||||
|
|
||||||
Found 1 tests
|
Found 1 tests
|
||||||
|
|
||||||
1 Fail
|
1 Pass
|
||||||
Fail Event propagation path when an element in it is removed from the DOM
|
Pass Event propagation path when an element in it is removed from the DOM
|
|
@ -0,0 +1,8 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 3 tests
|
||||||
|
|
||||||
|
3 Pass
|
||||||
|
Pass EventTarget methods on Window instances are inherited from the EventTarget prototype
|
||||||
|
Pass window.addEventListener respects custom `this`
|
||||||
|
Pass window.addEventListener treats nullish `this` as `window`
|
|
@ -0,0 +1,55 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Window extends EventTarget</title>
|
||||||
|
<link rel="help" href="https://github.com/jsdom/jsdom/issues/2830">
|
||||||
|
<script src="../resources/testharness.js"></script>
|
||||||
|
<script src="../resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
|
||||||
|
assert_equals(window.addEventListener, EventTarget.prototype.addEventListener);
|
||||||
|
assert_equals(window.removeEventListener, EventTarget.prototype.removeEventListener);
|
||||||
|
assert_equals(window.dispatchEvent, EventTarget.prototype.dispatchEvent);
|
||||||
|
|
||||||
|
}, "EventTarget methods on Window instances are inherited from the EventTarget prototype");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
|
||||||
|
const kCustom = "custom-event";
|
||||||
|
const customEvent = new CustomEvent(kCustom, {
|
||||||
|
bubbles: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let target;
|
||||||
|
window.addEventListener.call(document.body, kCustom, function () {
|
||||||
|
target = this;
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.dispatchEvent(customEvent);
|
||||||
|
|
||||||
|
assert_equals(target, document.body);
|
||||||
|
|
||||||
|
}, "window.addEventListener respects custom `this`");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
|
||||||
|
const kCustom = "custom-event";
|
||||||
|
const customEvent = new CustomEvent(kCustom, {
|
||||||
|
bubbles: true
|
||||||
|
});
|
||||||
|
|
||||||
|
let target;
|
||||||
|
window.addEventListener.call(null, kCustom, function () {
|
||||||
|
target = this;
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.dispatchEvent(customEvent);
|
||||||
|
|
||||||
|
assert_equals(target, window);
|
||||||
|
|
||||||
|
}, "window.addEventListener treats nullish `this` as `window`");
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue