mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Merge pull request #2875 from SimonSapin/rust-url
Start dogfooding rust-url
This commit is contained in:
commit
3670ee6f1f
43 changed files with 256 additions and 444 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -124,3 +124,6 @@
|
||||||
[submodule "src/support/stringcache/string-cache"]
|
[submodule "src/support/stringcache/string-cache"]
|
||||||
path = src/support/stringcache/string-cache
|
path = src/support/stringcache/string-cache
|
||||||
url = https://github.com/mozilla-servo/string-cache.git
|
url = https://github.com/mozilla-servo/string-cache.git
|
||||||
|
[submodule "src/support/url/rust-url"]
|
||||||
|
path = src/support/url/rust-url
|
||||||
|
url = https://github.com/mozilla-servo/rust-url.git
|
||||||
|
|
6
configure
vendored
6
configure
vendored
|
@ -528,7 +528,8 @@ CFG_SUBMODULES="\
|
||||||
support/opengles/rust-opengles \
|
support/opengles/rust-opengles \
|
||||||
support/sharegl/sharegl \
|
support/sharegl/sharegl \
|
||||||
support/phf/rust-phf \
|
support/phf/rust-phf \
|
||||||
support/stringcache/string-cache"
|
support/stringcache/string-cache \
|
||||||
|
support/url/rust-url"
|
||||||
|
|
||||||
if [ $CFG_OSTYPE = "apple-darwin" ]
|
if [ $CFG_OSTYPE = "apple-darwin" ]
|
||||||
then
|
then
|
||||||
|
@ -748,6 +749,9 @@ do
|
||||||
support/phf/rust-phf)
|
support/phf/rust-phf)
|
||||||
ENABLE_DEBUG=""
|
ENABLE_DEBUG=""
|
||||||
;;
|
;;
|
||||||
|
support/url/rust-url)
|
||||||
|
CONFIGURE_SCRIPT="${CFG_SRC_DIR}src/support/url/configure"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
|
@ -91,6 +91,15 @@ DEPS_rust-png += \
|
||||||
libpng \
|
libpng \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
DEPS_rust-url += \
|
||||||
|
rust-encoding \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
DEPS_rust-http += \
|
||||||
|
rust-encoding \
|
||||||
|
rust-url \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
# Platform-specific dependencies
|
# Platform-specific dependencies
|
||||||
ifeq ($(CFG_OSTYPE),apple-darwin)
|
ifeq ($(CFG_OSTYPE),apple-darwin)
|
||||||
DEPS_rust-azure += \
|
DEPS_rust-azure += \
|
||||||
|
|
|
@ -37,7 +37,7 @@ extern crate servo_util = "util";
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
extern crate url;
|
extern crate url = "url_";
|
||||||
|
|
||||||
#[cfg(target_os="macos")]
|
#[cfg(target_os="macos")]
|
||||||
extern crate core_graphics;
|
extern crate core_graphics;
|
||||||
|
|
|
@ -42,12 +42,13 @@ use servo_util::geometry::{DevicePixel, PagePx, ScreenPx, ViewportPx};
|
||||||
use servo_util::memory::MemoryProfilerChan;
|
use servo_util::memory::MemoryProfilerChan;
|
||||||
use servo_util::opts::Opts;
|
use servo_util::opts::Opts;
|
||||||
use servo_util::time::{profile, TimeProfilerChan};
|
use servo_util::time::{profile, TimeProfilerChan};
|
||||||
use servo_util::{memory, time, url};
|
use servo_util::{memory, time};
|
||||||
use std::io::timer::sleep;
|
use std::io::timer::sleep;
|
||||||
use std::collections::hashmap::HashMap;
|
use std::collections::hashmap::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use time::precise_time_s;
|
use time::precise_time_s;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
|
||||||
pub struct IOCompositor {
|
pub struct IOCompositor {
|
||||||
|
@ -626,7 +627,7 @@ impl IOCompositor {
|
||||||
layers"),
|
layers"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let msg = LoadUrlMsg(root_pipeline_id, url::parse_url(url_string.as_slice(), None));
|
let msg = LoadUrlMsg(root_pipeline_id, Url::parse(url_string.as_slice()).unwrap());
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||||
chan.send(msg);
|
chan.send(msg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ use servo_net::resource_task;
|
||||||
use servo_util::geometry::PagePx;
|
use servo_util::geometry::PagePx;
|
||||||
use servo_util::opts::Opts;
|
use servo_util::opts::Opts;
|
||||||
use servo_util::time::TimeProfilerChan;
|
use servo_util::time::TimeProfilerChan;
|
||||||
use servo_util::url::parse_url;
|
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::spawn_named;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::kinds::marker;
|
use std::kinds::marker;
|
||||||
|
@ -446,7 +445,7 @@ impl<LTF: LayoutTaskFactory> Constellation<LTF> {
|
||||||
debug!("creating replacement pipeline for about:failure");
|
debug!("creating replacement pipeline for about:failure");
|
||||||
|
|
||||||
let new_id = self.get_next_pipeline_id();
|
let new_id = self.get_next_pipeline_id();
|
||||||
let pipeline = self.new_pipeline(new_id, subpage_id, parse_url("about:failure", None));
|
let pipeline = self.new_pipeline(new_id, subpage_id, Url::parse("about:failure").unwrap());
|
||||||
pipeline.load();
|
pipeline.load();
|
||||||
|
|
||||||
let pipeline_wrapped = Rc::new(pipeline);
|
let pipeline_wrapped = Rc::new(pipeline);
|
||||||
|
@ -576,11 +575,11 @@ impl<LTF: LayoutTaskFactory> Constellation<LTF> {
|
||||||
|
|
||||||
let source_url = source_pipeline.url.clone();
|
let source_url = source_pipeline.url.clone();
|
||||||
|
|
||||||
let same_script = (source_url.host == url.host &&
|
let same_script = (source_url.host() == url.host() &&
|
||||||
source_url.port == url.port) && sandbox == IFrameUnsandboxed;
|
source_url.port() == url.port()) && sandbox == IFrameUnsandboxed;
|
||||||
// FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
|
// FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
|
||||||
let pipeline = if same_script {
|
let pipeline = if same_script {
|
||||||
debug!("Constellation: loading same-origin iframe at {:?}", url);
|
debug!("Constellation: loading same-origin iframe at {}", url.serialize());
|
||||||
// Reuse the script task if same-origin url's
|
// Reuse the script task if same-origin url's
|
||||||
Pipeline::with_script::<LTF>(next_pipeline_id,
|
Pipeline::with_script::<LTF>(next_pipeline_id,
|
||||||
subpage_id,
|
subpage_id,
|
||||||
|
@ -616,7 +615,7 @@ impl<LTF: LayoutTaskFactory> Constellation<LTF> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_load_url_msg(&mut self, source_id: PipelineId, url: Url) {
|
fn handle_load_url_msg(&mut self, source_id: PipelineId, url: Url) {
|
||||||
debug!("Constellation: received message to load {:s}", url.to_str());
|
debug!("Constellation: received message to load {:s}", url.serialize());
|
||||||
// Make sure no pending page would be overridden.
|
// Make sure no pending page would be overridden.
|
||||||
let source_frame = self.current_frame().get_ref().find(source_id).expect(
|
let source_frame = self.current_frame().get_ref().find(source_id).expect(
|
||||||
"Constellation: received a LoadUrlMsg from a pipeline_id associated
|
"Constellation: received a LoadUrlMsg from a pipeline_id associated
|
||||||
|
|
|
@ -56,9 +56,9 @@ use script::dom::element::{HTMLTableRowElementTypeId, HTMLTableSectionElementTyp
|
||||||
use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
|
use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
|
||||||
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
|
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
|
||||||
use script::dom::node::{TextNodeTypeId};
|
use script::dom::node::{TextNodeTypeId};
|
||||||
|
use script::dom::htmlobjectelement::is_image_data;
|
||||||
use servo_util::namespace;
|
use servo_util::namespace;
|
||||||
use servo_util::range::Range;
|
use servo_util::range::Range;
|
||||||
use servo_util::url::{is_image_data, parse_url};
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::atomics::Relaxed;
|
use std::sync::atomics::Relaxed;
|
||||||
use style::ComputedValues;
|
use style::ComputedValues;
|
||||||
|
@ -249,7 +249,7 @@ impl<'a> FlowConstructor<'a> {
|
||||||
IframeFragment(IframeFragmentInfo::new(node))
|
IframeFragment(IframeFragmentInfo::new(node))
|
||||||
}
|
}
|
||||||
Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => {
|
Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => {
|
||||||
let data = node.get_object_data(&self.layout_context.url);
|
let data = node.get_object_data();
|
||||||
self.build_fragment_info_for_image(node, data)
|
self.build_fragment_info_for_image(node, data)
|
||||||
}
|
}
|
||||||
Some(ElementNodeTypeId(HTMLTableElementTypeId)) => TableWrapperFragment,
|
Some(ElementNodeTypeId(HTMLTableElementTypeId)) => TableWrapperFragment,
|
||||||
|
@ -1007,7 +1007,7 @@ trait ObjectElement {
|
||||||
fn has_object_data(&self) -> bool;
|
fn has_object_data(&self) -> bool;
|
||||||
|
|
||||||
/// Returns the "data" attribute value parsed as a URL
|
/// Returns the "data" attribute value parsed as a URL
|
||||||
fn get_object_data(&self, base_url: &Url) -> Option<Url>;
|
fn get_object_data(&self) -> Option<Url>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> {
|
impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> {
|
||||||
|
@ -1023,9 +1023,9 @@ impl<'ln> ObjectElement for ThreadSafeLayoutNode<'ln> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_object_data(&self, base_url: &Url) -> Option<Url> {
|
fn get_object_data(&self) -> Option<Url> {
|
||||||
match self.get_type_and_data() {
|
match self.get_type_and_data() {
|
||||||
(None, Some(uri)) if is_image_data(uri) => Some(parse_url(uri, Some(base_url.clone()))),
|
(None, Some(uri)) if is_image_data(uri) => Url::parse(uri).ok(),
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use style::{Stylesheet, Stylist, UserAgentOrigin, with_errors_silenced};
|
use style::{Stylesheet, Stylist, UserAgentOrigin, with_errors_silenced};
|
||||||
use url;
|
use url::Url;
|
||||||
|
|
||||||
|
|
||||||
pub fn new_stylist() -> Stylist {
|
pub fn new_stylist() -> Stylist {
|
||||||
let mut stylist = Stylist::new();
|
let mut stylist = Stylist::new();
|
||||||
let ua_stylesheet = with_errors_silenced(|| Stylesheet::from_bytes(
|
let ua_stylesheet = with_errors_silenced(|| Stylesheet::from_bytes(
|
||||||
include_bin!("user-agent.css"),
|
include_bin!("user-agent.css"),
|
||||||
url::from_str("chrome:///user-agent.css").unwrap(),
|
Url::parse("chrome:///user-agent.css").unwrap(),
|
||||||
None,
|
None,
|
||||||
None));
|
None));
|
||||||
stylist.add_stylesheet(ua_stylesheet, UserAgentOrigin);
|
stylist.add_stylesheet(ua_stylesheet, UserAgentOrigin);
|
||||||
|
|
|
@ -33,7 +33,7 @@ extern crate collections;
|
||||||
extern crate green;
|
extern crate green;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
extern crate url;
|
extern crate url = "url_";
|
||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod construct;
|
pub mod construct;
|
||||||
|
|
|
@ -563,7 +563,7 @@ impl LayoutTask {
|
||||||
mem::transmute(&mut node)
|
mem::transmute(&mut node)
|
||||||
};
|
};
|
||||||
|
|
||||||
debug!("layout: received layout request for: {:s}", data.url.to_str());
|
debug!("layout: received layout request for: {:s}", data.url.serialize());
|
||||||
debug!("layout: damage is {:?}", data.damage);
|
debug!("layout: damage is {:?}", data.damage);
|
||||||
debug!("layout: parsed Node tree");
|
debug!("layout: parsed Node tree");
|
||||||
debug!("{:?}", node.dump());
|
debug!("{:?}", node.dump());
|
||||||
|
|
|
@ -26,7 +26,7 @@ extern crate gfx;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate native;
|
extern crate native;
|
||||||
extern crate rustrt;
|
extern crate rustrt;
|
||||||
extern crate url;
|
extern crate url = "url_";
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use compositing::{CompositorChan, CompositorTask, Constellation};
|
use compositing::{CompositorChan, CompositorTask, Constellation};
|
||||||
|
@ -48,8 +48,9 @@ use servo_util::memory::MemoryProfiler;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use servo_util::opts;
|
use servo_util::opts;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use servo_util::url::parse_url;
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
|
|
||||||
#[cfg(not(test), not(target_os="android"))]
|
#[cfg(not(test), not(target_os="android"))]
|
||||||
|
@ -58,8 +59,6 @@ use std::os;
|
||||||
use std::str;
|
use std::str;
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use rustrt::task::TaskOpts;
|
use rustrt::task::TaskOpts;
|
||||||
#[cfg(not(test))]
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(not(test), target_os="linux")]
|
#[cfg(not(test), target_os="linux")]
|
||||||
|
@ -134,16 +133,12 @@ pub fn run(opts: opts::Opts) {
|
||||||
font_cache_task,
|
font_cache_task,
|
||||||
time_profiler_chan_clone);
|
time_profiler_chan_clone);
|
||||||
|
|
||||||
|
let base_url = Url::from_directory_path(&os::getcwd()).unwrap();
|
||||||
|
let mut url_parser = UrlParser::new();
|
||||||
|
let url_parser = url_parser.base_url(&base_url);
|
||||||
// Send the URL command to the constellation.
|
// Send the URL command to the constellation.
|
||||||
for filename in opts.urls.iter() {
|
for url in opts.urls.iter() {
|
||||||
let url = if filename.as_slice().starts_with("data:") {
|
let url = url_parser.parse(url.as_slice()).ok().expect("URL parsing failed");
|
||||||
// As a hack for easier command-line testing,
|
|
||||||
// assume that data URLs are not URL-encoded.
|
|
||||||
Url::new("data".to_string(), None, "".to_string(), None,
|
|
||||||
filename.as_slice().slice_from(5).to_string(), vec!(), None)
|
|
||||||
} else {
|
|
||||||
parse_url(filename.as_slice(), None)
|
|
||||||
};
|
|
||||||
|
|
||||||
let ConstellationChan(ref chan) = constellation_chan;
|
let ConstellationChan(ref chan) = constellation_chan;
|
||||||
chan.send(InitLoadUrlMsg(url));
|
chan.send(InitLoadUrlMsg(url));
|
||||||
|
|
|
@ -13,7 +13,7 @@ extern crate layers;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate servo_util = "util";
|
extern crate servo_util = "util";
|
||||||
extern crate std;
|
extern crate std;
|
||||||
extern crate url;
|
extern crate url = "url_";
|
||||||
|
|
||||||
#[cfg(target_os="macos")]
|
#[cfg(target_os="macos")]
|
||||||
extern crate core_foundation;
|
extern crate core_foundation;
|
||||||
|
|
|
@ -2,12 +2,16 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::str;
|
||||||
|
|
||||||
use resource_task::{Done, Payload, Metadata, LoadData, LoadResponse, LoaderTask, start_sending};
|
use resource_task::{Done, Payload, Metadata, LoadData, LoadResponse, LoaderTask, start_sending};
|
||||||
|
|
||||||
use serialize::base64::FromBase64;
|
use serialize::base64::FromBase64;
|
||||||
|
|
||||||
use http::headers::test_utils::from_stream_with_str;
|
use http::headers::test_utils::from_stream_with_str;
|
||||||
use http::headers::content_type::MediaType;
|
use http::headers::content_type::MediaType;
|
||||||
|
use url::{percent_decode, OtherSchemeData};
|
||||||
|
|
||||||
|
|
||||||
pub fn factory() -> LoaderTask {
|
pub fn factory() -> LoaderTask {
|
||||||
proc(url, start_chan) {
|
proc(url, start_chan) {
|
||||||
|
@ -25,7 +29,18 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
||||||
let mut metadata = Metadata::default(url.clone());
|
let mut metadata = Metadata::default(url.clone());
|
||||||
|
|
||||||
// Split out content type and data.
|
// Split out content type and data.
|
||||||
let parts: Vec<&str> = url.path.as_slice().splitn(',', 1).collect();
|
let mut scheme_data = match url.scheme_data {
|
||||||
|
OtherSchemeData(scheme_data) => scheme_data,
|
||||||
|
_ => fail!("Expected a non-relative scheme URL.")
|
||||||
|
};
|
||||||
|
match url.query {
|
||||||
|
Some(query) => {
|
||||||
|
scheme_data.push_str("?");
|
||||||
|
scheme_data.push_str(query.as_slice());
|
||||||
|
},
|
||||||
|
None => ()
|
||||||
|
}
|
||||||
|
let parts: Vec<&str> = scheme_data.as_slice().splitn(',', 1).collect();
|
||||||
if parts.len() != 2 {
|
if parts.len() != 2 {
|
||||||
start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string())));
|
start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string())));
|
||||||
return;
|
return;
|
||||||
|
@ -46,23 +61,23 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
||||||
metadata.set_content_type(&content_type);
|
metadata.set_content_type(&content_type);
|
||||||
|
|
||||||
let progress_chan = start_sending(start_chan, metadata);
|
let progress_chan = start_sending(start_chan, metadata);
|
||||||
|
let bytes = percent_decode(parts.get(1).as_bytes());
|
||||||
|
|
||||||
if is_base64 {
|
if is_base64 {
|
||||||
match (*parts.get(1)).from_base64() {
|
// FIXME(#2877): use bytes.as_slice().from_base64() when we upgrade to a Rust version
|
||||||
|
// that includes https://github.com/rust-lang/rust/pull/15810
|
||||||
|
let fake_utf8 = unsafe { str::raw::from_utf8(bytes.as_slice()) };
|
||||||
|
match fake_utf8.from_base64() {
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
progress_chan.send(Done(Err("non-base64 data uri".to_string())));
|
progress_chan.send(Done(Err("non-base64 data uri".to_string())));
|
||||||
}
|
}
|
||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
let data: Vec<u8> = data;
|
progress_chan.send(Payload(data));
|
||||||
progress_chan.send(Payload(data.move_iter().collect()));
|
|
||||||
progress_chan.send(Done(Ok(())));
|
progress_chan.send(Done(Ok(())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Since the %-decoded URL is already a str, we can't
|
progress_chan.send(Payload(bytes));
|
||||||
// handle UTF8-incompatible encodings.
|
|
||||||
let bytes: &[u8] = (*parts.get(1)).as_bytes();
|
|
||||||
progress_chan.send(Payload(bytes.iter().map(|&x| x).collect()));
|
|
||||||
progress_chan.send(Done(Ok(())));
|
progress_chan.send(Done(Ok(())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,11 +87,11 @@ fn assert_parse(url: &'static str,
|
||||||
content_type: Option<(String, String)>,
|
content_type: Option<(String, String)>,
|
||||||
charset: Option<String>,
|
charset: Option<String>,
|
||||||
data: Option<Vec<u8>>) {
|
data: Option<Vec<u8>>) {
|
||||||
use std::from_str::FromStr;
|
|
||||||
use std::comm;
|
use std::comm;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
let (start_chan, start_port) = comm::channel();
|
let (start_chan, start_port) = comm::channel();
|
||||||
load(LoadData::new(FromStr::from_str(url).unwrap()), start_chan);
|
load(LoadData::new(Url::parse(url).unwrap()), start_chan);
|
||||||
|
|
||||||
let response = start_port.recv();
|
let response = start_port.recv();
|
||||||
assert_eq!(&response.metadata.content_type, &content_type);
|
assert_eq!(&response.metadata.content_type, &content_type);
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub fn factory() -> LoaderTask {
|
||||||
assert!("file" == url.scheme.as_slice());
|
assert!("file" == url.scheme.as_slice());
|
||||||
let progress_chan = start_sending(start_chan, Metadata::default(url.clone()));
|
let progress_chan = start_sending(start_chan, Metadata::default(url.clone()));
|
||||||
spawn_named("file_loader", proc() {
|
spawn_named("file_loader", proc() {
|
||||||
match File::open_mode(&Path::new(url.path), io::Open, io::Read) {
|
match File::open_mode(&Path::new(url.serialize_path().unwrap()), io::Open, io::Read) {
|
||||||
Ok(ref mut reader) => {
|
Ok(ref mut reader) => {
|
||||||
let res = read_all(reader as &mut io::Stream, &progress_chan);
|
let res = read_all(reader as &mut io::Stream, &progress_chan);
|
||||||
progress_chan.send(Done(res));
|
progress_chan.send(Done(res));
|
||||||
|
|
|
@ -56,7 +56,7 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("requesting {:s}", url.to_str());
|
info!("requesting {:s}", url.serialize());
|
||||||
|
|
||||||
let request = RequestWriter::<NetworkStream>::new(load_data.method.clone(), url.clone());
|
let request = RequestWriter::<NetworkStream>::new(load_data.method.clone(), url.clone());
|
||||||
let mut writer = match request {
|
let mut writer = match request {
|
||||||
|
@ -106,7 +106,7 @@ fn load(load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
||||||
if 3 == (response.status.code() / 100) {
|
if 3 == (response.status.code() / 100) {
|
||||||
match response.headers.location {
|
match response.headers.location {
|
||||||
Some(new_url) => {
|
Some(new_url) => {
|
||||||
info!("redirecting to {:s}", new_url.to_str());
|
info!("redirecting to {:s}", new_url.serialize());
|
||||||
url = new_url;
|
url = new_url;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ pub struct ImageHolder {
|
||||||
|
|
||||||
impl ImageHolder {
|
impl ImageHolder {
|
||||||
pub fn new(url: Url, local_image_cache: Arc<Mutex<LocalImageCache>>) -> ImageHolder {
|
pub fn new(url: Url, local_image_cache: Arc<Mutex<LocalImageCache>>) -> ImageHolder {
|
||||||
debug!("ImageHolder::new() {}", url.to_str());
|
debug!("ImageHolder::new() {}", url.serialize());
|
||||||
let holder = ImageHolder {
|
let holder = ImageHolder {
|
||||||
url: url,
|
url: url,
|
||||||
image: None,
|
image: None,
|
||||||
|
@ -61,7 +61,7 @@ impl ImageHolder {
|
||||||
|
|
||||||
/// Query and update the current image size.
|
/// Query and update the current image size.
|
||||||
pub fn get_size(&mut self) -> Option<Size2D<int>> {
|
pub fn get_size(&mut self) -> Option<Size2D<int>> {
|
||||||
debug!("get_size() {}", self.url.to_str());
|
debug!("get_size() {}", self.url.serialize());
|
||||||
self.get_image().map(|img| {
|
self.get_image().map(|img| {
|
||||||
self.cached_size = Size2D(img.width as int,
|
self.cached_size = Size2D(img.width as int,
|
||||||
img.height as int);
|
img.height as int);
|
||||||
|
@ -70,12 +70,12 @@ impl ImageHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_image_if_present(&self) -> Option<Arc<Box<Image>>> {
|
pub fn get_image_if_present(&self) -> Option<Arc<Box<Image>>> {
|
||||||
debug!("get_image_if_present() {}", self.url.to_str());
|
debug!("get_image_if_present() {}", self.url.serialize());
|
||||||
self.image.clone()
|
self.image.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_image(&mut self) -> Option<Arc<Box<Image>>> {
|
pub fn get_image(&mut self) -> Option<Arc<Box<Image>>> {
|
||||||
debug!("get_image() {}", self.url.to_str());
|
debug!("get_image() {}", self.url.serialize());
|
||||||
|
|
||||||
// If this is the first time we've called this function, load
|
// If this is the first time we've called this function, load
|
||||||
// the image and store it for the future
|
// the image and store it for the future
|
||||||
|
@ -90,10 +90,10 @@ impl ImageHolder {
|
||||||
self.image = Some(image);
|
self.image = Some(image);
|
||||||
}
|
}
|
||||||
ImageNotReady => {
|
ImageNotReady => {
|
||||||
debug!("image not ready for {:s}", self.url.to_str());
|
debug!("image not ready for {:s}", self.url.serialize());
|
||||||
}
|
}
|
||||||
ImageFailed => {
|
ImageFailed => {
|
||||||
debug!("image decoding failed for {:s}", self.url.to_str());
|
debug!("image decoding failed for {:s}", self.url.serialize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,11 @@
|
||||||
use image::base::{Image, load_from_memory};
|
use image::base::{Image, load_from_memory};
|
||||||
use resource_task;
|
use resource_task;
|
||||||
use resource_task::{LoadData, ResourceTask};
|
use resource_task::{LoadData, ResourceTask};
|
||||||
use servo_util::url::{UrlMap, url_map};
|
|
||||||
|
|
||||||
use std::comm::{channel, Receiver, Sender};
|
use std::comm::{channel, Receiver, Sender};
|
||||||
|
use std::collections::hashmap::HashMap;
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::task::spawn;
|
use std::task::spawn;
|
||||||
use std::to_str::ToStr;
|
|
||||||
use std::result;
|
use std::result;
|
||||||
use sync::{Arc, Mutex};
|
use sync::{Arc, Mutex};
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
|
@ -89,8 +88,8 @@ impl ImageCacheTask {
|
||||||
resource_task: resource_task.clone(),
|
resource_task: resource_task.clone(),
|
||||||
port: port,
|
port: port,
|
||||||
chan: chan_clone,
|
chan: chan_clone,
|
||||||
state_map: url_map(),
|
state_map: HashMap::new(),
|
||||||
wait_map: url_map(),
|
wait_map: HashMap::new(),
|
||||||
need_exit: None
|
need_exit: None
|
||||||
};
|
};
|
||||||
cache.run();
|
cache.run();
|
||||||
|
@ -137,9 +136,9 @@ struct ImageCache {
|
||||||
/// A copy of the shared chan to give to child tasks
|
/// A copy of the shared chan to give to child tasks
|
||||||
chan: Sender<Msg>,
|
chan: Sender<Msg>,
|
||||||
/// The state of processsing an image for a URL
|
/// The state of processsing an image for a URL
|
||||||
state_map: UrlMap<ImageState>,
|
state_map: HashMap<Url, ImageState>,
|
||||||
/// List of clients waiting on a WaitForImage response
|
/// List of clients waiting on a WaitForImage response
|
||||||
wait_map: UrlMap<Arc<Mutex<Vec<Sender<ImageResponseMsg>>>>>,
|
wait_map: HashMap<Url, Arc<Mutex<Vec<Sender<ImageResponseMsg>>>>>,
|
||||||
need_exit: Option<Sender<()>>,
|
need_exit: Option<Sender<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +247,7 @@ impl ImageCache {
|
||||||
|
|
||||||
spawn(proc() {
|
spawn(proc() {
|
||||||
let url = url_clone;
|
let url = url_clone;
|
||||||
debug!("image_cache_task: started fetch for {:s}", url.to_str());
|
debug!("image_cache_task: started fetch for {:s}", url.serialize());
|
||||||
|
|
||||||
let image = load_image_data(url.clone(), resource_task.clone());
|
let image = load_image_data(url.clone(), resource_task.clone());
|
||||||
|
|
||||||
|
@ -258,7 +257,7 @@ impl ImageCache {
|
||||||
Err(())
|
Err(())
|
||||||
};
|
};
|
||||||
to_cache.send(StorePrefetchedImageData(url.clone(), result));
|
to_cache.send(StorePrefetchedImageData(url.clone(), result));
|
||||||
debug!("image_cache_task: ended fetch for {:s}", (url.clone()).to_str());
|
debug!("image_cache_task: ended fetch for {:s}", url.serialize());
|
||||||
});
|
});
|
||||||
|
|
||||||
self.set_state(url, Prefetching(DoNotDecode));
|
self.set_state(url, Prefetching(DoNotDecode));
|
||||||
|
@ -317,7 +316,7 @@ impl ImageCache {
|
||||||
|
|
||||||
spawn(proc() {
|
spawn(proc() {
|
||||||
let url = url_clone;
|
let url = url_clone;
|
||||||
debug!("image_cache_task: started image decode for {:s}", url.to_str());
|
debug!("image_cache_task: started image decode for {:s}", url.serialize());
|
||||||
let image = load_from_memory(data.as_slice());
|
let image = load_from_memory(data.as_slice());
|
||||||
let image = if image.is_some() {
|
let image = if image.is_some() {
|
||||||
Some(Arc::new(box image.unwrap()))
|
Some(Arc::new(box image.unwrap()))
|
||||||
|
@ -325,7 +324,7 @@ impl ImageCache {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
to_cache.send(StoreImage(url.clone(), image));
|
to_cache.send(StoreImage(url.clone(), image));
|
||||||
debug!("image_cache_task: ended image decode for {:s}", url.to_str());
|
debug!("image_cache_task: ended image decode for {:s}", url.serialize());
|
||||||
});
|
});
|
||||||
|
|
||||||
self.set_state(url, Decoding);
|
self.set_state(url, Decoding);
|
||||||
|
@ -494,8 +493,8 @@ mod tests {
|
||||||
use resource_task;
|
use resource_task;
|
||||||
use resource_task::{ResourceTask, Metadata, start_sending};
|
use resource_task::{ResourceTask, Metadata, start_sending};
|
||||||
use image::base::test_image_bin;
|
use image::base::test_image_bin;
|
||||||
use servo_util::url::parse_url;
|
|
||||||
use std::comm;
|
use std::comm;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
trait Closure {
|
trait Closure {
|
||||||
fn invoke(&self, _response: Sender<resource_task::ProgressMsg>) { }
|
fn invoke(&self, _response: Sender<resource_task::ProgressMsg>) { }
|
||||||
|
@ -568,7 +567,8 @@ mod tests {
|
||||||
loop {
|
loop {
|
||||||
match port.recv() {
|
match port.recv() {
|
||||||
resource_task::Load(_, response) => {
|
resource_task::Load(_, response) => {
|
||||||
let chan = start_sending(response, Metadata::default(parse_url("file:///fake", None)));
|
let chan = start_sending(response, Metadata::default(
|
||||||
|
Url::parse("file:///fake").unwrap()));
|
||||||
on_load.invoke(chan);
|
on_load.invoke(chan);
|
||||||
}
|
}
|
||||||
resource_task::Exit => break
|
resource_task::Exit => break
|
||||||
|
@ -582,7 +582,6 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box DoesNothing);
|
let mock_resource_task = mock_resource_task(box DoesNothing);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let _url = parse_url("file", None);
|
|
||||||
|
|
||||||
image_cache_task.exit();
|
image_cache_task.exit();
|
||||||
mock_resource_task.send(resource_task::Exit);
|
mock_resource_task.send(resource_task::Exit);
|
||||||
|
@ -594,7 +593,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box DoesNothing);
|
let mock_resource_task = mock_resource_task(box DoesNothing);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
let (chan, port) = channel();
|
let (chan, port) = channel();
|
||||||
image_cache_task.send(GetImage(url, chan));
|
image_cache_task.send(GetImage(url, chan));
|
||||||
|
@ -608,7 +607,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan});
|
let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan});
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(url));
|
image_cache_task.send(Prefetch(url));
|
||||||
url_requested.recv();
|
url_requested.recv();
|
||||||
|
@ -623,7 +622,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan});
|
let mock_resource_task = mock_resource_task(box JustSendOK { url_requested_chan: url_requested_chan});
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(url.clone()));
|
image_cache_task.send(Prefetch(url.clone()));
|
||||||
image_cache_task.send(Prefetch(url));
|
image_cache_task.send(Prefetch(url));
|
||||||
|
@ -643,7 +642,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box WaitSendTestImage{wait_port: wait_port});
|
let mock_resource_task = mock_resource_task(box WaitSendTestImage{wait_port: wait_port});
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(url.clone()));
|
image_cache_task.send(Prefetch(url.clone()));
|
||||||
image_cache_task.send(Decode(url.clone()));
|
image_cache_task.send(Decode(url.clone()));
|
||||||
|
@ -660,7 +659,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box SendTestImage);
|
let mock_resource_task = mock_resource_task(box SendTestImage);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
let join_port = image_cache_task.wait_for_store();
|
let join_port = image_cache_task.wait_for_store();
|
||||||
|
|
||||||
|
@ -686,7 +685,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box SendTestImage);
|
let mock_resource_task = mock_resource_task(box SendTestImage);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
let join_port = image_cache_task.wait_for_store();
|
let join_port = image_cache_task.wait_for_store();
|
||||||
|
|
||||||
|
@ -719,7 +718,8 @@ mod tests {
|
||||||
loop {
|
loop {
|
||||||
match port.recv() {
|
match port.recv() {
|
||||||
resource_task::Load(_, response) => {
|
resource_task::Load(_, response) => {
|
||||||
let chan = start_sending(response, Metadata::default(parse_url("file:///fake", None)));
|
let chan = start_sending(response, Metadata::default(
|
||||||
|
Url::parse("file:///fake").unwrap()));
|
||||||
chan.send(resource_task::Payload(test_image_bin()));
|
chan.send(resource_task::Payload(test_image_bin()));
|
||||||
chan.send(resource_task::Done(Ok(())));
|
chan.send(resource_task::Done(Ok(())));
|
||||||
image_bin_sent_chan.send(());
|
image_bin_sent_chan.send(());
|
||||||
|
@ -733,7 +733,7 @@ mod tests {
|
||||||
});
|
});
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(url.clone()));
|
image_cache_task.send(Prefetch(url.clone()));
|
||||||
|
|
||||||
|
@ -765,7 +765,8 @@ mod tests {
|
||||||
loop {
|
loop {
|
||||||
match port.recv() {
|
match port.recv() {
|
||||||
resource_task::Load(_, response) => {
|
resource_task::Load(_, response) => {
|
||||||
let chan = start_sending(response, Metadata::default(parse_url("file:///fake", None)));
|
let chan = start_sending(response, Metadata::default(
|
||||||
|
Url::parse("file:///fake").unwrap()));
|
||||||
chan.send(resource_task::Payload(test_image_bin()));
|
chan.send(resource_task::Payload(test_image_bin()));
|
||||||
chan.send(resource_task::Done(Err("".to_string())));
|
chan.send(resource_task::Done(Err("".to_string())));
|
||||||
image_bin_sent_chan.send(());
|
image_bin_sent_chan.send(());
|
||||||
|
@ -779,7 +780,7 @@ mod tests {
|
||||||
});
|
});
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(url.clone()));
|
image_cache_task.send(Prefetch(url.clone()));
|
||||||
image_cache_task.send(Decode(url.clone()));
|
image_cache_task.send(Decode(url.clone()));
|
||||||
|
@ -808,7 +809,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box SendTestImageErr);
|
let mock_resource_task = mock_resource_task(box SendTestImageErr);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
let join_port = image_cache_task.wait_for_store_prefetched();
|
let join_port = image_cache_task.wait_for_store_prefetched();
|
||||||
|
|
||||||
|
@ -834,7 +835,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box SendTestImageErr);
|
let mock_resource_task = mock_resource_task(box SendTestImageErr);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
let join_port = image_cache_task.wait_for_store_prefetched();
|
let join_port = image_cache_task.wait_for_store_prefetched();
|
||||||
|
|
||||||
|
@ -868,7 +869,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box SendBogusImage);
|
let mock_resource_task = mock_resource_task(box SendBogusImage);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
let join_port = image_cache_task.wait_for_store();
|
let join_port = image_cache_task.wait_for_store();
|
||||||
|
|
||||||
|
@ -896,7 +897,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box SendTestImage);
|
let mock_resource_task = mock_resource_task(box SendTestImage);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
let join_port = image_cache_task.wait_for_store();
|
let join_port = image_cache_task.wait_for_store();
|
||||||
|
|
||||||
|
@ -924,7 +925,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box WaitSendTestImage {wait_port: wait_port});
|
let mock_resource_task = mock_resource_task(box WaitSendTestImage {wait_port: wait_port});
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(url.clone()));
|
image_cache_task.send(Prefetch(url.clone()));
|
||||||
image_cache_task.send(Decode(url.clone()));
|
image_cache_task.send(Decode(url.clone()));
|
||||||
|
@ -950,7 +951,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box WaitSendTestImageErr{wait_port: wait_port});
|
let mock_resource_task = mock_resource_task(box WaitSendTestImageErr{wait_port: wait_port});
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(url.clone()));
|
image_cache_task.send(Prefetch(url.clone()));
|
||||||
image_cache_task.send(Decode(url.clone()));
|
image_cache_task.send(Decode(url.clone()));
|
||||||
|
@ -974,7 +975,7 @@ mod tests {
|
||||||
let mock_resource_task = mock_resource_task(box SendTestImage);
|
let mock_resource_task = mock_resource_task(box SendTestImage);
|
||||||
|
|
||||||
let image_cache_task = ImageCacheTask::new_sync(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask::new_sync(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = Url::parse("file:///").unwrap();
|
||||||
|
|
||||||
image_cache_task.send(Prefetch(url.clone()));
|
image_cache_task.send(Prefetch(url.clone()));
|
||||||
image_cache_task.send(Decode(url.clone()));
|
image_cache_task.send(Decode(url.clone()));
|
||||||
|
|
|
@ -12,7 +12,7 @@ use image_cache_task::{Decode, GetImage, ImageCacheTask, ImageFailed, ImageNotRe
|
||||||
use image_cache_task::{ImageResponseMsg, Prefetch, WaitForImage};
|
use image_cache_task::{ImageResponseMsg, Prefetch, WaitForImage};
|
||||||
|
|
||||||
use std::comm::{Receiver, channel};
|
use std::comm::{Receiver, channel};
|
||||||
use servo_util::url::{UrlMap, url_map};
|
use std::collections::hashmap::HashMap;
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::spawn_named;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ pub struct LocalImageCache {
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
round_number: uint,
|
round_number: uint,
|
||||||
on_image_available: Option<Box<ImageResponder+Send>>,
|
on_image_available: Option<Box<ImageResponder+Send>>,
|
||||||
state_map: UrlMap<ImageState>
|
state_map: HashMap<Url, ImageState>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalImageCache {
|
impl LocalImageCache {
|
||||||
|
@ -33,7 +33,7 @@ impl LocalImageCache {
|
||||||
image_cache_task: image_cache_task,
|
image_cache_task: image_cache_task,
|
||||||
round_number: 1,
|
round_number: 1,
|
||||||
on_image_available: None,
|
on_image_available: None,
|
||||||
state_map: url_map()
|
state_map: HashMap::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern crate serialize;
|
||||||
extern crate servo_util = "util";
|
extern crate servo_util = "util";
|
||||||
extern crate stb_image;
|
extern crate stb_image;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
extern crate url;
|
extern crate url = "url_";
|
||||||
|
|
||||||
/// Image handling.
|
/// Image handling.
|
||||||
///
|
///
|
||||||
|
|
|
@ -10,6 +10,7 @@ use data_loader;
|
||||||
|
|
||||||
use std::comm::{channel, Receiver, Sender};
|
use std::comm::{channel, Receiver, Sender};
|
||||||
use std::task::TaskBuilder;
|
use std::task::TaskBuilder;
|
||||||
|
use std::os;
|
||||||
use http::headers::content_type::MediaType;
|
use http::headers::content_type::MediaType;
|
||||||
use ResponseHeaderCollection = http::headers::response::HeaderCollection;
|
use ResponseHeaderCollection = http::headers::response::HeaderCollection;
|
||||||
use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
||||||
|
@ -19,8 +20,6 @@ use url::Url;
|
||||||
use StatusOk = http::status::Ok;
|
use StatusOk = http::status::Ok;
|
||||||
use http::status::Status;
|
use http::status::Status;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
use std::from_str::FromStr;
|
|
||||||
|
|
||||||
pub enum ControlMsg {
|
pub enum ControlMsg {
|
||||||
/// Request the data associated with a particular URL
|
/// Request the data associated with a particular URL
|
||||||
|
@ -164,40 +163,27 @@ each URL scheme
|
||||||
*/
|
*/
|
||||||
type LoaderTaskFactory = extern "Rust" fn() -> LoaderTask;
|
type LoaderTaskFactory = extern "Rust" fn() -> LoaderTask;
|
||||||
|
|
||||||
/// Create a ResourceTask with the default loaders
|
/// Create a ResourceTask
|
||||||
pub fn new_resource_task() -> ResourceTask {
|
pub fn new_resource_task() -> ResourceTask {
|
||||||
let loaders = vec!(
|
|
||||||
("file".to_string(), file_loader::factory),
|
|
||||||
("http".to_string(), http_loader::factory),
|
|
||||||
("data".to_string(), data_loader::factory),
|
|
||||||
);
|
|
||||||
create_resource_task_with_loaders(loaders)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_resource_task_with_loaders(loaders: Vec<(String, LoaderTaskFactory)>) -> ResourceTask {
|
|
||||||
let (setup_chan, setup_port) = channel();
|
let (setup_chan, setup_port) = channel();
|
||||||
let builder = TaskBuilder::new().named("ResourceManager");
|
let builder = TaskBuilder::new().named("ResourceManager");
|
||||||
builder.spawn(proc() {
|
builder.spawn(proc() {
|
||||||
let (chan, port) = channel();
|
let (chan, port) = channel();
|
||||||
setup_chan.send(chan);
|
setup_chan.send(chan);
|
||||||
ResourceManager::new(port, loaders).start();
|
ResourceManager::new(port).start();
|
||||||
});
|
});
|
||||||
setup_port.recv()
|
setup_port.recv()
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ResourceManager {
|
struct ResourceManager {
|
||||||
from_client: Receiver<ControlMsg>,
|
from_client: Receiver<ControlMsg>,
|
||||||
/// Per-scheme resource loaders
|
|
||||||
loaders: Vec<(String, LoaderTaskFactory)>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl ResourceManager {
|
impl ResourceManager {
|
||||||
fn new(from_client: Receiver<ControlMsg>, loaders: Vec<(String, LoaderTaskFactory)>)
|
fn new(from_client: Receiver<ControlMsg>) -> ResourceManager {
|
||||||
-> ResourceManager {
|
|
||||||
ResourceManager {
|
ResourceManager {
|
||||||
from_client : from_client,
|
from_client : from_client,
|
||||||
loaders : loaders,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,30 +203,38 @@ impl ResourceManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(&self, load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
fn load(&self, mut load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
||||||
match self.get_loader_factory(&load_data) {
|
let loader = match load_data.url.scheme.as_slice() {
|
||||||
Some(loader_factory) => {
|
"file" => file_loader::factory(),
|
||||||
debug!("resource_task: loading url: {:s}", load_data.url.to_str());
|
"http" => http_loader::factory(),
|
||||||
loader_factory(load_data, start_chan);
|
"data" => data_loader::factory(),
|
||||||
}
|
"about" => {
|
||||||
None => {
|
match load_data.url.non_relative_scheme_data().unwrap() {
|
||||||
debug!("resource_task: no loader for scheme {:s}", load_data.url.scheme);
|
"crash" => fail!("Loading the about:crash URL."),
|
||||||
start_sending(start_chan, Metadata::default(load_data.url)).send(Done(Err("no loader for scheme".to_string())));
|
"failure" => {
|
||||||
}
|
// FIXME: Find a way to load this without relying on the `../src` directory.
|
||||||
}
|
let mut path = os::self_exe_path().expect("can't get exe path");
|
||||||
}
|
path.pop();
|
||||||
|
path.push_many(["src", "test", "html", "failure.html"]);
|
||||||
fn get_loader_factory(&self, load_data: &LoadData) -> Option<LoaderTask> {
|
load_data.url = Url::from_file_path(&path).unwrap();
|
||||||
for scheme_loader in self.loaders.iter() {
|
file_loader::factory()
|
||||||
match *scheme_loader {
|
}
|
||||||
(ref scheme, ref loader_factory) => {
|
_ => {
|
||||||
if (*scheme) == load_data.url.scheme {
|
start_sending(start_chan, Metadata::default(load_data.url))
|
||||||
return Some((*loader_factory)());
|
.send(Done(Err("Unknown about: URL.".to_string())));
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
debug!("resource_task: no loader for scheme {:s}", load_data.url.scheme);
|
||||||
|
start_sending(start_chan, Metadata::default(load_data.url))
|
||||||
|
.send(Done(Err("no loader for scheme".to_string())));
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
return None;
|
debug!("resource_task: loading url: {:s}", load_data.url.serialize());
|
||||||
|
loader(load_data, start_chan);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +248,8 @@ fn test_exit() {
|
||||||
fn test_bad_scheme() {
|
fn test_bad_scheme() {
|
||||||
let resource_task = new_resource_task();
|
let resource_task = new_resource_task();
|
||||||
let (start_chan, start) = channel();
|
let (start_chan, start) = channel();
|
||||||
resource_task.send(Load(LoadData::new(FromStr::from_str("bogus://whatever").unwrap()), start_chan));
|
let url = Url::parse("bogus://whatever").unwrap();
|
||||||
|
resource_task.send(Load(LoadData::new(url), start_chan));
|
||||||
let response = start.recv();
|
let response = start.recv();
|
||||||
match response.progress_port.recv() {
|
match response.progress_port.recv() {
|
||||||
Done(result) => { assert!(result.is_err()) }
|
Done(result) => { assert!(result.is_err()) }
|
||||||
|
@ -262,31 +257,3 @@ fn test_bad_scheme() {
|
||||||
}
|
}
|
||||||
resource_task.send(Exit);
|
resource_task.send(Exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
static snicklefritz_payload: [u8, ..3] = [1, 2, 3];
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
fn snicklefritz_loader_factory() -> LoaderTask {
|
|
||||||
let f: LoaderTask = proc(load_data: LoadData, start_chan: Sender<LoadResponse>) {
|
|
||||||
let progress_chan = start_sending(start_chan, Metadata::default(load_data.url));
|
|
||||||
progress_chan.send(Payload(Vec::from_slice(snicklefritz_payload)));
|
|
||||||
progress_chan.send(Done(Ok(())));
|
|
||||||
};
|
|
||||||
f
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_delegate_to_scheme_loader() {
|
|
||||||
let loader_factories = vec!(("snicklefritz".to_string(), snicklefritz_loader_factory));
|
|
||||||
let resource_task = create_resource_task_with_loaders(loader_factories);
|
|
||||||
let (start_chan, start) = channel();
|
|
||||||
resource_task.send(Load(LoadData::new(FromStr::from_str("snicklefritz://heya").unwrap()), start_chan));
|
|
||||||
|
|
||||||
let response = start.recv();
|
|
||||||
let progress = response.progress_port;
|
|
||||||
|
|
||||||
assert!(progress.recv() == Payload(Vec::from_slice(snicklefritz_payload)));
|
|
||||||
assert!(progress.recv() == Done(Ok(())));
|
|
||||||
resource_task.send(Exit);
|
|
||||||
}
|
|
||||||
|
|
|
@ -67,14 +67,15 @@ impl DedicatedWorkerGlobalScope {
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
script_chan: ScriptChan) {
|
script_chan: ScriptChan) {
|
||||||
let mut task_opts = TaskOpts::new();
|
let mut task_opts = TaskOpts::new();
|
||||||
task_opts.name = Some(format!("Web Worker at {}", worker_url).into_maybe_owned());
|
task_opts.name = Some(format!("Web Worker at {}", worker_url.serialize())
|
||||||
|
.into_maybe_owned());
|
||||||
native::task::spawn_opts(task_opts, proc() {
|
native::task::spawn_opts(task_opts, proc() {
|
||||||
let roots = RootCollection::new();
|
let roots = RootCollection::new();
|
||||||
let _stack_roots_tls = StackRootTLS::new(&roots);
|
let _stack_roots_tls = StackRootTLS::new(&roots);
|
||||||
|
|
||||||
let (filename, source) = match load_whole_resource(&resource_task, worker_url.clone()) {
|
let (url, source) = match load_whole_resource(&resource_task, worker_url.clone()) {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("error loading script {}", worker_url);
|
println!("error loading script {}", worker_url.serialize());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Ok((metadata, bytes)) => {
|
Ok((metadata, bytes)) => {
|
||||||
|
@ -87,7 +88,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
worker_url, js_context.clone(), receiver, resource_task,
|
worker_url, js_context.clone(), receiver, resource_task,
|
||||||
script_chan).root();
|
script_chan).root();
|
||||||
match js_context.evaluate_script(
|
match js_context.evaluate_script(
|
||||||
global.reflector().get_jsobject(), source, filename.to_str(), 1) {
|
global.reflector().get_jsobject(), source, url.serialize(), 1) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => println!("evaluate_script failed")
|
Err(_) => println!("evaluate_script failed")
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ use servo_util::str::{DOMString, null_str_as_empty_ref};
|
||||||
use std::collections::hashmap::HashMap;
|
use std::collections::hashmap::HashMap;
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use url::{Url, from_str};
|
use url::Url;
|
||||||
|
|
||||||
#[deriving(PartialEq,Encodable)]
|
#[deriving(PartialEq,Encodable)]
|
||||||
pub enum IsHTMLDocument {
|
pub enum IsHTMLDocument {
|
||||||
|
@ -196,7 +196,7 @@ impl Document {
|
||||||
url: Option<Url>,
|
url: Option<Url>,
|
||||||
is_html_document: IsHTMLDocument,
|
is_html_document: IsHTMLDocument,
|
||||||
content_type: Option<DOMString>) -> Document {
|
content_type: Option<DOMString>) -> Document {
|
||||||
let url = url.unwrap_or_else(|| from_str("about:blank").unwrap());
|
let url = url.unwrap_or_else(|| Url::parse("about:blank").unwrap());
|
||||||
|
|
||||||
Document {
|
Document {
|
||||||
node: Node::new_without_doc(DocumentNodeTypeId),
|
node: Node::new_without_doc(DocumentNodeTypeId),
|
||||||
|
@ -337,7 +337,7 @@ impl<'a> DocumentMethods for JSRef<'a, Document> {
|
||||||
|
|
||||||
// http://dom.spec.whatwg.org/#dom-document-url
|
// http://dom.spec.whatwg.org/#dom-document-url
|
||||||
fn URL(&self) -> DOMString {
|
fn URL(&self) -> DOMString {
|
||||||
self.url().to_str()
|
self.url().serialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
// http://dom.spec.whatwg.org/#dom-document-documenturi
|
// http://dom.spec.whatwg.org/#dom-document-documenturi
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
|
||||||
scope: *mut JSObject,
|
scope: *mut JSObject,
|
||||||
ty: &str,
|
ty: &str,
|
||||||
source: DOMString) {
|
source: DOMString) {
|
||||||
let url = url.to_str().to_c_str();
|
let url = url.serialize().to_c_str();
|
||||||
let name = ty.to_c_str();
|
let name = ty.to_c_str();
|
||||||
let lineno = 0; //XXXjdm need to get a real number here
|
let lineno = 0; //XXXjdm need to get a real number here
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,10 @@ use servo_msg::constellation_msg::{IFrameSandboxed, IFrameUnsandboxed};
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, LoadIframeUrlMsg};
|
use servo_msg::constellation_msg::{ConstellationChan, LoadIframeUrlMsg};
|
||||||
use servo_util::namespace::Null;
|
use servo_util::namespace::Null;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use servo_util::url::try_parse_url;
|
|
||||||
|
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use url::Url;
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
enum SandboxAllowance {
|
enum SandboxAllowance {
|
||||||
AllowNothing = 0x00,
|
AllowNothing = 0x00,
|
||||||
|
@ -70,8 +69,8 @@ impl<'a> HTMLIFrameElementHelpers for JSRef<'a, HTMLIFrameElement> {
|
||||||
let element: &JSRef<Element> = ElementCast::from_ref(self);
|
let element: &JSRef<Element> = ElementCast::from_ref(self);
|
||||||
element.get_attribute(Null, "src").root().and_then(|src| {
|
element.get_attribute(Null, "src").root().and_then(|src| {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self).root();
|
||||||
try_parse_url(src.deref().value().as_slice(),
|
UrlParser::new().base_url(&window.deref().page().get_url())
|
||||||
Some(window.deref().page().get_url())).ok()
|
.parse(src.deref().value().as_slice()).ok()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,9 @@ use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node};
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
use servo_util::geometry::to_px;
|
use servo_util::geometry::to_px;
|
||||||
use servo_net::image_cache_task;
|
use servo_net::image_cache_task;
|
||||||
use servo_util::url::parse_url;
|
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use url::Url;
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct HTMLImageElement {
|
pub struct HTMLImageElement {
|
||||||
|
@ -35,13 +34,13 @@ impl HTMLImageElementDerived for EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait PrivateHTMLImageElementHelpers {
|
trait PrivateHTMLImageElementHelpers {
|
||||||
fn update_image(&self, value: Option<DOMString>, url: Option<Url>);
|
fn update_image(&self, value: Option<(DOMString, &Url)>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> {
|
impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> {
|
||||||
/// Makes the local `image` member match the status of the `src` attribute and starts
|
/// 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.
|
/// prefetching the image. This method must be called after `src` is changed.
|
||||||
fn update_image(&self, value: Option<DOMString>, url: Option<Url>) {
|
fn update_image(&self, value: Option<(DOMString, &Url)>) {
|
||||||
let node: &JSRef<Node> = NodeCast::from_ref(self);
|
let node: &JSRef<Node> = NodeCast::from_ref(self);
|
||||||
let document = node.owner_doc().root();
|
let document = node.owner_doc().root();
|
||||||
let window = document.deref().window.root();
|
let window = document.deref().window.root();
|
||||||
|
@ -50,8 +49,10 @@ impl<'a> PrivateHTMLImageElementHelpers for JSRef<'a, HTMLImageElement> {
|
||||||
None => {
|
None => {
|
||||||
*self.image.deref().borrow_mut() = None;
|
*self.image.deref().borrow_mut() = None;
|
||||||
}
|
}
|
||||||
Some(src) => {
|
Some((src, base_url)) => {
|
||||||
let img_url = parse_url(src.as_slice(), url);
|
let img_url = UrlParser::new().base_url(base_url).parse(src.as_slice());
|
||||||
|
// FIXME: handle URL parse errors more gracefully.
|
||||||
|
let img_url = img_url.unwrap();
|
||||||
*self.image.deref().borrow_mut() = Some(img_url.clone());
|
*self.image.deref().borrow_mut() = Some(img_url.clone());
|
||||||
|
|
||||||
// inform the image cache to load this, but don't store a
|
// inform the image cache to load this, but don't store a
|
||||||
|
@ -254,8 +255,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
|
||||||
|
|
||||||
if "src" == name.as_slice() {
|
if "src" == name.as_slice() {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self).root();
|
||||||
let url = Some(window.deref().get_url());
|
let url = window.deref().get_url();
|
||||||
self.update_image(Some(value), url);
|
self.update_image(Some((value, &url)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +267,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLImageElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if "src" == name.as_slice() {
|
if "src" == name.as_slice() {
|
||||||
self.update_image(None, None);
|
self.update_image(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,7 @@ use servo_util::str::DOMString;
|
||||||
|
|
||||||
use servo_net::image_cache_task;
|
use servo_net::image_cache_task;
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_util::url::parse_url;
|
|
||||||
use servo_util::namespace::Null;
|
use servo_util::namespace::Null;
|
||||||
use servo_util::url::is_image_data;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
|
@ -50,13 +48,13 @@ impl HTMLObjectElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ProcessDataURL {
|
trait ProcessDataURL {
|
||||||
fn process_data_url(&self, image_cache: ImageCacheTask, url: Option<Url>);
|
fn process_data_url(&self, image_cache: ImageCacheTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
|
impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
|
||||||
// Makes the local `data` member match the status of the `data` attribute and starts
|
// Makes the local `data` member match the status of the `data` attribute and starts
|
||||||
/// prefetching the image. This method must be called after `data` is changed.
|
/// prefetching the image. This method must be called after `data` is changed.
|
||||||
fn process_data_url(&self, image_cache: ImageCacheTask, url: Option<Url>) {
|
fn process_data_url(&self, image_cache: ImageCacheTask) {
|
||||||
let elem: &JSRef<Element> = ElementCast::from_ref(self);
|
let elem: &JSRef<Element> = ElementCast::from_ref(self);
|
||||||
|
|
||||||
// TODO: support other values
|
// TODO: support other values
|
||||||
|
@ -64,7 +62,7 @@ impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
|
||||||
elem.get_attribute(Null, "data").map(|x| x.root().Value())) {
|
elem.get_attribute(Null, "data").map(|x| x.root().Value())) {
|
||||||
(None, Some(uri)) => {
|
(None, Some(uri)) => {
|
||||||
if is_image_data(uri.as_slice()) {
|
if is_image_data(uri.as_slice()) {
|
||||||
let data_url = parse_url(uri.as_slice(), url);
|
let data_url = Url::parse(uri.as_slice()).unwrap();
|
||||||
// Issue #84
|
// Issue #84
|
||||||
image_cache.send(image_cache_task::Prefetch(data_url));
|
image_cache.send(image_cache_task::Prefetch(data_url));
|
||||||
}
|
}
|
||||||
|
@ -74,6 +72,11 @@ impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_image_data(uri: &str) -> bool {
|
||||||
|
static types: &'static [&'static str] = &["data:image/png", "data:image/gif", "data:image/jpeg"];
|
||||||
|
types.iter().any(|&type_| uri.starts_with(type_))
|
||||||
|
}
|
||||||
|
|
||||||
pub trait HTMLObjectElementMethods {
|
pub trait HTMLObjectElementMethods {
|
||||||
fn Validity(&self) -> Temporary<ValidityState>;
|
fn Validity(&self) -> Temporary<ValidityState>;
|
||||||
}
|
}
|
||||||
|
@ -99,8 +102,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> {
|
||||||
|
|
||||||
if "data" == name.as_slice() {
|
if "data" == name.as_slice() {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self).root();
|
||||||
let url = Some(window.deref().get_url());
|
self.process_data_url(window.deref().image_cache_task.clone());
|
||||||
self.process_data_url(window.deref().image_cache_task.clone(), url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ use servo_util::str::DOMString;
|
||||||
|
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use url::query_to_str;
|
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct Location {
|
pub struct Location {
|
||||||
|
@ -43,15 +42,13 @@ pub trait LocationMethods {
|
||||||
|
|
||||||
impl<'a> LocationMethods for JSRef<'a, Location> {
|
impl<'a> LocationMethods for JSRef<'a, Location> {
|
||||||
fn Href(&self) -> DOMString {
|
fn Href(&self) -> DOMString {
|
||||||
self.page.get_url().to_str()
|
self.page.get_url().serialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn Search(&self) -> DOMString {
|
fn Search(&self) -> DOMString {
|
||||||
let query = query_to_str(&self.page.get_url().query);
|
match self.page.get_url().query {
|
||||||
if query.as_slice() == "" {
|
None => "".to_string(),
|
||||||
query
|
Some(ref query) => "?".to_string().append(query.as_slice())
|
||||||
} else {
|
|
||||||
"?".to_string().append(query.as_slice())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,6 @@ use servo_msg::compositor_msg::ScriptListener;
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use servo_util::task::{spawn_named};
|
use servo_util::task::{spawn_named};
|
||||||
use servo_util::url::parse_url;
|
|
||||||
|
|
||||||
use js::jsapi::JS_CallFunctionValue;
|
use js::jsapi::JS_CallFunctionValue;
|
||||||
use js::jsapi::JSContext;
|
use js::jsapi::JSContext;
|
||||||
|
@ -46,7 +45,7 @@ use std::rc::Rc;
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
use url::Url;
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
#[deriving(PartialEq, Encodable, Eq)]
|
#[deriving(PartialEq, Encodable, Eq)]
|
||||||
pub struct TimerId(i32);
|
pub struct TimerId(i32);
|
||||||
|
@ -316,9 +315,11 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
|
||||||
|
|
||||||
/// Commence a new URL load which will either replace this window or scroll to a fragment.
|
/// Commence a new URL load which will either replace this window or scroll to a fragment.
|
||||||
fn load_url(&self, href: DOMString) {
|
fn load_url(&self, href: DOMString) {
|
||||||
let base_url = Some(self.page().get_url());
|
let base_url = self.page().get_url();
|
||||||
debug!("current page url is {:?}", base_url);
|
debug!("current page url is {:?}", base_url);
|
||||||
let url = parse_url(href.as_slice(), base_url);
|
let url = UrlParser::new().base_url(&base_url).parse(href.as_slice());
|
||||||
|
// FIXME: handle URL parse errors more gracefully.
|
||||||
|
let url = url.unwrap();
|
||||||
let ScriptChan(ref script_chan) = self.script_chan;
|
let ScriptChan(ref script_chan) = self.script_chan;
|
||||||
if href.as_slice().starts_with("#") {
|
if href.as_slice().starts_with("#") {
|
||||||
script_chan.send(TriggerFragmentMsg(self.page.id, url));
|
script_chan.send(TriggerFragmentMsg(self.page.id, url));
|
||||||
|
|
|
@ -12,7 +12,7 @@ use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope;
|
||||||
use dom::eventtarget::{EventTarget, WorkerTypeId};
|
use dom::eventtarget::{EventTarget, WorkerTypeId};
|
||||||
|
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use servo_util::url::try_parse_url;
|
use url::UrlParser;
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct Worker {
|
pub struct Worker {
|
||||||
|
@ -37,7 +37,8 @@ impl Worker {
|
||||||
// http://www.whatwg.org/html/#dom-worker
|
// http://www.whatwg.org/html/#dom-worker
|
||||||
pub fn Constructor(global: &GlobalRef, scriptURL: DOMString) -> Fallible<Temporary<Worker>> {
|
pub fn Constructor(global: &GlobalRef, scriptURL: DOMString) -> Fallible<Temporary<Worker>> {
|
||||||
// Step 2-4.
|
// Step 2-4.
|
||||||
let worker_url = match try_parse_url(scriptURL.as_slice(), Some(global.get_url())) {
|
let worker_url = match UrlParser::new().base_url(&global.get_url())
|
||||||
|
.parse(scriptURL.as_slice()) {
|
||||||
Ok(url) => url,
|
Ok(url) => url,
|
||||||
Err(_) => return Err(Syntax),
|
Err(_) => return Err(Syntax),
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ use dom::xmlhttprequestupload::XMLHttpRequestUpload;
|
||||||
|
|
||||||
use encoding::all::UTF_8;
|
use encoding::all::UTF_8;
|
||||||
use encoding::label::encoding_from_whatwg_label;
|
use encoding::label::encoding_from_whatwg_label;
|
||||||
use encoding::types::{DecodeReplace, Encoding, EncodeReplace};
|
use encoding::types::{DecodeReplace, Encoding, EncodingRef, EncodeReplace};
|
||||||
|
|
||||||
use ResponseHeaderCollection = http::headers::response::HeaderCollection;
|
use ResponseHeaderCollection = http::headers::response::HeaderCollection;
|
||||||
use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
use RequestHeaderCollection = http::headers::request::HeaderCollection;
|
||||||
|
@ -46,7 +46,6 @@ use net::resource_task::{ResourceTask, Load, LoadData, Payload, Done};
|
||||||
use script_task::{ScriptChan, XHRProgressMsg};
|
use script_task::{ScriptChan, XHRProgressMsg};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::spawn_named;
|
||||||
use servo_util::url::{parse_url, try_parse_url};
|
|
||||||
|
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
|
@ -56,7 +55,7 @@ use std::from_str::FromStr;
|
||||||
use std::path::BytesContainer;
|
use std::path::BytesContainer;
|
||||||
use std::task::TaskBuilder;
|
use std::task::TaskBuilder;
|
||||||
use time;
|
use time;
|
||||||
use url::Url;
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eString, eURLSearchParams, StringOrURLSearchParams};
|
use dom::bindings::codegen::UnionTypes::StringOrURLSearchParams::{eString, eURLSearchParams, StringOrURLSearchParams};
|
||||||
pub type SendParam = StringOrURLSearchParams;
|
pub type SendParam = StringOrURLSearchParams;
|
||||||
|
@ -113,7 +112,7 @@ pub struct XMLHttpRequest {
|
||||||
|
|
||||||
// Associated concepts
|
// Associated concepts
|
||||||
request_method: Untraceable<RefCell<Method>>,
|
request_method: Untraceable<RefCell<Method>>,
|
||||||
request_url: Untraceable<RefCell<Url>>,
|
request_url: Untraceable<RefCell<Option<Url>>>,
|
||||||
request_headers: Untraceable<RefCell<RequestHeaderCollection>>,
|
request_headers: Untraceable<RefCell<RequestHeaderCollection>>,
|
||||||
request_body_len: Traceable<Cell<uint>>,
|
request_body_len: Traceable<Cell<uint>>,
|
||||||
sync: Traceable<Cell<bool>>,
|
sync: Traceable<Cell<bool>>,
|
||||||
|
@ -146,7 +145,7 @@ impl XMLHttpRequest {
|
||||||
response_headers: Untraceable::new(RefCell::new(ResponseHeaderCollection::new())),
|
response_headers: Untraceable::new(RefCell::new(ResponseHeaderCollection::new())),
|
||||||
|
|
||||||
request_method: Untraceable::new(RefCell::new(Get)),
|
request_method: Untraceable::new(RefCell::new(Get)),
|
||||||
request_url: Untraceable::new(RefCell::new(parse_url("", None))),
|
request_url: Untraceable::new(RefCell::new(None)),
|
||||||
request_headers: Untraceable::new(RefCell::new(RequestHeaderCollection::new())),
|
request_headers: Untraceable::new(RefCell::new(RequestHeaderCollection::new())),
|
||||||
request_body_len: Traceable::new(Cell::new(0)),
|
request_body_len: Traceable::new(Cell::new(0)),
|
||||||
sync: Traceable::new(Cell::new(false)),
|
sync: Traceable::new(Cell::new(false)),
|
||||||
|
@ -293,7 +292,6 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
Method::from_str_or_new(s.as_slice())
|
Method::from_str_or_new(s.as_slice())
|
||||||
});
|
});
|
||||||
// Step 2
|
// Step 2
|
||||||
let base: Option<Url> = Some(self.global.root().root_ref().get_url());
|
|
||||||
match maybe_method {
|
match maybe_method {
|
||||||
// Step 4
|
// Step 4
|
||||||
Some(Connect) | Some(Trace) => Err(Security),
|
Some(Connect) | Some(Trace) => Err(Security),
|
||||||
|
@ -303,7 +301,8 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
*self.request_method.deref().borrow_mut() = maybe_method.unwrap();
|
*self.request_method.deref().borrow_mut() = maybe_method.unwrap();
|
||||||
|
|
||||||
// Step 6
|
// Step 6
|
||||||
let parsed_url = match try_parse_url(url.as_slice(), base) {
|
let base = self.global.root().root_ref().get_url();
|
||||||
|
let parsed_url = match UrlParser::new().base_url(&base).parse(url.as_slice()) {
|
||||||
Ok(parsed) => parsed,
|
Ok(parsed) => parsed,
|
||||||
Err(_) => return Err(Syntax) // Step 7
|
Err(_) => return Err(Syntax) // Step 7
|
||||||
};
|
};
|
||||||
|
@ -316,7 +315,7 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
}
|
}
|
||||||
// XXXManishearth abort existing requests
|
// XXXManishearth abort existing requests
|
||||||
// Step 12
|
// Step 12
|
||||||
*self.request_url.deref().borrow_mut() = parsed_url;
|
*self.request_url.deref().borrow_mut() = Some(parsed_url);
|
||||||
*self.request_headers.deref().borrow_mut() = RequestHeaderCollection::new();
|
*self.request_headers.deref().borrow_mut() = RequestHeaderCollection::new();
|
||||||
self.send_flag.deref().set(false);
|
self.send_flag.deref().set(false);
|
||||||
*self.status_text.deref().borrow_mut() = ByteString::new(vec!());
|
*self.status_text.deref().borrow_mut() = ByteString::new(vec!());
|
||||||
|
@ -487,7 +486,7 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
|
|
||||||
let global = self.global.root();
|
let global = self.global.root();
|
||||||
let resource_task = global.root_ref().resource_task();
|
let resource_task = global.root_ref().resource_task();
|
||||||
let mut load_data = LoadData::new(self.request_url.deref().borrow().clone());
|
let mut load_data = LoadData::new(self.request_url.deref().borrow().clone().unwrap());
|
||||||
load_data.data = extracted;
|
load_data.data = extracted;
|
||||||
|
|
||||||
// Default headers
|
// Default headers
|
||||||
|
@ -517,16 +516,8 @@ impl<'a> XMLHttpRequestMethods<'a> for JSRef<'a, XMLHttpRequest> {
|
||||||
|
|
||||||
// XXXManishearth this is to be replaced with Origin for CORS (with no path)
|
// XXXManishearth this is to be replaced with Origin for CORS (with no path)
|
||||||
let referer_url = self.global.root().root_ref().get_url();
|
let referer_url = self.global.root().root_ref().get_url();
|
||||||
let mut buf = String::new();
|
self.request_headers.deref().borrow_mut().referer =
|
||||||
buf.push_str(referer_url.scheme.as_slice());
|
Some(referer_url.serialize_no_fragment());
|
||||||
buf.push_str("://".as_slice());
|
|
||||||
buf.push_str(referer_url.host.as_slice());
|
|
||||||
referer_url.port.as_ref().map(|p| {
|
|
||||||
buf.push_str(":".as_slice());
|
|
||||||
buf.push_str(p.as_slice());
|
|
||||||
});
|
|
||||||
buf.push_str(referer_url.path.as_slice());
|
|
||||||
self.request_headers.deref().borrow_mut().referer = Some(buf);
|
|
||||||
|
|
||||||
load_data.headers = (*self.request_headers.deref().borrow()).clone();
|
load_data.headers = (*self.request_headers.deref().borrow()).clone();
|
||||||
load_data.method = (*self.request_method.deref().borrow()).clone();
|
load_data.method = (*self.request_method.deref().borrow()).clone();
|
||||||
|
@ -910,7 +901,7 @@ impl<'a> PrivateXMLHttpRequestHelpers for JSRef<'a, XMLHttpRequest> {
|
||||||
self.timer.deref().borrow_mut().oneshot(0);
|
self.timer.deref().borrow_mut().oneshot(0);
|
||||||
}
|
}
|
||||||
fn text_response(&self) -> DOMString {
|
fn text_response(&self) -> DOMString {
|
||||||
let mut encoding = UTF_8 as &Encoding+Send;
|
let mut encoding = UTF_8 as EncodingRef;
|
||||||
match self.response_headers.deref().borrow().content_type {
|
match self.response_headers.deref().borrow().content_type {
|
||||||
Some(ref x) => {
|
Some(ref x) => {
|
||||||
for &(ref name, ref value) in x.parameters.iter() {
|
for &(ref name, ref value) in x.parameters.iter() {
|
||||||
|
@ -945,7 +936,7 @@ trait Extractable {
|
||||||
impl Extractable for SendParam {
|
impl Extractable for SendParam {
|
||||||
fn extract(&self) -> Vec<u8> {
|
fn extract(&self) -> Vec<u8> {
|
||||||
// http://fetch.spec.whatwg.org/#concept-fetchbodyinit-extract
|
// http://fetch.spec.whatwg.org/#concept-fetchbodyinit-extract
|
||||||
let encoding = UTF_8 as &Encoding+Send;
|
let encoding = UTF_8 as EncodingRef;
|
||||||
match *self {
|
match *self {
|
||||||
eString(ref s) => encoding.encode(s.as_slice(), EncodeReplace).unwrap(),
|
eString(ref s) => encoding.encode(s.as_slice(), EncodeReplace).unwrap(),
|
||||||
eURLSearchParams(ref usp) => usp.root().serialize(None) // Default encoding is UTF8
|
eURLSearchParams(ref usp) => usp.root().serialize(None) // Default encoding is UTF8
|
||||||
|
|
|
@ -29,7 +29,7 @@ fn parse_css(provenance: StylesheetProvenance) -> Stylesheet {
|
||||||
|
|
||||||
match provenance {
|
match provenance {
|
||||||
UrlProvenance(url, resource_task) => {
|
UrlProvenance(url, resource_task) => {
|
||||||
debug!("cssparse: loading style sheet at {:s}", url.to_str());
|
debug!("cssparse: loading style sheet at {:s}", url.serialize());
|
||||||
let (input_chan, input_port) = channel();
|
let (input_chan, input_port) = channel();
|
||||||
resource_task.send(Load(LoadData::new(url), input_chan));
|
resource_task.send(Load(LoadData::new(url), input_chan));
|
||||||
let LoadResponse { metadata: metadata, progress_port: progress_port , ..}
|
let LoadResponse { metadata: metadata, progress_port: progress_port , ..}
|
||||||
|
|
|
@ -23,13 +23,12 @@ use servo_util::namespace;
|
||||||
use servo_util::namespace::{Namespace, Null};
|
use servo_util::namespace::{Namespace, Null};
|
||||||
use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS};
|
use servo_util::str::{DOMString, HTML_SPACE_CHARACTERS};
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::spawn_named;
|
||||||
use servo_util::url::try_parse_url;
|
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::comm::{channel, Sender, Receiver};
|
use std::comm::{channel, Sender, Receiver};
|
||||||
use style::Stylesheet;
|
use style::Stylesheet;
|
||||||
use url::Url;
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
macro_rules! handle_element(
|
macro_rules! handle_element(
|
||||||
($document: expr,
|
($document: expr,
|
||||||
|
@ -133,7 +132,7 @@ fn js_script_listener(to_parent: Sender<HtmlDiscoveryMessage>,
|
||||||
Ok(JSTaskNewFile(url)) => {
|
Ok(JSTaskNewFile(url)) => {
|
||||||
match load_whole_resource(&resource_task, url.clone()) {
|
match load_whole_resource(&resource_task, url.clone()) {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
error!("error loading script {:s}", url.to_str());
|
error!("error loading script {:s}", url.serialize());
|
||||||
}
|
}
|
||||||
Ok((metadata, bytes)) => {
|
Ok((metadata, bytes)) => {
|
||||||
result_vec.push(JSFile {
|
result_vec.push(JSFile {
|
||||||
|
@ -421,8 +420,9 @@ pub fn parse_html(page: &Page,
|
||||||
s.as_slice().eq_ignore_ascii_case("stylesheet")
|
s.as_slice().eq_ignore_ascii_case("stylesheet")
|
||||||
}) => {
|
}) => {
|
||||||
debug!("found CSS stylesheet: {:s}", *href);
|
debug!("found CSS stylesheet: {:s}", *href);
|
||||||
match try_parse_url(href.as_slice(), Some(url2.clone())) {
|
match UrlParser::new().base_url(&url2).parse(href.as_slice()) {
|
||||||
Ok(url) => css_chan2.send(CSSTaskNewFile(UrlProvenance(url, resource_task.clone()))),
|
Ok(url) => css_chan2.send(CSSTaskNewFile(
|
||||||
|
UrlProvenance(url, resource_task.clone()))),
|
||||||
Err(e) => debug!("Parsing url {:s} failed: {:s}", *href, e)
|
Err(e) => debug!("Parsing url {:s} failed: {:s}", *href, e)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -504,9 +504,10 @@ pub fn parse_html(page: &Page,
|
||||||
match script.get_attribute(Null, "src").root() {
|
match script.get_attribute(Null, "src").root() {
|
||||||
Some(src) => {
|
Some(src) => {
|
||||||
debug!("found script: {:s}", src.deref().Value());
|
debug!("found script: {:s}", src.deref().Value());
|
||||||
match try_parse_url(src.deref().value().as_slice(), Some(url3.clone())) {
|
match UrlParser::new().base_url(&url3)
|
||||||
Ok(new_url) => js_chan2.send(JSTaskNewFile(new_url)),
|
.parse(src.deref().value().as_slice()) {
|
||||||
Err(e) => debug!("Parsing url {:s} failed: {:s}", src.deref().Value(), e)
|
Ok(new_url) => js_chan2.send(JSTaskNewFile(new_url)),
|
||||||
|
Err(e) => debug!("Parsing url {:s} failed: {:s}", src.deref().Value(), e)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -541,7 +542,7 @@ pub fn parse_html(page: &Page,
|
||||||
parser.parse_chunk(data.as_slice());
|
parser.parse_chunk(data.as_slice());
|
||||||
}
|
}
|
||||||
Done(Err(err)) => {
|
Done(Err(err)) => {
|
||||||
fail!("Failed to load page URL {:s}, error: {:s}", url.to_str(), err);
|
fail!("Failed to load page URL {:s}, error: {:s}", url.serialize(), err);
|
||||||
}
|
}
|
||||||
Done(..) => {
|
Done(..) => {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -40,7 +40,7 @@ extern crate servo_util = "util";
|
||||||
extern crate style;
|
extern crate style;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
extern crate servo_msg = "msg";
|
extern crate servo_msg = "msg";
|
||||||
extern crate url;
|
extern crate url = "url_";
|
||||||
|
|
||||||
pub mod dom {
|
pub mod dom {
|
||||||
pub mod bindings {
|
pub mod bindings {
|
||||||
|
|
|
@ -590,7 +590,7 @@ impl ScriptTask {
|
||||||
let global_obj = window.reflector().get_jsobject();
|
let global_obj = window.reflector().get_jsobject();
|
||||||
//FIXME: this should have some kind of error handling, or explicitly
|
//FIXME: this should have some kind of error handling, or explicitly
|
||||||
// drop an exception on the floor.
|
// drop an exception on the floor.
|
||||||
match cx.evaluate_script(global_obj, file.data.clone(), file.url.to_str(), 1) {
|
match cx.evaluate_script(global_obj, file.data.clone(), file.url.serialize(), 1) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => println!("evaluate_script failed")
|
Err(_) => println!("evaluate_script failed")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
pub use servo_util::geometry::Au;
|
pub use servo_util::geometry::Au;
|
||||||
|
|
||||||
pub type CSSFloat = f64;
|
pub type CSSFloat = f64;
|
||||||
|
@ -253,3 +255,8 @@ pub mod computed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_url(input: &str, base_url: &Url) -> Url {
|
||||||
|
UrlParser::new().base_url(base_url).parse(input)
|
||||||
|
.unwrap_or_else(|_| Url::parse("about:invalid").unwrap())
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
pub use std::ascii::StrAsciiExt;
|
pub use std::ascii::StrAsciiExt;
|
||||||
use serialize::{Encodable, Encoder};
|
use serialize::{Encodable, Encoder};
|
||||||
|
|
||||||
pub use servo_util::url::parse_url;
|
|
||||||
use servo_util::logical_geometry::{WritingMode, LogicalMargin};
|
use servo_util::logical_geometry::{WritingMode, LogicalMargin};
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
pub use url::Url;
|
pub use url::Url;
|
||||||
|
@ -597,7 +596,7 @@ pub mod longhands {
|
||||||
pub fn from_component_value(component_value: &ComponentValue, base_url: &Url) -> Option<SpecifiedValue> {
|
pub fn from_component_value(component_value: &ComponentValue, base_url: &Url) -> Option<SpecifiedValue> {
|
||||||
match component_value {
|
match component_value {
|
||||||
&ast::URL(ref url) => {
|
&ast::URL(ref url) => {
|
||||||
let image_url = parse_url(url.as_slice(), Some(base_url.clone()));
|
let image_url = parse_url(url.as_slice(), base_url);
|
||||||
Some(Some(image_url))
|
Some(Some(image_url))
|
||||||
},
|
},
|
||||||
&ast::Ident(ref value) if value.as_slice().eq_ignore_ascii_case("none") => Some(None),
|
&ast::Ident(ref value) if value.as_slice().eq_ignore_ascii_case("none") => Some(None),
|
||||||
|
|
|
@ -21,7 +21,7 @@ extern crate geom;
|
||||||
extern crate num;
|
extern crate num;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
extern crate url;
|
extern crate url = "url_";
|
||||||
|
|
||||||
extern crate cssparser;
|
extern crate cssparser;
|
||||||
extern crate encoding;
|
extern crate encoding;
|
||||||
|
|
|
@ -1,210 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
use std::collections::hashmap::HashMap;
|
|
||||||
use std::os;
|
|
||||||
use std_url;
|
|
||||||
use std_url::Url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a URL object from a string. Does various helpful browsery things like
|
|
||||||
|
|
||||||
* If there's no current url and the path looks like a file then it will
|
|
||||||
create a file url based of the current working directory
|
|
||||||
* If there's a current url and the new path is relative then the new url
|
|
||||||
is based off the current url
|
|
||||||
|
|
||||||
*/
|
|
||||||
// TODO: about:failure->
|
|
||||||
pub fn try_parse_url(str_url: &str, base_url: Option<std_url::Url>) -> Result<std_url::Url, String> {
|
|
||||||
let str_url = str_url.trim_chars(&[' ', '\t', '\n', '\r', '\x0C']).to_string();
|
|
||||||
let schm = std_url::get_scheme(str_url.as_slice());
|
|
||||||
let str_url = match schm {
|
|
||||||
Err(_) => {
|
|
||||||
if base_url.is_none() {
|
|
||||||
// Assume we've been given a file path. If it's absolute just return
|
|
||||||
// it, otherwise make it absolute with the cwd.
|
|
||||||
if str_url.as_slice().starts_with("/") {
|
|
||||||
format!("file://{}", str_url)
|
|
||||||
} else {
|
|
||||||
let mut path = os::getcwd();
|
|
||||||
path.push(str_url);
|
|
||||||
// FIXME (#1094): not the right way to transform a path
|
|
||||||
format!("file://{}", path.display().to_str())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let base_url = base_url.unwrap();
|
|
||||||
debug!("parse_url: base_url: {:?}", base_url);
|
|
||||||
|
|
||||||
let mut new_url = base_url.clone();
|
|
||||||
new_url.query = vec!();
|
|
||||||
new_url.fragment = None;
|
|
||||||
|
|
||||||
if str_url.as_slice().starts_with("//") {
|
|
||||||
format!("{}:{}", new_url.scheme, str_url)
|
|
||||||
} else if base_url.path.is_empty() || str_url.as_slice().starts_with("/") {
|
|
||||||
new_url.path = "/".to_string();
|
|
||||||
format!("{}{}", new_url, str_url.as_slice().trim_left_chars('/'))
|
|
||||||
} else if str_url.as_slice().starts_with("#") {
|
|
||||||
format!("{}{}", new_url, str_url)
|
|
||||||
} else { // relative path
|
|
||||||
let base_path = base_url.path.as_slice().trim_right_chars(|c: char| c != '/');
|
|
||||||
new_url.path = base_path.to_string();
|
|
||||||
format!("{}{}", new_url, str_url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Ok((scheme, page)) => {
|
|
||||||
match scheme.as_slice() {
|
|
||||||
"about" => {
|
|
||||||
match page.as_slice() {
|
|
||||||
"crash" => {
|
|
||||||
fail!("about:crash");
|
|
||||||
}
|
|
||||||
"failure" => {
|
|
||||||
let mut path = os::self_exe_path().expect("can't get exe path");
|
|
||||||
path.push("../src/test/html/failure.html");
|
|
||||||
// FIXME (#1094): not the right way to transform a path
|
|
||||||
format!("file://{}", path.display().to_str())
|
|
||||||
}
|
|
||||||
// TODO: handle the rest of the about: pages
|
|
||||||
_ => str_url.to_string()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"data" => {
|
|
||||||
// Drop whitespace within data: URLs, e.g. newlines within a base64
|
|
||||||
// src="..." block. Whitespace intended as content should be
|
|
||||||
// %-encoded or base64'd.
|
|
||||||
str_url.as_slice().chars().filter(|&c| !c.is_whitespace()).collect()
|
|
||||||
},
|
|
||||||
_ => str_url.to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std_url::from_str(str_url.as_slice())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_url(str_url: &str, base_url: Option<std_url::Url>) -> std_url::Url {
|
|
||||||
// FIXME: Need to handle errors
|
|
||||||
try_parse_url(str_url, base_url).ok().expect("URL parsing failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod parse_url_tests {
|
|
||||||
use super::parse_url;
|
|
||||||
use std::os;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_create_absolute_file_url_if_base_url_is_none_and_str_url_looks_filey() {
|
|
||||||
let file = "local.html";
|
|
||||||
let url = parse_url(file, None);
|
|
||||||
debug!("url: {:?}", url);
|
|
||||||
assert!("file" == url.scheme.as_slice());
|
|
||||||
let path = os::getcwd();
|
|
||||||
// FIXME (#1094): not the right way to transform a path
|
|
||||||
assert!(url.path.as_slice().contains(path.display().to_str().as_slice()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_create_url_based_on_old_url_1() {
|
|
||||||
let old_str = "http://example.com";
|
|
||||||
let old_url = parse_url(old_str, None);
|
|
||||||
let new_str = "index.html";
|
|
||||||
let new_url = parse_url(new_str, Some(old_url));
|
|
||||||
assert!("http" == new_url.scheme.as_slice());
|
|
||||||
assert!("example.com" == new_url.host.as_slice());
|
|
||||||
assert!("/index.html" == new_url.path.as_slice());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_create_url_based_on_old_url_2() {
|
|
||||||
let old_str = "http://example.com/";
|
|
||||||
let old_url = parse_url(old_str, None);
|
|
||||||
let new_str = "index.html";
|
|
||||||
let new_url = parse_url(new_str, Some(old_url));
|
|
||||||
assert!("http" == new_url.scheme.as_slice());
|
|
||||||
assert!("example.com" == new_url.host.as_slice());
|
|
||||||
assert!("/index.html" == new_url.path.as_slice());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_create_url_based_on_old_url_3() {
|
|
||||||
let old_str = "http://example.com/index.html";
|
|
||||||
let old_url = parse_url(old_str, None);
|
|
||||||
let new_str = "crumpet.html";
|
|
||||||
let new_url = parse_url(new_str, Some(old_url));
|
|
||||||
assert!("http" == new_url.scheme.as_slice());
|
|
||||||
assert!("example.com" == new_url.host.as_slice());
|
|
||||||
assert!("/crumpet.html" == new_url.path.as_slice());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_create_url_based_on_old_url_4() {
|
|
||||||
let old_str = "http://example.com/snarf/index.html";
|
|
||||||
let old_url = parse_url(old_str, None);
|
|
||||||
let new_str = "crumpet.html";
|
|
||||||
let new_url = parse_url(new_str, Some(old_url));
|
|
||||||
assert!("http" == new_url.scheme.as_slice());
|
|
||||||
assert!("example.com" == new_url.host.as_slice());
|
|
||||||
assert!("/snarf/crumpet.html" == new_url.path.as_slice());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_create_url_based_on_old_url_5() {
|
|
||||||
let old_str = "http://example.com/index.html";
|
|
||||||
let old_url = parse_url(old_str, None);
|
|
||||||
let new_str = "#top";
|
|
||||||
let new_url = parse_url(new_str, Some(old_url));
|
|
||||||
|
|
||||||
assert!("http" == new_url.scheme.as_slice());
|
|
||||||
assert!("example.com" == new_url.host.as_slice());
|
|
||||||
assert!("/index.html" == new_url.path.as_slice());
|
|
||||||
assert!(new_url.fragment == Some("top".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_create_url_based_on_old_url_6() {
|
|
||||||
use std_url::UserInfo;
|
|
||||||
|
|
||||||
let old_str = "http://foo:bar@example.com:8080/index.html";
|
|
||||||
let old_url = parse_url(old_str, None);
|
|
||||||
let new_str = "#top";
|
|
||||||
let new_url = parse_url(new_str, Some(old_url));
|
|
||||||
|
|
||||||
assert!("http" == new_url.scheme.as_slice());
|
|
||||||
assert!(new_url.user == Some(UserInfo { user: "foo".to_string(), pass: Some("bar".to_string()) }));
|
|
||||||
assert!("example.com" == new_url.host.as_slice());
|
|
||||||
assert!(new_url.port == Some("8080".to_string()));
|
|
||||||
assert!("/index.html" == new_url.path.as_slice());
|
|
||||||
assert!(new_url.fragment == Some("top".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_create_url_based_on_old_url_7() {
|
|
||||||
let old_str = "https://example.com/snarf/index.html";
|
|
||||||
let old_url = parse_url(old_str, None);
|
|
||||||
let new_str = "//example.com/crumpet.html";
|
|
||||||
let new_url = parse_url(new_str, Some(old_url));
|
|
||||||
assert!("https" == new_url.scheme.as_slice());
|
|
||||||
assert!("example.com" == new_url.host.as_slice());
|
|
||||||
assert!("/crumpet.html" == new_url.path.as_slice());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type UrlMap<T> = HashMap<std_url::Url, T>;
|
|
||||||
|
|
||||||
pub fn url_map<T: Clone + 'static>() -> UrlMap<T> {
|
|
||||||
HashMap::new()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn is_image_data(uri: &str) -> bool {
|
|
||||||
static types: &'static [&'static str] = &["data:image/png", "data:image/gif", "data:image/jpeg"];
|
|
||||||
types.iter().any(|&type_| uri.starts_with(type_))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ extern crate sync;
|
||||||
#[cfg(target_os="macos")]
|
#[cfg(target_os="macos")]
|
||||||
extern crate task_info;
|
extern crate task_info;
|
||||||
extern crate std_time = "time";
|
extern crate std_time = "time";
|
||||||
extern crate std_url = "url";
|
|
||||||
extern crate string_cache;
|
extern crate string_cache;
|
||||||
|
|
||||||
pub mod atom;
|
pub mod atom;
|
||||||
|
@ -45,6 +44,5 @@ pub mod sort;
|
||||||
pub mod str;
|
pub mod str;
|
||||||
pub mod task;
|
pub mod task;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
pub mod url;
|
|
||||||
pub mod vec;
|
pub mod vec;
|
||||||
pub mod workqueue;
|
pub mod workqueue;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit ae4820bfd19af931bfc84f406b74dfb67ab5ebe8
|
Subproject commit e95cdaef5f366d9911e6d06340b79b8d23245b7b
|
25
src/support/url/Makefile.in
Normal file
25
src/support/url/Makefile.in
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
VPATH=%VPATH%
|
||||||
|
|
||||||
|
RUSTC ?= rustc
|
||||||
|
RUSTFLAGS ?=
|
||||||
|
EXT_DEPS ?=
|
||||||
|
|
||||||
|
SRC=$(shell find $(VPATH)/src -type f)
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: liburl.dummy
|
||||||
|
|
||||||
|
liburl.dummy: src/url.rs $(SRC) $(EXT_DEPS)
|
||||||
|
$(RUSTC) $(RUSTFLAGS) $< --out-dir .
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
url-test: src/url.rs $(SRC)
|
||||||
|
$(RUSTC) $(RUSTFLAGS) $< -o $@ --test
|
||||||
|
|
||||||
|
.PHONY: check
|
||||||
|
check: url-test
|
||||||
|
./url-test $(TEST)
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -f *.o *.a *.so *.dylib *.rlib *.dll *.dummy *-test
|
4
src/support/url/configure
vendored
Normal file
4
src/support/url/configure
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
SRCDIR="$(cd $(dirname $0) && pwd)"
|
||||||
|
sed "s#%VPATH%#${SRCDIR}/rust-url#" ${SRCDIR}/Makefile.in > Makefile
|
1
src/support/url/rust-url
Submodule
1
src/support/url/rust-url
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 19c1aa0e73c3252761ca3d722cba9cc0ae1ba1ca
|
Loading…
Add table
Add a link
Reference in a new issue