diff options
author | Alan Jeffrey <ajeffrey@mozilla.com> | 2016-10-28 12:17:23 -0500 |
---|---|---|
committer | Alan Jeffrey <ajeffrey@mozilla.com> | 2016-11-03 12:51:33 -0500 |
commit | 1803a585e5eb388830efac7e80d582f2fa4eb652 (patch) | |
tree | d0efc8c4000c47a8537f166f63b18dc4dfb822bb /components/script/dom | |
parent | dafc57e8abb3723e62e32e82ef04eb770eee2ea2 (diff) | |
download | servo-1803a585e5eb388830efac7e80d582f2fa4eb652.tar.gz servo-1803a585e5eb388830efac7e80d582f2fa4eb652.zip |
Check that an iframe is in a document with a browsing context before processing src.
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/htmliframeelement.rs | 24 | ||||
-rw-r--r-- | components/script/dom/node.rs | 4 |
2 files changed, 24 insertions, 4 deletions
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 5215359df8a..2d9464df189 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -408,7 +408,7 @@ unsafe fn build_mozbrowser_event_detail(event: MozBrowserEvent, pub fn Navigate(iframe: &HTMLIFrameElement, direction: TraversalDirection) -> ErrorResult { if iframe.Mozbrowser() { - if iframe.upcast::<Node>().is_in_doc() { + if iframe.upcast::<Node>().is_in_doc_with_browsing_context() { let window = window_from_node(iframe); let msg = ConstellationMsg::TraverseHistory(iframe.pipeline_id(), direction); window.upcast::<GlobalScope>().constellation_chan().send(msg).unwrap(); @@ -494,7 +494,7 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement { // https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/reload fn Reload(&self, _hard_reload: bool) -> ErrorResult { if self.Mozbrowser() { - if self.upcast::<Node>().is_in_doc() { + if self.upcast::<Node>().is_in_doc_with_browsing_context() { self.navigate_or_reload_child_browsing_context(None, true); } Ok(()) @@ -592,7 +592,16 @@ impl VirtualMethods for HTMLIFrameElement { }, &atom!("src") => { if let AttributeMutation::Set(_) = mutation { - if self.upcast::<Node>().is_in_doc() { + // https://html.spec.whatwg.org/multipage/#the-iframe-element + // "Similarly, whenever an iframe element with a non-null nested browsing context + // but with no srcdoc attribute specified has its src attribute set, changed, or removed, + // the user agent must process the iframe attributes," + // but we can't check that directly, since the child browsing context + // may be in a different script thread. Instread, we check to see if the parent + // is in a document tree and has a browsing context, which is what causes + // the child browsing context to be created. + if self.upcast::<Node>().is_in_doc_with_browsing_context() { + debug!("iframe {} src set while in browsing context.", self.frame_id); self.process_the_iframe_attributes(); } } @@ -615,7 +624,14 @@ impl VirtualMethods for HTMLIFrameElement { s.bind_to_tree(tree_in_doc); } - if tree_in_doc { + // https://html.spec.whatwg.org/multipage/#the-iframe-element + // "When an iframe element is inserted into a document that has + // a browsing context, the user agent must create a new + // browsing context, set the element's nested browsing context + // to the newly-created browsing context, and then process the + // iframe attributes for the "first time"." + if self.upcast::<Node>().is_in_doc_with_browsing_context() { + debug!("iframe {} bound to browsing context.", self.frame_id); self.process_the_iframe_attributes(); } } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 767a3132eb3..b46caec35e9 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -771,6 +771,10 @@ impl Node { self.owner_doc().is_html_document() } + pub fn is_in_doc_with_browsing_context(&self) -> bool { + self.is_in_doc() && self.owner_doc().browsing_context().is_some() + } + pub fn children(&self) -> NodeSiblingIterator { NodeSiblingIterator { current: self.GetFirstChild(), |