mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Auto merge of #8026 - eefriedman:js-rooting, r=nox
Fix uses of JS<T> as a type on the stack `JS<T>` belongs on the heap, and only on the heap. This is a collection of fixes so that code uses either `Root<T>` or `&T` to pass around garbage-collected pointers. Ideally, we could completely ban constructing a `JS<T>` outside of constructor functions, but we aren't quite there yet. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8026) <!-- Reviewable:end -->
This commit is contained in:
commit
7c7dbde0f4
18 changed files with 204 additions and 186 deletions
|
@ -180,7 +180,7 @@ impl Attr {
|
|||
name: name,
|
||||
namespace: namespace,
|
||||
prefix: prefix,
|
||||
owner: MutNullableHeap::new(owner.map(JS::from_ref)),
|
||||
owner: MutNullableHeap::new(owner),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ impl Attr {
|
|||
}
|
||||
(old, new) => assert!(old == new)
|
||||
}
|
||||
self.owner.set(owner.map(JS::from_ref))
|
||||
self.owner.set(owner);
|
||||
}
|
||||
|
||||
pub fn owner(&self) -> Option<Root<Element>> {
|
||||
|
|
|
@ -32,13 +32,19 @@ use js::jsapi::{Heap, JSObject, JSTracer};
|
|||
use js::jsval::JSVal;
|
||||
use layout_interface::TrustedNodeAddress;
|
||||
use script_task::STACK_ROOTS;
|
||||
use std::cell::{Cell, UnsafeCell};
|
||||
use std::cell::UnsafeCell;
|
||||
use std::default::Default;
|
||||
use std::ops::Deref;
|
||||
use std::ptr;
|
||||
use util::mem::HeapSizeOf;
|
||||
|
||||
/// A traced reference to a DOM object. Must only be used as a field in other
|
||||
/// DOM objects.
|
||||
/// A traced reference to a DOM object
|
||||
///
|
||||
/// This type is critical to making garbage collection work with the DOM,
|
||||
/// but it is very dangerous; if garbage collection happens with a `JS<T>`
|
||||
/// on the stack, the `JS<T>` can point to freed memory.
|
||||
///
|
||||
/// This should only be used as a field in other DOM objects.
|
||||
#[must_root]
|
||||
pub struct JS<T> {
|
||||
ptr: NonZero<*const T>
|
||||
|
@ -54,12 +60,13 @@ impl<T> HeapSizeOf for JS<T> {
|
|||
|
||||
impl<T> JS<T> {
|
||||
/// Returns `LayoutJS<T>` containing the same pointer.
|
||||
pub unsafe fn to_layout(self) -> LayoutJS<T> {
|
||||
pub unsafe fn to_layout(&self) -> LayoutJS<T> {
|
||||
LayoutJS {
|
||||
ptr: self.ptr.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> JS<T> {
|
||||
/// Root this JS-owned value to prevent its collection as garbage.
|
||||
pub fn root(&self) -> Root<T> {
|
||||
|
@ -109,8 +116,6 @@ impl<T: Reflectable> LayoutJS<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Copy for JS<T> {}
|
||||
|
||||
impl<T> Copy for LayoutJS<T> {}
|
||||
|
||||
impl<T> PartialEq for JS<T> {
|
||||
|
@ -205,73 +210,76 @@ impl MutHeapJSVal {
|
|||
|
||||
|
||||
/// A holder that provides interior mutability for GC-managed values such as
|
||||
/// `JS<T>`.
|
||||
/// `JS<T>`. Essentially a `Cell<JS<T>>`, but safer.
|
||||
///
|
||||
/// This should only be used as a field in other DOM objects; see warning
|
||||
/// on `JS<T>`.
|
||||
#[must_root]
|
||||
#[derive(JSTraceable)]
|
||||
#[derive(HeapSizeOf)]
|
||||
pub struct MutHeap<T: HeapGCValue + Copy> {
|
||||
val: Cell<T>,
|
||||
pub struct MutHeap<T: HeapGCValue> {
|
||||
val: UnsafeCell<T>,
|
||||
}
|
||||
|
||||
impl<T: HeapGCValue + Copy> MutHeap<T> {
|
||||
impl<T: Reflectable> MutHeap<JS<T>> {
|
||||
/// Create a new `MutHeap`.
|
||||
pub fn new(initial: T) -> MutHeap<T> {
|
||||
pub fn new(initial: &T) -> MutHeap<JS<T>> {
|
||||
MutHeap {
|
||||
val: Cell::new(initial),
|
||||
val: UnsafeCell::new(JS::from_ref(initial)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set this `MutHeap` to the given value.
|
||||
pub fn set(&self, val: T) {
|
||||
self.val.set(val)
|
||||
pub fn set(&self, val: &T) {
|
||||
unsafe {
|
||||
*self.val.get() = JS::from_ref(val);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the value in this `MutHeap`.
|
||||
pub fn get(&self) -> T {
|
||||
self.val.get()
|
||||
pub fn get(&self) -> Root<T> {
|
||||
unsafe {
|
||||
ptr::read(self.val.get()).root()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A mutable holder for GC-managed values such as `JSval` and `JS<T>`, with
|
||||
/// nullability represented by an enclosing Option wrapper. Must be used in
|
||||
/// place of traditional internal mutability to ensure that the proper GC
|
||||
/// barriers are enforced.
|
||||
impl<T: HeapGCValue> HeapSizeOf for MutHeap<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
// See comment on HeapSizeOf for JS<T>.
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
/// A holder that provides interior mutability for GC-managed values such as
|
||||
/// `JS<T>`, with nullability represented by an enclosing Option wrapper.
|
||||
/// Essentially a `Cell<Option<JS<T>>>`, but safer.
|
||||
///
|
||||
/// This should only be used as a field in other DOM objects; see warning
|
||||
/// on `JS<T>`.
|
||||
#[must_root]
|
||||
#[derive(JSTraceable, HeapSizeOf)]
|
||||
pub struct MutNullableHeap<T: HeapGCValue + Copy> {
|
||||
ptr: Cell<Option<T>>
|
||||
}
|
||||
|
||||
impl<T: HeapGCValue + Copy> MutNullableHeap<T> {
|
||||
/// Create a new `MutNullableHeap`.
|
||||
pub fn new(initial: Option<T>) -> MutNullableHeap<T> {
|
||||
MutNullableHeap {
|
||||
ptr: Cell::new(initial)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set this `MutNullableHeap` to the given value.
|
||||
pub fn set(&self, val: Option<T>) {
|
||||
self.ptr.set(val);
|
||||
}
|
||||
|
||||
/// Retrieve a copy of the current optional inner value.
|
||||
pub fn get(&self) -> Option<T> {
|
||||
self.ptr.get()
|
||||
}
|
||||
#[derive(JSTraceable)]
|
||||
pub struct MutNullableHeap<T: HeapGCValue> {
|
||||
ptr: UnsafeCell<Option<T>>
|
||||
}
|
||||
|
||||
impl<T: Reflectable> MutNullableHeap<JS<T>> {
|
||||
/// Create a new `MutNullableHeap`.
|
||||
pub fn new(initial: Option<&T>) -> MutNullableHeap<JS<T>> {
|
||||
MutNullableHeap {
|
||||
ptr: UnsafeCell::new(initial.map(JS::from_ref))
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve a copy of the current inner value. If it is `None`, it is
|
||||
/// initialized with the result of `cb` first.
|
||||
pub fn or_init<F>(&self, cb: F) -> Root<T>
|
||||
where F: FnOnce() -> Root<T>
|
||||
{
|
||||
match self.get() {
|
||||
Some(inner) => Root::from_rooted(inner),
|
||||
Some(inner) => inner,
|
||||
None => {
|
||||
let inner = cb();
|
||||
self.set(Some(JS::from_rooted(&inner)));
|
||||
self.set(Some(&inner));
|
||||
inner
|
||||
},
|
||||
}
|
||||
|
@ -280,25 +288,45 @@ impl<T: Reflectable> MutNullableHeap<JS<T>> {
|
|||
/// Retrieve a copy of the inner optional `JS<T>` as `LayoutJS<T>`.
|
||||
/// For use by layout, which can't use safe types like Temporary.
|
||||
pub unsafe fn get_inner_as_layout(&self) -> Option<LayoutJS<T>> {
|
||||
self.ptr.get().map(|js| js.to_layout())
|
||||
ptr::read(self.ptr.get()).map(|js| js.to_layout())
|
||||
}
|
||||
|
||||
/// Get a rooted value out of this object
|
||||
pub fn get(&self) -> Option<Root<T>> {
|
||||
unsafe {
|
||||
ptr::read(self.ptr.get()).map(|o| o.root())
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a rooted value out of this object
|
||||
// FIXME(#6684)
|
||||
pub fn get_rooted(&self) -> Option<Root<T>> {
|
||||
self.get().map(|o| o.root())
|
||||
self.get()
|
||||
}
|
||||
|
||||
/// Set this `MutNullableHeap` to the given value.
|
||||
pub fn set(&self, val: Option<&T>) {
|
||||
unsafe {
|
||||
*self.ptr.get() = val.map(|p| JS::from_ref(p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapGCValue + Copy> Default for MutNullableHeap<T> {
|
||||
impl<T: HeapGCValue> Default for MutNullableHeap<T> {
|
||||
#[allow(unrooted_must_root)]
|
||||
fn default() -> MutNullableHeap<T> {
|
||||
MutNullableHeap {
|
||||
ptr: Cell::new(None)
|
||||
ptr: UnsafeCell::new(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HeapGCValue> HeapSizeOf for MutNullableHeap<T> {
|
||||
fn heap_size_of_children(&self) -> usize {
|
||||
// See comment on HeapSizeOf for JS<T>.
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> LayoutJS<T> {
|
||||
/// Returns an unsafe pointer to the interior of this JS object. This is
|
||||
/// the only method that be safely accessed from layout. (The fact that
|
||||
|
@ -435,12 +463,6 @@ impl<T: Reflectable> Root<T> {
|
|||
pub fn r(&self) -> &T {
|
||||
&**self
|
||||
}
|
||||
|
||||
/// Generate a new root from a JS<T> reference
|
||||
#[allow(unrooted_must_root)]
|
||||
pub fn from_rooted(js: JS<T>) -> Root<T> {
|
||||
js.root()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> Deref for Root<T> {
|
||||
|
|
|
@ -54,7 +54,7 @@ impl BrowsingContext {
|
|||
}
|
||||
|
||||
pub fn frame_element(&self) -> Option<Root<Element>> {
|
||||
self.frame_element.map(Root::from_rooted)
|
||||
self.frame_element.as_ref().map(JS::root)
|
||||
}
|
||||
|
||||
pub fn window_proxy(&self) -> *mut JSObject {
|
||||
|
|
|
@ -763,7 +763,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
|
|||
serialize(rgba, &mut result).unwrap();
|
||||
StringOrCanvasGradientOrCanvasPattern::eString(result)
|
||||
},
|
||||
CanvasFillOrStrokeStyle::Gradient(gradient) => {
|
||||
CanvasFillOrStrokeStyle::Gradient(ref gradient) => {
|
||||
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient.root())
|
||||
},
|
||||
}
|
||||
|
@ -803,7 +803,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
|
|||
serialize(rgba, &mut result).unwrap();
|
||||
StringOrCanvasGradientOrCanvasPattern::eString(result)
|
||||
},
|
||||
CanvasFillOrStrokeStyle::Gradient(gradient) => {
|
||||
CanvasFillOrStrokeStyle::Gradient(ref gradient) => {
|
||||
StringOrCanvasGradientOrCanvasPattern::eCanvasGradient(gradient.root())
|
||||
},
|
||||
}
|
||||
|
|
|
@ -297,7 +297,7 @@ impl Document {
|
|||
.filter_map(HTMLBaseElementCast::to_root)
|
||||
.filter(|element| ElementCast::from_ref(&**element).has_attribute(&atom!("href")))
|
||||
.next();
|
||||
self.base_element.set(base.map(|element| JS::from_ref(&*element)));
|
||||
self.base_element.set(base.r());
|
||||
}
|
||||
|
||||
pub fn quirks_mode(&self) -> QuirksMode {
|
||||
|
@ -506,7 +506,7 @@ impl Document {
|
|||
/// Request that the given element receive focus once the current transaction is complete.
|
||||
pub fn request_focus(&self, elem: &Element) {
|
||||
if elem.is_focusable_area() {
|
||||
self.possibly_focused.set(Some(JS::from_ref(elem)))
|
||||
self.possibly_focused.set(Some(elem))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,7 +520,7 @@ impl Document {
|
|||
node.set_focus_state(false);
|
||||
}
|
||||
|
||||
self.focused.set(self.possibly_focused.get());
|
||||
self.focused.set(self.possibly_focused.get().r());
|
||||
|
||||
if let Some(ref elem) = self.focused.get_rooted() {
|
||||
let node = NodeCast::from_ref(elem.r());
|
||||
|
@ -852,7 +852,7 @@ impl Document {
|
|||
}
|
||||
|
||||
pub fn set_current_script(&self, script: Option<&HTMLScriptElement>) {
|
||||
self.current_script.set(script.map(JS::from_ref));
|
||||
self.current_script.set(script);
|
||||
}
|
||||
|
||||
pub fn trigger_mozbrowser_event(&self, event: MozBrowserEvent) {
|
||||
|
@ -959,7 +959,7 @@ impl Document {
|
|||
}
|
||||
|
||||
pub fn set_current_parser(&self, script: Option<&ServoHTMLParser>) {
|
||||
self.current_parser.set(script.map(JS::from_ref));
|
||||
self.current_parser.set(script);
|
||||
}
|
||||
|
||||
pub fn get_current_parser(&self) -> Option<Root<ServoHTMLParser>> {
|
||||
|
@ -1119,8 +1119,7 @@ impl Document {
|
|||
let new_doc = Document::new(
|
||||
&*self.window(), None, doctype, None, None,
|
||||
DocumentSource::NotFromParser, DocumentLoader::new(&self.loader()));
|
||||
new_doc.appropriate_template_contents_owner_document.set(
|
||||
Some(JS::from_ref(&*new_doc)));
|
||||
new_doc.appropriate_template_contents_owner_document.set(Some(&new_doc));
|
||||
new_doc
|
||||
})
|
||||
}
|
||||
|
|
|
@ -106,12 +106,12 @@ impl Event {
|
|||
|
||||
#[inline]
|
||||
pub fn set_current_target(&self, val: &EventTarget) {
|
||||
self.current_target.set(Some(JS::from_ref(val)));
|
||||
self.current_target.set(Some(val));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_target(&self, val: &EventTarget) {
|
||||
self.target.set(Some(JS::from_ref(val)));
|
||||
self.target.set(Some(val));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -116,7 +116,7 @@ impl FileReader {
|
|||
|
||||
let global = fr.global.root();
|
||||
let exception = DOMException::new(global.r(), error);
|
||||
fr.error.set(Some(JS::from_rooted(&exception)));
|
||||
fr.error.set(Some(&exception));
|
||||
|
||||
fr.dispatch_progress_event("error".to_owned(), 0, None);
|
||||
return_on_abort!();
|
||||
|
@ -292,7 +292,7 @@ impl FileReaderMethods for FileReader {
|
|||
|
||||
let global = self.global.root();
|
||||
let exception = DOMException::new(global.r(), DOMErrorName::AbortError);
|
||||
self.error.set(Some(JS::from_rooted(&exception)));
|
||||
self.error.set(Some(&exception));
|
||||
|
||||
self.terminate_ongoing_reading();
|
||||
// Steps 5 & 6
|
||||
|
@ -346,7 +346,7 @@ impl FileReader {
|
|||
if blob.IsClosed() {
|
||||
let global = self.global.root();
|
||||
let exception = DOMException::new(global.r(), DOMErrorName::InvalidStateError);
|
||||
self.error.set(Some(JS::from_rooted(&exception)));
|
||||
self.error.set(Some(&exception));
|
||||
|
||||
self.dispatch_progress_event("error".to_owned(), 0, None);
|
||||
return Ok(());
|
||||
|
|
|
@ -4,13 +4,14 @@
|
|||
|
||||
use canvas_traits::{CanvasMsg, FromLayoutMsg};
|
||||
use dom::attr::Attr;
|
||||
use dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
|
||||
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods;
|
||||
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
|
||||
use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext;
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, MutNullableHeap, Root};
|
||||
use dom::bindings::js::{HeapGCValue, JS, LayoutJS, Root};
|
||||
use dom::bindings::utils::{Reflectable};
|
||||
use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers};
|
||||
use dom::document::Document;
|
||||
|
@ -24,7 +25,6 @@ use ipc_channel::ipc::{self, IpcSender};
|
|||
use js::jsapi::{HandleValue, JSContext};
|
||||
use offscreen_gl_context::GLContextAttributes;
|
||||
use std::cell::Cell;
|
||||
use std::default::Default;
|
||||
use std::iter::repeat;
|
||||
use util::str::{DOMString, parse_unsigned_integer};
|
||||
|
||||
|
@ -32,7 +32,7 @@ const DEFAULT_WIDTH: u32 = 300;
|
|||
const DEFAULT_HEIGHT: u32 = 150;
|
||||
|
||||
#[must_root]
|
||||
#[derive(JSTraceable, Clone, Copy, HeapSizeOf)]
|
||||
#[derive(JSTraceable, Clone, HeapSizeOf)]
|
||||
pub enum CanvasContext {
|
||||
Context2d(JS<CanvasRenderingContext2D>),
|
||||
WebGL(JS<WebGLRenderingContext>),
|
||||
|
@ -43,7 +43,7 @@ impl HeapGCValue for CanvasContext {}
|
|||
#[dom_struct]
|
||||
pub struct HTMLCanvasElement {
|
||||
htmlelement: HTMLElement,
|
||||
context: MutNullableHeap<CanvasContext>,
|
||||
context: DOMRefCell<Option<CanvasContext>>,
|
||||
width: Cell<u32>,
|
||||
height: Cell<u32>,
|
||||
}
|
||||
|
@ -59,9 +59,8 @@ impl HTMLCanvasElement {
|
|||
prefix: Option<DOMString>,
|
||||
document: &Document) -> HTMLCanvasElement {
|
||||
HTMLCanvasElement {
|
||||
htmlelement:
|
||||
HTMLElement::new_inherited(localName, prefix, document),
|
||||
context: Default::default(),
|
||||
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
|
||||
context: DOMRefCell::new(None),
|
||||
width: Cell::new(DEFAULT_WIDTH),
|
||||
height: Cell::new(DEFAULT_HEIGHT),
|
||||
}
|
||||
|
@ -77,10 +76,10 @@ impl HTMLCanvasElement {
|
|||
|
||||
fn recreate_contexts(&self) {
|
||||
let size = self.get_size();
|
||||
if let Some(context) = self.context.get() {
|
||||
match context {
|
||||
CanvasContext::Context2d(context) => context.root().r().recreate(size),
|
||||
CanvasContext::WebGL(context) => context.root().r().recreate(size),
|
||||
if let Some(ref context) = *self.context.borrow() {
|
||||
match *context {
|
||||
CanvasContext::Context2d(ref context) => context.root().r().recreate(size),
|
||||
CanvasContext::WebGL(ref context) => context.root().r().recreate(size),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,10 +104,10 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
|||
#[allow(unsafe_code)]
|
||||
unsafe fn get_renderer_id(&self) -> Option<usize> {
|
||||
let ref canvas = *self.unsafe_get();
|
||||
canvas.context.get().map(|context| {
|
||||
match context {
|
||||
CanvasContext::Context2d(context) => context.to_layout().get_renderer_id(),
|
||||
CanvasContext::WebGL(context) => context.to_layout().get_renderer_id(),
|
||||
canvas.context.borrow_for_layout().as_ref().map(|context| {
|
||||
match *context {
|
||||
CanvasContext::Context2d(ref context) => context.to_layout().get_renderer_id(),
|
||||
CanvasContext::WebGL(ref context) => context.to_layout().get_renderer_id(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -116,10 +115,10 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
|||
#[allow(unsafe_code)]
|
||||
unsafe fn get_ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||
let ref canvas = *self.unsafe_get();
|
||||
canvas.context.get().map(|context| {
|
||||
match context {
|
||||
CanvasContext::Context2d(context) => context.to_layout().get_ipc_renderer(),
|
||||
CanvasContext::WebGL(context) => context.to_layout().get_ipc_renderer(),
|
||||
canvas.context.borrow_for_layout().as_ref().map(|context| {
|
||||
match *context {
|
||||
CanvasContext::Context2d(ref context) => context.to_layout().get_ipc_renderer(),
|
||||
CanvasContext::WebGL(ref context) => context.to_layout().get_ipc_renderer(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -138,24 +137,24 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
|
|||
|
||||
impl HTMLCanvasElement {
|
||||
pub fn ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
|
||||
self.context.get().map(|context| {
|
||||
match context {
|
||||
CanvasContext::Context2d(context) => context.root().r().ipc_renderer(),
|
||||
CanvasContext::WebGL(context) => context.root().r().ipc_renderer(),
|
||||
self.context.borrow().as_ref().map(|context| {
|
||||
match *context {
|
||||
CanvasContext::Context2d(ref context) => context.root().r().ipc_renderer(),
|
||||
CanvasContext::WebGL(ref context) => context.root().r().ipc_renderer(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_or_init_2d_context(&self) -> Option<Root<CanvasRenderingContext2D>> {
|
||||
if self.context.get().is_none() {
|
||||
if self.context.borrow().is_none() {
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
let context = CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size);
|
||||
self.context.set(Some(CanvasContext::Context2d(JS::from_rooted(&context))));
|
||||
*self.context.borrow_mut() = Some(CanvasContext::Context2d(JS::from_rooted(&context)));
|
||||
}
|
||||
|
||||
match self.context.get().unwrap() {
|
||||
CanvasContext::Context2d(context) => Some(context.root()),
|
||||
match *self.context.borrow().as_ref().unwrap() {
|
||||
CanvasContext::Context2d(ref context) => Some(context.root()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -163,7 +162,7 @@ impl HTMLCanvasElement {
|
|||
pub fn get_or_init_webgl_context(&self,
|
||||
cx: *mut JSContext,
|
||||
attrs: Option<HandleValue>) -> Option<Root<WebGLRenderingContext>> {
|
||||
if self.context.get().is_none() {
|
||||
if self.context.borrow().is_none() {
|
||||
let window = window_from_node(self);
|
||||
let size = self.get_size();
|
||||
|
||||
|
@ -180,12 +179,12 @@ impl HTMLCanvasElement {
|
|||
|
||||
let maybe_ctx = WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size, attrs);
|
||||
|
||||
self.context.set(maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx))));
|
||||
*self.context.borrow_mut() = maybe_ctx.map( |ctx| CanvasContext::WebGL(JS::from_rooted(&ctx)));
|
||||
}
|
||||
|
||||
if let Some(context) = self.context.get() {
|
||||
match context {
|
||||
CanvasContext::WebGL(context) => Some(context.root()),
|
||||
if let Some(ref context) = *self.context.borrow() {
|
||||
match *context {
|
||||
CanvasContext::WebGL(ref context) => Some(context.root()),
|
||||
_ => None,
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -758,7 +758,7 @@ impl Activatable for HTMLInputElement {
|
|||
InputType::InputRadio => {
|
||||
// We want to restore state only if the element had been changed in the first place
|
||||
if cache.was_mutable {
|
||||
let old_checked: Option<Root<HTMLInputElement>> = cache.checked_radio.map(|t| t.root());
|
||||
let old_checked = cache.checked_radio.as_ref().map(|t| t.root());
|
||||
let name = self.get_radio_group_name();
|
||||
match old_checked {
|
||||
Some(ref o) => {
|
||||
|
|
|
@ -205,6 +205,6 @@ impl MouseEventMethods for MouseEvent {
|
|||
self.shift_key.set(shiftKeyArg);
|
||||
self.meta_key.set(metaKeyArg);
|
||||
self.button.set(buttonArg);
|
||||
self.related_target.set(relatedTargetArg.map(JS::from_ref));
|
||||
self.related_target.set(relatedTargetArg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,32 +271,32 @@ impl Node {
|
|||
match prev_sibling {
|
||||
None => {
|
||||
assert!(Some(*before) == self.first_child.get_rooted().r());
|
||||
self.first_child.set(Some(JS::from_ref(new_child)));
|
||||
self.first_child.set(Some(new_child));
|
||||
},
|
||||
Some(ref prev_sibling) => {
|
||||
prev_sibling.next_sibling.set(Some(JS::from_ref(new_child)));
|
||||
new_child.prev_sibling.set(Some(JS::from_ref(prev_sibling.r())));
|
||||
prev_sibling.next_sibling.set(Some(new_child));
|
||||
new_child.prev_sibling.set(Some(prev_sibling.r()));
|
||||
},
|
||||
}
|
||||
before.prev_sibling.set(Some(JS::from_ref(new_child)));
|
||||
new_child.next_sibling.set(Some(JS::from_ref(before)));
|
||||
before.prev_sibling.set(Some(new_child));
|
||||
new_child.next_sibling.set(Some(before));
|
||||
},
|
||||
None => {
|
||||
let last_child = self.GetLastChild();
|
||||
match last_child {
|
||||
None => self.first_child.set(Some(JS::from_ref(new_child))),
|
||||
None => self.first_child.set(Some(new_child)),
|
||||
Some(ref last_child) => {
|
||||
assert!(last_child.next_sibling.get().is_none());
|
||||
last_child.r().next_sibling.set(Some(JS::from_ref(new_child)));
|
||||
new_child.prev_sibling.set(Some(JS::from_rooted(&last_child)));
|
||||
last_child.r().next_sibling.set(Some(new_child));
|
||||
new_child.prev_sibling.set(Some(&last_child));
|
||||
}
|
||||
}
|
||||
|
||||
self.last_child.set(Some(JS::from_ref(new_child)));
|
||||
self.last_child.set(Some(new_child));
|
||||
},
|
||||
}
|
||||
|
||||
new_child.parent_node.set(Some(JS::from_ref(self)));
|
||||
new_child.parent_node.set(Some(self));
|
||||
|
||||
let parent_in_doc = self.is_in_doc();
|
||||
for node in new_child.traverse_preorder() {
|
||||
|
@ -315,19 +315,19 @@ impl Node {
|
|||
let prev_sibling = child.GetPreviousSibling();
|
||||
match prev_sibling {
|
||||
None => {
|
||||
self.first_child.set(child.next_sibling.get());
|
||||
self.first_child.set(child.next_sibling.get().r());
|
||||
}
|
||||
Some(ref prev_sibling) => {
|
||||
prev_sibling.next_sibling.set(child.next_sibling.get());
|
||||
prev_sibling.next_sibling.set(child.next_sibling.get().r());
|
||||
}
|
||||
}
|
||||
let next_sibling = child.GetNextSibling();
|
||||
match next_sibling {
|
||||
None => {
|
||||
self.last_child.set(child.prev_sibling.get());
|
||||
self.last_child.set(child.prev_sibling.get().r());
|
||||
}
|
||||
Some(ref next_sibling) => {
|
||||
next_sibling.prev_sibling.set(child.prev_sibling.get());
|
||||
next_sibling.prev_sibling.set(child.prev_sibling.get().r());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,7 +591,7 @@ impl Node {
|
|||
match self.parent_node.get() {
|
||||
None => return,
|
||||
Some(parent) => parent,
|
||||
}.root();
|
||||
};
|
||||
|
||||
for sibling in parent.r().children() {
|
||||
sibling.r().set_has_dirty_siblings(true);
|
||||
|
@ -660,7 +660,7 @@ impl Node {
|
|||
|
||||
pub fn is_parent_of(&self, child: &Node) -> bool {
|
||||
match child.parent_node.get() {
|
||||
Some(ref parent) => parent.root().r() == self,
|
||||
Some(ref parent) => parent.r() == self,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
@ -689,7 +689,7 @@ impl Node {
|
|||
// Step 2.
|
||||
let parent = match parent.get() {
|
||||
None => return Ok(()),
|
||||
Some(ref parent) => parent.root(),
|
||||
Some(parent) => parent,
|
||||
};
|
||||
|
||||
// Step 3.
|
||||
|
@ -702,7 +702,7 @@ impl Node {
|
|||
let viable_previous_sibling = match viable_previous_sibling {
|
||||
Some(ref viable_previous_sibling) => viable_previous_sibling.next_sibling.get(),
|
||||
None => parent.first_child.get(),
|
||||
}.map(|s| s.root());
|
||||
};
|
||||
|
||||
// Step 6.
|
||||
try!(Node::pre_insert(&node, &parent, viable_previous_sibling.r()));
|
||||
|
@ -718,7 +718,7 @@ impl Node {
|
|||
// Step 2.
|
||||
let parent = match parent.get() {
|
||||
None => return Ok(()),
|
||||
Some(ref parent) => parent.root(),
|
||||
Some(parent) => parent,
|
||||
};
|
||||
|
||||
// Step 3.
|
||||
|
@ -745,7 +745,7 @@ impl Node {
|
|||
let doc = self.owner_doc();
|
||||
let node = try!(doc.r().node_from_nodes_and_strings(nodes));
|
||||
// Step 3.
|
||||
parent_node.root().r().ReplaceChild(node.r(), self).map(|_| ())
|
||||
parent_node.r().ReplaceChild(node.r(), self).map(|_| ())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -823,11 +823,11 @@ impl Node {
|
|||
}
|
||||
|
||||
pub fn owner_doc(&self) -> Root<Document> {
|
||||
self.owner_doc.get().unwrap().root()
|
||||
self.owner_doc.get().unwrap()
|
||||
}
|
||||
|
||||
pub fn set_owner_doc(&self, document: &Document) {
|
||||
self.owner_doc.set(Some(JS::from_ref(document)));
|
||||
self.owner_doc.set(Some(document));
|
||||
}
|
||||
|
||||
pub fn is_in_html_doc(&self) -> bool {
|
||||
|
@ -1367,7 +1367,7 @@ impl Node {
|
|||
last_child: Default::default(),
|
||||
next_sibling: Default::default(),
|
||||
prev_sibling: Default::default(),
|
||||
owner_doc: MutNullableHeap::new(doc.map(JS::from_ref)),
|
||||
owner_doc: MutNullableHeap::new(doc),
|
||||
child_list: Default::default(),
|
||||
children_count: Cell::new(0u32),
|
||||
flags: Cell::new(flags),
|
||||
|
|
|
@ -36,7 +36,7 @@ impl NodeIterator {
|
|||
NodeIterator {
|
||||
reflector_: Reflector::new(),
|
||||
root_node: JS::from_ref(root_node),
|
||||
reference_node: MutHeap::new(JS::from_ref(root_node)),
|
||||
reference_node: MutHeap::new(root_node),
|
||||
pointer_before_reference_node: Cell::new(true),
|
||||
what_to_show: what_to_show,
|
||||
filter: filter
|
||||
|
@ -87,7 +87,7 @@ impl NodeIteratorMethods for NodeIterator {
|
|||
|
||||
// https://dom.spec.whatwg.org/#dom-nodeiterator-referencenode
|
||||
fn ReferenceNode(&self) -> Root<Node> {
|
||||
self.reference_node.get().root()
|
||||
self.reference_node.get()
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nodeiterator-pointerbeforereferencenode
|
||||
|
@ -99,7 +99,7 @@ impl NodeIteratorMethods for NodeIterator {
|
|||
fn NextNode(&self) -> Fallible<Option<Root<Node>>> {
|
||||
// https://dom.spec.whatwg.org/#concept-NodeIterator-traverse
|
||||
// Step 1.
|
||||
let node = self.reference_node.get().root();
|
||||
let node = self.reference_node.get();
|
||||
|
||||
// Step 2.
|
||||
let mut before_node = self.pointer_before_reference_node.get();
|
||||
|
@ -114,7 +114,7 @@ impl NodeIteratorMethods for NodeIterator {
|
|||
// Step 3-3.
|
||||
if result == NodeFilterConstants::FILTER_ACCEPT {
|
||||
// Step 4.
|
||||
self.reference_node.set(JS::from_ref(node.r()));
|
||||
self.reference_node.set(node.r());
|
||||
self.pointer_before_reference_node.set(before_node);
|
||||
|
||||
return Ok(Some(node));
|
||||
|
@ -129,7 +129,7 @@ impl NodeIteratorMethods for NodeIterator {
|
|||
// Step 3-3.
|
||||
if result == NodeFilterConstants::FILTER_ACCEPT {
|
||||
// Step 4.
|
||||
self.reference_node.set(JS::from_ref(following_node.r()));
|
||||
self.reference_node.set(following_node.r());
|
||||
self.pointer_before_reference_node.set(before_node);
|
||||
|
||||
return Ok(Some(following_node));
|
||||
|
@ -143,7 +143,7 @@ impl NodeIteratorMethods for NodeIterator {
|
|||
fn PreviousNode(&self) -> Fallible<Option<Root<Node>>> {
|
||||
// https://dom.spec.whatwg.org/#concept-NodeIterator-traverse
|
||||
// Step 1.
|
||||
let node = self.reference_node.get().root();
|
||||
let node = self.reference_node.get();
|
||||
|
||||
// Step 2.
|
||||
let mut before_node = self.pointer_before_reference_node.get();
|
||||
|
@ -158,7 +158,7 @@ impl NodeIteratorMethods for NodeIterator {
|
|||
// Step 3-3.
|
||||
if result == NodeFilterConstants::FILTER_ACCEPT {
|
||||
// Step 4.
|
||||
self.reference_node.set(JS::from_ref(node.r()));
|
||||
self.reference_node.set(node.r());
|
||||
self.pointer_before_reference_node.set(before_node);
|
||||
|
||||
return Ok(Some(node));
|
||||
|
@ -174,7 +174,7 @@ impl NodeIteratorMethods for NodeIterator {
|
|||
// Step 3-3.
|
||||
if result == NodeFilterConstants::FILTER_ACCEPT {
|
||||
// Step 4.
|
||||
self.reference_node.set(JS::from_ref(preceding_node.r()));
|
||||
self.reference_node.set(preceding_node.r());
|
||||
self.pointer_before_reference_node.set(before_node);
|
||||
|
||||
return Ok(Some(preceding_node));
|
||||
|
|
|
@ -6,7 +6,7 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
|||
use dom::bindings::codegen::Bindings::NodeListBinding;
|
||||
use dom::bindings::codegen::Bindings::NodeListBinding::NodeListMethods;
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{JS, MutNullableHeap, Root};
|
||||
use dom::bindings::js::{JS, MutNullableHeap, Root, RootedReference};
|
||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||
use dom::node::{ChildrenMutation, Node};
|
||||
use dom::window::Window;
|
||||
|
@ -64,7 +64,7 @@ impl NodeListMethods for NodeList {
|
|||
fn Item(&self, index: u32) -> Option<Root<Node>> {
|
||||
match self.list_type {
|
||||
NodeListType::Simple(ref elems) => {
|
||||
elems.get(index as usize).map(|node| Root::from_rooted(*node))
|
||||
elems.get(index as usize).map(|node| node.root())
|
||||
},
|
||||
NodeListType::Children(ref list) => list.item(index),
|
||||
}
|
||||
|
@ -103,8 +103,7 @@ impl ChildrenList {
|
|||
let last_visited = node.GetFirstChild();
|
||||
ChildrenList {
|
||||
node: JS::from_ref(node),
|
||||
last_visited:
|
||||
MutNullableHeap::new(last_visited.as_ref().map(JS::from_rooted)),
|
||||
last_visited: MutNullableHeap::new(last_visited.r()),
|
||||
last_index: Cell::new(0u32),
|
||||
}
|
||||
}
|
||||
|
@ -127,14 +126,14 @@ impl ChildrenList {
|
|||
let last_index = self.last_index.get();
|
||||
if index == last_index {
|
||||
// Item is last visited child, no need to update last visited.
|
||||
return Some(self.last_visited.get().unwrap().root());
|
||||
return Some(self.last_visited.get().unwrap());
|
||||
}
|
||||
let last_visited = if index - 1u32 == last_index {
|
||||
// Item is last visited's next sibling.
|
||||
self.last_visited.get().unwrap().root().GetNextSibling().unwrap()
|
||||
self.last_visited.get().unwrap().GetNextSibling().unwrap()
|
||||
} else if last_index > 0 && index == last_index - 1u32 {
|
||||
// Item is last visited's previous sibling.
|
||||
self.last_visited.get().unwrap().root().GetPreviousSibling().unwrap()
|
||||
self.last_visited.get().unwrap().GetPreviousSibling().unwrap()
|
||||
} else if index > last_index {
|
||||
if index == len - 1u32 {
|
||||
// Item is parent's last child, not worth updating last visited.
|
||||
|
@ -142,7 +141,7 @@ impl ChildrenList {
|
|||
}
|
||||
if index <= last_index + (len - last_index) / 2u32 {
|
||||
// Item is closer to the last visited child and follows it.
|
||||
self.last_visited.get().unwrap().root()
|
||||
self.last_visited.get().unwrap()
|
||||
.inclusively_following_siblings()
|
||||
.nth((index - last_index) as usize).unwrap()
|
||||
} else {
|
||||
|
@ -154,7 +153,7 @@ impl ChildrenList {
|
|||
}
|
||||
} else if index >= last_index / 2u32 {
|
||||
// Item is closer to the last visited child and precedes it.
|
||||
self.last_visited.get().unwrap().root()
|
||||
self.last_visited.get().unwrap()
|
||||
.inclusively_preceding_siblings()
|
||||
.nth((last_index - index) as usize).unwrap()
|
||||
} else {
|
||||
|
@ -165,7 +164,7 @@ impl ChildrenList {
|
|||
.nth(index as usize)
|
||||
.unwrap()
|
||||
};
|
||||
self.last_visited.set(Some(JS::from_rooted(&last_visited)));
|
||||
self.last_visited.set(Some(last_visited.r()));
|
||||
self.last_index.set(index);
|
||||
Some(last_visited)
|
||||
}
|
||||
|
@ -178,7 +177,7 @@ impl ChildrenList {
|
|||
}
|
||||
let index = list.last_index.get();
|
||||
if index < len {
|
||||
list.last_visited.set(Some(JS::from_ref(added[index as usize])));
|
||||
list.last_visited.set(Some(added[index as usize]));
|
||||
} else if index / 2u32 >= len {
|
||||
// If last index is twice as large as the number of added nodes,
|
||||
// updating only it means that less nodes will be traversed if
|
||||
|
@ -187,7 +186,7 @@ impl ChildrenList {
|
|||
} else {
|
||||
// If last index is not twice as large but still larger,
|
||||
// it's better to update it to the number of added nodes.
|
||||
list.last_visited.set(Some(JS::from_ref(next)));
|
||||
list.last_visited.set(Some(next));
|
||||
list.last_index.set(len);
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +197,7 @@ impl ChildrenList {
|
|||
added: &[&Node],
|
||||
next: Option<&Node>) {
|
||||
let index = list.last_index.get();
|
||||
if removed == &*list.last_visited.get().unwrap().root() {
|
||||
if removed == &*list.last_visited.get().unwrap() {
|
||||
let visited = match (prev, added, next) {
|
||||
(None, _, None) => {
|
||||
// Such cases where parent had only one child should
|
||||
|
@ -213,7 +212,7 @@ impl ChildrenList {
|
|||
prev
|
||||
},
|
||||
};
|
||||
list.last_visited.set(Some(JS::from_ref(visited)));
|
||||
list.last_visited.set(Some(visited));
|
||||
} else if added.len() != 1 {
|
||||
// The replaced child isn't the last visited one, and there are
|
||||
// 0 or more than 1 nodes to replace it. Special care must be
|
||||
|
@ -250,13 +249,13 @@ impl ChildrenList {
|
|||
self.last_visited.set(None);
|
||||
self.last_index.set(0u32);
|
||||
} else if index < len as u32 {
|
||||
self.last_visited.set(Some(JS::from_ref(added[index as usize])));
|
||||
self.last_visited.set(Some(added[index as usize]));
|
||||
} else {
|
||||
// Setting last visited to parent's last child serves no purpose,
|
||||
// so the middle is arbitrarily chosen here in case the caller
|
||||
// wants random access.
|
||||
let middle = len / 2;
|
||||
self.last_visited.set(Some(JS::from_ref(added[middle])));
|
||||
self.last_visited.set(Some(added[middle]));
|
||||
self.last_index.set(middle as u32);
|
||||
}
|
||||
},
|
||||
|
@ -264,8 +263,7 @@ impl ChildrenList {
|
|||
}
|
||||
|
||||
fn reset(&self) {
|
||||
self.last_visited.set(
|
||||
self.node.root().GetFirstChild().map(|node| JS::from_rooted(&node)));
|
||||
self.last_visited.set(self.node.root().GetFirstChild().as_ref().map(Root::r));
|
||||
self.last_index.set(0u32);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ impl StorageEvent {
|
|||
oldValue: oldValue,
|
||||
newValue: newValue,
|
||||
url: url,
|
||||
storageArea: MutNullableHeap::new(storageArea.map(JS::from_ref))
|
||||
storageArea: MutNullableHeap::new(storageArea)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ impl TreeWalker {
|
|||
TreeWalker {
|
||||
reflector_: Reflector::new(),
|
||||
root_node: JS::from_ref(root_node),
|
||||
current_node: MutHeap::new(JS::from_ref(root_node)),
|
||||
current_node: MutHeap::new(root_node),
|
||||
what_to_show: what_to_show,
|
||||
filter: filter
|
||||
}
|
||||
|
@ -85,18 +85,18 @@ impl TreeWalkerMethods for TreeWalker {
|
|||
|
||||
// https://dom.spec.whatwg.org/#dom-treewalker-currentnode
|
||||
fn CurrentNode(&self) -> Root<Node> {
|
||||
self.current_node.get().root()
|
||||
self.current_node.get()
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-treewalker-currentnode
|
||||
fn SetCurrentNode(&self, node: &Node) {
|
||||
self.current_node.set(JS::from_ref(node));
|
||||
self.current_node.set(node);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-treewalker-parentnode
|
||||
fn ParentNode(&self) -> Fallible<Option<Root<Node>>> {
|
||||
// "1. Let node be the value of the currentNode attribute."
|
||||
let mut node = self.current_node.get().root();
|
||||
let mut node = self.current_node.get();
|
||||
// "2. While node is not null and is not root, run these substeps:"
|
||||
while !self.is_root_node(node.r()) {
|
||||
// "1. Let node be node's parent."
|
||||
|
@ -106,7 +106,7 @@ impl TreeWalkerMethods for TreeWalker {
|
|||
// "2. If node is not null and filtering node returns FILTER_ACCEPT,
|
||||
// then set the currentNode attribute to node, return node."
|
||||
if NodeFilterConstants::FILTER_ACCEPT == try!(self.accept_node(node.r())) {
|
||||
self.current_node.set(JS::from_rooted(&node));
|
||||
self.current_node.set(&node);
|
||||
return Ok(Some(node))
|
||||
}
|
||||
},
|
||||
|
@ -148,7 +148,7 @@ impl TreeWalkerMethods for TreeWalker {
|
|||
// https://dom.spec.whatwg.org/#dom-treewalker-previousnode
|
||||
fn PreviousNode(&self) -> Fallible<Option<Root<Node>>> {
|
||||
// "1. Let node be the value of the currentNode attribute."
|
||||
let mut node = self.current_node.get().root();
|
||||
let mut node = self.current_node.get();
|
||||
// "2. While node is not root, run these substeps:"
|
||||
while !self.is_root_node(node.r()) {
|
||||
// "1. Let sibling be the previous sibling of node."
|
||||
|
@ -170,7 +170,7 @@ impl TreeWalkerMethods for TreeWalker {
|
|||
_ if node.GetFirstChild().is_some() =>
|
||||
node = node.GetLastChild().unwrap(),
|
||||
NodeFilterConstants::FILTER_ACCEPT => {
|
||||
self.current_node.set(JS::from_rooted(&node));
|
||||
self.current_node.set(&node);
|
||||
return Ok(Some(node))
|
||||
},
|
||||
_ => break
|
||||
|
@ -194,7 +194,7 @@ impl TreeWalkerMethods for TreeWalker {
|
|||
// "5. Filter node and if the return value is FILTER_ACCEPT, then
|
||||
// set the currentNode attribute to node and return node."
|
||||
if NodeFilterConstants::FILTER_ACCEPT == try!(self.accept_node(node.r())) {
|
||||
self.current_node.set(JS::from_rooted(&node));
|
||||
self.current_node.set(&node);
|
||||
return Ok(Some(node))
|
||||
}
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ impl TreeWalkerMethods for TreeWalker {
|
|||
// https://dom.spec.whatwg.org/#dom-treewalker-nextnode
|
||||
fn NextNode(&self) -> Fallible<Option<Root<Node>>> {
|
||||
// "1. Let node be the value of the currentNode attribute."
|
||||
let mut node = self.current_node.get().root();
|
||||
let mut node = self.current_node.get();
|
||||
// "2. Let result be FILTER_ACCEPT."
|
||||
let mut result = NodeFilterConstants::FILTER_ACCEPT;
|
||||
// "3. Run these substeps:"
|
||||
|
@ -225,7 +225,7 @@ impl TreeWalkerMethods for TreeWalker {
|
|||
// "3. If result is FILTER_ACCEPT, then
|
||||
// set the currentNode attribute to node and return node."
|
||||
if NodeFilterConstants::FILTER_ACCEPT == result {
|
||||
self.current_node.set(JS::from_rooted(&node));
|
||||
self.current_node.set(&node);
|
||||
return Ok(Some(node))
|
||||
}
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ impl TreeWalkerMethods for TreeWalker {
|
|||
// "4. If result is FILTER_ACCEPT, then
|
||||
// set the currentNode attribute to node and return node."
|
||||
if NodeFilterConstants::FILTER_ACCEPT == result {
|
||||
self.current_node.set(JS::from_rooted(&node));
|
||||
self.current_node.set(&node);
|
||||
return Ok(Some(node))
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ impl TreeWalker {
|
|||
{
|
||||
// "To **traverse children** of type *type*, run these steps:"
|
||||
// "1. Let node be the value of the currentNode attribute."
|
||||
let cur = self.current_node.get().root();
|
||||
let cur = self.current_node.get();
|
||||
|
||||
// "2. Set node to node's first child if type is first, and node's last child if type is last."
|
||||
// "3. If node is null, return null."
|
||||
|
@ -284,7 +284,7 @@ impl TreeWalker {
|
|||
// "2. If result is FILTER_ACCEPT, then set the currentNode
|
||||
// attribute to node and return node."
|
||||
NodeFilterConstants::FILTER_ACCEPT => {
|
||||
self.current_node.set(JS::from_rooted(&node));
|
||||
self.current_node.set(&node);
|
||||
return Ok(Some(Root::from_ref(node.r())))
|
||||
},
|
||||
// "3. If result is FILTER_SKIP, run these subsubsteps:"
|
||||
|
@ -342,7 +342,7 @@ impl TreeWalker {
|
|||
{
|
||||
// "To **traverse siblings** of type *type* run these steps:"
|
||||
// "1. Let node be the value of the currentNode attribute."
|
||||
let mut node = self.current_node.get().root();
|
||||
let mut node = self.current_node.get();
|
||||
// "2. If node is root, return null."
|
||||
if self.is_root_node(node.r()) {
|
||||
return Ok(None)
|
||||
|
@ -361,7 +361,7 @@ impl TreeWalker {
|
|||
// "3. If result is FILTER_ACCEPT, then set the currentNode
|
||||
// attribute to node and return node."
|
||||
if NodeFilterConstants::FILTER_ACCEPT == result {
|
||||
self.current_node.set(JS::from_rooted(&node));
|
||||
self.current_node.set(&node);
|
||||
return Ok(Some(node))
|
||||
}
|
||||
|
||||
|
@ -447,7 +447,7 @@ impl TreeWalker {
|
|||
}
|
||||
|
||||
fn is_current_node(&self, node: &Node) -> bool {
|
||||
JS::from_ref(node) == self.current_node.get()
|
||||
node == &*self.current_node.get()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ impl UIEventMethods for UIEvent {
|
|||
}
|
||||
|
||||
event.InitEvent(type_, can_bubble, cancelable);
|
||||
self.view.set(view.map(JS::from_ref));
|
||||
self.view.set(view);
|
||||
self.detail.set(detail);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ impl WebGLProgram {
|
|||
return Err(WebGLError::InvalidOperation);
|
||||
}
|
||||
|
||||
shader_slot.set(Some(JS::from_ref(shader)));
|
||||
shader_slot.set(Some(shader));
|
||||
|
||||
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::AttachShader(self.id, shader.id()))).unwrap();
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast, NodeCast}
|
|||
use dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement;
|
||||
use dom::bindings::conversions::ToJSValConvertible;
|
||||
use dom::bindings::global::{GlobalField, GlobalRef};
|
||||
use dom::bindings::js::{JS, LayoutJS, Root};
|
||||
use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root};
|
||||
use dom::bindings::utils::{Reflector, reflect_dom_object};
|
||||
use dom::event::{EventBubbles, EventCancelable};
|
||||
use dom::htmlcanvaselement::HTMLCanvasElement;
|
||||
|
@ -78,8 +78,8 @@ pub struct WebGLRenderingContext {
|
|||
canvas: JS<HTMLCanvasElement>,
|
||||
last_error: Cell<Option<WebGLError>>,
|
||||
texture_unpacking_settings: Cell<TextureUnpacking>,
|
||||
bound_texture_2d: Cell<Option<JS<WebGLTexture>>>,
|
||||
bound_texture_cube_map: Cell<Option<JS<WebGLTexture>>>,
|
||||
bound_texture_2d: MutNullableHeap<JS<WebGLTexture>>,
|
||||
bound_texture_cube_map: MutNullableHeap<JS<WebGLTexture>>,
|
||||
}
|
||||
|
||||
impl WebGLRenderingContext {
|
||||
|
@ -104,8 +104,8 @@ impl WebGLRenderingContext {
|
|||
canvas: JS::from_ref(canvas),
|
||||
last_error: Cell::new(None),
|
||||
texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE),
|
||||
bound_texture_2d: Cell::new(None),
|
||||
bound_texture_cube_map: Cell::new(None),
|
||||
bound_texture_2d: MutNullableHeap::new(None),
|
||||
bound_texture_cube_map: MutNullableHeap::new(None),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -149,8 +149,8 @@ impl WebGLRenderingContext {
|
|||
|
||||
pub fn bound_texture_for(&self, target: u32) -> Option<Root<WebGLTexture>> {
|
||||
match target {
|
||||
constants::TEXTURE_2D => self.bound_texture_2d.get().map(|t| t.root()),
|
||||
constants::TEXTURE_CUBE_MAP => self.bound_texture_cube_map.get().map(|t| t.root()),
|
||||
constants::TEXTURE_2D => self.bound_texture_2d.get_rooted(),
|
||||
constants::TEXTURE_CUBE_MAP => self.bound_texture_cube_map.get_rooted(),
|
||||
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -360,7 +360,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
|
||||
if let Some(texture) = texture {
|
||||
match texture.bind(target) {
|
||||
Ok(_) => slot.set(Some(JS::from_ref(texture))),
|
||||
Ok(_) => slot.set(Some(texture)),
|
||||
Err(err) => return self.webgl_error(err),
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue