diff options
author | bors-servo <metajack+bors@gmail.com> | 2014-11-13 23:54:28 -0700 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2014-11-13 23:54:28 -0700 |
commit | 85a2f0b66a32cfd6022b3e6cec6ec06f3b59baf1 (patch) | |
tree | 3613c0aee5a63360f13ea5eeb8498246cdf705f1 | |
parent | 10cd7728ff0daa7d2e5e13d002d008b5049f389b (diff) | |
parent | fb8a45c58ddca230571c4d9859af87d86d4896a9 (diff) | |
download | servo-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.rs | 18 | ||||
-rw-r--r-- | components/script/dom/urlhelper.rs | 14 | ||||
-rw-r--r-- | components/script/dom/webidls/HTMLIFrameElement.webidl | 2 | ||||
-rw-r--r-- | tests/content/resources/iframe_contentDocument_inner.html | 1 | ||||
-rw-r--r-- | tests/content/test_iframe_contentDocument.html | 27 | ||||
-rw-r--r-- | tests/wpt/metadata/html/dom/interfaces.html.ini | 3 |
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 |