mirror of
https://github.com/lexmount/moli.git
synced 2026-10-06 00:00:56 +00:00
refactor(renderer): centralize layout invalidation and publication
This commit is contained in:
@@ -2,6 +2,7 @@ use std::collections::HashSet;
|
||||
|
||||
use super::{
|
||||
JsContextHost,
|
||||
layout::LayoutInputChange,
|
||||
permissions::{permission_names_match, permission_override_name},
|
||||
};
|
||||
use crate::{
|
||||
@@ -793,8 +794,7 @@ impl JsContextHost {
|
||||
overrides: &crate::protocol_types::EmulatedMediaOverrides,
|
||||
) {
|
||||
if self.emulated_media != *overrides {
|
||||
self.style_engine
|
||||
.bump_target_context_epoch_for_document(self.document_handle());
|
||||
self.invalidate_layout_inputs(LayoutInputChange::StyleEnvironment);
|
||||
}
|
||||
self.emulated_media = overrides.clone();
|
||||
}
|
||||
@@ -809,8 +809,7 @@ impl JsContextHost {
|
||||
) -> bool {
|
||||
let changed = self.viewport_surface != viewport_surface;
|
||||
if changed {
|
||||
self.style_engine
|
||||
.bump_target_context_epoch_for_document(self.document_handle());
|
||||
self.invalidate_layout_inputs(LayoutInputChange::StyleEnvironment);
|
||||
}
|
||||
self.viewport_surface = viewport_surface;
|
||||
changed
|
||||
|
||||
@@ -14,6 +14,16 @@ use crate::{
|
||||
style_engine::{StyleViewport, StyloStyleEnvironment},
|
||||
};
|
||||
|
||||
/// Invalidation required by a changed native input. Publication is a separate
|
||||
/// owner decision; these changes retain the last frozen layout for readers.
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum LayoutInputChange {
|
||||
/// Media and viewport changes invalidate computed styles through Stylo.
|
||||
StyleEnvironment,
|
||||
/// Scrollbar policy and interactions change future geometry/paint output.
|
||||
UsedGeometry,
|
||||
}
|
||||
|
||||
/// Resets the entry flag on every return path, including unwinding.
|
||||
///
|
||||
/// This is a synchronous ownership guard, not a generation or a retry fence.
|
||||
@@ -57,13 +67,26 @@ impl JsContextHost {
|
||||
self.layout_policy
|
||||
}
|
||||
|
||||
pub(crate) fn set_scrollbars_hidden(&mut self, hidden: bool) {
|
||||
if self.scrollbars_hidden != hidden {
|
||||
pub(crate) fn set_scrollbars_hidden(&mut self, hidden: bool) -> bool {
|
||||
let changed = self.scrollbars_hidden != hidden;
|
||||
if changed {
|
||||
self.scrollbars_hidden = hidden;
|
||||
self.clear_layout_rect_cache();
|
||||
self.document_layout_state
|
||||
.get_mut()
|
||||
.mark_visual_state_dirty();
|
||||
self.invalidate_layout_inputs(LayoutInputChange::UsedGeometry);
|
||||
}
|
||||
changed
|
||||
}
|
||||
|
||||
pub(crate) fn invalidate_layout_inputs(&self, change: LayoutInputChange) {
|
||||
match change {
|
||||
LayoutInputChange::StyleEnvironment => self
|
||||
.style_engine
|
||||
.bump_target_context_epoch_for_document(self.document_handle()),
|
||||
LayoutInputChange::UsedGeometry => {
|
||||
self.clear_layout_rect_cache();
|
||||
self.document_layout_state
|
||||
.borrow_mut()
|
||||
.mark_visual_state_dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,12 +542,7 @@ impl JsContextHost {
|
||||
}
|
||||
|
||||
pub(crate) fn invalidate_layout_after_interaction_state_change(&self) {
|
||||
self.clear_layout_rect_cache();
|
||||
// Interactions dirty future visual publication, while ordinary geometry
|
||||
// and input keep consuming the last published frozen snapshot.
|
||||
self.document_layout_state
|
||||
.borrow_mut()
|
||||
.mark_visual_state_dirty();
|
||||
self.invalidate_layout_inputs(LayoutInputChange::UsedGeometry);
|
||||
}
|
||||
|
||||
pub(crate) fn document_web_font_resources_are_current(
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::script_vm::{DocumentSetting, DocumentSettingEffect, DocumentSettingsA
|
||||
impl PageVm {
|
||||
fn apply_document_setting(&mut self, setting: DocumentSetting<'_>) -> anyhow::Result<()> {
|
||||
let layout = self.layout_configuration;
|
||||
let effect = self.vm_mut().apply_document_setting(
|
||||
let effect: DocumentSettingEffect = self.vm_mut().apply_document_setting(
|
||||
setting,
|
||||
layout,
|
||||
DocumentSettingsApplication::Live,
|
||||
@@ -12,10 +12,8 @@ impl PageVm {
|
||||
// Retain the target value before publication. Even if publication
|
||||
// fails, a followed navigation must inherit the accepted native input.
|
||||
setting.retain_in(&mut self.document_settings);
|
||||
if effect == DocumentSettingEffect::PublishLayout {
|
||||
self.vm_mut().publish_layout()?;
|
||||
}
|
||||
Ok(())
|
||||
self.vm_mut()
|
||||
.complete_document_settings_application(DocumentSettingsApplication::Live, effect)
|
||||
}
|
||||
|
||||
pub(crate) fn set_script_execution_disabled(&mut self, disabled: bool) -> anyhow::Result<()> {
|
||||
|
||||
@@ -198,10 +198,10 @@ impl ScriptVm {
|
||||
self._context_host.borrow_mut().set_layout_policy(policy);
|
||||
}
|
||||
|
||||
pub(crate) fn set_scrollbars_hidden(&mut self, hidden: bool) {
|
||||
pub(crate) fn set_scrollbars_hidden(&mut self, hidden: bool) -> bool {
|
||||
self._context_host
|
||||
.borrow_mut()
|
||||
.set_scrollbars_hidden(hidden);
|
||||
.set_scrollbars_hidden(hidden)
|
||||
}
|
||||
|
||||
pub(super) fn sync_document_fonts_for_environment(&mut self) {
|
||||
|
||||
@@ -12,7 +12,9 @@ pub(crate) enum DocumentSettingsApplication {
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub(crate) enum DocumentSettingEffect {
|
||||
/// Native values are installed; queued rendering updates publish later.
|
||||
Deferred,
|
||||
/// Geometry must be current before a live setting command is acknowledged.
|
||||
PublishLayout,
|
||||
}
|
||||
|
||||
@@ -75,7 +77,9 @@ impl ScriptVm {
|
||||
DocumentSetting::DocumentActivity(*document_activity),
|
||||
DocumentSetting::ScrollbarsHidden(*scrollbars_hidden),
|
||||
] {
|
||||
self.apply_document_setting(setting, layout, DocumentSettingsApplication::Bootstrap)?;
|
||||
let application = DocumentSettingsApplication::Bootstrap;
|
||||
let effect = self.apply_document_setting(setting, layout, application)?;
|
||||
self.complete_document_settings_application(application, effect)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -134,13 +138,27 @@ impl ScriptVm {
|
||||
}
|
||||
DocumentSetting::ScrollbarsHidden(value) => {
|
||||
let hidden = layout.scrollbars_hidden_for(value);
|
||||
let changed = self._context_host.borrow().scrollbars_hidden() != hidden;
|
||||
self.set_scrollbars_hidden(hidden);
|
||||
if live && changed {
|
||||
if self.set_scrollbars_hidden(hidden) {
|
||||
effect = DocumentSettingEffect::PublishLayout;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(effect)
|
||||
}
|
||||
|
||||
/// Initialization never publishes layout or runs rendering notifications.
|
||||
/// Live commands publish only settings that require synchronous geometry.
|
||||
pub(crate) fn complete_document_settings_application(
|
||||
&mut self,
|
||||
application: DocumentSettingsApplication,
|
||||
effect: DocumentSettingEffect,
|
||||
) -> anyhow::Result<()> {
|
||||
match (application, effect) {
|
||||
(DocumentSettingsApplication::Bootstrap, _)
|
||||
| (DocumentSettingsApplication::Live, DocumentSettingEffect::Deferred) => Ok(()),
|
||||
(DocumentSettingsApplication::Live, DocumentSettingEffect::PublishLayout) => {
|
||||
self.publish_layout()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user