···11--- original
22+++ modified
33-@@ -208,6 +208,10 @@
44- /// Whether accessibility is active in this layout.
55- /// (Note: this is a temporary field which will be replaced with an optional accessibility tree member.)
66- accessibility_active: Cell<bool>,
33+@@ -213,6 +213,10 @@
44+55+ /// See [Layout::needs_accessibility_update()].
66+ needs_accessibility_update: Cell<bool>,
77+
88+ /// The current page zoom for rendering (used by embedded webviews).
99+ /// When this changes, we need to trigger a new stacking context tree build.
···1111 }
12121313 pub struct LayoutFactoryImpl();
1414-@@ -248,12 +252,25 @@
1414+@@ -253,12 +257,25 @@
1515 fn set_viewport_details(&mut self, viewport_details: ViewportDetails) -> bool {
1616 let device = self.stylist.device_mut();
1717 let device_pixel_ratio = Scale::new(viewport_details.hidpi_scale_factor.get());
···4141 device.set_viewport_size(viewport_details.size);
4242 device.set_device_pixel_ratio(device_pixel_ratio);
4343 self.device_has_changed = true;
4444-@@ -732,6 +749,7 @@
4545- paint_timing_handler: Default::default(),
4444+@@ -751,6 +768,7 @@
4645 user_stylesheets: config.user_stylesheets,
4747- accessibility_active: Cell::new(false),
4646+ accessibility_tree: Default::default(),
4747+ needs_accessibility_update: Cell::new(false),
4848+ page_zoom_for_rendering: Cell::new(config.viewport_details.page_zoom_for_rendering),
4949 }
5050 }
+1-1
patches/components/net/resource_thread.rs.patch
···6666 };
67676868 (Arc::new(http_state), Arc::new(private_http_state))
6969-@@ -646,20 +657,21 @@
6969+@@ -637,20 +648,21 @@
7070 return false;
7171 },
7272 // Ignore these messages as they are only sent on very specific channels.
···11--- original
22+++ modified
33-@@ -0,0 +1,1088 @@
33+@@ -0,0 +1,1109 @@
44+/* This Source Code Form is subject to the terms of the Mozilla Public
55+ * License, v. 2.0. If a copy of the MPL was not distributed with this
66+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
···341341+ PermissionFeature::BackgroundSync => "background-sync",
342342+ PermissionFeature::Bluetooth => "bluetooth",
343343+ PermissionFeature::PersistentStorage => "persistent-storage",
344344++ PermissionFeature::ScreenWakeLock => "screen-wake-lock",
344345+ };
345346+
346347+ let feature_name = match permission_request.feature {
···355356+ PermissionFeature::BackgroundSync => "Background Sync",
356357+ PermissionFeature::Bluetooth => "Bluetooth",
357358+ PermissionFeature::PersistentStorage => "Persistent Storage",
359359++ PermissionFeature::ScreenWakeLock => "Screen Wake Lock",
358360+ };
359361+
360362+ // Store the response sender for later use by respondToPermissionPrompt
···10291031+ .as_global_scope()
10301032+ .script_to_constellation_chan()
10311033+ .send(ScriptToConstellationMessage::EmbeddedWebViewMediaSessionAction(action_type))
10341034++ .unwrap();
10351035++ Ok(())
10361036++ }
10371037++
10381038++ /// Transfer input focus to this embedded webview.
10391039++ pub(crate) fn embedded_force_focus(&self) -> Fallible<()> {
10401040++ let Some(webview_id) = self.embedded_webview_id() else {
10411041++ return Err(Error::InvalidState(Some(
10421042++ "This iframe is not an embedded webview".to_string(),
10431043++ )));
10441044++ };
10451045++
10461046++ let window = self.owner_window();
10471047++ window
10481048++ .as_global_scope()
10491049++ .script_to_constellation_chan()
10501050++ .send(ScriptToConstellationMessage::EmbeddedWebViewFocus(
10511051++ webview_id,
10521052++ ))
10321053+ .unwrap();
10331054+ Ok(())
10341055+ }
···11--- original
22+++ modified
33-@@ -0,0 +1,173 @@
33+@@ -0,0 +1,176 @@
44+/* This Source Code Form is subject to the terms of the Mozilla Public
55+ * License, v. 2.0. If a copy of the MPL was not distributed with this
66+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
···4646+
4747+ // Media session control
4848+ [Throws] undefined mediaSessionAction(DOMString action);
4949++
5050++ // Focus control — transfers input focus to this embedded webview
5151++ [Throws] undefined forceFocus();
4952+};
5053+
5154+
+11-11
patches/components/servo/servo.rs.patch
···1717 #[cfg(all(
1818 not(target_os = "windows"),
1919 not(target_os = "ios"),
2020-@@ -245,9 +246,7 @@
2020+@@ -246,9 +247,7 @@
2121 }
22222323 if self.constellation_proxy.disconnected() {
···2828 }
29293030 self.paint.borrow_mut().perform_updates();
3131-@@ -306,10 +305,39 @@
3131+@@ -307,10 +306,39 @@
32323333 fn handle_delegate_errors(&self) {
3434 while let Some(error) = self.servo_errors.try_recv() {
···6969 fn clean_up_destroyed_webview_handles(&self) {
7070 // Remove any webview handles that have been destroyed and would not be upgradable.
7171 // Note that `retain` is O(capacity) because it visits empty buckets, so it may be worth
7272-@@ -450,6 +478,11 @@
7272+@@ -451,6 +479,11 @@
7373 );
7474 }
7575 },
···8181 EmbedderMsg::AllowUnload(webview_id, response_sender) => {
8282 if let Some(webview) = self.get_webview_handle(webview_id) {
8383 let request = AllowOrDenyRequest::new(
8484-@@ -548,10 +581,7 @@
8484+@@ -564,10 +597,7 @@
8585 .delegate
8686 .borrow()
8787 .notify_devtools_server_started(port, token),
···9393 },
9494 EmbedderMsg::RequestDevtoolsConnection(response_sender) => {
9595 self.delegate
9696-@@ -676,6 +706,47 @@
9797- .notify_accessibility_tree_update(webview, tree_update);
9696+@@ -690,6 +720,47 @@
9797+ webview.process_accessibility_tree_update(tree_update, epoch);
9898 }
9999 },
100100+ EmbedderMsg::EmbeddedWebViewCreated(
···141141 }
142142 }
143143144144-@@ -927,6 +998,7 @@
144144+@@ -936,6 +1007,7 @@
145145 async_runtime,
146146 public_storage_threads.clone(),
147147 private_storage_threads.clone(),
···149149 );
150150151151 if opts::get().multiprocess {
152152-@@ -1024,6 +1096,14 @@
152152+@@ -1033,6 +1105,14 @@
153153 &self.0.site_data_manager
154154 }
155155···164164 pub(crate) fn paint<'a>(&'a self) -> Ref<'a, Paint> {
165165 self.0.paint.borrow()
166166 }
167167-@@ -1126,6 +1206,7 @@
167167+@@ -1135,6 +1215,7 @@
168168 async_runtime: Box<dyn net_traits::AsyncRuntime>,
169169 public_storage_threads: StorageThreads,
170170 private_storage_threads: StorageThreads,
···172172 ) {
173173 // Global configuration options, parsed from the command line.
174174 let opts = opts::get();
175175-@@ -1168,6 +1249,7 @@
176176- wgpu_image_map: paint.webgpu_image_map(),
175175+@@ -1178,6 +1259,7 @@
177176 async_runtime,
178177 privileged_urls,
178178+ wake_lock_provider: Box::new(NoOpWakeLockProvider),
179179+ config_dir,
180180 };
181181
+3-3
patches/components/servo/webview.rs.patch
···11--- original
22+++ modified
33-@@ -239,6 +239,18 @@
33+@@ -245,6 +245,18 @@
44 self.delegate().request_create_new(self.clone(), request);
55 }
66···1919 pub(crate) fn viewport_details(&self) -> ViewportDetails {
2020 // The division by 1 represents the page's default zoom of 100%,
2121 // and gives us the appropriate CSSPixel type for the viewport.
2222-@@ -248,6 +260,7 @@
2222+@@ -254,6 +266,7 @@
2323 ViewportDetails {
2424 size: scaled_viewport_size / Scale::new(1.0),
2525 hidpi_scale_factor: Scale::new(inner.hidpi_scale_factor.0),
···2727 }
2828 }
29293030-@@ -781,6 +794,11 @@
3030+@@ -787,6 +800,11 @@
3131 EmbedderControlRequest::FilePicker { .. } => {
3232 unreachable!("This message should be routed through the FileManagerThread")
3333 },
···33@@ -16,7 +16,7 @@
44 };
55 use paint_api::rendering_context::RenderingContext;
66- use servo_base::generic_channel::{GenericSender, SendError};
66+ use servo_base::generic_channel::{GenericCallback, GenericSender, SendError};
77-use servo_base::id::PipelineId;
88+use servo_base::id::{BrowsingContextId, PipelineId, WebViewId};
99 use servo_constellation_traits::EmbedderToConstellationMessage;
1010 use tokio::sync::mpsc::UnboundedSender as TokioSender;
1111 use tokio::sync::oneshot::Sender;
1212-@@ -971,6 +971,14 @@
1212+@@ -982,6 +982,14 @@
1313 ///
1414 /// [`window.open`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/open
1515 fn request_create_new(&self, _parent_webview: WebView, _request: CreateNewWebViewRequest) {}
···2424 /// Content in a [`WebView`] is requesting permission to access a feature requiring
2525 /// permission from the user. The embedder should allow or deny the request, either by
2626 /// reading a cached value or querying the user for permission via the user interface.
2727-@@ -1029,6 +1037,25 @@
2727+@@ -1040,6 +1048,25 @@
2828 _tree_update: accesskit::TreeUpdate,
2929 ) {
3030 }
···1212 };
1313 use encoding_rs::Encoding;
1414 use euclid::default::Size2D as UntypedSize2D;
1515-@@ -35,6 +36,7 @@
1616- ServiceWorkerRegistrationId, WebViewId,
1515+@@ -36,6 +37,7 @@
1716 };
1817 use servo_canvas_traits::canvas::{CanvasId, CanvasMsg};
1818+ use servo_canvas_traits::webgl::WebGLChan;
1919+use servo_config::pref_util::PrefValue;
2020 use servo_url::{ImmutableOrigin, OriginSnapshot, ServoUrl};
2121+ use servo_wakelock::WakeLockType;
2122 use storage_traits::StorageThreads;
2222- use storage_traits::webstorage_thread::WebStorageType;
2323-@@ -44,7 +46,8 @@
2323+@@ -46,7 +48,8 @@
24242525 use crate::structured_data::{BroadcastChannelMsg, StructuredSerializedData};
2626 use crate::{
···3030 };
31313232 pub type ScriptToConstellationSender =
3333-@@ -401,11 +404,14 @@
3333+@@ -403,11 +406,14 @@
3434 pub opener_webview_id: WebViewId,
3535 /// The pipeline opener browsing context.
3636 pub opener_pipeline_id: PipelineId,
···4747 #[derive(Debug, Deserialize, Serialize)]
4848 pub struct AuxiliaryWebViewCreationResponse {
4949 /// The new webview ID.
5050-@@ -416,6 +422,38 @@
5050+@@ -418,6 +424,38 @@
5151 pub user_content_manager_id: Option<UserContentManagerId>,
5252 }
5353···8686 /// Specifies the information required to load an iframe.
8787 #[derive(Debug, Deserialize, Serialize)]
8888 pub struct IFrameLoadInfo {
8989-@@ -538,6 +576,90 @@
8989+@@ -542,6 +580,90 @@
9090 NoLongerActive,
9191 }
9292···177177 /// Messages from the script to the constellation.
178178 #[derive(Deserialize, IntoStaticStr, Serialize)]
179179 pub enum ScriptToConstellationMessage {
180180-@@ -582,6 +704,10 @@
180180+@@ -586,6 +708,10 @@
181181 NewBroadcastChannelNameInRouter(BroadcastChannelRouterId, String, ImmutableOrigin),
182182 /// A global stopped managing broadcast channels for a given channel-name.
183183 RemoveBroadcastChannelNameInRouter(BroadcastChannelRouterId, String, ImmutableOrigin),
···188188 /// Broadcast a message to all same-origin broadcast channels,
189189 /// excluding the source of the broadcast.
190190 ScheduleBroadcast(BroadcastChannelRouterId, BroadcastChannelMsg),
191191-@@ -594,6 +720,9 @@
191191+@@ -598,6 +724,9 @@
192192 Option<String>,
193193 Option<String>,
194194 ),
···198198 /// Indicates whether this pipeline is currently running animations.
199199 ChangeRunningAnimationsState(AnimationState),
200200 /// Requests that a new 2D canvas thread be created. (This is done in the constellation because
201201-@@ -677,6 +806,10 @@
201201+@@ -681,6 +810,10 @@
202202 ScriptNewIFrame(IFrameLoadInfoWithData),
203203 /// Script has opened a new auxiliary browsing context.
204204 CreateAuxiliaryWebView(AuxiliaryWebViewCreationRequest),
···209209 /// Mark a new document as active
210210 ActivateDocument,
211211 /// Set the document state for a pipeline (used by screenshot / reftests)
212212-@@ -726,6 +859,112 @@
213213- RespondToScreenshotReadinessRequest(ScreenshotReadinessResponse),
214214- /// Request the constellation to force garbage collection in all `ScriptThread`'s.
215215- TriggerGarbageCollection,
212212+@@ -738,6 +871,114 @@
213213+ /// aggregate lock count and notify the provider only when the count transitions from N to 0.
214214+ /// <https://w3c.github.io/screen-wake-lock/#dfn-release-wake-lock>
215215+ ReleaseWakeLock(WakeLockType),
216216+ /// Notification from an embedded webview to be forwarded to its parent iframe element.
217217+ /// The Constellation will forward this to the parent pipeline's script thread.
218218+ EmbeddedWebViewNotification(EmbeddedWebViewEventType),
···236236+ ),
237237+ /// Send a media session action to the active media session in an embedded webview.
238238+ EmbeddedWebViewMediaSessionAction(embedder_traits::MediaSessionActionType),
239239++ /// Transfer input focus to an embedded webview.
240240++ EmbeddedWebViewFocus(WebViewId),
239241+ /// Forward an input event to an embedded webview after the parent's DOM hit testing
240242+ /// determined that the event target is an embedded iframe element.
241243+ ForwardEventToEmbeddedWebView(WebViewId, InputEventAndId),
+11-11
patches/components/shared/embedder/lib.rs.patch
···11--- original
22+++ modified
33-@@ -33,7 +33,8 @@
33+@@ -34,7 +34,8 @@
44 use servo_base::generic_channel::{
55 GenericCallback, GenericSender, GenericSharedMemory, SendResult,
66 };
···1010 use servo_geometry::{DeviceIndependentIntRect, DeviceIndependentIntSize};
1111 use servo_url::ServoUrl;
1212 use strum::{EnumMessage, IntoStaticStr};
1313-@@ -68,6 +69,31 @@
1313+@@ -69,6 +70,31 @@
1414 Self::Page(point) => *point * scale,
1515 }
1616 }
···4242 }
43434444 impl From<DevicePoint> for WebViewPoint {
4545-@@ -320,9 +346,16 @@
4545+@@ -321,9 +347,16 @@
4646 /// The size of the layout viewport.
4747 pub size: Size2D<f32, CSSPixel>,
4848···6161 }
62626363 impl ViewportDetails {
6464-@@ -342,7 +375,7 @@
6464+@@ -343,7 +376,7 @@
6565 }
66666767 /// An opaque identifier for a single history traversal operation.
···7070 pub struct TraversalId(String);
71717272 impl TraversalId {
7373-@@ -352,6 +385,12 @@
7373+@@ -353,6 +386,12 @@
7474 }
7575 }
7676···8383 #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, MallocSizeOf)]
8484 pub enum PixelFormat {
8585 /// Luminance channel only
8686-@@ -431,6 +470,12 @@
8686+@@ -432,6 +471,12 @@
8787 pub name: String,
8888 }
8989···9696 /// Messages towards the embedder.
9797 #[derive(Deserialize, IntoStaticStr, Serialize)]
9898 pub enum EmbedderMsg {
9999-@@ -452,6 +497,21 @@
9999+@@ -453,6 +498,21 @@
100100 ProtocolHandlerUpdateRegistration,
101101 GenericSender<AllowOrDeny>,
102102 ),
···118118 /// Wether or not to unload a document
119119 AllowUnload(WebViewId, GenericSender<AllowOrDeny>),
120120 /// Inform embedder to clear the clipboard
121121-@@ -509,6 +569,24 @@
121121+@@ -514,6 +574,24 @@
122122 InputEventsHandled(WebViewId, Vec<InputEventOutcome>),
123123 /// Send the embedder an accessibility tree update.
124124- AccessibilityTreeUpdate(WebViewId, TreeUpdate),
124124+ AccessibilityTreeUpdate(WebViewId, TreeUpdate, Epoch),
125125+ /// Request from web content (via `navigator.embedder.openNewOSWindow()`) to open a new
126126+ /// OS-level window with the given URL and features.
127127+ OpenNewOSWindow(NewOSWindowParams),
···143143 }
144144145145 impl Debug for EmbedderMsg {
146146-@@ -1063,6 +1141,54 @@
146146+@@ -1069,6 +1147,54 @@
147147 WebViewDoesNotExist,
148148 }
149149···198198 #[derive(Clone, Copy, Debug, Deserialize, Serialize)]
199199 pub struct RgbColor {
200200 pub red: u8,
201201-@@ -1142,3 +1268,26 @@
201201+@@ -1148,3 +1274,26 @@
202202 self
203203 }
204204 }
···99 };
1010 use euclid::{Scale, Size2D};
1111 use fonts_traits::SystemFontServiceProxySender;
1212-@@ -41,8 +41,9 @@
1212+@@ -42,8 +42,9 @@
1313 use servo_canvas_traits::webgl::WebGLPipeline;
1414 use servo_config::prefs::PrefValue;
1515 use servo_constellation_traits::{
···2121 };
2222 use servo_url::{ImmutableOrigin, ServoUrl};
2323 use storage_traits::StorageThreads;
2424-@@ -79,6 +80,14 @@
2424+@@ -80,6 +81,14 @@
2525 pub theme: Theme,
2626 /// A snapshot of the navigation parameters of the target of this navigation.
2727 pub target_snapshot_params: TargetSnapshotParams,
···3636 }
37373838 /// When a pipeline is closed, should its browsing context be discarded too?
3939-@@ -291,6 +300,15 @@
3939+@@ -292,6 +301,15 @@
4040 SendImageKeysBatch(PipelineId, Vec<ImageKey>),
4141 /// Preferences were updated in the parent process.
4242 PreferencesUpdated(Vec<(String, PrefValue)>),
···5252 /// Notify the `ScriptThread` that the Servo renderer is no longer waiting on
5353 /// asynchronous image uploads for the given `Pipeline`. These are mainly used
5454 /// by canvas to perform uploads while the display list is being built.
5555-@@ -327,6 +345,24 @@
5656- SetAccessibilityActive(PipelineId, bool),
5555+@@ -328,6 +346,24 @@
5656+ SetAccessibilityActive(PipelineId, bool, Epoch),
5757 /// Force a garbage collection in this script thread.
5858 TriggerGarbageCollection,
5959+ /// Dispatch an event on an embedded webview's iframe element.