diff options
Diffstat (limited to 'components/script/dom')
60 files changed, 679 insertions, 545 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 246d155d1e0..b67ab0bd716 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -2316,10 +2316,13 @@ class CGAbstractMethod(CGThing): arguments. docs is None or documentation for the method in a string. + + unsafe is used to add the decorator 'unsafe' to a function, giving as a result + an 'unsafe fn()' declaration. """ def __init__(self, descriptor, name, returnType, args, inline=False, - alwaysInline=False, extern=False, unsafe_fn=False, pub=False, - templateArgs=None, unsafe=False, docs=None, doesNotPanic=False): + alwaysInline=False, extern=False, unsafe=False, pub=False, + templateArgs=None, docs=None, doesNotPanic=False): CGThing.__init__(self) self.descriptor = descriptor self.name = name @@ -2327,10 +2330,9 @@ class CGAbstractMethod(CGThing): self.args = args self.alwaysInline = alwaysInline self.extern = extern - self.unsafe_fn = extern or unsafe_fn + self.unsafe = extern or unsafe self.templateArgs = templateArgs self.pub = pub - self.unsafe = unsafe self.docs = docs self.catchPanic = self.extern and not doesNotPanic @@ -2357,7 +2359,7 @@ class CGAbstractMethod(CGThing): if self.pub: decorators.append('pub') - if self.unsafe_fn: + if self.unsafe: decorators.append('unsafe') if self.extern: @@ -2373,10 +2375,6 @@ class CGAbstractMethod(CGThing): def define(self): body = self.definition_body() - # Method will already be marked `unsafe` if `self.extern == True` - if self.unsafe and not self.extern: - body = CGWrapper(CGIndenter(body), pre="unsafe {\n", post="\n}") - if self.catchPanic: body = CGWrapper(CGIndenter(body), pre="return wrap_panic(|| {\n", @@ -2409,7 +2407,7 @@ class CGConstructorEnabled(CGAbstractMethod): 'ConstructorEnabled', 'bool', [Argument("*mut JSContext", "aCx"), Argument("HandleObject", "aObj")], - unsafe_fn=True) + unsafe=True) def definition_body(self): conditions = [] @@ -3089,7 +3087,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): Argument('HandleObject', 'global'), ] CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', - 'void', args, pub=True, unsafe_fn=True) + 'void', args, pub=True, unsafe=True) def define(self): return CGAbstractMethod.define(self) @@ -5349,10 +5347,19 @@ class CGInterfaceTrait(CGThing): def fmt(arguments): return "".join(", %s: %s" % argument for argument in arguments) - methods = [ - CGGeneric("fn %s(&self%s) -> %s;\n" % (name, fmt(arguments), rettype)) - for name, arguments, rettype in members() - ] + def contains_unsafe_arg(arguments): + if not arguments or len(arguments) == 0: + return False + return reduce((lambda x, y: x or y[1] == '*mut JSContext'), arguments, False) + + methods = [] + for name, arguments, rettype in members(): + arguments = list(arguments) + methods.append(CGGeneric("%sfn %s(&self%s) -> %s;\n" % ( + 'unsafe ' if contains_unsafe_arg(arguments) else '', + name, fmt(arguments), rettype)) + ) + if methods: self.cgRoot = CGWrapper(CGIndenter(CGList(methods, "")), pre="pub trait %sMethods {\n" % descriptor.interface.identifier.name, diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs index 3e6febeeb5d..a0d281a0afc 100644 --- a/components/script/dom/bindings/iterable.rs +++ b/components/script/dom/bindings/iterable.rs @@ -85,7 +85,7 @@ impl<T: Reflectable + JSTraceable + Iterable> IterableIterator<T> { /// Create a new iterator instance for the provided iterable DOM interface. pub fn new(iterable: &T, type_: IteratorType, - wrap: fn(*mut JSContext, &GlobalScope, Box<IterableIterator<T>>) + wrap: unsafe fn(*mut JSContext, &GlobalScope, Box<IterableIterator<T>>) -> Root<Self>) -> Root<Self> { let iterator = box IterableIterator { reflector: Reflector::new(), diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs index 11aed4be9af..528b1213ccb 100644 --- a/components/script/dom/bindings/js.rs +++ b/components/script/dom/bindings/js.rs @@ -408,6 +408,12 @@ impl<T: Reflectable> MutNullableHeap<JS<T>> { } } + /// Gets the current value out of this object and sets it to `None`. + pub fn take(&self) -> Option<Root<T>> { + let value = self.get(); + self.set(None); + value + } } impl<T: Reflectable> PartialEq for MutNullableHeap<JS<T>> { diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs index 737268bf7d0..05f262dab01 100644 --- a/components/script/dom/bindings/reflector.rs +++ b/components/script/dom/bindings/reflector.rs @@ -16,12 +16,14 @@ use std::ptr; pub fn reflect_dom_object<T, U>( obj: Box<T>, global: &U, - wrap_fn: fn(*mut JSContext, &GlobalScope, Box<T>) -> Root<T>) + wrap_fn: unsafe fn(*mut JSContext, &GlobalScope, Box<T>) -> Root<T>) -> Root<T> where T: Reflectable, U: DerivedFrom<GlobalScope> { let global_scope = global.upcast(); - wrap_fn(global_scope.get_cx(), global_scope, obj) + unsafe { + wrap_fn(global_scope.get_cx(), global_scope, obj) + } } /// A struct to store a reference to the reflector of a DOM object. diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index b38d5d4ec91..cd4f469c119 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -41,6 +41,7 @@ use dom::bindings::refcounted::{Trusted, TrustedPromise}; use dom::bindings::reflector::{Reflectable, Reflector}; use dom::bindings::str::{DOMString, USVString}; use dom::bindings::utils::WindowProxyHandler; +use dom::document::PendingRestyle; use encoding::types::EncodingRef; use euclid::{Matrix2D, Matrix4D, Point2D}; use euclid::length::Length as EuclidLength; @@ -79,6 +80,7 @@ use script_traits::{TimerEventId, TimerSource, TouchpadPressurePhase}; use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType}; use serde::{Deserialize, Serialize}; use servo_atoms::Atom; +use servo_url::ServoUrl; use smallvec::SmallVec; use std::boxed::FnBox; use std::cell::{Cell, UnsafeCell}; @@ -99,7 +101,6 @@ use style::selector_impl::{PseudoElement, Snapshot}; use style::values::specified::Length; use time::Duration; use url::Origin as UrlOrigin; -use url::Url; use uuid::Uuid; use webrender_traits::{WebGLBufferId, WebGLError, WebGLFramebufferId, WebGLProgramId}; use webrender_traits::{WebGLRenderbufferId, WebGLShaderId, WebGLTextureId}; @@ -301,7 +302,7 @@ impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, B, C) { } } -no_jsmanaged_fields!(bool, f32, f64, String, Url, AtomicBool, AtomicUsize, UrlOrigin, Uuid, char); +no_jsmanaged_fields!(bool, f32, f64, String, ServoUrl, AtomicBool, AtomicUsize, UrlOrigin, Uuid, char); no_jsmanaged_fields!(usize, u8, u16, u32, u64); no_jsmanaged_fields!(isize, i8, i16, i32, i64); no_jsmanaged_fields!(Sender<T>); @@ -348,6 +349,7 @@ no_jsmanaged_fields!(Mime); no_jsmanaged_fields!(AttrIdentifier); no_jsmanaged_fields!(AttrValue); no_jsmanaged_fields!(Snapshot); +no_jsmanaged_fields!(PendingRestyle); no_jsmanaged_fields!(HttpsState); no_jsmanaged_fields!(Request); no_jsmanaged_fields!(RequestInit); diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 5b36249be59..390a321fe5e 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -42,11 +42,11 @@ use net_traits::image::base::PixelFormat; use net_traits::image_cache_thread::ImageResponse; use num_traits::ToPrimitive; use script_traits::ScriptMsg as ConstellationMsg; +use servo_url::ServoUrl; use std::{cmp, fmt}; use std::cell::Cell; use std::str::FromStr; use unpremultiplytable::UNPREMULTIPLY_TABLE; -use url::Url; #[must_root] #[derive(JSTraceable, Clone, HeapSizeOf)] @@ -451,7 +451,7 @@ impl CanvasRenderingContext2D { } #[inline] - fn request_image_from_cache(&self, url: Url) -> ImageResponse { + fn request_image_from_cache(&self, url: ServoUrl) -> ImageResponse { let window = window_from_node(&*self.canvas); canvas_utils::request_image_from_cache(&window, url) } diff --git a/components/script/dom/client.rs b/components/script/dom/client.rs index 7f51b251627..bc763d41ea9 100644 --- a/components/script/dom/client.rs +++ b/components/script/dom/client.rs @@ -10,7 +10,7 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; use dom::serviceworker::ServiceWorker; use dom::window::Window; -use url::Url; +use servo_url::ServoUrl; use uuid::Uuid; #[dom_struct] @@ -24,7 +24,7 @@ pub struct Client { } impl Client { - fn new_inherited(url: Url) -> Client { + fn new_inherited(url: ServoUrl) -> Client { Client { reflector_: Reflector::new(), active_worker: None, diff --git a/components/script/dom/crypto.rs b/components/script/dom/crypto.rs index 45c1c4639d5..22466f3f14c 100644 --- a/components/script/dom/crypto.rs +++ b/components/script/dom/crypto.rs @@ -41,12 +41,12 @@ impl Crypto { impl CryptoMethods for Crypto { #[allow(unsafe_code)] // https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#Crypto-method-getRandomValues - fn GetRandomValues(&self, + unsafe fn GetRandomValues(&self, _cx: *mut JSContext, input: *mut JSObject) -> Fallible<NonZero<*mut JSObject>> { assert!(!input.is_null()); - let mut data = match unsafe { array_buffer_view_data::<u8>(input) } { + let mut data = match array_buffer_view_data::<u8>(input) { Some(data) => data, None => { return Err(Error::Type("Argument to Crypto.getRandomValues is not an ArrayBufferView" @@ -64,7 +64,7 @@ impl CryptoMethods for Crypto { self.rng.borrow_mut().fill_bytes(&mut data); - Ok(unsafe { NonZero::new(input) }) + Ok(NonZero::new(input)) } } diff --git a/components/script/dom/cssfontfacerule.rs b/components/script/dom/cssfontfacerule.rs index 88dcaf4603f..18371c89c45 100644 --- a/components/script/dom/cssfontfacerule.rs +++ b/components/script/dom/cssfontfacerule.rs @@ -12,6 +12,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::font_face::FontFaceRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSFontFaceRule { @@ -44,7 +45,6 @@ impl SpecificCSSRule for CSSFontFaceRule { } fn get_css(&self) -> DOMString { - // self.fontfacerule.read().to_css_string().into() - "".into() + self.fontfacerule.read().to_css_string().into() } } diff --git a/components/script/dom/csskeyframesrule.rs b/components/script/dom/csskeyframesrule.rs index 3fced7751d6..138c8b20558 100644 --- a/components/script/dom/csskeyframesrule.rs +++ b/components/script/dom/csskeyframesrule.rs @@ -12,6 +12,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::stylesheets::KeyframesRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSKeyframesRule { @@ -44,7 +45,6 @@ impl SpecificCSSRule for CSSKeyframesRule { } fn get_css(&self) -> DOMString { - // self.keyframesrule.read().to_css_string().into() - "".into() + self.keyframesrule.read().to_css_string().into() } } diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs index dc4f3e586ba..a8d8649b31f 100644 --- a/components/script/dom/cssmediarule.rs +++ b/components/script/dom/cssmediarule.rs @@ -13,6 +13,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::stylesheets::MediaRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSMediaRule { @@ -45,7 +46,6 @@ impl SpecificCSSRule for CSSMediaRule { } fn get_css(&self) -> DOMString { - // self.mediarule.read().to_css_string().into() - "".into() + self.mediarule.read().to_css_string().into() } } diff --git a/components/script/dom/cssnamespacerule.rs b/components/script/dom/cssnamespacerule.rs index 2c0866c5dbe..04c4431df77 100644 --- a/components/script/dom/cssnamespacerule.rs +++ b/components/script/dom/cssnamespacerule.rs @@ -12,6 +12,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::stylesheets::NamespaceRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSNamespaceRule { @@ -44,7 +45,6 @@ impl SpecificCSSRule for CSSNamespaceRule { } fn get_css(&self) -> DOMString { - // self.namespacerule.read().to_css_string().into() - "".into() + self.namespacerule.read().to_css_string().into() } } diff --git a/components/script/dom/cssviewportrule.rs b/components/script/dom/cssviewportrule.rs index 89f1ada597d..f534c535a64 100644 --- a/components/script/dom/cssviewportrule.rs +++ b/components/script/dom/cssviewportrule.rs @@ -12,6 +12,7 @@ use dom::window::Window; use parking_lot::RwLock; use std::sync::Arc; use style::viewport::ViewportRule; +use style_traits::ToCss; #[dom_struct] pub struct CSSViewportRule { @@ -44,7 +45,6 @@ impl SpecificCSSRule for CSSViewportRule { } fn get_css(&self) -> DOMString { - // self.viewportrule.read().to_css_string().into() - "".into() + self.viewportrule.read().to_css_string().into() } } diff --git a/components/script/dom/customevent.rs b/components/script/dom/customevent.rs index a70aa096e43..f4346280cb7 100644 --- a/components/script/dom/customevent.rs +++ b/components/script/dom/customevent.rs @@ -76,13 +76,15 @@ impl CustomEvent { } impl CustomEventMethods for CustomEvent { + #[allow(unsafe_code)] // https://dom.spec.whatwg.org/#dom-customevent-detail - fn Detail(&self, _cx: *mut JSContext) -> JSVal { + unsafe fn Detail(&self, _cx: *mut JSContext) -> JSVal { self.detail.get() } + #[allow(unsafe_code)] // https://dom.spec.whatwg.org/#dom-customevent-initcustomevent - fn InitCustomEvent(&self, + unsafe fn InitCustomEvent(&self, _cx: *mut JSContext, type_: DOMString, can_bubble: bool, diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 86aac32df1b..85f4db49e02 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -33,12 +33,12 @@ use rand::random; use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, StackRootTLS, get_reports, new_rt_and_cx}; use script_runtime::ScriptThreadEventCategory::WorkerEvent; use script_traits::{TimerEvent, TimerSource, WorkerGlobalScopeInit, WorkerScriptLoadOrigin}; +use servo_url::ServoUrl; use std::mem::replace; use std::sync::{Arc, Mutex}; use std::sync::atomic::AtomicBool; use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel}; use style::thread_state; -use url::Url; use util::thread::spawn_named; /// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular @@ -92,7 +92,7 @@ pub struct DedicatedWorkerGlobalScope { impl DedicatedWorkerGlobalScope { fn new_inherited(init: WorkerGlobalScopeInit, - worker_url: Url, + worker_url: ServoUrl, from_devtools_receiver: Receiver<DevtoolScriptControlMsg>, runtime: Runtime, parent_sender: Box<ScriptChan + Send>, @@ -117,8 +117,9 @@ impl DedicatedWorkerGlobalScope { } } + #[allow(unsafe_code)] pub fn new(init: WorkerGlobalScopeInit, - worker_url: Url, + worker_url: ServoUrl, from_devtools_receiver: Receiver<DevtoolScriptControlMsg>, runtime: Runtime, parent_sender: Box<ScriptChan + Send>, @@ -139,12 +140,14 @@ impl DedicatedWorkerGlobalScope { timer_event_chan, timer_event_port, closing); - DedicatedWorkerGlobalScopeBinding::Wrap(cx, scope) + unsafe { + DedicatedWorkerGlobalScopeBinding::Wrap(cx, scope) + } } #[allow(unsafe_code)] pub fn run_worker_scope(init: WorkerGlobalScopeInit, - worker_url: Url, + worker_url: ServoUrl, from_devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>, worker_rt_for_mainthread: Arc<Mutex<Option<SharedRt>>>, worker: TrustedWorkerAddress, @@ -366,8 +369,9 @@ unsafe extern "C" fn interrupt_callback(cx: *mut JSContext) -> bool { } impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope { + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage - fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { + unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { let data = try!(StructuredCloneData::write(cx, message)); let worker = self.worker.borrow().as_ref().unwrap().clone(); self.parent_sender diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 56b7b17b0ca..ec71cf20085 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -108,6 +108,7 @@ use script_traits::{ScriptMsg as ConstellationMsg, TouchpadPressurePhase}; use script_traits::{TouchEventType, TouchId}; use script_traits::UntrustedNodeAddress; use servo_atoms::Atom; +use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::boxed::FnBox; @@ -122,11 +123,11 @@ use std::sync::Arc; use std::time::{Duration, Instant}; use style::attr::AttrValue; use style::context::ReflowGoal; -use style::selector_impl::Snapshot; +use style::restyle_hints::RestyleHint; +use style::selector_impl::{RestyleDamage, Snapshot}; use style::str::{split_html_space_chars, str_join}; use style::stylesheets::Stylesheet; use time; -use url::Url; use url::percent_encoding::percent_decode; use util::prefs::PREFS; @@ -155,6 +156,29 @@ pub struct StylesheetInDocument { pub stylesheet: Arc<Stylesheet>, } +#[derive(Debug, HeapSizeOf)] +pub struct PendingRestyle { + /// If this element had a state or attribute change since the last restyle, track + /// the original condition of the element. + pub snapshot: Option<Snapshot>, + + /// Any explicit restyles hints that have been accumulated for this element. + pub hint: RestyleHint, + + /// Any explicit restyles damage that have been accumulated for this element. + pub damage: RestyleDamage, +} + +impl PendingRestyle { + pub fn new() -> Self { + PendingRestyle { + snapshot: None, + hint: RestyleHint::empty(), + damage: RestyleDamage::empty(), + } + } +} + // https://dom.spec.whatwg.org/#document #[dom_struct] pub struct Document { @@ -168,7 +192,7 @@ pub struct Document { last_modified: Option<String>, encoding: Cell<EncodingRef>, is_html_document: bool, - url: Url, + url: ServoUrl, quirks_mode: Cell<QuirksMode>, /// Caches for the getElement methods id_map: DOMRefCell<HashMap<Atom, Vec<JS<Element>>>>, @@ -232,9 +256,9 @@ pub struct Document { /// This field is set to the document itself for inert documents. /// https://html.spec.whatwg.org/multipage/#appropriate-template-contents-owner-document appropriate_template_contents_owner_document: MutNullableHeap<JS<Document>>, - /// For each element that has had a state or attribute change since the last restyle, - /// track the original condition of the element. - modified_elements: DOMRefCell<HashMap<JS<Element>, Snapshot>>, + /// Information on elements needing restyle to ship over to the layout thread when the + /// time comes. + pending_restyles: DOMRefCell<HashMap<JS<Element>, PendingRestyle>>, /// This flag will be true if layout suppressed a reflow attempt that was /// needed in order for the page to be painted. needs_paint: Cell<bool>, @@ -374,12 +398,12 @@ impl Document { } // https://dom.spec.whatwg.org/#concept-document-url - pub fn url(&self) -> &Url { + pub fn url(&self) -> &ServoUrl { &self.url } // https://html.spec.whatwg.org/multipage/#fallback-base-url - pub fn fallback_base_url(&self) -> Url { + pub fn fallback_base_url(&self) -> ServoUrl { // Step 1: iframe srcdoc (#4767). // Step 2: about:blank with a creator browsing context. // Step 3. @@ -387,7 +411,7 @@ impl Document { } // https://html.spec.whatwg.org/multipage/#document-base-url - pub fn base_url(&self) -> Url { + pub fn base_url(&self) -> ServoUrl { match self.base_element() { // Step 1. None => self.fallback_base_url(), @@ -408,7 +432,7 @@ impl Document { Some(root) => { root.upcast::<Node>().is_dirty() || root.upcast::<Node>().has_dirty_descendants() || - !self.modified_elements.borrow().is_empty() || + !self.pending_restyles.borrow().is_empty() || self.needs_paint() } None => false, @@ -451,7 +475,7 @@ impl Document { } pub fn content_and_heritage_changed(&self, node: &Node, damage: NodeDamage) { - node.force_dirty_ancestors(damage); + node.dirty(damage); } /// Reflows and disarms the timer if the reflow timer has expired. @@ -1706,7 +1730,7 @@ pub enum DocumentSource { #[allow(unsafe_code)] pub trait LayoutDocumentHelpers { unsafe fn is_html_document_for_layout(&self) -> bool; - unsafe fn drain_modified_elements(&self) -> Vec<(LayoutJS<Element>, Snapshot)>; + unsafe fn drain_pending_restyles(&self) -> Vec<(LayoutJS<Element>, PendingRestyle)>; unsafe fn needs_paint_from_layout(&self); unsafe fn will_paint(&self); } @@ -1720,8 +1744,8 @@ impl LayoutDocumentHelpers for LayoutJS<Document> { #[inline] #[allow(unrooted_must_root)] - unsafe fn drain_modified_elements(&self) -> Vec<(LayoutJS<Element>, Snapshot)> { - let mut elements = (*self.unsafe_get()).modified_elements.borrow_mut_for_layout(); + unsafe fn drain_pending_restyles(&self) -> Vec<(LayoutJS<Element>, PendingRestyle)> { + let mut elements = (*self.unsafe_get()).pending_restyles.borrow_mut_for_layout(); let result = elements.drain().map(|(k, v)| (k.to_layout(), v)).collect(); result } @@ -1738,7 +1762,7 @@ impl LayoutDocumentHelpers for LayoutJS<Document> { } /// https://url.spec.whatwg.org/#network-scheme -fn url_has_network_scheme(url: &Url) -> bool { +fn url_has_network_scheme(url: &ServoUrl) -> bool { match url.scheme() { "ftp" | "http" | "https" => true, _ => false, @@ -1748,7 +1772,7 @@ fn url_has_network_scheme(url: &Url) -> bool { impl Document { pub fn new_inherited(window: &Window, browsing_context: Option<&BrowsingContext>, - url: Option<Url>, + url: Option<ServoUrl>, is_html_document: IsHTMLDocument, content_type: Option<DOMString>, last_modified: Option<String>, @@ -1757,7 +1781,7 @@ impl Document { referrer: Option<String>, referrer_policy: Option<ReferrerPolicy>) -> Document { - let url = url.unwrap_or_else(|| Url::parse("about:blank").unwrap()); + let url = url.unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap()); let (ready_state, domcontentloaded_dispatched) = if source == DocumentSource::FromParser { (DocumentReadyState::Loading, false) @@ -1829,7 +1853,7 @@ impl Document { reflow_timeout: Cell::new(None), base_element: Default::default(), appropriate_template_contents_owner_document: Default::default(), - modified_elements: DOMRefCell::new(HashMap::new()), + pending_restyles: DOMRefCell::new(HashMap::new()), needs_paint: Cell::new(false), active_touch_points: DOMRefCell::new(Vec::new()), dom_loading: Cell::new(Default::default()), @@ -1868,7 +1892,7 @@ impl Document { pub fn new(window: &Window, browsing_context: Option<&BrowsingContext>, - url: Option<Url>, + url: Option<ServoUrl>, doctype: IsHTMLDocument, content_type: Option<DOMString>, last_modified: Option<String>, @@ -1967,23 +1991,28 @@ impl Document { self.id_map.borrow().get(&id).map(|ref elements| Root::from_ref(&*(*elements)[0])) } + pub fn ensure_pending_restyle(&self, el: &Element) -> RefMut<PendingRestyle> { + let map = self.pending_restyles.borrow_mut(); + RefMut::map(map, |m| m.entry(JS::from_ref(el)).or_insert_with(PendingRestyle::new)) + } + + pub fn ensure_snapshot(&self, el: &Element) -> RefMut<Snapshot> { + let mut entry = self.ensure_pending_restyle(el); + if entry.snapshot.is_none() { + entry.snapshot = Some(Snapshot::new(el.html_element_in_html_document())); + } + RefMut::map(entry, |e| e.snapshot.as_mut().unwrap()) + } + pub fn element_state_will_change(&self, el: &Element) { - let mut map = self.modified_elements.borrow_mut(); - let snapshot = map.entry(JS::from_ref(el)) - .or_insert_with(|| { - Snapshot::new(el.html_element_in_html_document()) - }); + let mut snapshot = self.ensure_snapshot(el); if snapshot.state.is_none() { snapshot.state = Some(el.state()); } } pub fn element_attr_will_change(&self, el: &Element) { - let mut map = self.modified_elements.borrow_mut(); - let mut snapshot = map.entry(JS::from_ref(el)) - .or_insert_with(|| { - Snapshot::new(el.html_element_in_html_document()) - }); + let mut snapshot = self.ensure_snapshot(el); if snapshot.attrs.is_none() { let attrs = el.attrs() .iter() @@ -2803,7 +2832,7 @@ impl DocumentMethods for Document { #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter - fn NamedGetter(&self, _cx: *mut JSContext, name: DOMString) -> Option<NonZero<*mut JSObject>> { + unsafe fn NamedGetter(&self, _cx: *mut JSContext, name: DOMString) -> Option<NonZero<*mut JSObject>> { #[derive(JSTraceable, HeapSizeOf)] struct NamedElementFilter { name: Atom, @@ -2871,9 +2900,7 @@ impl DocumentMethods for Document { if elements.peek().is_none() { // TODO: Step 2. // Step 3. - return unsafe { - Some(NonZero::new(first.reflector().get_jsobject().get())) - }; + return Some(NonZero::new(first.reflector().get_jsobject().get())); } } else { return None; @@ -2884,9 +2911,7 @@ impl DocumentMethods for Document { name: name, }; let collection = HTMLCollection::create(self.window(), root, box filter); - unsafe { - Some(NonZero::new(collection.reflector().get_jsobject().get())) - } + Some(NonZero::new(collection.reflector().get_jsobject().get())) } // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:supported-property-names diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index ac65c01e24c..8ee0f7b7912 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -84,13 +84,15 @@ use std::fmt; use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; +use style::dom::TRestyleDamage; use style::element_state::*; use style::matching::{common_style_affecting_attributes, rare_style_affecting_attributes}; use style::parser::ParserContextExtraData; use style::properties::{DeclaredValue, Importance}; use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, parse_style_attribute}; use style::properties::longhands::{background_image, border_spacing, font_family, font_size, overflow_x}; -use style::selector_impl::{NonTSPseudoClass, ServoSelectorImpl}; +use style::restyle_hints::RESTYLE_SELF; +use style::selector_impl::{NonTSPseudoClass, RestyleDamage, ServoSelectorImpl}; use style::selector_matching::ApplicableDeclarationBlock; use style::sink::Push; use style::values::CSSFloat; @@ -201,6 +203,19 @@ impl Element { ElementBinding::Wrap) } + pub fn restyle(&self, damage: NodeDamage) { + let doc = self.node.owner_doc(); + let mut restyle = doc.ensure_pending_restyle(self); + + // FIXME(bholley): I think we should probably only do this for + // NodeStyleDamaged, but I'm preserving existing behavior. + restyle.hint |= RESTYLE_SELF; + + if damage == NodeDamage::OtherNodeDamage { + restyle.damage = RestyleDamage::rebuild_and_reflow(); + } + } + // https://drafts.csswg.org/cssom-view/#css-layout-box // Elements that have a computed value of the display property // that is table-column or table-column-group @@ -368,7 +383,7 @@ impl LayoutElementHelpers for LayoutJS<Element> { PropertyDeclaration::BackgroundImage(DeclaredValue::Value( background_image::SpecifiedValue(vec![ background_image::single_value::SpecifiedValue(Some( - specified::Image::for_cascade(Some(Arc::new(url)), specified::url::UrlExtraData { }) + specified::Image::for_cascade(Some(url.into()), specified::url::UrlExtraData { }) )) ]))))); } diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs index 65f3be9e32b..3739d5732f3 100644 --- a/components/script/dom/errorevent.rs +++ b/components/script/dom/errorevent.rs @@ -130,8 +130,9 @@ impl ErrorEventMethods for ErrorEvent { self.filename.borrow().clone() } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-errorevent-error - fn Error(&self, _cx: *mut JSContext) -> JSVal { + unsafe fn Error(&self, _cx: *mut JSContext) -> JSVal { self.error.get() } diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 2eabfcbc8b0..c667267cd83 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -31,13 +31,13 @@ use net_traits::request::{RequestInit, RequestMode}; use network_listener::{NetworkListener, PreInvoke}; use script_thread::Runnable; use servo_atoms::Atom; +use servo_url::ServoUrl; use std::cell::Cell; use std::mem; use std::str::{Chars, FromStr}; use std::sync::{Arc, Mutex}; use task_source::TaskSource; use timers::OneshotTimerCallback; -use url::Url; header! { (LastEventId, "Last-Event-ID") => [String] } @@ -57,7 +57,7 @@ enum ReadyState { #[dom_struct] pub struct EventSource { eventtarget: EventTarget, - url: Url, + url: ServoUrl, request: DOMRefCell<Option<RequestInit>>, last_event_id: DOMRefCell<DOMString>, reconnection_time: Cell<u64>, @@ -309,7 +309,7 @@ impl PreInvoke for EventSourceContext { } impl EventSource { - fn new_inherited(url: Url, with_credentials: bool) -> EventSource { + fn new_inherited(url: ServoUrl, with_credentials: bool) -> EventSource { EventSource { eventtarget: EventTarget::new_inherited(), url: url, @@ -323,7 +323,7 @@ impl EventSource { } } - fn new(global: &GlobalScope, url: Url, with_credentials: bool) -> Root<EventSource> { + fn new(global: &GlobalScope, url: ServoUrl, with_credentials: bool) -> Root<EventSource> { reflect_dom_object(box EventSource::new_inherited(url, with_credentials), global, Wrap) diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 48ba920ad60..d29d7a0e2ff 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -33,6 +33,7 @@ use js::jsapi::{CompileFunction, JS_GetFunctionObject, JSAutoCompartment}; use js::rust::{AutoObjectVectorWrapper, CompileOptionsWrapper}; use libc::{c_char, size_t}; use servo_atoms::Atom; +use servo_url::ServoUrl; use std::collections::HashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::default::Default; @@ -42,7 +43,6 @@ use std::mem; use std::ops::{Deref, DerefMut}; use std::ptr; use std::rc::Rc; -use url::Url; #[derive(PartialEq, Clone, JSTraceable)] pub enum CommonEventHandler { @@ -71,7 +71,7 @@ pub enum ListenerPhase { #[derive(JSTraceable, Clone, PartialEq)] pub struct InternalRawUncompiledHandler { source: DOMString, - url: Url, + url: ServoUrl, line: usize, } @@ -140,6 +140,7 @@ pub enum CompiledEventListener { } impl CompiledEventListener { + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#the-event-handler-processing-algorithm pub fn call_or_handle_event<T: Reflectable>(&self, object: &T, @@ -155,7 +156,7 @@ impl CompiledEventListener { CommonEventHandler::ErrorEventHandler(ref handler) => { if let Some(event) = event.downcast::<ErrorEvent>() { let cx = object.global().get_cx(); - rooted!(in(cx) let error = event.Error(cx)); + rooted!(in(cx) let error = unsafe { event.Error(cx) }); let return_value = handler.Call_(object, EventOrString::String(event.Message()), Some(event.Filename()), @@ -347,7 +348,7 @@ impl EventTarget { /// Store the raw uncompiled event handler for on-demand compilation later. /// https://html.spec.whatwg.org/multipage/#event-handler-attributes:event-handler-content-attributes-3 pub fn set_event_handler_uncompiled(&self, - url: Url, + url: ServoUrl, line: usize, ty: &str, source: DOMString) { diff --git a/components/script/dom/extendablemessageevent.rs b/components/script/dom/extendablemessageevent.rs index b3f3a5318f7..fbbdd59cbd3 100644 --- a/components/script/dom/extendablemessageevent.rs +++ b/components/script/dom/extendablemessageevent.rs @@ -74,8 +74,9 @@ impl ExtendableMessageEvent { } impl ExtendableMessageEventMethods for ExtendableMessageEvent { + #[allow(unsafe_code)] // https://w3c.github.io/ServiceWorker/#extendablemessage-event-data-attribute - fn Data(&self, _cx: *mut JSContext) -> JSVal { + unsafe fn Data(&self, _cx: *mut JSContext) -> JSVal { self.data.get() } diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index 2594b196918..7197de9a2fa 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -339,14 +339,12 @@ impl FileReaderMethods for FileReader { #[allow(unsafe_code)] // https://w3c.github.io/FileAPI/#dfn-result - fn GetResult(&self, _: *mut JSContext) -> Option<StringOrObject> { + unsafe fn GetResult(&self, _: *mut JSContext) -> Option<StringOrObject> { self.result.borrow().as_ref().map(|r| match *r { FileReaderResult::String(ref string) => StringOrObject::String(string.clone()), FileReaderResult::ArrayBuffer(ref arr_buffer) => { - unsafe { - StringOrObject::Object((*arr_buffer.ptr.get()).to_object()) - } + StringOrObject::Object((*arr_buffer.ptr.get()).to_object()) } }) } diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 2338dcf32e7..0251bd8143e 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -36,6 +36,7 @@ use script_runtime::{ScriptPort, maybe_take_panic_result}; use script_thread::{MainThreadScriptChan, RunnableWrapper, ScriptThread}; use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEvent}; use script_traits::{TimerEventId, TimerEventRequest, TimerSource}; +use servo_url::ServoUrl; use std::cell::Cell; use std::collections::HashMap; use std::collections::hash_map::Entry; @@ -46,7 +47,6 @@ use task_source::networking::NetworkingTaskSource; use time::{Timespec, get_time}; use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle}; use timers::{OneshotTimers, TimerCallback}; -use url::Url; #[dom_struct] pub struct GlobalScope { @@ -239,7 +239,7 @@ impl GlobalScope { /// Get the [base url](https://html.spec.whatwg.org/multipage/#api-base-url) /// for this global scope. - pub fn api_base_url(&self) -> Url { + pub fn api_base_url(&self) -> ServoUrl { if let Some(window) = self.downcast::<Window>() { // https://html.spec.whatwg.org/multipage/#script-settings-for-browsing-contexts:api-base-url return window.Document().base_url(); @@ -252,7 +252,7 @@ impl GlobalScope { } /// Get the URL for this global scope. - pub fn get_url(&self) -> Url { + pub fn get_url(&self) -> ServoUrl { if let Some(window) = self.downcast::<Window>() { return window.get_url(); } diff --git a/components/script/dom/htmlanchorelement.rs b/components/script/dom/htmlanchorelement.rs index 24d86df0cc0..a983c75bf91 100644 --- a/components/script/dom/htmlanchorelement.rs +++ b/components/script/dom/htmlanchorelement.rs @@ -28,16 +28,16 @@ use html5ever_atoms::LocalName; use net_traits::ReferrerPolicy; use num_traits::ToPrimitive; use script_traits::MozBrowserEvent; +use servo_url::ServoUrl; use std::default::Default; use style::attr::AttrValue; -use url::Url; use util::prefs::PREFS; #[dom_struct] pub struct HTMLAnchorElement { htmlelement: HTMLElement, rel_list: MutNullableHeap<JS<DOMTokenList>>, - url: DOMRefCell<Option<Url>>, + url: DOMRefCell<Option<ServoUrl>>, } impl HTMLAnchorElement { diff --git a/components/script/dom/htmlbaseelement.rs b/components/script/dom/htmlbaseelement.rs index 9fd34768b36..0db9b5398dd 100644 --- a/components/script/dom/htmlbaseelement.rs +++ b/components/script/dom/htmlbaseelement.rs @@ -14,8 +14,8 @@ use dom::htmlelement::HTMLElement; use dom::node::{Node, UnbindContext, document_from_node}; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; +use servo_url::ServoUrl; use style::attr::AttrValue; -use url::Url; #[dom_struct] pub struct HTMLBaseElement { @@ -39,7 +39,7 @@ impl HTMLBaseElement { } /// https://html.spec.whatwg.org/multipage/#frozen-base-url - pub fn frozen_base_url(&self) -> Url { + pub fn frozen_base_url(&self) -> ServoUrl { let href = self.upcast::<Element>().get_attribute(&ns!(), &local_name!("href")) .expect("The frozen base url is only defined for base elements \ that have a base url."); diff --git a/components/script/dom/htmlbodyelement.rs b/components/script/dom/htmlbodyelement.rs index e89dc21f3da..ea9b1775787 100644 --- a/components/script/dom/htmlbodyelement.rs +++ b/components/script/dom/htmlbodyelement.rs @@ -19,9 +19,9 @@ use dom::node::{Node, document_from_node, window_from_node}; use dom::virtualmethods::VirtualMethods; use html5ever_atoms::LocalName; use script_traits::ScriptMsg as ConstellationMsg; +use servo_url::ServoUrl; use style::attr::AttrValue; use time; -use url::Url; /// How long we should wait before performing the initial reflow after `<body>` is parsed, in /// nanoseconds. @@ -85,7 +85,7 @@ impl HTMLBodyElementMethods for HTMLBodyElement { pub trait HTMLBodyElementLayoutHelpers { fn get_background_color(&self) -> Option<RGBA>; fn get_color(&self) -> Option<RGBA>; - fn get_background(&self) -> Option<Url>; + fn get_background(&self) -> Option<ServoUrl>; } impl HTMLBodyElementLayoutHelpers for LayoutJS<HTMLBodyElement> { @@ -110,7 +110,7 @@ impl HTMLBodyElementLayoutHelpers for LayoutJS<HTMLBodyElement> { } #[allow(unsafe_code)] - fn get_background(&self) -> Option<Url> { + fn get_background(&self) -> Option<ServoUrl> { unsafe { (*self.upcast::<Element>().unsafe_get()) .get_attr_for_layout(&ns!(), &local_name!("background")) diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 326b1804ddf..b5621364c13 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -235,8 +235,9 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { // https://html.spec.whatwg.org/multipage/#dom-canvas-height make_uint_setter!(SetHeight, "height", DEFAULT_HEIGHT); + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext - fn GetContext(&self, + unsafe fn GetContext(&self, cx: *mut JSContext, id: DOMString, attributes: Vec<HandleValue>) @@ -254,8 +255,9 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { } } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl - fn ToDataURL(&self, + unsafe fn ToDataURL(&self, _context: *mut JSContext, _mime_type: Option<DOMString>, _arguments: Vec<HandleValue>) -> Fallible<DOMString> { @@ -339,12 +341,12 @@ pub mod utils { use dom::window::Window; use ipc_channel::ipc; use net_traits::image_cache_thread::{ImageCacheChan, ImageResponse}; - use url::Url; + use servo_url::ServoUrl; - pub fn request_image_from_cache(window: &Window, url: Url) -> ImageResponse { + pub fn request_image_from_cache(window: &Window, url: ServoUrl) -> ImageResponse { let image_cache = window.image_cache_thread(); let (response_chan, response_port) = ipc::channel().unwrap(); - image_cache.request_image(url, ImageCacheChan(response_chan), None); + image_cache.request_image(url.into(), ImageCacheChan(response_chan), None); let result = response_port.recv().unwrap(); result.image_response } diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index 4ecc6a44fa0..cbf32ef9aab 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -380,10 +380,12 @@ impl HTMLFormElement { fn mutate_action_url(&self, form_data: &mut Vec<FormDatum>, mut load_data: LoadData, encoding: EncodingRef) { let charset = &*encoding.whatwg_name().unwrap(); - load_data.url.query_pairs_mut().clear() - .encoding_override(Some(self.pick_encoding())) - .extend_pairs(form_data.into_iter() - .map(|field| (field.name.clone(), field.replace_value(charset)))); + if let Some(ref mut url) = load_data.url.as_mut_url() { + url.query_pairs_mut().clear() + .encoding_override(Some(self.pick_encoding())) + .extend_pairs(form_data.into_iter() + .map(|field| (field.name.clone(), field.replace_value(charset)))); + } self.plan_to_navigate(load_data); } @@ -394,16 +396,18 @@ impl HTMLFormElement { let boundary = generate_boundary(); let bytes = match enctype { FormEncType::UrlEncoded => { - let mut url = load_data.url.clone(); let charset = &*encoding.whatwg_name().unwrap(); load_data.headers.set(ContentType::form_url_encoded()); - url.query_pairs_mut().clear() - .encoding_override(Some(self.pick_encoding())) - .extend_pairs(form_data.into_iter() - .map(|field| (field.name.clone(), field.replace_value(charset)))); - url.query().unwrap_or("").to_string().into_bytes() + if let Some(ref mut url) = load_data.url.as_mut_url() { + url.query_pairs_mut().clear() + .encoding_override(Some(self.pick_encoding())) + .extend_pairs(form_data.into_iter() + .map(|field| (field.name.clone(), field.replace_value(charset)))); + } + + load_data.url.query().unwrap_or("").to_string().into_bytes() } FormEncType::FormDataEncoded => { let mime = mime!(Multipart / FormData; Boundary =(&boundary)); diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 0430a0f7d26..311cc80aa8c 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -46,10 +46,10 @@ use script_thread::ScriptThread; use script_traits::{IFrameLoadInfo, LoadData, MozBrowserEvent, ScriptMsg as ConstellationMsg}; use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed}; use servo_atoms::Atom; +use servo_url::ServoUrl; use std::cell::Cell; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use style::context::ReflowGoal; -use url::Url; use util::prefs::PREFS; use util::servo_version; @@ -84,7 +84,7 @@ impl HTMLIFrameElement { /// <https://html.spec.whatwg.org/multipage/#otherwise-steps-for-iframe-or-frame-elements>, /// step 1. - fn get_url(&self) -> Url { + fn get_url(&self) -> ServoUrl { let element = self.upcast::<Element>(); element.get_attribute(&ns!(), &local_name!("src")).and_then(|src| { let url = src.value(); @@ -93,7 +93,7 @@ impl HTMLIFrameElement { } else { document_from_node(self).base_url().join(&url).ok() } - }).unwrap_or_else(|| Url::parse("about:blank").unwrap()) + }).unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap()) } pub fn generate_new_pipeline_id(&self) -> (Option<PipelineId>, PipelineId) { diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index d8ecda30943..3b58b383bf4 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -27,11 +27,11 @@ use ipc_channel::router::ROUTER; use net_traits::image::base::{Image, ImageMetadata}; use net_traits::image_cache_thread::{ImageResponder, ImageResponse}; use script_thread::Runnable; +use servo_url::ServoUrl; use std::i32; use std::sync::Arc; use style::attr::{AttrValue, LengthOrPercentageOrAuto}; use task_source::TaskSource; -use url::Url; #[derive(JSTraceable, HeapSizeOf)] #[allow(dead_code)] @@ -44,7 +44,7 @@ enum State { #[derive(JSTraceable, HeapSizeOf)] struct ImageRequest { state: State, - parsed_url: Option<Url>, + parsed_url: Option<ServoUrl>, source_url: Option<DOMString>, #[ignore_heap_size_of = "Arc"] image: Option<Arc<Image>>, @@ -58,7 +58,7 @@ pub struct HTMLImageElement { } impl HTMLImageElement { - pub fn get_url(&self) -> Option<Url> { + pub fn get_url(&self) -> Option<ServoUrl> { self.current_request.borrow().parsed_url.clone() } } @@ -120,7 +120,7 @@ impl Runnable for ImageResponseHandlerRunnable { impl HTMLImageElement { /// Makes the local `image` member match the status of the `src` attribute and starts /// prefetching the image. This method must be called after `src` is changed. - fn update_image(&self, value: Option<(DOMString, Url)>) { + fn update_image(&self, value: Option<(DOMString, ServoUrl)>) { let document = document_from_node(self); let window = document.window(); let image_cache = window.image_cache_thread(); @@ -149,7 +149,7 @@ impl HTMLImageElement { let _ = task_source.queue_with_wrapper(runnable, &wrapper); }); - image_cache.request_image_and_metadata(img_url, + image_cache.request_image_and_metadata(img_url.into(), window.image_cache_chan(), Some(ImageResponder::new(responder_sender))); } else { @@ -241,7 +241,7 @@ pub trait LayoutHTMLImageElementHelpers { unsafe fn image(&self) -> Option<Arc<Image>>; #[allow(unsafe_code)] - unsafe fn image_url(&self) -> Option<Url>; + unsafe fn image_url(&self) -> Option<ServoUrl>; fn get_width(&self) -> LengthOrPercentageOrAuto; fn get_height(&self) -> LengthOrPercentageOrAuto; @@ -254,7 +254,7 @@ impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> { } #[allow(unsafe_code)] - unsafe fn image_url(&self) -> Option<Url> { + unsafe fn image_url(&self) -> Option<ServoUrl> { (*self.unsafe_get()).current_request.borrow_for_layout().parsed_url.clone() } diff --git a/components/script/dom/htmllinkelement.rs b/components/script/dom/htmllinkelement.rs index 17c9514287e..f670d8757e3 100644 --- a/components/script/dom/htmllinkelement.rs +++ b/components/script/dom/htmllinkelement.rs @@ -36,6 +36,7 @@ use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as Req use network_listener::{NetworkListener, PreInvoke}; use script_layout_interface::message::Msg; use script_traits::{MozBrowserEvent, ScriptMsg as ConstellationMsg}; +use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; @@ -47,7 +48,6 @@ use style::media_queries::{MediaList, parse_media_query_list}; use style::parser::ParserContextExtraData; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::{Stylesheet, Origin}; -use url::Url; no_jsmanaged_fields!(Stylesheet); @@ -318,7 +318,7 @@ struct StylesheetContext { /// The response metadata received to date. metadata: Option<Metadata>, /// The initial URL requested. - url: Url, + url: ServoUrl, } impl PreInvoke for StylesheetContext {} diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 09a1b7cc438..b1480391223 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -35,11 +35,11 @@ use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as Req use network_listener::{NetworkListener, PreInvoke}; use script_thread::{Runnable, ScriptThread}; use servo_atoms::Atom; +use servo_url::ServoUrl; use std::cell::Cell; use std::sync::{Arc, Mutex}; use task_source::TaskSource; use time::{self, Timespec, Duration}; -use url::Url; struct HTMLMediaElementContext { /// The element that initiated the request. @@ -53,7 +53,7 @@ struct HTMLMediaElementContext { /// Time of last progress notification. next_progress_event: Timespec, /// Url of resource requested. - url: Url, + url: ServoUrl, /// Whether the media metadata has been completely received. have_metadata: bool, /// True if this response is invalid and should be ignored. @@ -164,7 +164,7 @@ impl PreInvoke for HTMLMediaElementContext { } impl HTMLMediaElementContext { - fn new(elem: &HTMLMediaElement, url: Url) -> HTMLMediaElementContext { + fn new(elem: &HTMLMediaElement, url: ServoUrl) -> HTMLMediaElementContext { HTMLMediaElementContext { elem: Trusted::new(elem), data: vec![], @@ -437,7 +437,7 @@ impl HTMLMediaElement { } // https://html.spec.whatwg.org/multipage/#concept-media-load-algorithm - fn resource_selection_algorithm_sync(&self, base_url: Url) { + fn resource_selection_algorithm_sync(&self, base_url: ServoUrl) { // TODO step 5 (populate pending text tracks) // Step 6 @@ -814,11 +814,11 @@ impl Runnable for FireSimpleEventTask { struct ResourceSelectionTask { elem: Trusted<HTMLMediaElement>, - base_url: Url, + base_url: ServoUrl, } impl ResourceSelectionTask { - fn new(elem: &HTMLMediaElement, url: Url) -> ResourceSelectionTask { + fn new(elem: &HTMLMediaElement, url: ServoUrl) -> ResourceSelectionTask { ResourceSelectionTask { elem: Trusted::new(elem), base_url: url, @@ -885,5 +885,5 @@ enum ResourceSelectionMode { enum Resource { Object, - Url(Url), + Url(ServoUrl), } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 68b65f93142..50c7658daab 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -35,11 +35,11 @@ use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError}; use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode, Type as RequestType}; use network_listener::{NetworkListener, PreInvoke}; use servo_atoms::Atom; +use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::cell::Cell; use std::sync::{Arc, Mutex}; use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec}; -use url::Url; #[dom_struct] pub struct HTMLScriptElement { @@ -115,12 +115,12 @@ static SCRIPT_JS_MIMES: StaticStringVec = &[ #[derive(HeapSizeOf, JSTraceable)] pub struct ScriptOrigin { text: DOMString, - url: Url, + url: ServoUrl, external: bool, } impl ScriptOrigin { - fn internal(text: DOMString, url: Url) -> ScriptOrigin { + fn internal(text: DOMString, url: ServoUrl) -> ScriptOrigin { ScriptOrigin { text: text, url: url, @@ -128,7 +128,7 @@ impl ScriptOrigin { } } - fn external(text: DOMString, url: Url) -> ScriptOrigin { + fn external(text: DOMString, url: ServoUrl) -> ScriptOrigin { ScriptOrigin { text: text, url: url, @@ -149,7 +149,7 @@ struct ScriptContext { /// The response metadata received to date. metadata: Option<Metadata>, /// The initial URL requested. - url: Url, + url: ServoUrl, /// Indicates whether the request failed, and why status: Result<(), NetworkError> } @@ -219,7 +219,7 @@ impl PreInvoke for ScriptContext {} /// https://html.spec.whatwg.org/multipage/#fetch-a-classic-script fn fetch_a_classic_script(script: &HTMLScriptElement, - url: Url, + url: ServoUrl, cors_setting: Option<CorsSettings>, character_encoding: EncodingRef) { let doc = document_from_node(script); diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs index 5f99fb9db57..877510c7d9a 100644 --- a/components/script/dom/imagedata.rs +++ b/components/script/dom/imagedata.rs @@ -85,8 +85,8 @@ impl ImageDataMethods for ImageData { #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-imagedata-data - fn Data(&self, _: *mut JSContext) -> NonZero<*mut JSObject> { + unsafe fn Data(&self, _: *mut JSContext) -> NonZero<*mut JSObject> { assert!(!self.data.get().is_null()); - unsafe { NonZero::new(self.data.get()) } + NonZero::new(self.data.get()) } } diff --git a/components/script/dom/location.rs b/components/script/dom/location.rs index cf91c683f2f..c992486b8d1 100644 --- a/components/script/dom/location.rs +++ b/components/script/dom/location.rs @@ -10,7 +10,7 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; use dom::urlhelper::UrlHelper; use dom::window::Window; -use url::Url; +use servo_url::ServoUrl; #[dom_struct] pub struct Location { @@ -32,12 +32,12 @@ impl Location { LocationBinding::Wrap) } - fn get_url(&self) -> Url { + fn get_url(&self) -> ServoUrl { self.window.get_url() } fn set_url_component(&self, value: USVString, - setter: fn(&mut Url, USVString)) { + setter: fn(&mut ServoUrl, USVString)) { let mut url = self.window.get_url(); setter(&mut url, value); self.window.load_url(url, false, None); diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs index f3d2aa79ba4..b457461723c 100644 --- a/components/script/dom/messageevent.rs +++ b/components/script/dom/messageevent.rs @@ -95,8 +95,9 @@ impl MessageEvent { } impl MessageEventMethods for MessageEvent { + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-messageevent-data - fn Data(&self, _cx: *mut JSContext) -> JSVal { + unsafe fn Data(&self, _cx: *mut JSContext) -> JSVal { self.data.get() } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 37e0548fa13..8d009bc2f98 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -73,6 +73,7 @@ use script_traits::UntrustedNodeAddress; use selectors::matching::{MatchingReason, matches}; use selectors::parser::Selector; use selectors::parser::parse_author_origin_selector_list_from_str; +use servo_url::ServoUrl; use std::borrow::ToOwned; use std::cell::{Cell, UnsafeCell}; use std::cmp::max; @@ -85,7 +86,6 @@ use style::dom::OpaqueNode; use style::selector_impl::ServoSelectorImpl; use style::stylesheets::Stylesheet; use style::thread_state; -use url::Url; use uuid::Uuid; // @@ -149,8 +149,6 @@ bitflags! { pub flags NodeFlags: u8 { #[doc = "Specifies whether this node is in a document."] const IS_IN_DOC = 0x01, - #[doc = "Specifies whether this node _must_ be reflowed regardless of style differences."] - const HAS_CHANGED = 0x02, #[doc = "Specifies whether this node needs style recalc on next reflow."] const IS_DIRTY = 0x04, #[doc = "Specifies whether this node has descendants (inclusive of itself) which \ @@ -175,7 +173,7 @@ bitflags! { impl NodeFlags { pub fn new() -> NodeFlags { - HAS_CHANGED | IS_DIRTY | HAS_DIRTY_DESCENDANTS + IS_DIRTY } } @@ -251,6 +249,8 @@ impl Node { let parent_in_doc = self.is_in_doc(); for node in new_child.traverse_preorder() { node.set_flag(IS_IN_DOC, parent_in_doc); + // Out-of-document elements never have the descendants flag set. + debug_assert!(!node.get_flag(HAS_DIRTY_DESCENDANTS)); vtable_for(&&*node).bind_to_tree(parent_in_doc); } let document = new_child.owner_doc(); @@ -289,7 +289,8 @@ impl Node { self.children_count.set(self.children_count.get() - 1); for node in child.traverse_preorder() { - node.set_flag(IS_IN_DOC, false); + // Out-of-document elements never have the descendants flag set. + node.set_flag(IS_IN_DOC | HAS_DIRTY_DESCENDANTS, false); vtable_for(&&*node).unbind_from_tree(&context); node.style_and_layout_data.get().map(|d| node.dispose(d)); } @@ -428,14 +429,6 @@ impl Node { self.flags.set(flags); } - pub fn has_changed(&self) -> bool { - self.get_flag(HAS_CHANGED) - } - - pub fn set_has_changed(&self, state: bool) { - self.set_flag(HAS_CHANGED, state) - } - pub fn is_dirty(&self) -> bool { self.get_flag(IS_DIRTY) } @@ -452,10 +445,6 @@ impl Node { self.set_flag(HAS_DIRTY_DESCENDANTS, state) } - pub fn force_dirty_ancestors(&self, damage: NodeDamage) { - self.dirty_impl(damage, true) - } - pub fn rev_version(&self) { // The new version counter is 1 plus the max of the node's current version counter, // its descendants version, and the document's version. Normally, this will just be @@ -470,30 +459,18 @@ impl Node { } pub fn dirty(&self, damage: NodeDamage) { - self.dirty_impl(damage, false) - } - - pub fn dirty_impl(&self, damage: NodeDamage, force_ancestors: bool) { - // 0. Set version counter self.rev_version(); - - // 1. Dirty self. - match damage { - NodeDamage::NodeStyleDamaged => {} - NodeDamage::OtherNodeDamage => self.set_has_changed(true), + if !self.is_in_doc() { + return; } - if self.is_dirty() && !force_ancestors { - return - } - - self.set_flag(IS_DIRTY, true); - - // 4. Dirty ancestors. - for ancestor in self.ancestors() { - if !force_ancestors && ancestor.has_dirty_descendants() { break } - ancestor.set_has_dirty_descendants(true); - } + match self.type_id() { + NodeTypeId::CharacterData(CharacterDataTypeId::Text) => + self.parent_node.get().unwrap().downcast::<Element>().unwrap().restyle(damage), + NodeTypeId::Element(_) => + self.downcast::<Element>().unwrap().restyle(damage), + _ => {}, + }; } /// The maximum version number of this node's descendants, including itself @@ -991,7 +968,7 @@ pub trait LayoutNodeHelpers { fn text_content(&self) -> String; fn selection(&self) -> Option<Range<usize>>; - fn image_url(&self) -> Option<Url>; + fn image_url(&self) -> Option<ServoUrl>; fn canvas_data(&self) -> Option<HTMLCanvasData>; fn svg_data(&self) -> Option<SVGSVGData>; fn iframe_pipeline_id(&self) -> PipelineId; @@ -1126,7 +1103,7 @@ impl LayoutNodeHelpers for LayoutJS<Node> { } #[allow(unsafe_code)] - fn image_url(&self) -> Option<Url> { + fn image_url(&self) -> Option<ServoUrl> { unsafe { self.downcast::<HTMLImageElement>() .expect("not an image!") @@ -1394,7 +1371,7 @@ impl Node { pub fn reflect_node<N>( node: Box<N>, document: &Document, - wrap_fn: extern "Rust" fn(*mut JSContext, &GlobalScope, Box<N>) -> Root<N>) + wrap_fn: unsafe extern "Rust" fn(*mut JSContext, &GlobalScope, Box<N>) -> Root<N>) -> Root<N> where N: DerivedFrom<Node> + Reflectable { diff --git a/components/script/dom/popstateevent.rs b/components/script/dom/popstateevent.rs index 153c30531fe..44183f7483f 100644 --- a/components/script/dom/popstateevent.rs +++ b/components/script/dom/popstateevent.rs @@ -67,8 +67,9 @@ impl PopStateEvent { } impl PopStateEventMethods for PopStateEvent { + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-popstateevent-state - fn State(&self, _cx: *mut JSContext) -> JSVal { + unsafe fn State(&self, _cx: *mut JSContext) -> JSVal { self.state.get() } diff --git a/components/script/dom/request.rs b/components/script/dom/request.rs index 614c51398e8..33a28da99ea 100644 --- a/components/script/dom/request.rs +++ b/components/script/dom/request.rs @@ -35,10 +35,10 @@ use net_traits::request::Referrer as NetTraitsRequestReferrer; use net_traits::request::Request as NetTraitsRequest; use net_traits::request::RequestMode as NetTraitsRequestMode; use net_traits::request::Type as NetTraitsRequestType; +use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::cell::{Cell, Ref}; use std::rc::Rc; -use url::Url; #[dom_struct] pub struct Request { @@ -53,7 +53,7 @@ pub struct Request { impl Request { fn new_inherited(global: &GlobalScope, - url: Url, + url: ServoUrl, is_service_worker_global_scope: bool) -> Request { Request { reflector_: Reflector::new(), @@ -69,7 +69,7 @@ impl Request { } pub fn new(global: &GlobalScope, - url: Url, + url: ServoUrl, is_service_worker_global_scope: bool) -> Root<Request> { reflect_dom_object(box Request::new_inherited(global, url, @@ -468,7 +468,7 @@ impl Request { } fn net_request_from_global(global: &GlobalScope, - url: Url, + url: ServoUrl, is_service_worker_global_scope: bool) -> NetTraitsRequest { let origin = Origin::Origin(global.get_url().origin()); let pipeline_id = global.pipeline_id(); @@ -524,7 +524,7 @@ fn is_cors_safelisted_method(m: &HttpMethod) -> bool { } // https://url.spec.whatwg.org/#include-credentials -fn includes_credentials(input: &Url) -> bool { +fn includes_credentials(input: &ServoUrl) -> bool { !input.username().is_empty() || input.password().is_some() } diff --git a/components/script/dom/response.rs b/components/script/dom/response.rs index 7607cacc972..484a1d0beee 100644 --- a/components/script/dom/response.rs +++ b/components/script/dom/response.rs @@ -22,12 +22,12 @@ use hyper::header::Headers as HyperHeaders; use hyper::status::StatusCode; use hyper_serde::Serde; use net_traits::response::{ResponseBody as NetTraitsResponseBody}; +use servo_url::ServoUrl; use std::cell::Ref; use std::mem; use std::rc::Rc; use std::str::FromStr; use url::Position; -use url::Url; #[dom_struct] pub struct Response { @@ -40,8 +40,8 @@ pub struct Response { status: DOMRefCell<Option<StatusCode>>, raw_status: DOMRefCell<Option<(u16, Vec<u8>)>>, response_type: DOMRefCell<DOMResponseType>, - url: DOMRefCell<Option<Url>>, - url_list: DOMRefCell<Vec<Url>>, + url: DOMRefCell<Option<ServoUrl>>, + url_list: DOMRefCell<Vec<ServoUrl>>, // For now use the existing NetTraitsResponseBody enum body: DOMRefCell<NetTraitsResponseBody>, #[ignore_heap_size_of = "Rc"] @@ -156,7 +156,7 @@ impl Response { // Step 2 let url = match parsed_url { Ok(url) => url, - Err(_) => return Err(Error::Type("Url could not be parsed".to_string())), + Err(_) => return Err(Error::Type("ServoUrl could not be parsed".to_string())), }; // Step 3 @@ -357,8 +357,8 @@ impl ResponseMethods for Response { } } -fn serialize_without_fragment(url: &Url) -> &str { - &url[..Position::AfterQuery] +fn serialize_without_fragment(url: &ServoUrl) -> &str { + &url.as_url().unwrap()[..Position::AfterQuery] } impl Response { @@ -377,7 +377,7 @@ impl Response { *self.raw_status.borrow_mut() = status; } - pub fn set_final_url(&self, final_url: Url) { + pub fn set_final_url(&self, final_url: ServoUrl) { *self.url.borrow_mut() = Some(final_url); } diff --git a/components/script/dom/serviceworker.rs b/components/script/dom/serviceworker.rs index f61dcc4e41c..d61f1120906 100644 --- a/components/script/dom/serviceworker.rs +++ b/components/script/dom/serviceworker.rs @@ -18,8 +18,8 @@ use dom::globalscope::GlobalScope; use js::jsapi::{HandleValue, JSContext}; use script_thread::Runnable; use script_traits::{ScriptMsg, DOMMessage}; +use servo_url::ServoUrl; use std::cell::Cell; -use url::Url; pub type TrustedServiceWorkerAddress = Trusted<ServiceWorker>; @@ -27,7 +27,7 @@ pub type TrustedServiceWorkerAddress = Trusted<ServiceWorker>; pub struct ServiceWorker { eventtarget: EventTarget, script_url: DOMRefCell<String>, - scope_url: Url, + scope_url: ServoUrl, state: Cell<ServiceWorkerState>, skip_waiting: Cell<bool> } @@ -35,7 +35,7 @@ pub struct ServiceWorker { impl ServiceWorker { fn new_inherited(script_url: &str, skip_waiting: bool, - scope_url: Url) -> ServiceWorker { + scope_url: ServoUrl) -> ServiceWorker { ServiceWorker { eventtarget: EventTarget::new_inherited(), script_url: DOMRefCell::new(String::from(script_url)), @@ -46,8 +46,8 @@ impl ServiceWorker { } pub fn install_serviceworker(global: &GlobalScope, - script_url: Url, - scope_url: Url, + script_url: ServoUrl, + scope_url: ServoUrl, skip_waiting: bool) -> Root<ServiceWorker> { reflect_dom_object(box ServiceWorker::new_inherited(script_url.as_str(), skip_waiting, @@ -64,8 +64,8 @@ impl ServiceWorker { self.upcast::<EventTarget>().fire_event(atom!("statechange")); } - pub fn get_script_url(&self) -> Url { - Url::parse(&self.script_url.borrow().clone()).unwrap() + pub fn get_script_url(&self) -> ServoUrl { + ServoUrl::parse(&self.script_url.borrow().clone()).unwrap() } } @@ -80,8 +80,9 @@ impl ServiceWorkerMethods for ServiceWorker { USVString(self.script_url.borrow().clone()) } + #[allow(unsafe_code)] // https://w3c.github.io/ServiceWorker/#service-worker-postmessage - fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { + unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { // Step 1 if let ServiceWorkerState::Redundant = self.state.get() { return Err(Error::InvalidState); diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs index 6a39aad418f..a3877064131 100644 --- a/components/script/dom/serviceworkerglobalscope.rs +++ b/components/script/dom/serviceworkerglobalscope.rs @@ -28,11 +28,11 @@ use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as Req use rand::random; use script_runtime::{CommonScriptMsg, StackRootTLS, get_reports, new_rt_and_cx, ScriptChan}; use script_traits::{TimerEvent, WorkerGlobalScopeInit, ScopeThings, ServiceWorkerMsg, WorkerScriptLoadOrigin}; +use servo_url::ServoUrl; use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel}; use std::thread; use std::time::Duration; use style::thread_state::{self, IN_WORKER, SCRIPT}; -use url::Url; use util::prefs::PREFS; use util::thread::spawn_named; @@ -80,12 +80,12 @@ pub struct ServiceWorkerGlobalScope { timer_event_port: Receiver<()>, #[ignore_heap_size_of = "Defined in std"] swmanager_sender: IpcSender<ServiceWorkerMsg>, - scope_url: Url, + scope_url: ServoUrl, } impl ServiceWorkerGlobalScope { fn new_inherited(init: WorkerGlobalScopeInit, - worker_url: Url, + worker_url: ServoUrl, from_devtools_receiver: Receiver<DevtoolScriptControlMsg>, runtime: Runtime, own_sender: Sender<ServiceWorkerScriptMsg>, @@ -93,7 +93,7 @@ impl ServiceWorkerGlobalScope { timer_event_chan: IpcSender<TimerEvent>, timer_event_port: Receiver<()>, swmanager_sender: IpcSender<ServiceWorkerMsg>, - scope_url: Url) + scope_url: ServoUrl) -> ServiceWorkerGlobalScope { ServiceWorkerGlobalScope { workerglobalscope: WorkerGlobalScope::new_inherited(init, @@ -110,8 +110,9 @@ impl ServiceWorkerGlobalScope { } } + #[allow(unsafe_code)] pub fn new(init: WorkerGlobalScopeInit, - worker_url: Url, + worker_url: ServoUrl, from_devtools_receiver: Receiver<DevtoolScriptControlMsg>, runtime: Runtime, own_sender: Sender<ServiceWorkerScriptMsg>, @@ -119,7 +120,7 @@ impl ServiceWorkerGlobalScope { timer_event_chan: IpcSender<TimerEvent>, timer_event_port: Receiver<()>, swmanager_sender: IpcSender<ServiceWorkerMsg>, - scope_url: Url) + scope_url: ServoUrl) -> Root<ServiceWorkerGlobalScope> { let cx = runtime.cx(); let scope = box ServiceWorkerGlobalScope::new_inherited(init, @@ -132,7 +133,9 @@ impl ServiceWorkerGlobalScope { timer_event_port, swmanager_sender, scope_url); - ServiceWorkerGlobalScopeBinding::Wrap(cx, scope) + unsafe { + ServiceWorkerGlobalScopeBinding::Wrap(cx, scope) + } } #[allow(unsafe_code)] @@ -141,7 +144,7 @@ impl ServiceWorkerGlobalScope { receiver: Receiver<ServiceWorkerScriptMsg>, devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>, swmanager_sender: IpcSender<ServiceWorkerMsg>, - scope_url: Url) { + scope_url: ServoUrl) { let ScopeThings { script_url, init, worker_load_origin, diff --git a/components/script/dom/serviceworkerregistration.rs b/components/script/dom/serviceworkerregistration.rs index c3a08e514e4..58ca0933d69 100644 --- a/components/script/dom/serviceworkerregistration.rs +++ b/components/script/dom/serviceworkerregistration.rs @@ -13,7 +13,7 @@ use dom::serviceworker::ServiceWorker; use dom::serviceworkercontainer::Controllable; use dom::workerglobalscope::prepare_workerscope_init; use script_traits::{WorkerScriptLoadOrigin, ScopeThings}; -use url::Url; +use servo_url::ServoUrl; #[dom_struct] pub struct ServiceWorkerRegistration { @@ -25,7 +25,7 @@ pub struct ServiceWorkerRegistration { } impl ServiceWorkerRegistration { - fn new_inherited(active_sw: &ServiceWorker, scope: Url) -> ServiceWorkerRegistration { + fn new_inherited(active_sw: &ServiceWorker, scope: ServoUrl) -> ServiceWorkerRegistration { ServiceWorkerRegistration { eventtarget: EventTarget::new_inherited(), active: Some(JS::from_ref(active_sw)), @@ -36,8 +36,8 @@ impl ServiceWorkerRegistration { } #[allow(unrooted_must_root)] pub fn new(global: &GlobalScope, - script_url: Url, - scope: Url, + script_url: ServoUrl, + scope: ServoUrl, container: &Controllable) -> Root<ServiceWorkerRegistration> { let active_worker = ServiceWorker::install_serviceworker(global, script_url.clone(), scope.clone(), true); active_worker.set_transition_state(ServiceWorkerState::Installed); @@ -49,7 +49,7 @@ impl ServiceWorkerRegistration { self.active.as_ref().unwrap() } - pub fn create_scope_things(global: &GlobalScope, script_url: Url) -> ScopeThings { + pub fn create_scope_things(global: &GlobalScope, script_url: ServoUrl) -> ScopeThings { let worker_load_origin = WorkerScriptLoadOrigin { referrer_url: None, referrer_policy: None, @@ -69,7 +69,7 @@ impl ServiceWorkerRegistration { } } -pub fn longest_prefix_match(stored_scope: &Url, potential_match: &Url) -> bool { +pub fn longest_prefix_match(stored_scope: &ServoUrl, potential_match: &ServoUrl) -> bool { if stored_scope.origin() != potential_match.origin() { return false; } diff --git a/components/script/dom/servoparser/html.rs b/components/script/dom/servoparser/html.rs index a2d636da6f3..0f806171a9b 100644 --- a/components/script/dom/servoparser/html.rs +++ b/components/script/dom/servoparser/html.rs @@ -31,25 +31,22 @@ use html5ever::tree_builder::{NodeOrText, QuirksMode}; use html5ever::tree_builder::{Tracer as HtmlTracer, TreeBuilder, TreeBuilderOpts, TreeSink}; use html5ever_atoms::QualName; use js::jsapi::JSTracer; +use servo_url::ServoUrl; use std::borrow::Cow; use std::io::{self, Write}; -use super::{FragmentContext, Sink}; -use url::Url; #[derive(HeapSizeOf, JSTraceable)] #[must_root] pub struct Tokenizer { #[ignore_heap_size_of = "Defined in html5ever"] inner: HtmlTokenizer<TreeBuilder<JS<Node>, Sink>>, - #[ignore_heap_size_of = "Defined in html5ever"] - input_buffer: BufferQueue, } impl Tokenizer { pub fn new( document: &Document, - url: Url, - fragment_context: Option<FragmentContext>) + url: ServoUrl, + fragment_context: Option<super::FragmentContext>) -> Self { let sink = Sink { base_url: url, @@ -80,27 +77,17 @@ impl Tokenizer { Tokenizer { inner: inner, - input_buffer: BufferQueue::new(), } } - pub fn feed(&mut self, input: String) { - self.input_buffer.push_back(input.into()); - self.run(); - } - - #[allow(unrooted_must_root)] - pub fn run(&mut self) { - while let TokenizerResult::Script(script) = self.inner.feed(&mut self.input_buffer) { - let script = Root::from_ref(script.downcast::<HTMLScriptElement>().unwrap()); - if !script.prepare() { - break; - } + pub fn feed(&mut self, input: &mut BufferQueue) -> Result<(), Root<HTMLScriptElement>> { + match self.inner.feed(input) { + TokenizerResult::Done => Ok(()), + TokenizerResult::Script(script) => Err(Root::from_ref(script.downcast().unwrap())), } } pub fn end(&mut self) { - assert!(self.input_buffer.is_empty()); self.inner.end(); } @@ -128,6 +115,13 @@ impl JSTraceable for HtmlTokenizer<TreeBuilder<JS<Node>, Sink>> { } } +#[derive(JSTraceable, HeapSizeOf)] +#[must_root] +struct Sink { + base_url: ServoUrl, + document: JS<Document>, +} + impl<'a> TreeSink for Sink { type Output = Self; fn finish(self) -> Self { self } diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index 7b5c5c7f4ab..fe650477123 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -17,9 +17,11 @@ use dom::document::{Document, DocumentSource, IsHTMLDocument}; use dom::globalscope::GlobalScope; use dom::htmlformelement::HTMLFormElement; use dom::htmlimageelement::HTMLImageElement; +use dom::htmlscriptelement::HTMLScriptElement; use dom::node::{Node, document_from_node, window_from_node}; use encoding::all::UTF_8; use encoding::types::{DecoderTrap, Encoding}; +use html5ever::tokenizer::buffer_queue::BufferQueue; use hyper::header::ContentType; use hyper::mime::{Mime, SubLevel, TopLevel}; use hyper_serde::Serde; @@ -29,9 +31,8 @@ use network_listener::PreInvoke; use profile_traits::time::{TimerMetadata, TimerMetadataFrameType}; use profile_traits::time::{TimerMetadataReflowType, ProfilerCategory, profile}; use script_thread::ScriptThread; +use servo_url::ServoUrl; use std::cell::Cell; -use std::collections::VecDeque; -use url::Url; use util::resource_files::read_resource_file; mod html; @@ -46,7 +47,8 @@ pub struct ServoParser { /// does not correspond to a page load. pipeline: Option<PipelineId>, /// Input chunks received but not yet passed to the parser. - pending_input: DOMRefCell<VecDeque<String>>, + #[ignore_heap_size_of = "Defined in html5ever"] + pending_input: DOMRefCell<BufferQueue>, /// The tokenizer of this parser. tokenizer: DOMRefCell<Tokenizer>, /// Whether to expect any further input from the associated network request. @@ -65,7 +67,7 @@ impl ServoParser { pub fn parse_html_document( document: &Document, input: DOMString, - url: Url, + url: ServoUrl, owner: Option<PipelineId>) { let parser = ServoParser::new( document, @@ -122,7 +124,7 @@ impl ServoParser { pub fn parse_xml_document( document: &Document, input: DOMString, - url: Url, + url: ServoUrl, owner: Option<PipelineId>) { let parser = ServoParser::new( document, @@ -143,7 +145,7 @@ impl ServoParser { reflector: Reflector::new(), document: JS::from_ref(document), pipeline: pipeline, - pending_input: DOMRefCell::new(VecDeque::new()), + pending_input: DOMRefCell::new(BufferQueue::new()), tokenizer: DOMRefCell::new(tokenizer), last_chunk_received: Cell::new(last_chunk_state == LastChunkState::Received), suspended: Default::default(), @@ -176,16 +178,7 @@ impl ServoParser { } fn push_input_chunk(&self, chunk: String) { - self.pending_input.borrow_mut().push_back(chunk); - } - - fn take_next_input_chunk(&self) -> Option<String> { - let mut pending_input = self.pending_input.borrow_mut(); - if pending_input.is_empty() { - None - } else { - pending_input.pop_front() - } + self.pending_input.borrow_mut().push_back(chunk.into()); } fn last_chunk_received(&self) -> bool { @@ -233,10 +226,10 @@ impl ServoParser { // the parser remains unsuspended. loop { self.document().reflow_if_reflow_timer_expired(); - if let Some(chunk) = self.take_next_input_chunk() { - self.tokenizer.borrow_mut().feed(chunk); - } else { - self.tokenizer.borrow_mut().run(); + if let Err(script) = self.tokenizer.borrow_mut().feed(&mut *self.pending_input.borrow_mut()) { + if script.prepare() { + continue; + } } // Document parsing is blocked on an external resource. @@ -284,25 +277,11 @@ enum Tokenizer { Xml(self::xml::Tokenizer), } -#[derive(JSTraceable, HeapSizeOf)] -#[must_root] -struct Sink { - pub base_url: Url, - pub document: JS<Document>, -} - impl Tokenizer { - fn feed(&mut self, input: String) { + fn feed(&mut self, input: &mut BufferQueue) -> Result<(), Root<HTMLScriptElement>> { match *self { Tokenizer::Html(ref mut tokenizer) => tokenizer.feed(input), - Tokenizer::Xml(ref mut tokenizer) => tokenizer.feed(input.into()), - } - } - - fn run(&mut self) { - match *self { - Tokenizer::Html(ref mut tokenizer) => tokenizer.run(), - Tokenizer::Xml(ref mut tokenizer) => tokenizer.run(), + Tokenizer::Xml(ref mut tokenizer) => tokenizer.feed(input), } } @@ -338,11 +317,11 @@ pub struct ParserContext { /// The pipeline associated with this document. id: PipelineId, /// The URL for this document. - url: Url, + url: ServoUrl, } impl ParserContext { - pub fn new(id: PipelineId, url: Url) -> ParserContext { + pub fn new(id: PipelineId, url: ServoUrl) -> ParserContext { ParserContext { parser: None, is_synthesized_document: false, diff --git a/components/script/dom/servoparser/xml.rs b/components/script/dom/servoparser/xml.rs index 6f87d6a389c..4f233bd80ec 100644 --- a/components/script/dom/servoparser/xml.rs +++ b/components/script/dom/servoparser/xml.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods; use dom::bindings::inheritance::Castable; -use dom::bindings::js::{JS, Root}; +use dom::bindings::js::{JS, MutNullableHeap, Root}; use dom::bindings::str::DOMString; use dom::bindings::trace::JSTraceable; use dom::comment::Comment; @@ -17,11 +17,11 @@ use dom::htmlscriptelement::HTMLScriptElement; use dom::node::Node; use dom::processinginstruction::ProcessingInstruction; use dom::text::Text; +use html5ever::tokenizer::buffer_queue::BufferQueue; use html5ever_atoms::{Prefix, QualName}; use js::jsapi::JSTracer; +use servo_url::ServoUrl; use std::borrow::Cow; -use super::Sink; -use url::Url; use xml5ever::tendril::StrTendril; use xml5ever::tokenizer::{Attribute, QName, XmlTokenizer}; use xml5ever::tree_builder::{NextParserState, NodeOrText}; @@ -35,10 +35,11 @@ pub struct Tokenizer { } impl Tokenizer { - pub fn new(document: &Document, url: Url) -> Self { + pub fn new(document: &Document, url: ServoUrl) -> Self { let sink = Sink { base_url: url, document: JS::from_ref(document), + script: Default::default(), }; let tb = XmlTreeBuilder::new(sink); @@ -49,12 +50,21 @@ impl Tokenizer { } } - pub fn feed(&mut self, input: String) { - self.inner.feed(input.into()) - } - - pub fn run(&mut self) { - self.inner.run() + pub fn feed(&mut self, input: &mut BufferQueue) -> Result<(), Root<HTMLScriptElement>> { + if !input.is_empty() { + while let Some(chunk) = input.pop_front() { + self.inner.feed(chunk); + if let Some(script) = self.inner.sink().sink().script.take() { + return Err(script); + } + } + } else { + self.inner.run(); + if let Some(script) = self.inner.sink().sink().script.take() { + return Err(script); + } + } + Ok(()) } pub fn end(&mut self) { @@ -81,6 +91,14 @@ impl JSTraceable for XmlTokenizer<XmlTreeBuilder<JS<Node>, Sink>> { } } +#[derive(JSTraceable, HeapSizeOf)] +#[must_root] +struct Sink { + base_url: ServoUrl, + document: JS<Document>, + script: MutNullableHeap<JS<HTMLScriptElement>>, +} + impl<'a> TreeSink for Sink { type Handle = JS<Node>; @@ -165,13 +183,11 @@ impl<'a> TreeSink for Sink { } fn complete_script(&mut self, node: Self::Handle) -> NextParserState { - let script = node.downcast::<HTMLScriptElement>(); - if let Some(script) = script { - return match script.prepare() { - true => NextParserState::Continue, - false => NextParserState::Suspend, - }; + if let Some(script) = node.downcast() { + self.script.set(Some(script)); + NextParserState::Suspend + } else { + NextParserState::Continue } - NextParserState::Continue } } diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs index 3eb2b1ca844..6b85241e04f 100644 --- a/components/script/dom/storage.rs +++ b/components/script/dom/storage.rs @@ -18,8 +18,8 @@ use net_traits::IpcSend; use net_traits::storage_thread::{StorageThreadMsg, StorageType}; use script_thread::{Runnable, ScriptThread}; use script_traits::ScriptMsg; +use servo_url::ServoUrl; use task_source::TaskSource; -use url::Url; #[dom_struct] pub struct Storage { @@ -39,7 +39,7 @@ impl Storage { reflect_dom_object(box Storage::new_inherited(storage_type), global, StorageBinding::Wrap) } - fn get_url(&self) -> Url { + fn get_url(&self) -> ServoUrl { self.global().get_url() } @@ -158,7 +158,7 @@ impl Storage { } /// https://html.spec.whatwg.org/multipage/#send-a-storage-notification - pub fn queue_storage_event(&self, url: Url, + pub fn queue_storage_event(&self, url: ServoUrl, key: Option<String>, old_value: Option<String>, new_value: Option<String>) { let global = self.global(); let window = global.as_window(); @@ -173,14 +173,14 @@ impl Storage { pub struct StorageEventRunnable { element: Trusted<Storage>, - url: Url, + url: ServoUrl, key: Option<String>, old_value: Option<String>, new_value: Option<String> } impl StorageEventRunnable { - fn new(storage: Trusted<Storage>, url: Url, + fn new(storage: Trusted<Storage>, url: ServoUrl, key: Option<String>, old_value: Option<String>, new_value: Option<String>) -> StorageEventRunnable { StorageEventRunnable { element: storage, url: url, key: key, old_value: old_value, new_value: new_value } } diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index fe76ddccab9..08daf6eefa7 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -149,24 +149,23 @@ impl TestBindingMethods for TestBinding { } fn SetUnion9Attribute(&self, _: ByteStringOrLong) {} #[allow(unsafe_code)] - fn ArrayAttribute(&self, cx: *mut JSContext) -> NonZero<*mut JSObject> { - unsafe { - rooted!(in(cx) let array = JS_NewUint8ClampedArray(cx, 16)); - assert!(!array.is_null()); - NonZero::new(array.get()) - } + unsafe fn ArrayAttribute(&self, cx: *mut JSContext) -> NonZero<*mut JSObject> { + rooted!(in(cx) let array = JS_NewUint8ClampedArray(cx, 16)); + assert!(!array.is_null()); + NonZero::new(array.get()) } - fn AnyAttribute(&self, _: *mut JSContext) -> JSVal { NullValue() } - fn SetAnyAttribute(&self, _: *mut JSContext, _: HandleValue) {} #[allow(unsafe_code)] - fn ObjectAttribute(&self, cx: *mut JSContext) -> NonZero<*mut JSObject> { - unsafe { - rooted!(in(cx) let obj = JS_NewPlainObject(cx)); - assert!(!obj.is_null()); - NonZero::new(obj.get()) - } + unsafe fn AnyAttribute(&self, _: *mut JSContext) -> JSVal { NullValue() } + #[allow(unsafe_code)] + unsafe fn SetAnyAttribute(&self, _: *mut JSContext, _: HandleValue) {} + #[allow(unsafe_code)] + unsafe fn ObjectAttribute(&self, cx: *mut JSContext) -> NonZero<*mut JSObject> { + rooted!(in(cx) let obj = JS_NewPlainObject(cx)); + assert!(!obj.is_null()); + NonZero::new(obj.get()) } - fn SetObjectAttribute(&self, _: *mut JSContext, _: *mut JSObject) {} + #[allow(unsafe_code)] + unsafe fn SetObjectAttribute(&self, _: *mut JSContext, _: *mut JSObject) {} fn GetBooleanAttributeNullable(&self) -> Option<bool> { Some(false) } fn SetBooleanAttributeNullable(&self, _: Option<bool>) {} @@ -218,8 +217,10 @@ impl TestBindingMethods for TestBinding { fn SetInterfaceAttributeWeak(&self, url: Option<&URL>) { self.url.set(url); } - fn GetObjectAttributeNullable(&self, _: *mut JSContext) -> Option<NonZero<*mut JSObject>> { None } - fn SetObjectAttributeNullable(&self, _: *mut JSContext, _: *mut JSObject) {} + #[allow(unsafe_code)] + unsafe fn GetObjectAttributeNullable(&self, _: *mut JSContext) -> Option<NonZero<*mut JSObject>> { None } + #[allow(unsafe_code)] + unsafe fn SetObjectAttributeNullable(&self, _: *mut JSContext, _: *mut JSObject) {} fn GetUnionAttributeNullable(&self) -> Option<HTMLElementOrLong> { Some(HTMLElementOrLong::Long(0)) } @@ -266,8 +267,10 @@ impl TestBindingMethods for TestBinding { fn ReceiveInterface(&self) -> Root<Blob> { Blob::new(&self.global(), BlobImpl::new_from_bytes(vec![]), "".to_owned()) } - fn ReceiveAny(&self, _: *mut JSContext) -> JSVal { NullValue() } - fn ReceiveObject(&self, cx: *mut JSContext) -> NonZero<*mut JSObject> { + #[allow(unsafe_code)] + unsafe fn ReceiveAny(&self, _: *mut JSContext) -> JSVal { NullValue() } + #[allow(unsafe_code)] + unsafe fn ReceiveObject(&self, cx: *mut JSContext) -> NonZero<*mut JSObject> { self.ObjectAttribute(cx) } fn ReceiveUnion(&self) -> HTMLElementOrLong { HTMLElementOrLong::Long(0) } @@ -310,7 +313,8 @@ impl TestBindingMethods for TestBinding { fn ReceiveNullableInterface(&self) -> Option<Root<Blob>> { Some(Blob::new(&self.global(), BlobImpl::new_from_bytes(vec![]), "".to_owned())) } - fn ReceiveNullableObject(&self, cx: *mut JSContext) -> Option<NonZero<*mut JSObject>> { + #[allow(unsafe_code)] + unsafe fn ReceiveNullableObject(&self, cx: *mut JSContext) -> Option<NonZero<*mut JSObject>> { self.GetObjectAttributeNullable(cx) } fn ReceiveNullableUnion(&self) -> Option<HTMLElementOrLong> { @@ -432,8 +436,10 @@ impl TestBindingMethods for TestBinding { fn PassUnion8(&self, _: ByteStringSequenceOrLong) {} fn PassUnionWithTypedef(&self, _: DocumentOrTestTypedef) {} fn PassUnionWithTypedef2(&self, _: LongSequenceOrTestTypedef) {} - fn PassAny(&self, _: *mut JSContext, _: HandleValue) {} - fn PassObject(&self, _: *mut JSContext, _: *mut JSObject) {} + #[allow(unsafe_code)] + unsafe fn PassAny(&self, _: *mut JSContext, _: HandleValue) {} + #[allow(unsafe_code)] + unsafe fn PassObject(&self, _: *mut JSContext, _: *mut JSObject) {} fn PassCallbackFunction(&self, _: Rc<Function>) {} fn PassCallbackInterface(&self, _: Rc<EventListener>) {} fn PassSequence(&self, _: Vec<i32>) {} @@ -458,7 +464,8 @@ impl TestBindingMethods for TestBinding { fn PassNullableByteString(&self, _: Option<ByteString>) {} // fn PassNullableEnum(self, _: Option<TestEnum>) {} fn PassNullableInterface(&self, _: Option<&Blob>) {} - fn PassNullableObject(&self, _: *mut JSContext, _: *mut JSObject) {} + #[allow(unsafe_code)] + unsafe fn PassNullableObject(&self, _: *mut JSContext, _: *mut JSObject) {} fn PassNullableUnion(&self, _: Option<HTMLElementOrLong>) {} fn PassNullableUnion2(&self, _: Option<EventOrString>) {} fn PassNullableUnion3(&self, _: Option<StringOrLongSequence>) {} @@ -493,8 +500,10 @@ impl TestBindingMethods for TestBinding { fn PassOptionalUnion4(&self, _: Option<LongSequenceOrBoolean>) {} fn PassOptionalUnion5(&self, _: Option<UnsignedLongOrBoolean>) {} fn PassOptionalUnion6(&self, _: Option<ByteStringOrLong>) {} - fn PassOptionalAny(&self, _: *mut JSContext, _: HandleValue) {} - fn PassOptionalObject(&self, _: *mut JSContext, _: Option<*mut JSObject>) {} + #[allow(unsafe_code)] + unsafe fn PassOptionalAny(&self, _: *mut JSContext, _: HandleValue) {} + #[allow(unsafe_code)] + unsafe fn PassOptionalObject(&self, _: *mut JSContext, _: Option<*mut JSObject>) {} fn PassOptionalCallbackFunction(&self, _: Option<Rc<Function>>) {} fn PassOptionalCallbackInterface(&self, _: Option<Rc<EventListener>>) {} fn PassOptionalSequence(&self, _: Option<Vec<i32>>) {} @@ -517,7 +526,8 @@ impl TestBindingMethods for TestBinding { fn PassOptionalNullableByteString(&self, _: Option<Option<ByteString>>) {} // fn PassOptionalNullableEnum(self, _: Option<Option<TestEnum>>) {} fn PassOptionalNullableInterface(&self, _: Option<Option<&Blob>>) {} - fn PassOptionalNullableObject(&self, _: *mut JSContext, _: Option<*mut JSObject>) {} + #[allow(unsafe_code)] + unsafe fn PassOptionalNullableObject(&self, _: *mut JSContext, _: Option<*mut JSObject>) {} fn PassOptionalNullableUnion(&self, _: Option<Option<HTMLElementOrLong>>) {} fn PassOptionalNullableUnion2(&self, _: Option<Option<EventOrString>>) {} fn PassOptionalNullableUnion3(&self, _: Option<Option<StringOrLongSequence>>) {} @@ -560,12 +570,14 @@ impl TestBindingMethods for TestBinding { fn PassOptionalNullableByteStringWithDefault(&self, _: Option<ByteString>) {} // fn PassOptionalNullableEnumWithDefault(self, _: Option<TestEnum>) {} fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<&Blob>) {} - fn PassOptionalNullableObjectWithDefault(&self, _: *mut JSContext, _: *mut JSObject) {} + #[allow(unsafe_code)] + unsafe fn PassOptionalNullableObjectWithDefault(&self, _: *mut JSContext, _: *mut JSObject) {} fn PassOptionalNullableUnionWithDefault(&self, _: Option<HTMLElementOrLong>) {} fn PassOptionalNullableUnion2WithDefault(&self, _: Option<EventOrString>) {} // fn PassOptionalNullableCallbackFunctionWithDefault(self, _: Option<Function>) {} fn PassOptionalNullableCallbackInterfaceWithDefault(&self, _: Option<Rc<EventListener>>) {} - fn PassOptionalAnyWithDefault(&self, _: *mut JSContext, _: HandleValue) {} + #[allow(unsafe_code)] + unsafe fn PassOptionalAnyWithDefault(&self, _: *mut JSContext, _: HandleValue) {} fn PassOptionalNullableBooleanWithNonNullDefault(&self, _: Option<bool>) {} fn PassOptionalNullableByteWithNonNullDefault(&self, _: Option<i8>) {} @@ -610,8 +622,10 @@ impl TestBindingMethods for TestBinding { fn PassVariadicUnion5(&self, _: Vec<StringOrUnsignedLong>) {} fn PassVariadicUnion6(&self, _: Vec<UnsignedLongOrBoolean>) {} fn PassVariadicUnion7(&self, _: Vec<ByteStringOrLong>) {} - fn PassVariadicAny(&self, _: *mut JSContext, _: Vec<HandleValue>) {} - fn PassVariadicObject(&self, _: *mut JSContext, _: Vec<*mut JSObject>) {} + #[allow(unsafe_code)] + unsafe fn PassVariadicAny(&self, _: *mut JSContext, _: Vec<HandleValue>) {} + #[allow(unsafe_code)] + unsafe fn PassVariadicObject(&self, _: *mut JSContext, _: Vec<*mut JSObject>) {} fn BooleanMozPreference(&self, pref_name: DOMString) -> bool { PREFS.get(pref_name.as_ref()).as_boolean().unwrap_or(false) } @@ -654,20 +668,24 @@ impl TestBindingMethods for TestBinding { fn ReceiveAnyMozMap(&self) -> MozMap<JSVal> { MozMap::new() } #[allow(unrooted_must_root)] - fn ReturnResolvedPromise(&self, cx: *mut JSContext, v: HandleValue) -> Fallible<Rc<Promise>> { + #[allow(unsafe_code)] + unsafe fn ReturnResolvedPromise(&self, cx: *mut JSContext, v: HandleValue) -> Fallible<Rc<Promise>> { Promise::Resolve(&self.global(), cx, v) } #[allow(unrooted_must_root)] - fn ReturnRejectedPromise(&self, cx: *mut JSContext, v: HandleValue) -> Fallible<Rc<Promise>> { + #[allow(unsafe_code)] + unsafe fn ReturnRejectedPromise(&self, cx: *mut JSContext, v: HandleValue) -> Fallible<Rc<Promise>> { Promise::Reject(&self.global(), cx, v) } - fn PromiseResolveNative(&self, cx: *mut JSContext, p: &Promise, v: HandleValue) { + #[allow(unsafe_code)] + unsafe fn PromiseResolveNative(&self, cx: *mut JSContext, p: &Promise, v: HandleValue) { p.resolve(cx, v); } - fn PromiseRejectNative(&self, cx: *mut JSContext, p: &Promise, v: HandleValue) { + #[allow(unsafe_code)] + unsafe fn PromiseRejectNative(&self, cx: *mut JSContext, p: &Promise, v: HandleValue) { p.reject(cx, v); } diff --git a/components/script/dom/textdecoder.rs b/components/script/dom/textdecoder.rs index db18d9a5be4..abb2f0c4195 100644 --- a/components/script/dom/textdecoder.rs +++ b/components/script/dom/textdecoder.rs @@ -78,14 +78,14 @@ impl TextDecoderMethods for TextDecoder { #[allow(unsafe_code)] // https://encoding.spec.whatwg.org/#dom-textdecoder-decode - fn Decode(&self, _cx: *mut JSContext, input: Option<*mut JSObject>) + unsafe fn Decode(&self, _cx: *mut JSContext, input: Option<*mut JSObject>) -> Fallible<USVString> { let input = match input { Some(input) => input, None => return Ok(USVString("".to_owned())), }; - let data = match unsafe { array_buffer_view_data::<u8>(input) } { + let data = match array_buffer_view_data::<u8>(input) { Some(data) => data, None => { return Err(Error::Type("Argument to TextDecoder.decode is not an ArrayBufferView".to_owned())); diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs index 9c8ad647080..1bb35418714 100644 --- a/components/script/dom/textencoder.rs +++ b/components/script/dom/textencoder.rs @@ -50,17 +50,15 @@ impl TextEncoderMethods for TextEncoder { #[allow(unsafe_code)] // https://encoding.spec.whatwg.org/#dom-textencoder-encode - fn Encode(&self, cx: *mut JSContext, input: USVString) -> NonZero<*mut JSObject> { - unsafe { - let encoded = UTF_8.encode(&input.0, EncoderTrap::Strict).unwrap(); - let length = encoded.len() as u32; - rooted!(in(cx) let js_object = JS_NewUint8Array(cx, length)); - assert!(!js_object.is_null()); - let mut is_shared = false; - let js_object_data: *mut uint8_t = JS_GetUint8ArrayData(js_object.get(), &mut is_shared, ptr::null()); - assert!(!is_shared); - ptr::copy_nonoverlapping(encoded.as_ptr(), js_object_data, length as usize); - NonZero::new(js_object.get()) - } + unsafe fn Encode(&self, cx: *mut JSContext, input: USVString) -> NonZero<*mut JSObject> { + let encoded = UTF_8.encode(&input.0, EncoderTrap::Strict).unwrap(); + let length = encoded.len() as u32; + rooted!(in(cx) let js_object = JS_NewUint8Array(cx, length)); + assert!(!js_object.is_null()); + let mut is_shared = false; + let js_object_data: *mut uint8_t = JS_GetUint8ArrayData(js_object.get(), &mut is_shared, ptr::null()); + assert!(!is_shared); + ptr::copy_nonoverlapping(encoded.as_ptr(), js_object_data, length as usize); + NonZero::new(js_object.get()) } } diff --git a/components/script/dom/url.rs b/components/script/dom/url.rs index dbcefe48e53..50fe85a507b 100644 --- a/components/script/dom/url.rs +++ b/components/script/dom/url.rs @@ -17,8 +17,8 @@ use ipc_channel::ipc; use net_traits::{CoreResourceMsg, IpcSend}; use net_traits::blob_url_store::{get_blob_origin, parse_blob_url}; use net_traits::filemanager_thread::FileManagerThreadMsg; +use servo_url::ServoUrl; use std::default::Default; -use url::Url; use uuid::Uuid; // https://url.spec.whatwg.org/#url @@ -27,14 +27,14 @@ pub struct URL { reflector_: Reflector, // https://url.spec.whatwg.org/#concept-url-url - url: DOMRefCell<Url>, + url: DOMRefCell<ServoUrl>, // https://url.spec.whatwg.org/#dom-url-searchparams search_params: MutNullableHeap<JS<URLSearchParams>>, } impl URL { - fn new_inherited(url: Url) -> URL { + fn new_inherited(url: ServoUrl) -> URL { URL { reflector_: Reflector::new(), url: DOMRefCell::new(url), @@ -42,18 +42,19 @@ impl URL { } } - pub fn new(global: &GlobalScope, url: Url) -> Root<URL> { + pub fn new(global: &GlobalScope, url: ServoUrl) -> Root<URL> { reflect_dom_object(box URL::new_inherited(url), global, URLBinding::Wrap) } pub fn query_pairs(&self) -> Vec<(String, String)> { - self.url.borrow().query_pairs().into_owned().collect() + self.url.borrow().as_url().unwrap().query_pairs().into_owned().collect() } pub fn set_query_pairs(&self, pairs: &[(String, String)]) { - let mut url = self.url.borrow_mut(); - url.query_pairs_mut().clear().extend_pairs(pairs); + if let Some(ref mut url) = self.url.borrow_mut().as_mut_url() { + url.query_pairs_mut().clear().extend_pairs(pairs); + } } } @@ -69,7 +70,7 @@ impl URL { }, Some(base) => // Step 2.1. - match Url::parse(&base.0) { + match ServoUrl::parse(&base.0) { Ok(base) => Some(base), Err(error) => { // Step 2.2. @@ -78,7 +79,7 @@ impl URL { } }; // Step 3. - let parsed_url = match Url::options().base_url(parsed_base.as_ref()).parse(&url.0) { + let parsed_url = match ServoUrl::parse_with_base(parsed_base.as_ref(), &url.0) { Ok(url) => url, Err(error) => { // Step 4. @@ -124,7 +125,7 @@ impl URL { */ let origin = get_blob_origin(&global.get_url()); - if let Ok(url) = Url::parse(&url) { + if let Ok(url) = ServoUrl::parse(&url) { if let Ok((id, _, _)) = parse_blob_url(&url) { let resource_threads = global.resource_threads(); let (tx, rx) = ipc::channel().unwrap(); @@ -192,7 +193,7 @@ impl URLMethods for URL { // https://url.spec.whatwg.org/#dom-url-href fn SetHref(&self, value: USVString) -> ErrorResult { - match Url::parse(&value.0) { + match ServoUrl::parse(&value.0) { Ok(url) => { *self.url.borrow_mut() = url; self.search_params.set(None); // To be re-initialized in the SearchParams getter. @@ -258,7 +259,7 @@ impl URLMethods for URL { fn SetSearch(&self, value: USVString) { UrlHelper::SetSearch(&mut self.url.borrow_mut(), value); if let Some(search_params) = self.search_params.get() { - search_params.set_list(self.url.borrow().query_pairs().into_owned().collect()); + search_params.set_list(self.query_pairs()); } } diff --git a/components/script/dom/urlhelper.rs b/components/script/dom/urlhelper.rs index cd58612a6c1..dd22e16f551 100644 --- a/components/script/dom/urlhelper.rs +++ b/components/script/dom/urlhelper.rs @@ -3,32 +3,93 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::str::USVString; +use servo_url::ServoUrl; use std::borrow::ToOwned; -use url::{Url, quirks}; +use url::quirks; #[derive(HeapSizeOf)] pub struct UrlHelper; impl UrlHelper { - pub fn SameOrigin(url_a: &Url, url_b: &Url) -> bool { url_a.origin() == url_b.origin() } - pub fn Origin(url: &Url) -> USVString { USVString(quirks::origin(url)) } - pub fn Href(url: &Url) -> USVString { USVString(quirks::href(url).to_owned()) } - pub fn Hash(url: &Url) -> USVString { USVString(quirks::hash(url).to_owned()) } - pub fn Host(url: &Url) -> USVString { USVString(quirks::host(url).to_owned()) } - pub fn Port(url: &Url) -> USVString { USVString(quirks::port(url).to_owned()) } - pub fn Search(url: &Url) -> USVString { USVString(quirks::search(url).to_owned()) } - pub fn Hostname(url: &Url) -> USVString { USVString(quirks::hostname(url).to_owned()) } - pub fn Password(url: &Url) -> USVString { USVString(quirks::password(url).to_owned()) } - pub fn Pathname(url: &Url) -> USVString { USVString(quirks::pathname(url).to_owned()) } - pub fn Protocol(url: &Url) -> USVString { USVString(quirks::protocol(url).to_owned()) } - pub fn Username(url: &Url) -> USVString { USVString(quirks::username(url).to_owned()) } - pub fn SetHash(url: &mut Url, value: USVString) { quirks::set_hash(url, &value.0) } - pub fn SetHost(url: &mut Url, value: USVString) { let _ = quirks::set_host(url, &value.0); } - pub fn SetPort(url: &mut Url, value: USVString) { let _ = quirks::set_port(url, &value.0); } - pub fn SetSearch(url: &mut Url, value: USVString) { quirks::set_search(url, &value.0) } - pub fn SetPathname(url: &mut Url, value: USVString) { quirks::set_pathname(url, &value.0) } - pub fn SetHostname(url: &mut Url, value: USVString) { let _ = quirks::set_hostname(url, &value.0); } - pub fn SetPassword(url: &mut Url, value: USVString) { let _ = quirks::set_password(url, &value.0); } - pub fn SetProtocol(url: &mut Url, value: USVString) { let _ = quirks::set_protocol(url, &value.0); } - pub fn SetUsername(url: &mut Url, value: USVString) { let _ = quirks::set_username(url, &value.0); } + pub fn SameOrigin(url_a: &ServoUrl, url_b: &ServoUrl) -> bool { + url_a.origin() == url_b.origin() + } + pub fn Origin(url: &ServoUrl) -> USVString { + USVString(quirks::origin(url.as_url().unwrap()).to_owned()) + } + pub fn Href(url: &ServoUrl) -> USVString { + USVString(quirks::href(url.as_url().unwrap()).to_owned()) + } + pub fn Hash(url: &ServoUrl) -> USVString { + USVString(quirks::hash(url.as_url().unwrap()).to_owned()) + } + pub fn Host(url: &ServoUrl) -> USVString { + USVString(quirks::host(url.as_url().unwrap()).to_owned()) + } + pub fn Port(url: &ServoUrl) -> USVString { + USVString(quirks::port(url.as_url().unwrap()).to_owned()) + } + pub fn Search(url: &ServoUrl) -> USVString { + USVString(quirks::search(url.as_url().unwrap()).to_owned()) + } + pub fn Hostname(url: &ServoUrl) -> USVString { + USVString(quirks::hostname(url.as_url().unwrap()).to_owned()) + } + pub fn Password(url: &ServoUrl) -> USVString { + USVString(quirks::password(url.as_url().unwrap()).to_owned()) + } + pub fn Pathname(url: &ServoUrl) -> USVString { + USVString(quirks::pathname(url.as_url().unwrap()).to_owned()) + } + pub fn Protocol(url: &ServoUrl) -> USVString { + USVString(quirks::protocol(url.as_url().unwrap()).to_owned()) + } + pub fn Username(url: &ServoUrl) -> USVString { + USVString(quirks::username(url.as_url().unwrap()).to_owned()) + } + pub fn SetHash(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + quirks::set_hash(url, &value.0) + } + } + pub fn SetHost(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + let _ = quirks::set_host(url, &value.0); + } + } + pub fn SetPort(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + let _ = quirks::set_port(url, &value.0); + } + } + pub fn SetSearch(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + quirks::set_search(url, &value.0) + } + } + pub fn SetPathname(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + quirks::set_pathname(url, &value.0) + } + } + pub fn SetHostname(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + let _ = quirks::set_hostname(url, &value.0); + } + } + pub fn SetPassword(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + let _ = quirks::set_password(url, &value.0); + } + } + pub fn SetProtocol(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + let _ = quirks::set_protocol(url, &value.0); + } + } + pub fn SetUsername(url: &mut ServoUrl, value: USVString) { + if let Some(ref mut url) = url.as_mut_url() { + let _ = quirks::set_username(url, &value.0); + } + } } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index c5af5f4c39d..5428fc794fa 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -94,9 +94,7 @@ macro_rules! object_binding_to_js_or_null { { rooted!(in($cx) let mut rval = NullValue()); if let Some(bound_object) = $binding.get() { - unsafe { - bound_object.to_jsval($cx, rval.handle_mut()); - } + bound_object.to_jsval($cx, rval.handle_mut()); } rval.get() } @@ -624,8 +622,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { receiver.recv().unwrap() } + #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal { + unsafe fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal { let (sender, receiver) = ipc::channel().unwrap(); self.ipc_renderer .send(CanvasMsg::WebGL(WebGLCommand::GetBufferParameter(target, parameter, sender))) @@ -642,7 +641,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 - fn GetParameter(&self, cx: *mut JSContext, parameter: u32) -> JSVal { + unsafe fn GetParameter(&self, cx: *mut JSContext, parameter: u32) -> JSVal { // Handle the GL_*_BINDING without going all the way // to the GL, since we would just need to map back from GL's // returned ID to the WebGL* object we're tracking. @@ -693,9 +692,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { WebGLParameter::FloatArray(_) => panic!("Parameter should not be float array"), WebGLParameter::String(val) => { rooted!(in(cx) let mut rval = UndefinedValue()); - unsafe { - val.to_jsval(cx, rval.handle_mut()); - } + val.to_jsval(cx, rval.handle_mut()); rval.get() } WebGLParameter::Invalid => NullValue(), @@ -748,8 +745,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { Some(vec![]) } + #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.14 - fn GetExtension(&self, _cx: *mut JSContext, _name: DOMString) + unsafe fn GetExtension(&self, _cx: *mut JSContext, _name: DOMString) -> Option<NonZero<*mut JSObject>> { None } @@ -927,17 +925,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BufferData(&self, _cx: *mut JSContext, target: u32, data: *mut JSObject, usage: u32) -> Fallible<()> { + unsafe fn BufferData(&self, _cx: *mut JSContext, target: u32, data: *mut JSObject, usage: u32) -> Fallible<()> { if data.is_null() { return Ok(self.webgl_error(InvalidValue)); } - let data_vec = unsafe { - match array_buffer_to_vec::<u8>(data) { - Some(data) => data, - // Not an ArrayBuffer object, maybe an ArrayBufferView? - None => try!(fallible_array_buffer_view_to_vec::<u8>(data)), - } + let data_vec = match array_buffer_to_vec::<u8>(data) { + Some(data) => data, + // Not an ArrayBuffer object, maybe an ArrayBufferView? + None => try!(fallible_array_buffer_view_to_vec::<u8>(data)), }; let bound_buffer = match target { @@ -965,17 +961,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - fn BufferSubData(&self, _cx: *mut JSContext, target: u32, offset: i64, data: *mut JSObject) -> Fallible<()> { + unsafe fn BufferSubData(&self, _cx: *mut JSContext, target: u32, offset: i64, data: *mut JSObject) -> Fallible<()> { if data.is_null() { return Ok(self.webgl_error(InvalidValue)); } - let data_vec = unsafe { - match array_buffer_to_vec::<u8>(data) { - Some(data) => data, - // Not an ArrayBuffer object, maybe an ArrayBufferView? - None => try!(fallible_array_buffer_view_to_vec::<u8>(data)), - } + let data_vec = match array_buffer_to_vec::<u8>(data) { + Some(data) => data, + // Not an ArrayBuffer object, maybe an ArrayBufferView? + None => try!(fallible_array_buffer_view_to_vec::<u8>(data)), }; let bound_buffer = match target { @@ -1005,9 +999,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - fn CompressedTexImage2D(&self, _cx: *mut JSContext, _target: u32, _level: i32, _internal_format: u32, + unsafe fn CompressedTexImage2D(&self, _cx: *mut JSContext, _target: u32, _level: i32, _internal_format: u32, _width: i32, _height: i32, _border: i32, pixels: *mut JSObject) -> Fallible<()> { - let _data = try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(pixels) }); + let _data = try!(fallible_array_buffer_view_to_vec::<u8>(pixels) ); // FIXME: No compressed texture format is currently supported, so error out as per // https://www.khronos.org/registry/webgl/specs/latest/1.0/#COMPRESSED_TEXTURE_SUPPORT self.webgl_error(InvalidEnum); @@ -1016,10 +1010,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - fn CompressedTexSubImage2D(&self, _cx: *mut JSContext, _target: u32, _level: i32, + unsafe fn CompressedTexSubImage2D(&self, _cx: *mut JSContext, _target: u32, _level: i32, _xoffset: i32, _yoffset: i32, _width: i32, _height: i32, _format: u32, pixels: *mut JSObject) -> Fallible<()> { - let _data = try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(pixels) }); + let _data = try!(fallible_array_buffer_view_to_vec::<u8>(pixels)); // FIXME: No compressed texture format is currently supported, so error out as per // https://www.khronos.org/registry/webgl/specs/latest/1.0/#COMPRESSED_TEXTURE_SUPPORT self.webgl_error(InvalidEnum); @@ -1568,8 +1562,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } } + #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn GetProgramParameter(&self, _: *mut JSContext, program: Option<&WebGLProgram>, param_id: u32) -> JSVal { + unsafe fn GetProgramParameter(&self, _: *mut JSContext, program: Option<&WebGLProgram>, param_id: u32) -> JSVal { if let Some(program) = program { match handle_potential_webgl_error!(self, program.parameter(param_id), WebGLParameter::Invalid) { WebGLParameter::Int(val) => Int32Value(val), @@ -1591,8 +1586,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { shader.and_then(|s| s.info_log()).map(DOMString::from) } + #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn GetShaderParameter(&self, _: *mut JSContext, shader: Option<&WebGLShader>, param_id: u32) -> JSVal { + unsafe fn GetShaderParameter(&self, _: *mut JSContext, shader: Option<&WebGLShader>, param_id: u32) -> JSVal { if let Some(shader) = shader { match handle_potential_webgl_error!(self, shader.parameter(param_id), WebGLParameter::Invalid) { WebGLParameter::Int(val) => Int32Value(val), @@ -1621,14 +1617,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - fn GetVertexAttrib(&self, cx: *mut JSContext, index: u32, pname: u32) -> JSVal { + unsafe fn GetVertexAttrib(&self, cx: *mut JSContext, index: u32, pname: u32) -> JSVal { if index == 0 && pname == constants::CURRENT_VERTEX_ATTRIB { rooted!(in(cx) let mut result = UndefinedValue()); let (x, y, z, w) = self.current_vertex_attrib_0.get(); let attrib = vec![x, y, z, w]; - unsafe { - attrib.to_jsval(cx, result.handle_mut()); - } + attrib.to_jsval(cx, result.handle_mut()); return result.get() } @@ -1642,9 +1636,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { WebGLParameter::Float(_) => panic!("Vertex attrib should not be float"), WebGLParameter::FloatArray(val) => { rooted!(in(cx) let mut result = UndefinedValue()); - unsafe { - val.to_jsval(cx, result.handle_mut()); - } + val.to_jsval(cx, result.handle_mut()); result.get() } WebGLParameter::Invalid => NullValue(), @@ -1787,13 +1779,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.12 - fn ReadPixels(&self, _cx: *mut JSContext, x: i32, y: i32, width: i32, height: i32, + unsafe fn ReadPixels(&self, _cx: *mut JSContext, x: i32, y: i32, width: i32, height: i32, format: u32, pixel_type: u32, pixels: *mut JSObject) -> Fallible<()> { if pixels.is_null() { return Ok(self.webgl_error(InvalidValue)); } - let mut data = match unsafe { array_buffer_view_data::<u8>(pixels) } { + let mut data = match { array_buffer_view_data::<u8>(pixels) } { Some(data) => data, None => return Err(Error::Type("Not an ArrayBufferView".to_owned())), }; @@ -1802,7 +1794,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { return Ok(()); } - match unsafe { JS_GetArrayBufferViewType(pixels) } { + match { JS_GetArrayBufferViewType(pixels) } { Type::Uint8 => (), _ => return Ok(self.webgl_error(InvalidOperation)), } @@ -2035,12 +2027,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn Uniform1iv(&self, + unsafe fn Uniform1iv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default)); if self.validate_uniform_parameters(uniform, UniformSetterType::Int, &data_vec) { self.ipc_renderer @@ -2053,12 +2045,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn Uniform1fv(&self, + unsafe fn Uniform1fv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if self.validate_uniform_parameters(uniform, UniformSetterType::Float, &data_vec) { self.ipc_renderer @@ -2082,12 +2074,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn Uniform2fv(&self, + unsafe fn Uniform2fv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec2, @@ -2115,12 +2107,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn Uniform2iv(&self, + unsafe fn Uniform2iv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default)); if self.validate_uniform_parameters(uniform, UniformSetterType::IntVec2, @@ -2148,12 +2140,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn Uniform3fv(&self, + unsafe fn Uniform3fv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec3, @@ -2181,12 +2173,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn Uniform3iv(&self, + unsafe fn Uniform3iv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default)); if self.validate_uniform_parameters(uniform, UniformSetterType::IntVec3, @@ -2215,12 +2207,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn Uniform4iv(&self, + unsafe fn Uniform4iv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<i32>(cx, data, ConversionBehavior::Default)); if self.validate_uniform_parameters(uniform, UniformSetterType::IntVec4, @@ -2248,12 +2240,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn Uniform4fv(&self, + unsafe fn Uniform4fv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if self.validate_uniform_parameters(uniform, UniformSetterType::FloatVec4, @@ -2268,13 +2260,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn UniformMatrix2fv(&self, + unsafe fn UniformMatrix2fv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, transpose: bool, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if self.validate_uniform_parameters(uniform, UniformSetterType::FloatMat2, &data_vec) { @@ -2288,13 +2280,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn UniformMatrix3fv(&self, + unsafe fn UniformMatrix3fv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, transpose: bool, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if self.validate_uniform_parameters(uniform, UniformSetterType::FloatMat3, &data_vec) { @@ -2308,13 +2300,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn UniformMatrix4fv(&self, + unsafe fn UniformMatrix4fv(&self, cx: *mut JSContext, uniform: Option<&WebGLUniformLocation>, transpose: bool, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if self.validate_uniform_parameters(uniform, UniformSetterType::FloatMat4, &data_vec) { @@ -2352,9 +2344,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn VertexAttrib1fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> { + unsafe fn VertexAttrib1fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if data_vec.len() < 1 { return Ok(self.webgl_error(InvalidOperation)); } @@ -2369,9 +2361,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn VertexAttrib2fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> { + unsafe fn VertexAttrib2fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if data_vec.len() < 2 { return Ok(self.webgl_error(InvalidOperation)); } @@ -2386,9 +2378,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn VertexAttrib3fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> { + unsafe fn VertexAttrib3fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if data_vec.len() < 3 { return Ok(self.webgl_error(InvalidOperation)); } @@ -2403,9 +2395,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - fn VertexAttrib4fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> { + unsafe fn VertexAttrib4fv(&self, cx: *mut JSContext, indx: u32, data: *mut JSObject) -> Fallible<()> { assert!(!data.is_null()); - let data_vec = try!(unsafe { typed_array_or_sequence_to_vec::<f32>(cx, data, ()) }); + let data_vec = try!(typed_array_or_sequence_to_vec::<f32>(cx, data, ())); if data_vec.len() < 4 { return Ok(self.webgl_error(InvalidOperation)); } @@ -2468,7 +2460,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 #[allow(unsafe_code)] - fn TexImage2D(&self, + unsafe fn TexImage2D(&self, _cx: *mut JSContext, target: u32, level: i32, @@ -2482,7 +2474,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { let data = if data_ptr.is_null() { None } else { - Some(try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(data_ptr) })) + Some(try!(fallible_array_buffer_view_to_vec::<u8>(data_ptr))) }; let validator = TexImage2DValidator::new(self, target, level, @@ -2504,7 +2496,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { }; let expected_byte_length = - match unsafe { self.validate_tex_image_2d_data(width, height, + match { self.validate_tex_image_2d_data(width, height, format, data_type, data_ptr) } { Ok(byte_length) => byte_length, @@ -2574,7 +2566,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 #[allow(unsafe_code)] - fn TexSubImage2D(&self, + unsafe fn TexSubImage2D(&self, _cx: *mut JSContext, target: u32, level: i32, @@ -2588,7 +2580,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { let data = if data_ptr.is_null() { None } else { - Some(try!(unsafe { fallible_array_buffer_view_to_vec::<u8>(data_ptr) })) + Some(try!(fallible_array_buffer_view_to_vec::<u8>(data_ptr))) }; @@ -2610,7 +2602,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { }; let expected_byte_length = - match unsafe { self.validate_tex_image_2d_data(width, height, + match { self.validate_tex_image_2d_data(width, height, format, data_type, data_ptr) } { Ok(byte_length) => byte_length, diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 1764db20764..d3486b7ad22 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -36,6 +36,7 @@ use net_traits::unwrap_websocket_protocol; use script_runtime::CommonScriptMsg; use script_runtime::ScriptThreadEventCategory::WebSocketEvent; use script_thread::{Runnable, RunnableWrapper}; +use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; @@ -43,7 +44,6 @@ use std::ptr; use std::thread; use task_source::TaskSource; use task_source::networking::NetworkingTaskSource; -use websocket::client::request::Url; use websocket::header::{Headers, WebSocketProtocol}; use websocket::ws::util::url::parse_url; @@ -171,7 +171,7 @@ pub fn fail_the_websocket_connection(address: Trusted<WebSocket>, #[dom_struct] pub struct WebSocket { eventtarget: EventTarget, - url: Url, + url: ServoUrl, ready_state: Cell<WebSocketRequestState>, buffered_amount: Cell<u64>, clearing_buffer: Cell<bool>, //Flag to tell if there is a running thread to clear buffered_amount @@ -182,7 +182,7 @@ pub struct WebSocket { } impl WebSocket { - fn new_inherited(url: Url) -> WebSocket { + fn new_inherited(url: ServoUrl) -> WebSocket { WebSocket { eventtarget: EventTarget::new_inherited(), url: url, @@ -195,7 +195,7 @@ impl WebSocket { } } - fn new(global: &GlobalScope, url: Url) -> Root<WebSocket> { + fn new(global: &GlobalScope, url: ServoUrl) -> Root<WebSocket> { reflect_dom_object(box WebSocket::new_inherited(url), global, WebSocketBinding::Wrap) } @@ -205,10 +205,10 @@ impl WebSocket { protocols: Option<StringOrStringSequence>) -> Fallible<Root<WebSocket>> { // Step 1. - let resource_url = try!(Url::parse(&url).map_err(|_| Error::Syntax)); + let resource_url = try!(ServoUrl::parse(&url).map_err(|_| Error::Syntax)); // Although we do this replace and parse operation again in the resource thread, // we try here to be able to immediately throw a syntax error on failure. - let _ = try!(parse_url(&replace_hosts(&resource_url)).map_err(|_| Error::Syntax)); + let _ = try!(parse_url(&replace_hosts(&resource_url).as_url().unwrap()).map_err(|_| Error::Syntax)); // Step 2: Disallow https -> ws connections. // Step 3: Potentially block access to some ports. diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 63485e45dfc..066643f3fb1 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -76,6 +76,7 @@ use script_traits::{DocumentState, TimerEvent, TimerEventId}; use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, WindowSizeData, WindowSizeType}; use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use servo_atoms::Atom; +use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; @@ -102,7 +103,6 @@ use time; use timers::{IsInterval, TimerCallback}; #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] use tinyfiledialogs::{self, MessageBoxIcon}; -use url::Url; use util::geometry::{self, max_rect}; use util::opts; use util::prefs::PREFS; @@ -483,8 +483,10 @@ impl WindowMethods for Window { self.navigator.or_init(|| Navigator::new(self)) } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout - fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 { + unsafe fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, + args: Vec<HandleValue>) -> i32 { self.upcast::<GlobalScope>().set_timeout_or_interval( TimerCallback::FunctionTimerCallback(callback), args, @@ -492,8 +494,10 @@ impl WindowMethods for Window { IsInterval::NonInterval) } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout - fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 { + unsafe fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString, + timeout: i32, args: Vec<HandleValue>) -> i32 { self.upcast::<GlobalScope>().set_timeout_or_interval( TimerCallback::StringTimerCallback(callback), args, @@ -506,8 +510,10 @@ impl WindowMethods for Window { self.upcast::<GlobalScope>().clear_timeout_or_interval(handle); } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval - fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 { + unsafe fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>, + timeout: i32, args: Vec<HandleValue>) -> i32 { self.upcast::<GlobalScope>().set_timeout_or_interval( TimerCallback::FunctionTimerCallback(callback), args, @@ -515,8 +521,10 @@ impl WindowMethods for Window { IsInterval::Interval) } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval - fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 { + unsafe fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString, + timeout: i32, args: Vec<HandleValue>) -> i32 { self.upcast::<GlobalScope>().set_timeout_or_interval( TimerCallback::StringTimerCallback(callback), args, @@ -610,8 +618,9 @@ impl WindowMethods for Window { doc.cancel_animation_frame(ident); } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-window-postmessage - fn PostMessage(&self, + unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue, origin: DOMString) @@ -624,7 +633,7 @@ impl WindowMethods for Window { // object, not self's. Some(self.Document().origin().copy()) }, - url => match Url::parse(&url) { + url => match ServoUrl::parse(&url) { Ok(url) => Some(Origin::new(&url)), Err(_) => return Err(Error::Syntax), } @@ -670,8 +679,8 @@ impl WindowMethods for Window { } #[allow(unsafe_code)] - fn WebdriverCallback(&self, cx: *mut JSContext, val: HandleValue) { - let rv = unsafe { jsval_to_webdriver(cx, val) }; + unsafe fn WebdriverCallback(&self, cx: *mut JSContext, val: HandleValue) { + let rv = jsval_to_webdriver(cx, val); let opt_chan = self.webdriver_script_chan.borrow_mut().take(); if let Some(chan) = opt_chan { chan.send(rv).unwrap(); @@ -860,7 +869,7 @@ impl WindowMethods for Window { // check-tidy: no specs after this line fn OpenURLInDefaultBrowser(&self, href: DOMString) -> ErrorResult { - let url = try!(Url::parse(&href).map_err(|e| { + let url = try!(ServoUrl::parse(&href).map_err(|e| { Error::Type(format!("Couldn't parse URL: {}", e)) })); match open::that(url.as_str()) { @@ -1322,7 +1331,7 @@ impl Window { } /// Commence a new URL load which will either replace this window or scroll to a fragment. - pub fn load_url(&self, url: Url, replace: bool, referrer_policy: Option<ReferrerPolicy>) { + pub fn load_url(&self, url: ServoUrl, replace: bool, referrer_policy: Option<ReferrerPolicy>) { let doc = self.Document(); let referrer_policy = referrer_policy.or(doc.get_referrer_policy()); @@ -1355,7 +1364,7 @@ impl Window { self.window_size.get() } - pub fn get_url(&self) -> Url { + pub fn get_url(&self) -> ServoUrl { (*self.Document().url()).clone() } @@ -1511,6 +1520,7 @@ impl Window { } impl Window { + #[allow(unsafe_code)] pub fn new(runtime: Rc<Runtime>, script_chan: MainThreadScriptChan, dom_task_source: DOMManipulationTaskSource, @@ -1598,7 +1608,9 @@ impl Window { test_runner: Default::default(), }; - WindowBinding::Wrap(runtime.cx(), win) + unsafe { + WindowBinding::Wrap(runtime.cx(), win) + } } } diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 42c0d1e553d..011159715f8 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -164,8 +164,9 @@ impl Worker { } impl WorkerMethods for Worker { + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-worker-postmessage - fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { + unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { let data = try!(StructuredCloneData::write(cx, message)); let address = Trusted::new(self); diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 041ce8448de..81004a9dbd2 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -34,6 +34,7 @@ use script_runtime::{ScriptThreadEventCategory, PromiseJobQueue, EnqueuedPromise use script_thread::{Runnable, RunnableWrapper}; use script_traits::{TimerEvent, TimerEventId}; use script_traits::WorkerGlobalScopeInit; +use servo_url::ServoUrl; use std::default::Default; use std::panic; use std::rc::Rc; @@ -43,7 +44,6 @@ use std::sync::mpsc::Receiver; use task_source::file_reading::FileReadingTaskSource; use task_source::networking::NetworkingTaskSource; use timers::{IsInterval, TimerCallback}; -use url::Url; pub fn prepare_workerscope_init(global: &GlobalScope, devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>) -> WorkerGlobalScopeInit { @@ -68,7 +68,7 @@ pub struct WorkerGlobalScope { globalscope: GlobalScope, worker_id: WorkerId, - worker_url: Url, + worker_url: ServoUrl, #[ignore_heap_size_of = "Arc"] closing: Option<Arc<AtomicBool>>, #[ignore_heap_size_of = "Defined in js"] @@ -91,7 +91,7 @@ pub struct WorkerGlobalScope { impl WorkerGlobalScope { pub fn new_inherited(init: WorkerGlobalScopeInit, - worker_url: Url, + worker_url: ServoUrl, runtime: Runtime, from_devtools_receiver: Receiver<DevtoolScriptControlMsg>, timer_event_chan: IpcSender<TimerEvent>, @@ -144,7 +144,7 @@ impl WorkerGlobalScope { } } - pub fn get_url(&self) -> &Url { + pub fn get_url(&self) -> &ServoUrl { &self.worker_url } @@ -268,8 +268,10 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { base64_atob(atob) } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout - fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 { + unsafe fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>, + timeout: i32, args: Vec<HandleValue>) -> i32 { self.upcast::<GlobalScope>().set_timeout_or_interval( TimerCallback::FunctionTimerCallback(callback), args, @@ -277,8 +279,10 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { IsInterval::NonInterval) } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout - fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 { + unsafe fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString, + timeout: i32, args: Vec<HandleValue>) -> i32 { self.upcast::<GlobalScope>().set_timeout_or_interval( TimerCallback::StringTimerCallback(callback), args, @@ -291,8 +295,10 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { self.upcast::<GlobalScope>().clear_timeout_or_interval(handle); } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval - fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 { + unsafe fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>, + timeout: i32, args: Vec<HandleValue>) -> i32 { self.upcast::<GlobalScope>().set_timeout_or_interval( TimerCallback::FunctionTimerCallback(callback), args, @@ -300,8 +306,10 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { IsInterval::Interval) } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval - fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 { + unsafe fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString, + timeout: i32, args: Vec<HandleValue>) -> i32 { self.upcast::<GlobalScope>().set_timeout_or_interval( TimerCallback::StringTimerCallback(callback), args, diff --git a/components/script/dom/workerlocation.rs b/components/script/dom/workerlocation.rs index 287a803a612..aee42330463 100644 --- a/components/script/dom/workerlocation.rs +++ b/components/script/dom/workerlocation.rs @@ -9,24 +9,24 @@ use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::{DOMString, USVString}; use dom::urlhelper::UrlHelper; use dom::workerglobalscope::WorkerGlobalScope; -use url::Url; +use servo_url::ServoUrl; // https://html.spec.whatwg.org/multipage/#worker-locations #[dom_struct] pub struct WorkerLocation { reflector_: Reflector, - url: Url, + url: ServoUrl, } impl WorkerLocation { - fn new_inherited(url: Url) -> WorkerLocation { + fn new_inherited(url: ServoUrl) -> WorkerLocation { WorkerLocation { reflector_: Reflector::new(), url: url, } } - pub fn new(global: &WorkerGlobalScope, url: Url) -> Root<WorkerLocation> { + pub fn new(global: &WorkerGlobalScope, url: ServoUrl) -> Root<WorkerLocation> { reflect_dom_object(box WorkerLocation::new_inherited(url), global, WorkerLocationBinding::Wrap) diff --git a/components/script/dom/xmldocument.rs b/components/script/dom/xmldocument.rs index 87038d3aa45..191b142dbea 100644 --- a/components/script/dom/xmldocument.rs +++ b/components/script/dom/xmldocument.rs @@ -16,7 +16,7 @@ use dom::location::Location; use dom::node::Node; use dom::window::Window; use js::jsapi::{JSContext, JSObject}; -use url::Url; +use servo_url::ServoUrl; // https://dom.spec.whatwg.org/#xmldocument #[dom_struct] @@ -27,7 +27,7 @@ pub struct XMLDocument { impl XMLDocument { fn new_inherited(window: &Window, browsing_context: Option<&BrowsingContext>, - url: Option<Url>, + url: Option<ServoUrl>, is_html_document: IsHTMLDocument, content_type: Option<DOMString>, last_modified: Option<String>, @@ -49,7 +49,7 @@ impl XMLDocument { pub fn new(window: &Window, browsing_context: Option<&BrowsingContext>, - url: Option<Url>, + url: Option<ServoUrl>, doctype: IsHTMLDocument, content_type: Option<DOMString>, last_modified: Option<String>, @@ -86,8 +86,9 @@ impl XMLDocumentMethods for XMLDocument { self.upcast::<Document>().SupportedPropertyNames() } + #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter - fn NamedGetter(&self, _cx: *mut JSContext, name: DOMString) -> Option<NonZero<*mut JSObject>> { + unsafe fn NamedGetter(&self, _cx: *mut JSContext, name: DOMString) -> Option<NonZero<*mut JSObject>> { self.upcast::<Document>().NamedGetter(_cx, name) } } diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 57191d1d4e9..e9d440ffed9 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -55,6 +55,7 @@ use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode use net_traits::trim_http_whitespace; use network_listener::{NetworkListener, PreInvoke}; use servo_atoms::Atom; +use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::borrow::ToOwned; use std::cell::Cell; @@ -64,7 +65,7 @@ use std::sync::{Arc, Mutex}; use task_source::networking::NetworkingTaskSource; use time; use timers::{OneshotTimerCallback, OneshotTimerHandle}; -use url::{Position, Url}; +use url::Position; use util::prefs::PREFS; #[derive(JSTraceable, PartialEq, Copy, Clone, HeapSizeOf)] @@ -137,7 +138,7 @@ pub struct XMLHttpRequest { // Associated concepts #[ignore_heap_size_of = "Defined in hyper"] request_method: DOMRefCell<Method>, - request_url: DOMRefCell<Option<Url>>, + request_url: DOMRefCell<Option<ServoUrl>>, #[ignore_heap_size_of = "Defined in hyper"] request_headers: DOMRefCell<Headers>, request_body_len: Cell<usize>, @@ -149,7 +150,7 @@ pub struct XMLHttpRequest { fetch_time: Cell<i64>, generation_id: Cell<GenerationId>, response_status: Cell<Result<(), ()>>, - referrer_url: Option<Url>, + referrer_url: Option<ServoUrl>, referrer_policy: Option<ReferrerPolicy>, } @@ -169,7 +170,7 @@ impl XMLHttpRequest { timeout: Cell::new(0u32), with_credentials: Cell::new(false), upload: JS::from_ref(&*XMLHttpRequestUpload::new(global)), - response_url: DOMRefCell::new(String::from("")), + response_url: DOMRefCell::new(String::new()), status: Cell::new(0), status_text: DOMRefCell::new(ByteString::new(vec!())), response: DOMRefCell::new(ByteString::new(vec!())), @@ -272,7 +273,7 @@ impl XMLHttpRequest { } impl LoadOrigin for XMLHttpRequest { - fn referrer_url(&self) -> Option<Url> { + fn referrer_url(&self) -> Option<ServoUrl> { return self.referrer_url.clone(); } @@ -760,47 +761,45 @@ impl XMLHttpRequestMethods for XMLHttpRequest { #[allow(unsafe_code)] // https://xhr.spec.whatwg.org/#the-response-attribute - fn Response(&self, cx: *mut JSContext) -> JSVal { - unsafe { - rooted!(in(cx) let mut rval = UndefinedValue()); - match self.response_type.get() { - XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Text => { - let ready_state = self.ready_state.get(); - // Step 2 - if ready_state == XMLHttpRequestState::Done || ready_state == XMLHttpRequestState::Loading { - self.text_response().to_jsval(cx, rval.handle_mut()); - } else { - // Step 1 - "".to_jsval(cx, rval.handle_mut()); - } - }, + unsafe fn Response(&self, cx: *mut JSContext) -> JSVal { + rooted!(in(cx) let mut rval = UndefinedValue()); + match self.response_type.get() { + XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Text => { + let ready_state = self.ready_state.get(); + // Step 2 + if ready_state == XMLHttpRequestState::Done || ready_state == XMLHttpRequestState::Loading { + self.text_response().to_jsval(cx, rval.handle_mut()); + } else { // Step 1 - _ if self.ready_state.get() != XMLHttpRequestState::Done => { + "".to_jsval(cx, rval.handle_mut()); + } + }, + // Step 1 + _ if self.ready_state.get() != XMLHttpRequestState::Done => { + return NullValue(); + }, + // Step 2 + XMLHttpRequestResponseType::Document => { + let op_doc = self.document_response(); + if let Some(doc) = op_doc { + doc.to_jsval(cx, rval.handle_mut()); + } else { + // Substep 1 return NullValue(); - }, - // Step 2 - XMLHttpRequestResponseType::Document => { - let op_doc = self.document_response(); - if let Some(doc) = op_doc { - doc.to_jsval(cx, rval.handle_mut()); - } else { - // Substep 1 - return NullValue(); - } - }, - XMLHttpRequestResponseType::Json => { - self.json_response(cx).to_jsval(cx, rval.handle_mut()); - }, - XMLHttpRequestResponseType::Blob => { - self.blob_response().to_jsval(cx, rval.handle_mut()); - }, - _ => { - // XXXManishearth handle other response types - self.response.borrow().to_jsval(cx, rval.handle_mut()); } + }, + XMLHttpRequestResponseType::Json => { + self.json_response(cx).to_jsval(cx, rval.handle_mut()); + }, + XMLHttpRequestResponseType::Blob => { + self.blob_response().to_jsval(cx, rval.handle_mut()); + }, + _ => { + // XXXManishearth handle other response types + self.response.borrow().to_jsval(cx, rval.handle_mut()); } - rval.get() } + rval.get() } // https://xhr.spec.whatwg.org/#the-responsetext-attribute @@ -862,7 +861,8 @@ impl XMLHttpRequest { } fn process_headers_available(&self, - gen_id: GenerationId, metadata: Result<FetchMetadata, NetworkError>) + gen_id: GenerationId, + metadata: Result<FetchMetadata, NetworkError>) -> Result<(), Error> { let metadata = match metadata { Ok(meta) => match meta { @@ -878,7 +878,7 @@ impl XMLHttpRequest { }, }; - *self.response_url.borrow_mut() = metadata.final_url[..Position::AfterQuery].to_owned(); + *self.response_url.borrow_mut() = metadata.final_url.as_url().unwrap()[..Position::AfterQuery].to_owned(); // XXXManishearth Clear cache entries in case of a network error self.process_partial_response(XHRProgress::HeadersReceived( |