···69 #[dom_struct]
70 pub(crate) struct HTMLIFrameElement {
71 htmlelement: HTMLElement,
72-@@ -93,6 +105,30 @@
73- /// while script at this point(when the flag is set)
74- /// expects those to run only for the navigated documented.
75- pending_navigation: Cell<bool>,
76+ /// Whether this iframe is in "embed" mode (hosting a top-level webview).
77+ is_embedded_webview: Cell<bool>,
78+ /// The embedded webview ID when in embed mode.
···100 }
101102 impl HTMLIFrameElement {
103-@@ -229,6 +265,8 @@
104 viewport_details,
105 user_content_manager_id: None,
106 theme: window.theme(),
···109 };
110111 self.pipeline_id.set(Some(new_pipeline_id));
112-@@ -443,6 +481,143 @@
113 );
114 }
115116+ /// Create an embedded webview for this iframe when the "embed" attribute is present.
117+ /// This creates a new top-level WebView instead of a nested browsing context.
118+ fn create_embedded_webview(&self) {
119-+ let url = self.get_url();
0000120+ let document = self.owner_document();
121+ let window = self.owner_window();
122+
···253 fn destroy_nested_browsing_context(&self) {
254 self.pipeline_id.set(None);
255 self.pending_pipeline_id.set(None);
256-@@ -502,6 +677,13 @@
257- throttled: Cell::new(false),
258 script_window_proxies: ScriptThread::window_proxies(),
259 pending_navigation: Default::default(),
0260+ is_embedded_webview: Cell::new(false),
261+ embedded_webview_id: Cell::new(None),
262+ embedded_history: DomRefCell::new(Vec::new()),
···267 }
268 }
269270-@@ -537,7 +719,150 @@
271 self.webview_id.get()
272 }
273···353+
354+ /// Get the effective webview ID, taking into account embedded webview mode.
355+ /// Returns the embedded webview ID if in embed mode, otherwise the parent webview ID.
356- #[inline]
357+ pub(crate) fn embedded_webview_id(&self) -> Option<WebViewId> {
358+ if self.is_embedded_webview.get() {
359+ self.embedded_webview_id.get()
···414+ self.page_zoom.set(zoom);
415+ }
416+
417-+ #[inline]
418 pub(crate) fn sandboxing_flag_set(&self) -> SandboxingFlagSet {
419 self.sandboxing_flag_set
420- .get()
421-@@ -871,6 +1196,85 @@
422 // This is specified as reflecting the name content attribute of the
423 // element, not the name of the child browsing context.
424 make_getter!(Name, "name");
···504 }
505506 impl VirtualMethods for HTMLIFrameElement {
507-@@ -922,8 +1326,34 @@
508 // is in a document tree and has a browsing context, which is what causes
509 // the child browsing context to be created.
510 if self.upcast::<Node>().is_connected_with_browsing_context() {
···514+ // processing iframe attributes (which is for regular nested iframes).
515+ if self.is_embedded_webview.get() {
516+ if let Some(webview_id) = self.embedded_webview_id.get() {
517-+ let url = self.get_url();
00518+ let window = self.owner_window();
519+ window
520+ .as_global_scope()
···541 }
542 },
543 _ => {},
544-@@ -967,6 +1397,23 @@
545546 debug!("<iframe> running post connection steps");
547···565 // Step 1. Create a new child navigable for insertedNode.
566 self.create_nested_browsing_context(can_gc);
567568-@@ -989,8 +1436,22 @@
569 fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) {
570 self.super_type().unwrap().unbind_from_tree(context, can_gc);
571
···69 #[dom_struct]
70 pub(crate) struct HTMLIFrameElement {
71 htmlelement: HTMLElement,
72+@@ -97,6 +109,30 @@
73+ /// an empty iframe is attached. In that case, we shouldn't fire a
74+ /// subsequent asynchronous load event.
75+ already_fired_synchronous_load_event: Cell<bool>,
76+ /// Whether this iframe is in "embed" mode (hosting a top-level webview).
77+ is_embedded_webview: Cell<bool>,
78+ /// The embedded webview ID when in embed mode.
···100 }
101102 impl HTMLIFrameElement {
103+@@ -255,6 +291,8 @@
104 viewport_details,
105 user_content_manager_id: None,
106 theme: window.theme(),
···109 };
110111 self.pipeline_id.set(Some(new_pipeline_id));
112+@@ -484,6 +522,147 @@
113 );
114 }
115116+ /// Create an embedded webview for this iframe when the "embed" attribute is present.
117+ /// This creates a new top-level WebView instead of a nested browsing context.
118+ fn create_embedded_webview(&self) {
119++ let Some(url) = self.shared_attribute_processing_steps_for_iframe_and_frame_elements()
120++ else {
121++ error!("Can't create embedded webview without url");
122++ return;
123++ };
124+ let document = self.owner_document();
125+ let window = self.owner_window();
126+
···257 fn destroy_nested_browsing_context(&self) {
258 self.pipeline_id.set(None);
259 self.pending_pipeline_id.set(None);
260+@@ -544,6 +723,13 @@
0261 script_window_proxies: ScriptThread::window_proxies(),
262 pending_navigation: Default::default(),
263+ already_fired_synchronous_load_event: Default::default(),
264+ is_embedded_webview: Cell::new(false),
265+ embedded_webview_id: Cell::new(None),
266+ embedded_history: DomRefCell::new(Vec::new()),
···271 }
272 }
273274+@@ -579,6 +765,149 @@
275 self.webview_id.get()
276 }
277···357+
358+ /// Get the effective webview ID, taking into account embedded webview mode.
359+ /// Returns the embedded webview ID if in embed mode, otherwise the parent webview ID.
360++ #[inline]
361+ pub(crate) fn embedded_webview_id(&self) -> Option<WebViewId> {
362+ if self.is_embedded_webview.get() {
363+ self.embedded_webview_id.get()
···418+ self.page_zoom.set(zoom);
419+ }
420+
421+ #[inline]
422 pub(crate) fn sandboxing_flag_set(&self) -> SandboxingFlagSet {
423 self.sandboxing_flag_set
424+@@ -917,6 +1246,85 @@
0425 // This is specified as reflecting the name content attribute of the
426 // element, not the name of the child browsing context.
427 make_getter!(Name, "name");
···507 }
508509 impl VirtualMethods for HTMLIFrameElement {
510+@@ -968,8 +1376,36 @@
511 // is in a document tree and has a browsing context, which is what causes
512 // the child browsing context to be created.
513 if self.upcast::<Node>().is_connected_with_browsing_context() {
···517+ // processing iframe attributes (which is for regular nested iframes).
518+ if self.is_embedded_webview.get() {
519+ if let Some(webview_id) = self.embedded_webview_id.get() {
520++ let url = self
521++ .shared_attribute_processing_steps_for_iframe_and_frame_elements()
522++ .expect("Failed to get embedding iframe url");
523+ let window = self.owner_window();
524+ window
525+ .as_global_scope()
···546 }
547 },
548 _ => {},
549+@@ -1013,6 +1449,23 @@
550551 debug!("<iframe> running post connection steps");
552···570 // Step 1. Create a new child navigable for insertedNode.
571 self.create_nested_browsing_context(can_gc);
572573+@@ -1035,8 +1488,22 @@
574 fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) {
575 self.super_type().unwrap().unbind_from_tree(context, can_gc);
576
+1-1
patches/components/script/links.rs.patch
···1--- original
2+++ modified
3-@@ -386,7 +386,7 @@
4 let source = document.browsing_context().unwrap();
5 let (maybe_chosen, history_handling) = match target_attribute_value {
6 Some(name) => {
···1--- original
2+++ modified
3+@@ -434,7 +434,7 @@
4 let source = document.browsing_context().unwrap();
5 let (maybe_chosen, history_handling) = match target_attribute_value {
6 Some(name) => {