mirror of
https://github.com/servo/servo.git
synced 2025-08-01 03:30:33 +01:00
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](f0184a2d01/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.
This commit is contained in:
commit
85a2f0b66a
6 changed files with 61 additions and 4 deletions
|
@ -6,6 +6,7 @@ use dom::attr::Attr;
|
||||||
use dom::attr::AttrHelpers;
|
use dom::attr::AttrHelpers;
|
||||||
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLIFrameElementBinding::HTMLIFrameElementMethods;
|
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::{NodeCast, ElementCast};
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLIFrameElementDerived};
|
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, HTMLIFrameElementDerived};
|
||||||
use dom::bindings::js::{JSRef, Temporary, OptionalRootable};
|
use dom::bindings::js::{JSRef, Temporary, OptionalRootable};
|
||||||
|
@ -16,6 +17,7 @@ use dom::element::AttributeHandlers;
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node};
|
use dom::node::{Node, NodeHelpers, ElementNodeTypeId, window_from_node};
|
||||||
|
use dom::urlhelper::UrlHelper;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use dom::window::Window;
|
use dom::window::Window;
|
||||||
use page::IterablePage;
|
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> {
|
impl<'a> VirtualMethods for JSRef<'a, HTMLIFrameElement> {
|
||||||
|
|
|
@ -27,4 +27,18 @@ impl UrlHelper {
|
||||||
Some(ref hash) => format!("#{}", hash)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ interface HTMLIFrameElement : HTMLElement {
|
||||||
// attribute boolean allowFullscreen;
|
// attribute boolean allowFullscreen;
|
||||||
// attribute DOMString width;
|
// attribute DOMString width;
|
||||||
// attribute DOMString height;
|
// attribute DOMString height;
|
||||||
//readonly attribute Document? contentDocument;
|
readonly attribute Document? contentDocument;
|
||||||
//readonly attribute WindowProxy? contentWindow;
|
//readonly attribute WindowProxy? contentWindow;
|
||||||
readonly attribute Window? contentWindow;
|
readonly attribute Window? contentWindow;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<html><body><div id="test">value</div></body></html>
|
27
tests/content/test_iframe_contentDocument.html
Normal file
27
tests/content/test_iframe_contentDocument.html
Normal file
|
@ -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>
|
|
@ -3105,9 +3105,6 @@
|
||||||
[HTMLIFrameElement interface: attribute height]
|
[HTMLIFrameElement interface: attribute height]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLIFrameElement interface: attribute contentDocument]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLIFrameElement interface: attribute align]
|
[HTMLIFrameElement interface: attribute align]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue