diff options
Diffstat (limited to 'src/components/script/dom')
-rw-r--r-- | src/components/script/dom/bindings/codegen/CodegenRust.py | 10 | ||||
-rw-r--r-- | src/components/script/dom/bindings/js.rs | 3 | ||||
-rw-r--r-- | src/components/script/dom/bindings/trace.rs | 69 | ||||
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 8 | ||||
-rw-r--r-- | src/components/script/dom/document.rs | 37 | ||||
-rw-r--r-- | src/components/script/dom/htmliframeelement.rs | 21 | ||||
-rw-r--r-- | src/components/script/dom/htmlimageelement.rs | 26 | ||||
-rw-r--r-- | src/components/script/dom/htmlstyleelement.rs | 2 | ||||
-rw-r--r-- | src/components/script/dom/location.rs | 16 | ||||
-rw-r--r-- | src/components/script/dom/node.rs | 3 | ||||
-rw-r--r-- | src/components/script/dom/window.rs | 67 |
11 files changed, 137 insertions, 125 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index 9470b61fab2..8d89fe1b879 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1864,7 +1864,7 @@ def CreateBindingJSObject(descriptor, parent=None): assert not descriptor.createGlobal handler = """ let js_info = aScope.get().page().js_info(); - let handler = js_info.get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint)); + let handler = js_info.get_ref().dom_static.proxy_handlers.deref().get(&(PrototypeList::id::%s as uint)); """ % descriptor.name create += handler + """ let obj = NewProxyObject(aCx, *handler, &PrivateValue(squirrel_away_unique(aObject) as *libc::c_void), @@ -2204,7 +2204,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): ('Some(%s)' % TRACE_HOOK_NAME), self.descriptor.name) - return (body + """ let cx = js_info.js_context.deref().ptr; + return (body + """ let cx = (*js_info.js_context).deref().ptr; let receiver = js_info.js_compartment.global_obj; let global: *JSObject = JS_GetGlobalForObject(cx, receiver); assert!(%s(cx, global, receiver).is_not_null());""" % (getter)) @@ -4517,7 +4517,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::utils::{ThrowingConstructor, unwrap, unwrap_jsmanaged}', 'dom::bindings::utils::{VoidVal, with_gc_disabled}', 'dom::bindings::utils::{with_gc_enabled}', - 'dom::bindings::trace::Traceable', + 'dom::bindings::trace::JSTraceable', 'dom::bindings::callback::{CallbackContainer,CallbackInterface}', 'dom::bindings::callback::{CallSetup,ExceptionHandling}', 'dom::bindings::callback::{WrapCallThisObject}', @@ -5472,7 +5472,7 @@ class GlobalGenRoots(): allprotos = [CGGeneric("#[allow(unused_imports)];\n"), CGGeneric("use dom::types::*;\n"), CGGeneric("use dom::bindings::js::JS;\n"), - CGGeneric("use dom::bindings::trace::Traceable;\n"), + CGGeneric("use dom::bindings::trace::JSTraceable;\n"), CGGeneric("use serialize::{Encodable, Encoder};\n"), CGGeneric("use js::jsapi::JSTracer;\n\n")] for descriptor in descriptors: @@ -5523,7 +5523,7 @@ class GlobalGenRoots(): 'toBound': name + 'Derived'})), CGGeneric("impl %s for %s {}\n\n" % (name + 'Cast', name))] - trace = [CGGeneric(string.Template('''impl Traceable for ${name} { + trace = [CGGeneric(string.Template('''impl JSTraceable for ${name} { fn trace(&self, tracer: *mut JSTracer) { unsafe { self.encode(&mut *tracer); diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs index 71ca2d7ac86..5d2640a2bdf 100644 --- a/src/components/script/dom/bindings/js.rs +++ b/src/components/script/dom/bindings/js.rs @@ -44,8 +44,9 @@ impl<T: Reflectable> JS<T> { pub unsafe fn from_trusted_node_address(inner: TrustedNodeAddress) -> JS<T> { + let TrustedNodeAddress(addr) = inner; JS { - ptr: RefCell::new(inner as *mut T) + ptr: RefCell::new(addr as *mut T) } } } diff --git a/src/components/script/dom/bindings/trace.rs b/src/components/script/dom/bindings/trace.rs index 1cedf246728..4e32bacec68 100644 --- a/src/components/script/dom/bindings/trace.rs +++ b/src/components/script/dom/bindings/trace.rs @@ -8,6 +8,7 @@ use dom::bindings::utils::{Reflectable, Reflector}; use js::jsapi::{JSTracer, JS_CallTracer, JSTRACE_OBJECT}; use std::cast; +use std::cell::RefCell; use std::libc; use std::ptr; use std::ptr::null; @@ -30,7 +31,7 @@ impl<S: Encoder> Encodable<S> for Reflector { } } -pub trait Traceable { +pub trait JSTraceable { fn trace(&self, trc: *mut JSTracer); } @@ -46,3 +47,69 @@ pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Ref }); } } + +/// Encapsulates a type that cannot easily have Encodable derived automagically, +/// but also does not need to be made known to the SpiderMonkey garbage collector. +/// Use only with types that are not associated with a JS reflector and do not contain +/// fields of types associated with JS reflectors. +pub struct Untraceable<T> { + priv inner: T, +} + +impl<T> Untraceable<T> { + pub fn new(val: T) -> Untraceable<T> { + Untraceable { + inner: val + } + } +} + +impl<S: Encoder, T> Encodable<S> for Untraceable<T> { + fn encode(&self, _s: &mut S) { + } +} + +impl<T> Deref<T> for Untraceable<T> { + fn deref<'a>(&'a self) -> &'a T { + &self.inner + } +} + +impl<T> DerefMut<T> for Untraceable<T> { + fn deref_mut<'a>(&'a mut self) -> &'a mut T { + &mut self.inner + } +} + +/// Encapsulates a type that can be traced but is boxed in a type we don't control +/// (such as RefCell). Wrap a field in Traceable and implement the Encodable trait +/// for that new concrete type to achieve magic compiler-derived trace hooks. +pub struct Traceable<T> { + priv inner: T +} + +impl<T> Traceable<T> { + pub fn new(val: T) -> Traceable<T> { + Traceable { + inner: val + } + } +} + +impl<T> Deref<T> for Traceable<T> { + fn deref<'a>(&'a self) -> &'a T { + &self.inner + } +} + +impl<T> DerefMut<T> for Traceable<T> { + fn deref_mut<'a>(&'a mut self) -> &'a mut T { + &mut self.inner + } +} + +impl<S: Encoder, T: Encodable<S>> Encodable<S> for Traceable<RefCell<T>> { + fn encode(&self, s: &mut S) { + self.borrow().encode(s) + } +}
\ No newline at end of file diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index ec1472bac28..71c82ae86dc 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -6,6 +6,7 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; use dom::bindings::conversions::FromJSValConvertible; use dom::bindings::js::JS; +use dom::bindings::trace::Untraceable; use dom::window; use servo_util::str::DOMString; @@ -42,13 +43,14 @@ use js::JSPROP_PERMANENT; use js::{JSFUN_CONSTRUCTOR, JSPROP_READONLY}; use js; +#[deriving(Encodable)] pub struct GlobalStaticData { - proxy_handlers: HashMap<uint, *libc::c_void> + proxy_handlers: Untraceable<HashMap<uint, *libc::c_void>> } pub fn GlobalStaticData() -> GlobalStaticData { GlobalStaticData { - proxy_handlers: HashMap::new() + proxy_handlers: Untraceable::new(HashMap::new()) } } @@ -533,7 +535,7 @@ fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext { let win = global_object_for_js_object(obj); let js_info = win.get().page().js_info(); match *js_info { - Some(ref info) => info.js_context.deref().ptr, + Some(ref info) => info.js_context.deref().deref().ptr, None => fail!("no JS context for DOM global") } } diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs index f4391e4e541..637785a6bbc 100644 --- a/src/components/script/dom/document.rs +++ b/src/components/script/dom/document.rs @@ -8,6 +8,7 @@ use dom::bindings::codegen::InheritTypes::{HTMLHeadElementCast, TextCast, Elemen use dom::bindings::codegen::InheritTypes::{DocumentTypeCast, HTMLHtmlElementCast}; use dom::bindings::codegen::DocumentBinding; use dom::bindings::js::JS; +use dom::bindings::trace::Untraceable; use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object}; use dom::bindings::error::{ErrorResult, Fallible, NotSupported, InvalidCharacter, HierarchyRequest, NamespaceError}; use dom::bindings::utils::{xml_name_type, InvalidXMLName, Name, QName}; @@ -46,8 +47,6 @@ use js::jsapi::JSContext; use std::ascii::StrAsciiExt; use url::{Url, from_str}; -use serialize::{Encoder, Encodable}; - #[deriving(Eq,Encodable)] pub enum IsHTMLDocument { HTMLDocument, @@ -64,17 +63,8 @@ pub struct Document { content_type: DOMString, encoding_name: DOMString, is_html_document: bool, - priv extra: Untraceable, -} - -struct Untraceable { - url: Url, - quirks_mode: QuirksMode, -} - -impl<S: Encoder> Encodable<S> for Untraceable { - fn encode(&self, _: &mut S) { - } + url: Untraceable<Url>, + quirks_mode: Untraceable<QuirksMode>, } impl DocumentDerived for EventTarget { @@ -106,6 +96,8 @@ impl Document { url: Option<Url>, is_html_document: IsHTMLDocument, content_type: Option<DOMString>) -> Document { + let url = url.unwrap_or_else(|| from_str("about:blank").unwrap()); + Document { node: Node::new_without_doc(DocumentNodeTypeId), reflector_: Reflector::new(), @@ -121,14 +113,9 @@ impl Document { NonHTMLDocument => ~"application/xml" } }, - extra: Untraceable { - url: match url { - None => from_str("about:blank").unwrap(), - Some(_url) => _url - }, - // http://dom.spec.whatwg.org/#concept-document-quirks - quirks_mode: NoQuirks, - }, + url: Untraceable::new(url), + // http://dom.spec.whatwg.org/#concept-document-quirks + quirks_mode: Untraceable::new(NoQuirks), // http://dom.spec.whatwg.org/#concept-document-encoding encoding_name: ~"utf-8", is_html_document: is_html_document == HTMLDocument, @@ -143,7 +130,7 @@ impl Document { impl Document { pub fn url<'a>(&'a self) -> &'a Url { - &self.extra.url + &*self.url } } @@ -185,18 +172,18 @@ impl Document { // http://dom.spec.whatwg.org/#dom-document-compatmode pub fn CompatMode(&self) -> DOMString { - match self.extra.quirks_mode { + match *self.quirks_mode { NoQuirks => ~"CSS1Compat", LimitedQuirks | FullQuirks => ~"BackCompat" } } pub fn quirks_mode(&self) -> QuirksMode { - self.extra.quirks_mode + *self.quirks_mode } pub fn set_quirks_mode(&mut self, mode: QuirksMode) { - self.extra.quirks_mode = mode; + *self.quirks_mode = mode; } // http://dom.spec.whatwg.org/#dom-document-characterset diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs index c98634682a6..d0f127fbc94 100644 --- a/src/components/script/dom/htmliframeelement.rs +++ b/src/components/script/dom/htmliframeelement.rs @@ -4,8 +4,9 @@ use dom::bindings::codegen::HTMLIFrameElementBinding; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementDerived, HTMLElementCast}; -use dom::bindings::js::JS; use dom::bindings::error::ErrorResult; +use dom::bindings::js::JS; +use dom::bindings::trace::Untraceable; use dom::document::Document; use dom::element::{HTMLIFrameElementTypeId, Element}; use dom::element::AttributeHandlers; @@ -16,7 +17,6 @@ use dom::virtualmethods::VirtualMethods; use dom::windowproxy::WindowProxy; use servo_util::str::DOMString; -use serialize::{Encoder, Encodable}; use servo_msg::constellation_msg::{PipelineId, SubpageId}; use std::ascii::StrAsciiExt; use url::Url; @@ -34,20 +34,11 @@ enum SandboxAllowance { #[deriving(Encodable)] pub struct HTMLIFrameElement { htmlelement: HTMLElement, - priv extra: Untraceable, + frame: Untraceable<Option<Url>>, size: Option<IFrameSize>, sandbox: Option<u8> } -struct Untraceable { - frame: Option<Url>, -} - -impl<S: Encoder> Encodable<S> for Untraceable { - fn encode(&self, _s: &mut S) { - } -} - impl HTMLIFrameElementDerived for EventTarget { fn is_htmliframeelement(&self) -> bool { match self.type_id { @@ -69,7 +60,7 @@ impl HTMLIFrameElement { } pub fn set_frame(&mut self, frame: Url) { - self.extra.frame = Some(frame); + *self.frame = Some(frame); } } @@ -77,9 +68,7 @@ impl HTMLIFrameElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLIFrameElement { HTMLIFrameElement { htmlelement: HTMLElement::new_inherited(HTMLIFrameElementTypeId, localName, document), - extra: Untraceable { - frame: None - }, + frame: Untraceable::new(None), size: None, sandbox: None, } diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs index 3b966bbfe24..a62aea8b991 100644 --- a/src/components/script/dom/htmlimageelement.rs +++ b/src/components/script/dom/htmlimageelement.rs @@ -5,8 +5,9 @@ use dom::bindings::codegen::HTMLImageElementBinding; use dom::bindings::codegen::InheritTypes::{NodeCast, HTMLImageElementDerived}; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast}; -use dom::bindings::js::JS; use dom::bindings::error::ErrorResult; +use dom::bindings::js::JS; +use dom::bindings::trace::Untraceable; use dom::document::Document; use dom::element::{Element, HTMLImageElementTypeId}; use dom::element::AttributeHandlers; @@ -21,21 +22,10 @@ use servo_util::url::parse_url; use servo_util::str::DOMString; use url::Url; -use serialize::{Encoder, Encodable}; - #[deriving(Encodable)] pub struct HTMLImageElement { htmlelement: HTMLElement, - priv extra: Untraceable, -} - -struct Untraceable { - image: Option<Url>, -} - -impl<S: Encoder> Encodable<S> for Untraceable { - fn encode(&self, _s: &mut S) { - } + image: Untraceable<Option<Url>>, } impl HTMLImageElementDerived for EventTarget { @@ -51,9 +41,7 @@ impl HTMLImageElement { pub fn new_inherited(localName: DOMString, document: JS<Document>) -> HTMLImageElement { HTMLImageElement { htmlelement: HTMLElement::new_inherited(HTMLImageElementTypeId, localName, document), - extra: Untraceable { - image: None, - } + image: Untraceable::new(None), } } @@ -65,7 +53,7 @@ impl HTMLImageElement { impl HTMLImageElement { pub fn image<'a>(&'a self) -> &'a Option<Url> { - &self.extra.image + &*self.image } /// Makes the local `image` member match the status of the `src` attribute and starts @@ -77,11 +65,11 @@ impl HTMLImageElement { let image_cache = &window.image_cache_task; match value { None => { - self.extra.image = None; + *self.image = None; } Some(src) => { let img_url = parse_url(src, url); - self.extra.image = Some(img_url.clone()); + *self.image = Some(img_url.clone()); // inform the image cache to load this, but don't store a // handle. diff --git a/src/components/script/dom/htmlstyleelement.rs b/src/components/script/dom/htmlstyleelement.rs index ed335dd70eb..32e4276a2a1 100644 --- a/src/components/script/dom/htmlstyleelement.rs +++ b/src/components/script/dom/htmlstyleelement.rs @@ -88,7 +88,7 @@ impl StyleElementHelpers for JS<HTMLStyleElement> { let data = node.get().GetTextContent(&node).expect("Element.textContent must be a string"); let sheet = parse_inline_css(url, data); - let LayoutChan(ref layout_chan) = win.get().page().layout_chan; + let LayoutChan(ref layout_chan) = *win.get().page().layout_chan; layout_chan.send(AddStylesheetMsg(sheet)); } } diff --git a/src/components/script/dom/location.rs b/src/components/script/dom/location.rs index 168ded0a4c7..f813b375eca 100644 --- a/src/components/script/dom/location.rs +++ b/src/components/script/dom/location.rs @@ -18,26 +18,14 @@ use serialize::{Encoder, Encodable}; #[deriving(Encodable)] pub struct Location { reflector_: Reflector, //XXXjdm cycle: window->Location->window - priv extra: Untraceable, -} - -struct Untraceable { page: Rc<Page>, } -impl<S: Encoder> Encodable<S> for Untraceable { - fn encode(&self, s: &mut S) { - self.page.encode(s); - } -} - impl Location { pub fn new_inherited(page: Rc<Page>) -> Location { Location { reflector_: Reflector::new(), - extra: Untraceable { - page: page - } + page: page } } @@ -60,7 +48,7 @@ impl Location { } pub fn Href(&self) -> DOMString { - self.extra.page.get_url().to_str() + self.page.get_url().to_str() } pub fn SetHref(&self, _href: DOMString) -> Fallible<()> { diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs index bf2669512ff..fd55732da82 100644 --- a/src/components/script/dom/node.rs +++ b/src/components/script/dom/node.rs @@ -37,6 +37,7 @@ use std::cast::transmute; use std::cast; use std::cell::{RefCell, Ref, RefMut}; use std::iter::{Map, Filter}; +use std::libc; use std::libc::uintptr_t; use std::mem; @@ -562,7 +563,7 @@ impl NodeHelpers for JS<Node> { } fn to_trusted_node_address(&self) -> TrustedNodeAddress { - self.get() as *Node as TrustedNodeAddress + TrustedNodeAddress(self.get() as *Node as *libc::c_void) } } diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs index a0b7ef3740b..87d94eaff62 100644 --- a/src/components/script/dom/window.rs +++ b/src/components/script/dom/window.rs @@ -4,6 +4,7 @@ use dom::bindings::codegen::WindowBinding; use dom::bindings::js::JS; +use dom::bindings::trace::Untraceable; use dom::bindings::utils::{Reflectable, Reflector}; use dom::document::Document; use dom::element::Element; @@ -84,29 +85,19 @@ pub struct Window { image_cache_task: ImageCacheTask, active_timers: ~HashMap<i32, TimerHandle>, next_timer_handle: i32, - priv extra: Untraceable -} - -struct Untraceable { + compositor: Untraceable<~ScriptListener>, + timer_chan: Untraceable<Sender<TimerControlMsg>>, page: Rc<Page>, - compositor: ~ScriptListener, - timer_chan: Sender<TimerControlMsg>, -} - -impl<S: Encoder> Encodable<S> for Untraceable { - fn encode(&self, s: &mut S) { - self.page.encode(s); - } } impl Window { pub fn get_cx(&self) -> *JSObject { let js_info = self.page().js_info(); - js_info.get_ref().js_compartment.cx.deref().ptr + js_info.get_ref().js_compartment.deref().cx.deref().ptr } pub fn page<'a>(&'a self) -> &'a Page { - &*self.extra.page + &*self.page } pub fn get_url(&self) -> Url { self.page().get_url() @@ -116,7 +107,7 @@ impl Window { #[unsafe_destructor] impl Drop for Window { fn drop(&mut self) { - self.extra.timer_chan.send(TimerMessageClose); + self.timer_chan.send(TimerMessageClose); for timer_handle in self.active_timers.values() { timer_handle.cancel(); } @@ -140,7 +131,7 @@ impl Window { } pub fn Close(&self) { - self.extra.timer_chan.send(TimerMessageTriggerExit); + self.timer_chan.deref().send(TimerMessageTriggerExit); } pub fn Document(&self) -> JS<Document> { @@ -181,7 +172,7 @@ impl Window { pub fn Location(&mut self, abstract_self: &JS<Window>) -> JS<Location> { if self.location.is_none() { - self.location = Some(Location::new(abstract_self, self.extra.page.clone())); + self.location = Some(Location::new(abstract_self, self.page.clone())); } self.location.get_ref().clone() } @@ -236,7 +227,7 @@ impl Window { // to the relevant script handler that will deal with it. let tm = Timer::new().unwrap(); let (cancel_chan, cancel_port) = channel(); - let chan = self.extra.timer_chan.clone(); + let chan = self.timer_chan.clone(); let spawn_name = if is_interval { "Window:SetInterval" } else { @@ -304,7 +295,7 @@ impl Window { // currently rely on the display list, which means we can't destroy it by // doing a query reflow. self.page().damage(damage); - self.page().reflow(ReflowForDisplay, self.script_chan.clone(), self.extra.compositor); + self.page().reflow(ReflowForDisplay, self.script_chan.clone(), *self.compositor); } pub fn wait_until_safe_to_modify_dom(&self) { @@ -319,29 +310,27 @@ impl Window { compositor: ~ScriptListener, image_cache_task: ImageCacheTask) -> JS<Window> { + let script_chan_clone = script_chan.clone(); + let (timer_chan, timer_port): (Sender<TimerControlMsg>, Receiver<TimerControlMsg>) = channel(); + let id = page.id.clone(); + spawn_named("timer controller", proc() { + let ScriptChan(script_chan) = script_chan; + loop { + match timer_port.recv() { + TimerMessageClose => break, + TimerMessageFire(td) => script_chan.send(FireTimerMsg(id, td)), + TimerMessageTriggerExit => script_chan.send(ExitWindowMsg(id)), + } + } + }); + let win = ~Window { eventtarget: EventTarget::new_inherited(WindowTypeId), - script_chan: script_chan.clone(), + script_chan: script_chan_clone, console: None, - extra: Untraceable { - compositor: compositor, - page: page.clone(), - timer_chan: { - let (timer_chan, timer_port): (Sender<TimerControlMsg>, Receiver<TimerControlMsg>) = channel(); - let id = page.id.clone(); - spawn_named("timer controller", proc() { - let ScriptChan(script_chan) = script_chan; - loop { - match timer_port.recv() { - TimerMessageClose => break, - TimerMessageFire(td) => script_chan.send(FireTimerMsg(id, td)), - TimerMessageTriggerExit => script_chan.send(ExitWindowMsg(id)), - } - } - }); - timer_chan - } - }, + compositor: Untraceable::new(compositor), + timer_chan: Untraceable::new(timer_chan), + page: page.clone(), location: None, navigator: None, image_cache_task: image_cache_task, |