auto merge of #927 : pcwalton/servo/image-src-set, r=pcwalton

r? @metajack
This commit is contained in:
bors-servo 2013-09-12 18:24:50 -07:00
commit 3c7a837ee6
14 changed files with 85 additions and 23 deletions

View file

@ -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')

View file

@ -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 {

View file

@ -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 {

View file

@ -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));
}
}
} }
} }

View file

@ -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());

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
src/test/html/rust-135.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
src/test/html/rust-180.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
src/test/html/rust-225.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/test/html/rust-270.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
src/test/html/rust-315.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
src/test/html/rust-45.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
src/test/html/rust-90.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB