auto merge of #927 : pcwalton/servo/image-src-set, r=pcwalton
r? @metajack
|
@ -589,7 +589,7 @@ addHTMLElement('HTMLHeadingElement')
|
||||||
addHTMLElement('HTMLHtmlElement')
|
addHTMLElement('HTMLHtmlElement')
|
||||||
addHTMLElement('HTMLHRElement')
|
addHTMLElement('HTMLHRElement')
|
||||||
addHTMLElement('HTMLIFrameElement', needsAbstract=['sandbox'])
|
addHTMLElement('HTMLIFrameElement', needsAbstract=['sandbox'])
|
||||||
addHTMLElement('HTMLImageElement', needsAbstract=['width', 'height'])
|
addHTMLElement('HTMLImageElement', needsAbstract=['src', 'width', 'height'])
|
||||||
addHTMLElement('HTMLInputElement')
|
addHTMLElement('HTMLInputElement')
|
||||||
addHTMLElement('HTMLLabelElement')
|
addHTMLElement('HTMLLabelElement')
|
||||||
addHTMLElement('HTMLLegendElement')
|
addHTMLElement('HTMLLegendElement')
|
||||||
|
|
|
@ -6,8 +6,10 @@ use dom::bindings::utils::{DOMString, str, null_string, ErrorResult};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{ScriptView, AbstractNode};
|
use dom::node::{ScriptView, AbstractNode};
|
||||||
use extra::url::Url;
|
use extra::url::Url;
|
||||||
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
|
|
||||||
use gfx::geometry::to_px;
|
use gfx::geometry::to_px;
|
||||||
|
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
|
||||||
|
use servo_net::image_cache_task;
|
||||||
|
use servo_util::url::make_url;
|
||||||
|
|
||||||
pub struct HTMLImageElement {
|
pub struct HTMLImageElement {
|
||||||
parent: HTMLElement,
|
parent: HTMLElement,
|
||||||
|
@ -15,6 +17,41 @@ pub struct HTMLImageElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HTMLImageElement {
|
impl HTMLImageElement {
|
||||||
|
/// Makes the local `image` member match the status of the `src` attribute and starts
|
||||||
|
/// prefetching the image. This method must be called after `src` is changed.
|
||||||
|
pub fn update_image(&mut self) {
|
||||||
|
let elem = &mut self.parent.parent;
|
||||||
|
let src_opt = elem.get_attr("src").map(|x| x.to_str());
|
||||||
|
let node = &mut elem.parent;
|
||||||
|
match node.owner_doc {
|
||||||
|
Some(doc) => {
|
||||||
|
match doc.with_base(|doc| doc.window) {
|
||||||
|
Some(window) => {
|
||||||
|
match src_opt {
|
||||||
|
None => {}
|
||||||
|
Some(src) => {
|
||||||
|
let page = window.page;
|
||||||
|
let img_url = make_url(src,
|
||||||
|
(*page).url
|
||||||
|
.map(|&(ref url, _)| url.clone()));
|
||||||
|
self.image = Some(img_url.clone());
|
||||||
|
|
||||||
|
// inform the image cache to load this, but don't store a
|
||||||
|
// handle.
|
||||||
|
//
|
||||||
|
// TODO (Issue #84): don't prefetch if we are within a
|
||||||
|
// <noscript> tag.
|
||||||
|
window.image_cache_task.send(image_cache_task::Prefetch(img_url));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn Alt(&self) -> DOMString {
|
pub fn Alt(&self) -> DOMString {
|
||||||
null_string
|
null_string
|
||||||
}
|
}
|
||||||
|
@ -22,11 +59,21 @@ impl HTMLImageElement {
|
||||||
pub fn SetAlt(&mut self, _alt: &DOMString, _rv: &mut ErrorResult) {
|
pub fn SetAlt(&mut self, _alt: &DOMString, _rv: &mut ErrorResult) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Src(&self) -> DOMString {
|
pub fn Src(&self, _abstract_self: AbstractNode<ScriptView>) -> DOMString {
|
||||||
null_string
|
null_string
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn SetSrc(&mut self, _src: &DOMString, _rv: &mut ErrorResult) {
|
pub fn SetSrc(&mut self,
|
||||||
|
abstract_self: AbstractNode<ScriptView>,
|
||||||
|
src: &DOMString,
|
||||||
|
_rv: &mut ErrorResult) {
|
||||||
|
{
|
||||||
|
let node = &mut self.parent.parent;
|
||||||
|
node.set_attr(abstract_self,
|
||||||
|
&str(~"src"),
|
||||||
|
&str(src.to_str()));
|
||||||
|
}
|
||||||
|
self.update_image();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn CrossOrigin(&self) -> DOMString {
|
pub fn CrossOrigin(&self) -> DOMString {
|
||||||
|
|
|
@ -12,6 +12,7 @@ use dom::navigator::Navigator;
|
||||||
use layout_interface::ReflowForDisplay;
|
use layout_interface::ReflowForDisplay;
|
||||||
use script_task::{ExitMsg, FireTimerMsg, Page, ScriptChan};
|
use script_task::{ExitMsg, FireTimerMsg, Page, ScriptChan};
|
||||||
use servo_msg::compositor_msg::ScriptListener;
|
use servo_msg::compositor_msg::ScriptListener;
|
||||||
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
|
|
||||||
use js::glue::*;
|
use js::glue::*;
|
||||||
use js::jsapi::{JSObject, JSContext, JS_DefineProperty, JS_CallTracer};
|
use js::jsapi::{JSObject, JSContext, JS_DefineProperty, JS_CallTracer};
|
||||||
|
@ -43,6 +44,7 @@ pub struct Window {
|
||||||
wrapper: WrapperCache,
|
wrapper: WrapperCache,
|
||||||
timer_chan: SharedChan<TimerControlMsg>,
|
timer_chan: SharedChan<TimerControlMsg>,
|
||||||
navigator: Option<@mut Navigator>,
|
navigator: Option<@mut Navigator>,
|
||||||
|
image_cache_task: ImageCacheTask,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
|
@ -172,7 +174,11 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fixed_stack_segment]
|
#[fixed_stack_segment]
|
||||||
pub fn new(cx: *JSContext, page: @mut Page, script_chan: ScriptChan, compositor: @ScriptListener)
|
pub fn new(cx: *JSContext,
|
||||||
|
page: @mut Page,
|
||||||
|
script_chan: ScriptChan,
|
||||||
|
compositor: @ScriptListener,
|
||||||
|
image_cache_task: ImageCacheTask)
|
||||||
-> @mut Window {
|
-> @mut Window {
|
||||||
let script_chan_clone = script_chan.clone();
|
let script_chan_clone = script_chan.clone();
|
||||||
let win = @mut Window {
|
let win = @mut Window {
|
||||||
|
@ -195,6 +201,7 @@ impl Window {
|
||||||
SharedChan::new(timer_chan)
|
SharedChan::new(timer_chan)
|
||||||
},
|
},
|
||||||
navigator: None,
|
navigator: None,
|
||||||
|
image_cache_task: image_cache_task,
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -24,8 +24,6 @@ use std::task;
|
||||||
use std::from_str::FromStr;
|
use std::from_str::FromStr;
|
||||||
use hubbub::hubbub;
|
use hubbub::hubbub;
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, SubpageId};
|
use servo_msg::constellation_msg::{ConstellationChan, SubpageId};
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
|
||||||
use servo_net::image_cache_task;
|
|
||||||
use servo_net::resource_task::{Done, Load, Payload, ResourceTask};
|
use servo_net::resource_task::{Done, Load, Payload, ResourceTask};
|
||||||
use servo_util::tree::TreeNodeRef;
|
use servo_util::tree::TreeNodeRef;
|
||||||
use servo_util::url::make_url;
|
use servo_util::url::make_url;
|
||||||
|
@ -302,7 +300,6 @@ pub fn build_element_from_tag(cx: *JSContext, tag: &str) -> AbstractNode<ScriptV
|
||||||
pub fn parse_html(cx: *JSContext,
|
pub fn parse_html(cx: *JSContext,
|
||||||
url: Url,
|
url: Url,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
image_cache_task: ImageCacheTask,
|
|
||||||
next_subpage_id: SubpageId,
|
next_subpage_id: SubpageId,
|
||||||
constellation_chan: ConstellationChan) -> HtmlParserResult {
|
constellation_chan: ConstellationChan) -> HtmlParserResult {
|
||||||
debug!("Hubbub: parsing %?", url);
|
debug!("Hubbub: parsing %?", url);
|
||||||
|
@ -436,19 +433,7 @@ pub fn parse_html(cx: *JSContext,
|
||||||
|
|
||||||
ElementNodeTypeId(HTMLImageElementTypeId) => {
|
ElementNodeTypeId(HTMLImageElementTypeId) => {
|
||||||
do node.with_mut_image_element |image_element| {
|
do node.with_mut_image_element |image_element| {
|
||||||
let elem = &mut image_element.parent.parent;
|
image_element.update_image();
|
||||||
let src_opt = elem.get_attr("src").map(|x| x.to_str());
|
|
||||||
match src_opt {
|
|
||||||
None => {}
|
|
||||||
Some(src) => {
|
|
||||||
let img_url = make_url(src, Some(url2.clone()));
|
|
||||||
image_element.image = Some(img_url.clone());
|
|
||||||
// inform the image cache to load this, but don't store a handle.
|
|
||||||
// TODO (Issue #84): don't prefetch if we are within a <noscript>
|
|
||||||
// tag.
|
|
||||||
image_cache_task.send(image_cache_task::Prefetch(img_url));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -631,7 +631,11 @@ impl ScriptTask {
|
||||||
|
|
||||||
let cx = self.js_runtime.cx();
|
let cx = self.js_runtime.cx();
|
||||||
// Create the window and document objects.
|
// Create the window and document objects.
|
||||||
let window = Window::new(cx.ptr, page, self.chan.clone(), self.compositor);
|
let window = Window::new(cx.ptr,
|
||||||
|
page,
|
||||||
|
self.chan.clone(),
|
||||||
|
self.compositor,
|
||||||
|
self.image_cache_task.clone());
|
||||||
page.initialize_js_info(cx, window.get_wrappercache().get_wrapper());
|
page.initialize_js_info(cx, window.get_wrappercache().get_wrapper());
|
||||||
|
|
||||||
RegisterBindings::Register(page.js_info.get_ref().js_compartment);
|
RegisterBindings::Register(page.js_info.get_ref().js_compartment);
|
||||||
|
@ -643,7 +647,6 @@ impl ScriptTask {
|
||||||
let html_parsing_result = hubbub_html_parser::parse_html(cx.ptr,
|
let html_parsing_result = hubbub_html_parser::parse_html(cx.ptr,
|
||||||
url.clone(),
|
url.clone(),
|
||||||
self.resource_task.clone(),
|
self.resource_task.clone(),
|
||||||
self.image_cache_task.clone(),
|
|
||||||
page.next_subpage_id.clone(),
|
page.next_subpage_id.clone(),
|
||||||
self.constellation_chan.clone());
|
self.constellation_chan.clone());
|
||||||
|
|
||||||
|
|
20
src/test/html/filmstrip.html
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Filmstrip</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p><img src="longcattop.png"></p>
|
||||||
|
<p><img src="longcatbot.png"></p>
|
||||||
|
<script>
|
||||||
|
var index = 0;
|
||||||
|
function change() {
|
||||||
|
document.getElementsByTagName("img")[0].src = "rust-" + (index * 45) + ".png";
|
||||||
|
index = (index + 1) % 8;
|
||||||
|
setTimeout(change, 100);
|
||||||
|
}
|
||||||
|
change();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
BIN
src/test/html/rust-0.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/test/html/rust-135.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/test/html/rust-180.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
src/test/html/rust-225.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
src/test/html/rust-270.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
src/test/html/rust-315.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
src/test/html/rust-45.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
src/test/html/rust-90.png
Normal file
After Width: | Height: | Size: 4.4 KiB |