mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 17:24:48 -05:00
LibWeb: Resolve document.fonts.ready() after fonts defined in CSS loaded
This is an ad-hoc implementation that resolves the ready() promise once the document and all fonts collected by the style computer are done loading. A spec-compliant implementation would include creating a proxy CSS::FontFace for each @font-face and correctly implementing the specification steps for font fetching, but we are far from there yet. This hackish implementation should yield good WPT progress because it will actually start waiting for the Ahem font to load before capturing layout measurements. For example, it makes https://wpt.live/css/css-grid/abspos/positioned-grid-descendants-001.html go from 0/100 to 36/100 passing subtests.
This commit is contained in:
parent
814fa0682a
commit
5faca4f027
Notes:
github-actions[bot]
2024-09-30 06:08:51 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/5faca4f0270 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1569
5 changed files with 35 additions and 5 deletions
|
@ -29,9 +29,6 @@ JS::NonnullGCPtr<FontFaceSet> FontFaceSet::construct_impl(JS::Realm& realm, Vect
|
||||||
for (auto const& face : initial_faces)
|
for (auto const& face : initial_faces)
|
||||||
set_entries->set_add(face);
|
set_entries->set_add(face);
|
||||||
|
|
||||||
if (set_entries->set_size() == 0)
|
|
||||||
WebIDL::resolve_promise(realm, *ready_promise);
|
|
||||||
|
|
||||||
return realm.heap().allocate<FontFaceSet>(realm, realm, ready_promise, set_entries);
|
return realm.heap().allocate<FontFaceSet>(realm, realm, ready_promise, set_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,9 +41,8 @@ FontFaceSet::FontFaceSet(JS::Realm& realm, JS::NonnullGCPtr<WebIDL::Promise> rea
|
||||||
: DOM::EventTarget(realm)
|
: DOM::EventTarget(realm)
|
||||||
, m_set_entries(set_entries)
|
, m_set_entries(set_entries)
|
||||||
, m_ready_promise(ready_promise)
|
, m_ready_promise(ready_promise)
|
||||||
|
, m_status(Bindings::FontFaceSetLoadStatus::Loaded)
|
||||||
{
|
{
|
||||||
bool const is_ready = ready()->state() == JS::Promise::State::Fulfilled;
|
|
||||||
m_status = is_ready ? Bindings::FontFaceSetLoadStatus::Loaded : Bindings::FontFaceSetLoadStatus::Loading;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FontFaceSet::initialize(JS::Realm& realm)
|
void FontFaceSet::initialize(JS::Realm& realm)
|
||||||
|
@ -162,4 +158,9 @@ JS::NonnullGCPtr<JS::Promise> FontFaceSet::ready() const
|
||||||
return verify_cast<JS::Promise>(*m_ready_promise->promise());
|
return verify_cast<JS::Promise>(*m_ready_promise->promise());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FontFaceSet::resolve_ready_promise()
|
||||||
|
{
|
||||||
|
WebIDL::resolve_promise(realm(), *m_ready_promise);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,8 @@ public:
|
||||||
JS::NonnullGCPtr<JS::Promise> ready() const;
|
JS::NonnullGCPtr<JS::Promise> ready() const;
|
||||||
Bindings::FontFaceSetLoadStatus status() const { return m_status; }
|
Bindings::FontFaceSetLoadStatus status() const { return m_status; }
|
||||||
|
|
||||||
|
void resolve_ready_promise();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FontFaceSet(JS::Realm&, JS::NonnullGCPtr<WebIDL::Promise> ready_promise, JS::NonnullGCPtr<JS::Set> set_entries);
|
FontFaceSet(JS::Realm&, JS::NonnullGCPtr<WebIDL::Promise> ready_promise, JS::NonnullGCPtr<JS::Set> set_entries);
|
||||||
|
|
||||||
|
|
|
@ -2863,4 +2863,16 @@ void StyleComputer::pop_ancestor(DOM::Element const& element)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t StyleComputer::number_of_css_font_faces_with_loading_in_progress() const
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
for (auto const& [_, loaders] : m_loaded_fonts) {
|
||||||
|
for (auto const& loader : loaders) {
|
||||||
|
if (loader->is_loading())
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,8 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] bool has_has_selectors() const { return m_has_has_selectors; }
|
[[nodiscard]] bool has_has_selectors() const { return m_has_has_selectors; }
|
||||||
|
|
||||||
|
size_t number_of_css_font_faces_with_loading_in_progress() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum class ComputeStyleMode {
|
enum class ComputeStyleMode {
|
||||||
Normal,
|
Normal,
|
||||||
|
@ -261,6 +263,8 @@ public:
|
||||||
RefPtr<Gfx::Font> font_with_point_size(float point_size);
|
RefPtr<Gfx::Font> font_with_point_size(float point_size);
|
||||||
void start_loading_next_url();
|
void start_loading_next_url();
|
||||||
|
|
||||||
|
bool is_loading() const { return resource() && resource()->is_pending(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// ^ResourceClient
|
// ^ResourceClient
|
||||||
virtual void resource_did_load() override;
|
virtual void resource_did_load() override;
|
||||||
|
|
|
@ -8,10 +8,13 @@
|
||||||
#include <LibCore/EventLoop.h>
|
#include <LibCore/EventLoop.h>
|
||||||
#include <LibJS/Runtime/VM.h>
|
#include <LibJS/Runtime/VM.h>
|
||||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||||
|
#include <LibWeb/CSS/FontFaceSet.h>
|
||||||
|
#include <LibWeb/CSS/StyleComputer.h>
|
||||||
#include <LibWeb/DOM/Document.h>
|
#include <LibWeb/DOM/Document.h>
|
||||||
#include <LibWeb/HTML/BrowsingContext.h>
|
#include <LibWeb/HTML/BrowsingContext.h>
|
||||||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||||
|
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||||
#include <LibWeb/HTML/TraversableNavigable.h>
|
#include <LibWeb/HTML/TraversableNavigable.h>
|
||||||
#include <LibWeb/HTML/Window.h>
|
#include <LibWeb/HTML/Window.h>
|
||||||
#include <LibWeb/HighResolutionTime/Performance.h>
|
#include <LibWeb/HighResolutionTime/Performance.h>
|
||||||
|
@ -381,6 +384,14 @@ void EventLoop::process()
|
||||||
for_each_fully_active_document_in_docs([&](DOM::Document& document) {
|
for_each_fully_active_document_in_docs([&](DOM::Document& document) {
|
||||||
document.process_top_layer_removals();
|
document.process_top_layer_removals();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Not in the spec:
|
||||||
|
for_each_fully_active_document_in_docs([&](DOM::Document& document) {
|
||||||
|
if (document.readiness() == HTML::DocumentReadyState::Complete && document.style_computer().number_of_css_font_faces_with_loading_in_progress() == 0) {
|
||||||
|
HTML::TemporaryExecutionContext context(HTML::relevant_settings_object(document), HTML::TemporaryExecutionContext::CallbacksEnabled::Yes);
|
||||||
|
document.fonts()->resolve_ready_promise();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task
|
// https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task
|
||||||
|
|
Loading…
Reference in a new issue