diff options
Diffstat (limited to 'components/script/script_thread.rs')
-rw-r--r-- | components/script/script_thread.rs | 108 |
1 files changed, 52 insertions, 56 deletions
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 5f2ecd095ba..d21a0f6ce0d 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -61,7 +61,7 @@ use layout_interface::{self, LayoutChan, NewLayoutThreadInfo, ScriptLayoutChan}; use mem::heap_size_of_self_and_children; use msg::constellation_msg::{ConstellationChan, LoadData}; use msg::constellation_msg::{PipelineId, PipelineNamespace}; -use msg::constellation_msg::{SubpageId, WindowSizeData}; +use msg::constellation_msg::{SubpageId, WindowSizeData, WindowSizeType}; use msg::webdriver_msg::WebDriverScriptCommand; use net_traits::LoadData as NetLoadData; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; @@ -100,7 +100,7 @@ use task_source::history_traversal::HistoryTraversalTaskSource; use task_source::networking::NetworkingTaskSource; use task_source::user_interaction::UserInteractionTaskSource; use time::Tm; -use url::Url; +use url::{Url, Position}; use util::opts; use util::str::DOMString; use util::thread; @@ -389,7 +389,7 @@ pub struct ScriptThread { content_process_shutdown_chan: IpcSender<()>, } -/// In the event of thread failure, all data on the stack runs its destructor. However, there +/// In the event of thread panic, all data on the stack runs its destructor. However, there /// are no reachable, owning pointers to the DOM memory, so it never gets freed by default /// when the script thread fails. The ScriptMemoryFailsafe uses the destructor bomb pattern /// to forcibly tear down the JS compartments for pages associated with the failing ScriptThread. @@ -442,11 +442,11 @@ impl ScriptThreadFactory for ScriptThread { state: InitialScriptState, layout_chan: &OpaqueScriptLayoutChannel, load_data: LoadData) { - let ConstellationChan(const_chan) = state.constellation_chan.clone(); + let ConstellationChan(panic_chan) = state.panic_chan.clone(); let (script_chan, script_port) = channel(); let layout_chan = LayoutChan(layout_chan.sender()); - let failure_info = state.failure_info.clone(); - thread::spawn_named_with_send_on_failure(format!("ScriptThread {:?}", state.id), + let pipeline_id = state.id; + thread::spawn_named_with_send_on_panic(format!("ScriptThread {:?}", state.id), thread_state::SCRIPT, move || { PipelineNamespace::install(state.pipeline_namespace_id); @@ -481,7 +481,7 @@ impl ScriptThreadFactory for ScriptThread { // This must always be the very last operation performed before the thread completes failsafe.neuter(); - }, failure_info, const_chan); + }, Some(pipeline_id), panic_chan); } } @@ -492,7 +492,7 @@ pub unsafe extern "C" fn shadow_check_callback(_cx: *mut JSContext, } impl ScriptThread { - pub fn page_fetch_complete(id: PipelineId, subpage: Option<SubpageId>, metadata: Metadata) + pub fn page_fetch_complete(id: PipelineId, subpage: Option<SubpageId>, metadata: Option<Metadata>) -> Option<ParserRoot> { SCRIPT_THREAD_ROOT.with(|root| { let script_thread = unsafe { &*root.borrow().unwrap() }; @@ -521,7 +521,7 @@ impl ScriptThread { port: Receiver<MainThreadScriptMsg>, chan: Sender<MainThreadScriptMsg>) -> ScriptThread { - let runtime = new_rt_and_cx(); + let runtime = unsafe { new_rt_and_cx() }; unsafe { JS_SetWrapObjectCallbacks(runtime.rt(), @@ -635,8 +635,8 @@ impl ScriptThread { } } - for (id, size) in resizes { - self.handle_event(id, ResizeEvent(size)); + for (id, (size, size_type)) in resizes { + self.handle_event(id, ResizeEvent(size, size_type)); } // Store new resizes, and gather all other events. @@ -689,9 +689,9 @@ impl ScriptThread { self.handle_new_layout(new_layout_info); }) } - FromConstellation(ConstellationControlMsg::Resize(id, size)) => { + FromConstellation(ConstellationControlMsg::Resize(id, size, size_type)) => { self.profile_event(ScriptThreadEventCategory::Resize, || { - self.handle_resize(id, size); + self.handle_resize(id, size, size_type); }) } FromConstellation(ConstellationControlMsg::Viewport(id, rect)) => { @@ -1020,10 +1020,10 @@ impl ScriptThread { } } - fn handle_resize(&self, id: PipelineId, size: WindowSizeData) { + fn handle_resize(&self, id: PipelineId, size: WindowSizeData, size_type: WindowSizeType) { if let Some(ref page) = self.find_subpage(id) { let window = page.window(); - window.set_resize_event(size); + window.set_resize_event(size, size_type); return; } let mut loads = self.incomplete_loads.borrow_mut(); @@ -1061,7 +1061,7 @@ impl ScriptThread { subpage_id, load_data, paint_chan, - failure, + panic_chan, pipeline_port, layout_shutdown_chan, content_process_shutdown_chan, @@ -1079,7 +1079,7 @@ impl ScriptThread { layout_pair: layout_pair, pipeline_port: pipeline_port, constellation_chan: self.layout_to_constellation_chan.clone(), - failure: failure, + panic_chan: panic_chan, paint_chan: paint_chan, script_chan: self.control_chan.clone(), image_cache_thread: self.image_cache_thread.clone(), @@ -1132,8 +1132,7 @@ impl ScriptThread { if let Some(root_page) = self.page.borrow().as_ref() { for it_page in root_page.iter() { - let current_url = it_page.document().url().serialize(); - urls.push(current_url.clone()); + let current_url = it_page.document().url().to_string(); for child in it_page.document().upcast::<Node>().traverse_preorder() { dom_tree_size += heap_size_of_self_and_children(&*child); @@ -1145,7 +1144,8 @@ impl ScriptThread { path: path![format!("url({})", current_url), "dom-tree"], kind: ReportKind::ExplicitJemallocHeapSize, size: dom_tree_size, - }) + }); + urls.push(current_url); } } let path_seg = format!("url({})", urls.join(", ")); @@ -1280,7 +1280,7 @@ impl ScriptThread { /// We have received notification that the response associated with a load has completed. /// Kick off the document and frame tree creation process using the result. fn handle_page_fetch_complete(&self, id: PipelineId, subpage: Option<SubpageId>, - metadata: Metadata) -> Option<ParserRoot> { + metadata: Option<Metadata>) -> Option<ParserRoot> { let idx = self.incomplete_loads.borrow().iter().position(|load| { load.pipeline_id == id && load.parent_info.map(|info| info.1) == subpage }); @@ -1289,7 +1289,7 @@ impl ScriptThread { match idx { Some(idx) => { let load = self.incomplete_loads.borrow_mut().remove(idx); - Some(self.load(metadata, load)) + metadata.map(|meta| self.load(meta, load)) } None => { assert!(self.closed_pipelines.borrow().contains(&id)); @@ -1387,7 +1387,7 @@ impl ScriptThread { let ConstellationChan(ref chan) = self.constellation_chan; chan.send(ConstellationMsg::SetFinalUrl(incomplete.pipeline_id, final_url.clone())).unwrap(); } - debug!("ScriptThread: loading {} on page {:?}", incomplete.url.serialize(), incomplete.pipeline_id); + debug!("ScriptThread: loading {} on page {:?}", incomplete.url, incomplete.pipeline_id); let frame_element = incomplete.parent_info.and_then(|(parent_id, subpage_id)| { // The root page may not exist yet, if the parent of this frame @@ -1554,30 +1554,22 @@ impl ScriptThread { // Notify devtools that a new script global exists. self.notify_devtools(document.Title(), final_url.clone(), (page.pipeline(), None)); - let is_javascript = incomplete.url.scheme == "javascript"; + let is_javascript = incomplete.url.scheme() == "javascript"; let parse_input = if is_javascript { - use url::percent_encoding::percent_decode_to; + use url::percent_encoding::percent_decode; // Turn javascript: URL into JS code to eval, according to the steps in // https://html.spec.whatwg.org/multipage/#javascript-protocol let _ar = JSAutoRequest::new(self.get_cx()); - let mut script_source_bytes = Vec::new(); - // Start with the scheme data of the parsed URL (5.), while percent-decoding (8.) - percent_decode_to(incomplete.url.non_relative_scheme_data().unwrap().as_bytes(), - &mut script_source_bytes); - // Append question mark and query component, if any (6.), while percent-decoding (8.) - if let Some(ref query) = incomplete.url.query { - script_source_bytes.push(b'?'); - percent_decode_to(query.as_bytes(), &mut script_source_bytes); - } - // Append number sign and fragment component if any (7.), while percent-decoding (8.) - if let Some(ref fragment) = incomplete.url.fragment { - script_source_bytes.push(b'#'); - percent_decode_to(fragment.as_bytes(), &mut script_source_bytes); - } - // UTF-8 decode (9.) - let script_source = String::from_utf8_lossy(&script_source_bytes); + // This slice of the URL’s serialization is equivalent to (5.) to (7.): + // Start with the scheme data of the parsed URL; + // append question mark and query component, if any; + // append number sign and fragment component if any. + let encoded = &incomplete.url[Position::BeforePath..]; + + // Percent-decode (8.) and UTF-8 decode (9.) + let script_source = percent_decode(encoded.as_bytes()).decode_utf8_lossy(); // Script source is ready to be evaluated (11.) unsafe { @@ -1670,8 +1662,8 @@ impl ScriptThread { } match event { - ResizeEvent(new_size) => { - self.handle_resize_event(pipeline_id, new_size); + ResizeEvent(new_size, size_type) => { + self.handle_resize_event(pipeline_id, new_size, size_type); } MouseButtonEvent(event_type, button, point) => { @@ -1706,7 +1698,7 @@ impl ScriptThread { .and_then(|href| { let value = href.value(); let url = document.url(); - url.join(&value).map(|url| url.serialize()).ok() + url.join(&value).map(|url| url.to_string()).ok() }); let event = ConstellationMsg::NodeStatus(status); @@ -1795,14 +1787,14 @@ impl ScriptThread { // Step 8. { let nurl = &load_data.url; - if let Some(ref fragment) = nurl.fragment { + if let Some(fragment) = nurl.fragment() { let page = get_page(&self.root_page(), pipeline_id); let document = page.document(); let document = document.r(); let url = document.url(); - if url.scheme == nurl.scheme && url.scheme_data == nurl.scheme_data && - url.query == nurl.query && load_data.method == Method::Get { - match document.find_fragment_node(&*fragment) { + if &url[..Position::AfterQuery] == &nurl[..Position::AfterQuery] && + load_data.method == Method::Get { + match document.find_fragment_node(fragment) { Some(ref node) => { self.scroll_fragment_point(pipeline_id, node.r()); } @@ -1831,7 +1823,7 @@ impl ScriptThread { } } - fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData) { + fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData, size_type: WindowSizeType) { let page = get_page(&self.root_page(), pipeline_id); let window = page.window(); window.set_window_size(new_size); @@ -1849,11 +1841,13 @@ impl ScriptThread { // http://dev.w3.org/csswg/cssom-view/#resizing-viewports // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize - let uievent = UIEvent::new(window.r(), - DOMString::from("resize"), EventBubbles::DoesNotBubble, - EventCancelable::NotCancelable, Some(window.r()), - 0i32); - uievent.upcast::<Event>().fire(window.upcast()); + if size_type == WindowSizeType::Resize { + let uievent = UIEvent::new(window.r(), + DOMString::from("resize"), EventBubbles::DoesNotBubble, + EventCancelable::NotCancelable, Some(window.r()), + 0i32); + uievent.upcast::<Event>().fire(window.upcast()); + } } /// Initiate a non-blocking fetch for a specified resource. Stores the InProgressLoad @@ -1879,7 +1873,7 @@ impl ScriptThread { sender: action_sender, }; - if load_data.url.scheme == "javascript" { + if load_data.url.scheme() == "javascript" { load_data.url = Url::parse("about:blank").unwrap(); } @@ -1893,6 +1887,8 @@ impl ScriptThread { cors: None, pipeline_id: Some(id), credentials_flag: true, + referrer_policy: load_data.referrer_policy, + referrer_url: load_data.referrer_url, }, LoadConsumer::Listener(response_target), None)).unwrap(); self.incomplete_loads.borrow_mut().push(incomplete); @@ -1926,7 +1922,7 @@ impl ScriptThread { // https://html.spec.whatwg.org/multipage/#the-end steps 3-4. document.process_deferred_scripts(); - window.set_fragment_name(final_url.fragment.clone()); + window.set_fragment_name(final_url.fragment().map(str::to_owned)); } fn handle_css_error_reporting(&self, pipeline_id: PipelineId, filename: String, |