aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2014-11-13 23:54:28 -0700
committerbors-servo <metajack+bors@gmail.com>2014-11-13 23:54:28 -0700
commit85a2f0b66a32cfd6022b3e6cec6ec06f3b59baf1 (patch)
tree3613c0aee5a63360f13ea5eeb8498246cdf705f1
parent10cd7728ff0daa7d2e5e13d002d008b5049f389b (diff)
parentfb8a45c58ddca230571c4d9859af87d86d4896a9 (diff)
downloadservo-85a2f0b66a32cfd6022b3e6cec6ec06f3b59baf1.tar.gz
servo-85a2f0b66a32cfd6022b3e6cec6ec06f3b59baf1.zip
auto merge of #3953 : neojski/servo/implement-HTMLIFrameElement.contentDocument, r=jdm
Because of #2122 I cannot write test for this right now because it will be failing randomly due to that iframe issue. However, if it doesn't fail due to that issue a test like this: ```html <html> <head> <meta charset="utf8" /> <script src="harness.js"></script> <title>Iframe contentDocument test.</title> </head> <body> <iframe src="test_iframe_contentDocument_inner.html" id="iframe"></iframe> <script> waitForExplicitFinish(); var timeout = 100; var iframe = document.getElementById('iframe'); function test_contentWindow() { if (!iframe.contentWindow) { // Iframe not loaded yet, try again. // No load event for iframe, insert bug number here. setTimeout(test_contentWindow, timeout); return; } is(iframe.contentDocument.getElementById('test').textContent, 'value'); finish(); } test_contentWindow(); </script> </body> </html> ``` where inner is simply: ```html <html><body><div id="test">value</div></body></html> ``` passes. I have added `SameOrigin` method to the `UrlHelper`. I wanted to reuse it in [`constellation.rs` same_script check](https://github.com/servo/servo/blob/f0184a2d011e12845258a242d2d2f6b8b504a28d/components/compositing/constellation.rs#L625) but I it didn't want to compile saying ``` error: unresolved import `dom::urlhelper::UrlHelper`. Maybe a missing `extern crate dom`? ``` So I didn't include it in this PR for now. There is more discussion about the cross origin iframes in [another issue](https://github.com/servo/servo/issues/3939). In this PR I just added same origin check.
-rw-r--r--components/script/dom/htmliframeelement.rs18
-rw-r--r--components/script/dom/urlhelper.rs14
-rw-r--r--components/script/dom/webidls/HTMLIFrameElement.webidl2
-rw-r--r--tests/content/resources/iframe_contentDocument_inner.html1
-rw-r--r--tests/content/test_iframe_contentDocument.html27
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini3
6 files changed, 61 insertions, 4 deletions
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index e9e1fae2e27..59c7011a9c7 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -6,6 +6,7 @@ use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
+use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::InheritTypes::{NodeCast, ElementCast};
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLIFrameElementDerived};
use dom::bindings::js::{JSRef, Temporary, OptionalRootable};
@@ -16,6 +17,7 @@ use dom::element::AttributeHandlers;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node};
+use dom::urlhelper::UrlHelper;
use dom::virtualmethods::VirtualMethods;
use dom::window::Window;
use page::IterablePage;
@@ -180,6 +182,22 @@ impl<'a> HTMLIFrameElementMethods for JSRef<'a, HTMLIFrameElement> {
})
})
}
+
+ fn GetContentDocument(self) -> Option<Temporary<Document>> {
+ self.GetContentWindow().root().and_then(|window| {
+ let self_url = match self.get_url() {
+ Some(self_url) => self_url,
+ None => return None,
+ };
+ let win_url = window_from_node(self).root().page().get_url();
+
+ if UrlHelper::SameOrigin(&self_url, &win_url) {
+ Some(window.Document())
+ } else {
+ None
+ }
+ })
+ }
}
impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> {
diff --git a/components/script/dom/urlhelper.rs b/components/script/dom/urlhelper.rs
index f678e273876..251f8283e1e 100644
--- a/components/script/dom/urlhelper.rs
+++ b/components/script/dom/urlhelper.rs
@@ -27,4 +27,18 @@ impl UrlHelper {
Some(ref hash) => format!("#{}", hash)
}
}
+
+ /// https://html.spec.whatwg.org/multipage/browsers.html#same-origin
+ pub fn SameOrigin(urlA: &Url, urlB: &Url) -> bool {
+ if urlA.host() != urlB.host() {
+ return false
+ }
+ if urlA.scheme != urlB.scheme {
+ return false
+ }
+ if urlA.port() != urlB.port() {
+ return false
+ }
+ return true
+ }
}
diff --git a/components/script/dom/webidls/HTMLIFrameElement.webidl b/components/script/dom/webidls/HTMLIFrameElement.webidl
index 201f8700ce4..7768065545c 100644
--- a/components/script/dom/webidls/HTMLIFrameElement.webidl
+++ b/components/script/dom/webidls/HTMLIFrameElement.webidl
@@ -14,7 +14,7 @@ interface HTMLIFrameElement : HTMLElement {
// attribute boolean allowFullscreen;
// attribute DOMString width;
// attribute DOMString height;
- //readonly attribute Document? contentDocument;
+ readonly attribute Document? contentDocument;
//readonly attribute WindowProxy? contentWindow;
readonly attribute Window? contentWindow;
diff --git a/tests/content/resources/iframe_contentDocument_inner.html b/tests/content/resources/iframe_contentDocument_inner.html
new file mode 100644
index 00000000000..2fb85a9b2c2
--- /dev/null
+++ b/tests/content/resources/iframe_contentDocument_inner.html
@@ -0,0 +1 @@
+<html><body><div id="test">value</div></body></html>
diff --git a/tests/content/test_iframe_contentDocument.html b/tests/content/test_iframe_contentDocument.html
new file mode 100644
index 00000000000..93e5c9c8c62
--- /dev/null
+++ b/tests/content/test_iframe_contentDocument.html
@@ -0,0 +1,27 @@
+<html>
+<head>
+<meta charset="utf8" />
+<script src="harness.js"></script>
+<title>Iframe contentDocument test.</title>
+</head>
+<body>
+<iframe src="resources/iframe_contentDocument_inner.html" id="iframe"></iframe>
+<script>
+waitForExplicitFinish();
+
+var timeout = 100;
+var iframe = document.getElementById('iframe');
+function test_contentWindow() {
+ if (!iframe.contentWindow) {
+ // Iframe not loaded yet, try again.
+ // No load event for iframe, insert bug number here.
+ setTimeout(test_contentWindow, timeout);
+ return;
+ }
+ is(iframe.contentDocument.getElementById('test').textContent, 'value');
+ finish();
+}
+test_contentWindow();
+</script>
+</body>
+</html>
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index 1b10c3fd820..957c1886542 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -3105,9 +3105,6 @@
[HTMLIFrameElement interface: attribute height]
expected: FAIL
- [HTMLIFrameElement interface: attribute contentDocument]
- expected: FAIL
-
[HTMLIFrameElement interface: attribute align]
expected: FAIL