aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/bindings/global.rs10
-rw-r--r--components/script/dom/bindings/trace.rs16
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs170
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs45
-rw-r--r--components/script/dom/document.rs12
-rw-r--r--components/script/dom/element.rs6
-rw-r--r--components/script/dom/eventdispatcher.rs18
-rw-r--r--components/script/dom/filereader.rs104
-rw-r--r--components/script/dom/htmlcanvaselement.rs29
-rw-r--r--components/script/dom/htmlscriptelement.rs7
-rw-r--r--components/script/dom/htmlstyleelement.rs8
-rw-r--r--components/script/dom/htmltextareaelement.rs15
-rw-r--r--components/script/dom/htmltitleelement.rs10
-rw-r--r--components/script/dom/node.rs327
-rw-r--r--components/script/dom/storage.rs13
-rw-r--r--components/script/dom/virtualmethods.rs9
-rw-r--r--components/script/dom/webglbuffer.rs13
-rw-r--r--components/script/dom/webglframebuffer.rs14
-rw-r--r--components/script/dom/webglprogram.rs17
-rw-r--r--components/script/dom/webglrenderbuffer.rs14
-rw-r--r--components/script/dom/webglrenderingcontext.rs118
-rw-r--r--components/script/dom/webglshader.rs16
-rw-r--r--components/script/dom/webgltexture.rs13
-rw-r--r--components/script/dom/worker.rs3
-rw-r--r--components/script/dom/workerglobalscope.rs11
25 files changed, 564 insertions, 454 deletions
diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs
index 85dd955628b..5335db1d928 100644
--- a/components/script/dom/bindings/global.rs
+++ b/components/script/dom/bindings/global.rs
@@ -17,7 +17,7 @@ use dom::window::{self, WindowHelpers};
use devtools_traits::DevtoolsControlChan;
use script_task::{ScriptChan, ScriptPort, ScriptMsg, ScriptTask};
-use msg::constellation_msg::{PipelineId, WorkerId};
+use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
use net_traits::ResourceTask;
use profile_traits::mem;
@@ -91,6 +91,14 @@ impl<'a> GlobalRef<'a> {
}
}
+ /// Get a `ConstellationChan` to send messages to the constellation channel when available.
+ pub fn constellation_chan(&self) -> ConstellationChan {
+ match *self {
+ GlobalRef::Window(window) => window.constellation_chan(),
+ GlobalRef::Worker(worker) => worker.constellation_chan(),
+ }
+ }
+
/// Get a `DevtoolsControlChan` to send messages to Devtools
/// task when available.
pub fn devtools_chan(&self) -> Option<DevtoolsControlChan> {
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 079f1ecbafc..ad8da0e41b0 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -62,14 +62,15 @@ use msg::compositor_msg::ScriptListener;
use msg::constellation_msg::ConstellationChan;
use net_traits::image::base::Image;
use profile_traits::mem::ProfilerChan;
-use serde::Serialize;
use util::str::{LengthOrPercentageOrAuto};
+use serde::{Deserialize, Serialize};
use std::cell::{Cell, UnsafeCell, RefCell};
use std::collections::{HashMap, HashSet};
use std::collections::hash_state::HashState;
use std::ffi::CString;
use std::hash::{Hash, Hasher};
use std::intrinsics::return_address;
+use std::mem;
use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::sync::Arc;
@@ -332,21 +333,21 @@ impl<A,B> JSTraceable for fn(A) -> B {
}
}
-impl JSTraceable for ScriptListener {
+impl<T> JSTraceable for IpcSender<T> where T: Deserialize + Serialize {
#[inline]
fn trace(&self, _: *mut JSTracer) {
// Do nothing
}
}
-impl JSTraceable for Box<LayoutRPC+'static> {
+impl JSTraceable for ScriptListener {
#[inline]
fn trace(&self, _: *mut JSTracer) {
// Do nothing
}
}
-impl<T> JSTraceable for IpcSender<T> where T: Serialize {
+impl JSTraceable for Box<LayoutRPC+'static> {
#[inline]
fn trace(&self, _: *mut JSTracer) {
// Do nothing
@@ -482,6 +483,13 @@ impl<T: JSTraceable + Reflectable> RootedVec<T> {
}
}
+impl<T: JSTraceable + Reflectable> RootedVec<JS<T>> {
+ /// Obtain a safe slice of references that can't outlive that RootedVec.
+ pub fn r(&self) -> &[&T] {
+ unsafe { mem::transmute(&*self.v) }
+ }
+}
+
impl<T: JSTraceable + Reflectable> Drop for RootedVec<T> {
fn drop(&mut self) {
RootedTraceableSet::remove(self);
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index 4d9ea26c6b7..671177f95db 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -28,20 +28,22 @@ use euclid::matrix2d::Matrix2D;
use euclid::point::Point2D;
use euclid::rect::Rect;
use euclid::size::Size2D;
+use ipc_channel::ipc;
use canvas_traits::{CanvasMsg, Canvas2dMsg, CanvasCommonMsg};
use canvas_traits::{FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle, RepetitionStyle};
use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending};
-use canvas::canvas_paint_task::CanvasPaintTask;
+use msg::constellation_msg::Msg as ConstellationMsg;
use net_traits::image_cache_task::{ImageCacheChan, ImageResponse};
use net_traits::image::base::PixelFormat;
+use ipc_channel::ipc::IpcSender;
use num::{Float, ToPrimitive};
use std::borrow::ToOwned;
use std::cell::RefCell;
use std::fmt;
-use std::sync::mpsc::{channel, Sender};
+use std::sync::mpsc::channel;
use util::str::DOMString;
use url::Url;
@@ -60,7 +62,8 @@ pub enum CanvasFillOrStrokeStyle {
pub struct CanvasRenderingContext2D {
reflector_: Reflector,
global: GlobalField,
- renderer: Sender<CanvasMsg>,
+ renderer_id: usize,
+ ipc_renderer: IpcSender<CanvasMsg>,
canvas: JS<HTMLCanvasElement>,
state: RefCell<CanvasContextState>,
saved_states: RefCell<Vec<CanvasContextState>>,
@@ -115,10 +118,15 @@ impl CanvasContextState {
impl CanvasRenderingContext2D {
fn new_inherited(global: GlobalRef, canvas: &HTMLCanvasElement, size: Size2D<i32>)
-> CanvasRenderingContext2D {
+ let (sender, receiver) = ipc::channel().unwrap();
+ let constellation_chan = global.constellation_chan();
+ constellation_chan.0.send(ConstellationMsg::CreateCanvasPaintTask(size, sender)).unwrap();
+ let (ipc_renderer, renderer_id) = receiver.recv().unwrap();
CanvasRenderingContext2D {
reflector_: Reflector::new(),
global: GlobalField::from_rooted(&global),
- renderer: CanvasPaintTask::start(size),
+ renderer_id: renderer_id,
+ ipc_renderer: ipc_renderer,
canvas: JS::from_ref(canvas),
state: RefCell::new(CanvasContextState::new()),
saved_states: RefCell::new(Vec::new()),
@@ -132,7 +140,9 @@ impl CanvasRenderingContext2D {
}
pub fn recreate(&self, size: Size2D<i32>) {
- self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size)))
+ .unwrap();
}
fn mark_as_dirty(&self) {
@@ -142,7 +152,9 @@ impl CanvasRenderingContext2D {
}
fn update_transform(&self) {
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetTransform(self.state.borrow().transform))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetTransform(self.state.borrow().transform)))
+ .unwrap()
}
// It is used by DrawImage to calculate the size of the source and destination rectangles based
@@ -237,17 +249,19 @@ impl CanvasRenderingContext2D {
None => return Err(InvalidState),
};
- let renderer = context.r().get_renderer();
- let (sender, receiver) = channel::<Vec<u8>>();
+ let renderer = context.r().get_ipc_renderer();
+ let (sender, receiver) = ipc::channel::<Vec<u8>>().unwrap();
// Reads pixels from source image
- renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect, image_size, sender))).unwrap();
+ renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect,
+ image_size,
+ sender))).unwrap();
let imagedata = receiver.recv().unwrap();
// Writes pixels to destination canvas
CanvasMsg::Canvas2d(
Canvas2dMsg::DrawImage(imagedata, source_rect.size, dest_rect, source_rect, smoothing_enabled))
};
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
self.mark_as_dirty();
Ok(())
}
@@ -265,9 +279,13 @@ impl CanvasRenderingContext2D {
}
let smoothing_enabled = self.state.borrow().image_smoothing_enabled;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(
- image_data, image_size, dest_rect,
- source_rect, smoothing_enabled))).unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::DrawImage(image_data,
+ image_size,
+ dest_rect,
+ source_rect,
+ smoothing_enabled)))
+ .unwrap();
self.mark_as_dirty();
Ok(())
}
@@ -282,7 +300,9 @@ impl CanvasRenderingContext2D {
let img = match self.request_image_from_cache(url) {
ImageResponse::Loaded(img) => img,
- ImageResponse::PlaceholderLoaded(_) | ImageResponse::None => return None,
+ ImageResponse::PlaceholderLoaded(_) | ImageResponse::None => {
+ return None
+ }
};
let image_size = Size2D::new(img.width as f64, img.height as f64);
@@ -308,8 +328,8 @@ impl CanvasRenderingContext2D {
let canvas_size = canvas_element.get_size();
let image_size = Size2D::new(canvas_size.width as f64, canvas_size.height as f64);
- let renderer = context.r().get_renderer();
- let (sender, receiver) = channel::<Vec<u8>>();
+ let renderer = context.r().get_ipc_renderer();
+ let (sender, receiver) = ipc::channel::<Vec<u8>>().unwrap();
// Reads pixels from source canvas
renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(source_rect, image_size, sender))).unwrap();
@@ -341,24 +361,34 @@ impl CanvasRenderingContext2D {
}
pub trait CanvasRenderingContext2DHelpers {
- fn get_renderer(self) -> Sender<CanvasMsg>;
+ fn get_renderer_id(self) -> usize;
+ fn get_ipc_renderer(self) -> IpcSender<CanvasMsg>;
}
impl<'a> CanvasRenderingContext2DHelpers for &'a CanvasRenderingContext2D {
- fn get_renderer(self) -> Sender<CanvasMsg> {
- self.renderer.clone()
+ fn get_renderer_id(self) -> usize {
+ self.renderer_id
+ }
+ fn get_ipc_renderer(self) -> IpcSender<CanvasMsg> {
+ self.ipc_renderer.clone()
}
}
pub trait LayoutCanvasRenderingContext2DHelpers {
#[allow(unsafe_code)]
- unsafe fn get_renderer(&self) -> Sender<CanvasMsg>;
+ unsafe fn get_renderer_id(&self) -> usize;
+ #[allow(unsafe_code)]
+ unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg>;
}
impl LayoutCanvasRenderingContext2DHelpers for LayoutJS<CanvasRenderingContext2D> {
#[allow(unsafe_code)]
- unsafe fn get_renderer(&self) -> Sender<CanvasMsg> {
- (*self.unsafe_get()).renderer.clone()
+ unsafe fn get_renderer_id(&self) -> usize {
+ (*self.unsafe_get()).renderer_id
+ }
+ #[allow(unsafe_code)]
+ unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
+ (*self.unsafe_get()).ipc_renderer.clone()
}
}
@@ -380,7 +410,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-save
fn Save(self) {
self.saved_states.borrow_mut().push(self.state.borrow().clone());
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SaveContext)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SaveContext)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-restore
@@ -388,7 +418,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let mut saved_states = self.saved_states.borrow_mut();
if let Some(state) = saved_states.pop() {
self.state.borrow_mut().clone_from(&state);
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::RestoreContext)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::RestoreContext)).unwrap();
}
}
@@ -480,7 +510,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
self.state.borrow_mut().global_alpha = alpha;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetGlobalAlpha(alpha as f32))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetGlobalAlpha(alpha as f32)))
+ .unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation
@@ -496,14 +528,16 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
fn SetGlobalCompositeOperation(self, op_str: DOMString) {
if let Some(op) = CompositionOrBlending::from_str(&op_str) {
self.state.borrow_mut().global_composition = op;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetGlobalComposition(op))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetGlobalComposition(op)))
+ .unwrap()
}
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fillrect
fn FillRect(self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::FillRect(rect))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::FillRect(rect))).unwrap();
self.mark_as_dirty();
}
}
@@ -511,7 +545,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-clearrect
fn ClearRect(self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClearRect(rect))).unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::ClearRect(rect)))
+ .unwrap();
self.mark_as_dirty();
}
}
@@ -519,38 +555,40 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokerect
fn StrokeRect(self, x: f64, y: f64, width: f64, height: f64) {
if let Some(rect) = self.create_drawable_rect(x, y, width, height) {
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::StrokeRect(rect))).unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::StrokeRect(rect)))
+ .unwrap();
self.mark_as_dirty();
}
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-beginpath
fn BeginPath(self) {
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::BeginPath)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::BeginPath)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-closepath
fn ClosePath(self) {
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClosePath)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::ClosePath)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fill
fn Fill(self, _: CanvasWindingRule) {
// TODO: Process winding rule
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Fill)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Fill)).unwrap();
self.mark_as_dirty();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-stroke
fn Stroke(self) {
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Stroke)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Stroke)).unwrap();
self.mark_as_dirty();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-clip
fn Clip(self, _: CanvasWindingRule) {
// TODO: Process winding rule
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Clip)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::Clip)).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
@@ -728,7 +766,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let msg = CanvasMsg::Canvas2d(
Canvas2dMsg::MoveTo(
Point2D::new(x as f32, y as f32)));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-lineto
@@ -740,7 +778,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let msg = CanvasMsg::Canvas2d(
Canvas2dMsg::LineTo(
Point2D::new(x as f32, y as f32)));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-rect
@@ -749,7 +787,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let rect = Rect::new(Point2D::new(x as f32, y as f32),
Size2D::new(width as f32, height as f32));
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::Rect(rect));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
}
}
@@ -764,7 +802,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
Canvas2dMsg::QuadraticCurveTo(
Point2D::new(cpx as f32, cpy as f32),
Point2D::new(x as f32, y as f32)));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-beziercurveto
@@ -779,7 +817,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
Point2D::new(cp1x as f32, cp1y as f32),
Point2D::new(cp2x as f32, cp2y as f32),
Point2D::new(x as f32, y as f32)));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-arc
@@ -800,7 +838,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
Point2D::new(x as f32, y as f32), r as f32,
start as f32, end as f32, ccw));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
Ok(())
}
@@ -818,7 +856,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
Point2D::new(cp1x as f32, cp1y as f32),
Point2D::new(cp2x as f32, cp2y as f32),
r as f32));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
Ok(())
}
@@ -854,8 +892,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
match parse_color(&string) {
Ok(rgba) => {
self.state.borrow_mut().stroke_style = CanvasFillOrStrokeStyle::Color(rgba);
- self.renderer
- .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetStrokeStyle(FillOrStrokeStyle::Color(rgba))))
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetStrokeStyle(
+ FillOrStrokeStyle::Color(rgba))))
.unwrap();
}
_ => {}
@@ -866,7 +905,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
JS::from_ref(gradient.r()));
let msg = CanvasMsg::Canvas2d(
Canvas2dMsg::SetStrokeStyle(gradient.r().to_fill_or_stroke_style()));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
},
_ => {}
}
@@ -893,8 +932,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
match parse_color(&string) {
Ok(rgba) => {
self.state.borrow_mut().fill_style = CanvasFillOrStrokeStyle::Color(rgba);
- self.renderer
- .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(FillOrStrokeStyle::Color(rgba))))
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
+ FillOrStrokeStyle::Color(rgba))))
.unwrap()
}
_ => {}
@@ -905,10 +945,10 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
JS::from_rooted(&gradient));
let msg = CanvasMsg::Canvas2d(
Canvas2dMsg::SetFillStyle(gradient.r().to_fill_or_stroke_style()));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
}
StringOrCanvasGradientOrCanvasPattern::eCanvasPattern(pattern) => {
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
pattern.r().to_fill_or_stroke_style()))).unwrap();
}
}
@@ -947,12 +987,14 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
return Err(IndexSize)
}
- let (sender, receiver) = channel::<Vec<u8>>();
+ let (sender, receiver) = ipc::channel::<Vec<u8>>().unwrap();
let dest_rect = Rect::new(Point2D::new(sx as f64, sy as f64),
Size2D::new(sw as f64, sh as f64));
let canvas_size = self.canvas.root().r().get_size();
let canvas_size = Size2D::new(canvas_size.width as f64, canvas_size.height as f64);
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(dest_rect, canvas_size, sender))).unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::GetImageData(dest_rect, canvas_size, sender)))
+ .unwrap();
let data = receiver.recv().unwrap();
Ok(ImageData::new(self.global.root().r(), sw.abs().to_u32().unwrap(), sh.abs().to_u32().unwrap(), Some(data)))
}
@@ -975,7 +1017,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let image_data_rect = Rect::new(Point2D::new(dx, dy), image_data_size);
let dirty_rect = None;
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::PutImageData(data, image_data_rect, dirty_rect));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
self.mark_as_dirty();
}
@@ -1003,7 +1045,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
let dirty_rect = Some(Rect::new(Point2D::new(dirtyX, dirtyY),
Size2D::new(dirtyWidth, dirtyHeight)));
let msg = CanvasMsg::Canvas2d(Canvas2dMsg::PutImageData(data, image_data_rect, dirty_rect));
- self.renderer.send(msg).unwrap();
+ self.ipc_renderer.send(msg).unwrap();
self.mark_as_dirty();
}
@@ -1106,7 +1148,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
self.state.borrow_mut().line_width = width;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineWidth(width as f32))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineWidth(width as f32)))
+ .unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linecap
@@ -1123,7 +1167,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
fn SetLineCap(self, cap_str: DOMString) {
if let Some(cap) = LineCapStyle::from_str(&cap_str) {
self.state.borrow_mut().line_cap = cap;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineCap(cap))).unwrap()
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineCap(cap))).unwrap()
}
}
@@ -1141,7 +1185,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
fn SetLineJoin(self, join_str: DOMString) {
if let Some(join) = LineJoinStyle::from_str(&join_str) {
self.state.borrow_mut().line_join = join;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineJoin(join))).unwrap()
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetLineJoin(join))).unwrap()
}
}
@@ -1158,7 +1202,9 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
}
self.state.borrow_mut().miter_limit = limit;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetMiterLimit(limit as f32))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetMiterLimit(limit as f32)))
+ .unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsetx
@@ -1172,7 +1218,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
return;
}
self.state.borrow_mut().shadow_offset_x = value;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowOffsetX(value))).unwrap()
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowOffsetX(value))).unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsety
@@ -1186,7 +1232,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
return;
}
self.state.borrow_mut().shadow_offset_y = value;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowOffsetY(value))).unwrap()
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowOffsetY(value))).unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowblur
@@ -1200,7 +1246,7 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
return;
}
self.state.borrow_mut().shadow_blur = value;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowBlur(value))).unwrap()
+ self.ipc_renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowBlur(value))).unwrap()
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
@@ -1214,14 +1260,16 @@ impl<'a> CanvasRenderingContext2DMethods for &'a CanvasRenderingContext2D {
fn SetShadowColor(self, value: DOMString) {
if let Ok(color) = parse_color(&value) {
self.state.borrow_mut().shadow_color = color;
- self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowColor(color))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::Canvas2d(Canvas2dMsg::SetShadowColor(color)))
+ .unwrap()
}
}
}
impl Drop for CanvasRenderingContext2D {
fn drop(&mut self) {
- self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
}
}
diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs
index b298f37bee1..6c27b895906 100644
--- a/components/script/dom/dedicatedworkerglobalscope.rs
+++ b/components/script/dom/dedicatedworkerglobalscope.rs
@@ -24,16 +24,18 @@ use dom::workerglobalscope::WorkerGlobalScopeTypeId;
use script_task::{ScriptTask, ScriptChan, ScriptMsg, TimerSource, ScriptPort};
use script_task::StackRootTLS;
-use msg::constellation_msg::PipelineId;
+use msg::constellation_msg::{ConstellationChan, PipelineId};
use devtools_traits::DevtoolsControlChan;
use net_traits::{load_whole_resource, ResourceTask};
-use profile_traits::mem::{self, Reporter, ReportsChan};
+use profile_traits::mem::{self, Reporter, ReporterRequest};
use util::task::spawn_named;
use util::task_state;
use util::task_state::{SCRIPT, IN_WORKER};
+use ipc_channel::ipc;
+use ipc_channel::router::ROUTER;
use js::jsapi::{JSContext, RootedValue, HandleValue};
use js::jsapi::{JSAutoRequest, JSAutoCompartment};
use js::jsval::UndefinedValue;
@@ -66,13 +68,6 @@ impl ScriptChan for SendableWorkerScriptChan {
}
}
-impl Reporter for SendableWorkerScriptChan {
- // Just injects an appropriate event into the worker task's queue.
- fn collect_reports(&self, reports_chan: ReportsChan) -> bool {
- self.send(ScriptMsg::CollectReports(reports_chan)).is_ok()
- }
-}
-
/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
/// value for the duration of this object's lifetime. This ensures that the related Worker
/// object only lives as long as necessary (ie. while events are being executed), while
@@ -118,6 +113,7 @@ impl DedicatedWorkerGlobalScope {
devtools_chan: Option<DevtoolsControlChan>,
runtime: Rc<Runtime>,
resource_task: ResourceTask,
+ constellation_chan: ConstellationChan,
parent_sender: Box<ScriptChan+Send>,
own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>,
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>)
@@ -125,7 +121,7 @@ impl DedicatedWorkerGlobalScope {
DedicatedWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope::new_inherited(
WorkerGlobalScopeTypeId::DedicatedGlobalScope, worker_url,
- runtime, resource_task, mem_profiler_chan, devtools_chan),
+ runtime, resource_task, mem_profiler_chan, devtools_chan, constellation_chan),
id: id,
receiver: receiver,
own_sender: own_sender,
@@ -140,13 +136,14 @@ impl DedicatedWorkerGlobalScope {
devtools_chan: Option<DevtoolsControlChan>,
runtime: Rc<Runtime>,
resource_task: ResourceTask,
+ constellation_chan: ConstellationChan,
parent_sender: Box<ScriptChan+Send>,
own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>,
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>)
-> Root<DedicatedWorkerGlobalScope> {
let scope = box DedicatedWorkerGlobalScope::new_inherited(
worker_url, id, mem_profiler_chan, devtools_chan, runtime.clone(), resource_task,
- parent_sender, own_sender, receiver);
+ constellation_chan, parent_sender, own_sender, receiver);
DedicatedWorkerGlobalScopeBinding::Wrap(runtime.cx(), scope)
}
}
@@ -158,6 +155,7 @@ impl DedicatedWorkerGlobalScope {
devtools_chan: Option<DevtoolsControlChan>,
worker: TrustedWorkerAddress,
resource_task: ResourceTask,
+ constellation_chan: ConstellationChan,
parent_sender: Box<ScriptChan+Send>,
own_sender: Sender<(TrustedWorkerAddress, ScriptMsg)>,
receiver: Receiver<(TrustedWorkerAddress, ScriptMsg)>) {
@@ -182,9 +180,10 @@ impl DedicatedWorkerGlobalScope {
let runtime = Rc::new(ScriptTask::new_rt_and_cx());
let serialized_url = url.serialize();
+ let parent_sender_for_reporter = parent_sender.clone();
let global = DedicatedWorkerGlobalScope::new(
url, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(), resource_task,
- parent_sender, own_sender, receiver);
+ constellation_chan, parent_sender, own_sender, receiver);
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
// registration (#6631), so we instead use a random number and cross our fingers.
let reporter_name = format!("worker-reporter-{}", random::<u64>());
@@ -206,9 +205,16 @@ impl DedicatedWorkerGlobalScope {
// Register this task as a memory reporter. This needs to be done within the
// scope of `_ar` otherwise script_chan_as_reporter() will panic.
- let reporter = global.script_chan_as_reporter();
- let msg = mem::ProfilerMsg::RegisterReporter(reporter_name.clone(), reporter);
- mem_profiler_chan.send(msg);
+ let (reporter_sender, reporter_receiver) = ipc::channel().unwrap();
+ ROUTER.add_route(reporter_receiver.to_opaque(), box move |reporter_request| {
+ // Just injects an appropriate event into the worker task's queue.
+ let reporter_request: ReporterRequest = reporter_request.to().unwrap();
+ parent_sender_for_reporter.send(ScriptMsg::CollectReports(
+ reporter_request.reports_channel)).unwrap()
+ });
+ mem_profiler_chan.send(mem::ProfilerMsg::RegisterReporter(
+ reporter_name.clone(),
+ Reporter(reporter_sender)));
}
loop {
@@ -230,7 +236,6 @@ impl DedicatedWorkerGlobalScope {
pub trait DedicatedWorkerGlobalScopeHelpers {
fn script_chan(self) -> Box<ScriptChan+Send>;
- fn script_chan_as_reporter(self) -> Box<Reporter+Send>;
fn pipeline(self) -> PipelineId;
fn new_script_pair(self) -> (Box<ScriptChan+Send>, Box<ScriptPort+Send>);
fn process_event(self, msg: ScriptMsg);
@@ -244,14 +249,6 @@ impl<'a> DedicatedWorkerGlobalScopeHelpers for &'a DedicatedWorkerGlobalScope {
}
}
- fn script_chan_as_reporter(self) -> Box<Reporter+Send> {
- box SendableWorkerScriptChan {
- sender: self.own_sender.clone(),
- worker: self.worker.borrow().as_ref().unwrap().clone(),
- }
- }
-
-
fn pipeline(self) -> PipelineId {
self.id
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index d074dca0d4e..0e494b79a89 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -733,15 +733,13 @@ impl<'a> DocumentHelpers<'a> for &'a Document {
// Set hover state for any elements in the current mouse over list.
// Check if any of them changed state to determine whether to
// force a reflow below.
- for target in mouse_over_targets.iter() {
- let target = target.root();
- let target_ref = target.r();
- if !target_ref.get_hover_state() {
- target_ref.set_hover_state(true);
+ for target in mouse_over_targets.r() {
+ if !target.get_hover_state() {
+ target.set_hover_state(true);
- let target = EventTargetCast::from_ref(target_ref);
+ let target = EventTargetCast::from_ref(*target);
- self.fire_mouse_event(point, &target, "mouseover".to_owned());
+ self.fire_mouse_event(point, target, "mouseover".to_owned());
}
}
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 0fb55d0ff82..dd6afd3061b 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -866,9 +866,9 @@ impl<'a> AttributeHandlers for &'a Element {
fn get_attribute(self, namespace: &Namespace, local_name: &Atom) -> Option<Root<Attr>> {
let mut attributes = RootedVec::new();
self.get_attributes(local_name, &mut attributes);
- attributes.iter()
- .map(|attr| attr.root())
- .find(|attr| attr.r().namespace() == namespace)
+ attributes.r().iter()
+ .find(|attr| attr.namespace() == namespace)
+ .map(|attr| Root::from_ref(*attr))
}
// https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
diff --git a/components/script/dom/eventdispatcher.rs b/components/script/dom/eventdispatcher.rs
index 8633f63df7c..0c6c7e14b18 100644
--- a/components/script/dom/eventdispatcher.rs
+++ b/components/script/dom/eventdispatcher.rs
@@ -41,14 +41,13 @@ pub fn dispatch_event<'a, 'b>(target: &'a EventTarget,
//FIXME: The "callback this value" should be currentTarget
/* capturing */
- for cur_target in chain.iter().rev() {
- let cur_target = cur_target.root();
- let stopped = match cur_target.r().get_listeners_for(&type_, ListenerPhase::Capturing) {
+ for cur_target in chain.r().iter().rev() {
+ let stopped = match cur_target.get_listeners_for(&type_, ListenerPhase::Capturing) {
Some(listeners) => {
- event.set_current_target(cur_target.r());
+ event.set_current_target(cur_target);
for listener in listeners.iter() {
// Explicitly drop any exception on the floor.
- let _ = listener.HandleEvent_(cur_target.r(), event, Report);
+ let _ = listener.HandleEvent_(*cur_target, event, Report);
if event.stop_immediate() {
break;
@@ -87,14 +86,13 @@ pub fn dispatch_event<'a, 'b>(target: &'a EventTarget,
if event.bubbles() && !event.stop_propagation() {
event.set_phase(EventPhase::Bubbling);
- for cur_target in chain.iter() {
- let cur_target = cur_target.root();
- let stopped = match cur_target.r().get_listeners_for(&type_, ListenerPhase::Bubbling) {
+ for cur_target in chain.r() {
+ let stopped = match cur_target.get_listeners_for(&type_, ListenerPhase::Bubbling) {
Some(listeners) => {
- event.set_current_target(cur_target.r());
+ event.set_current_target(cur_target);
for listener in listeners.iter() {
// Explicitly drop any exception on the floor.
- let _ = listener.HandleEvent_(cur_target.r(), event, Report);
+ let _ = listener.HandleEvent_(*cur_target, event, Report);
if event.stop_immediate() {
break;
diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs
index 7ac8f876157..964a980a0b1 100644
--- a/components/script/dom/filereader.rs
+++ b/components/script/dom/filereader.rs
@@ -2,8 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use dom::bindings::codegen::Bindings::FileReaderBinding;
-use dom::bindings::codegen::Bindings::FileReaderBinding::{FileReaderConstants, FileReaderMethods};
+use dom::bindings::codegen::Bindings::FileReaderBinding::{self, FileReaderConstants, FileReaderMethods};
use dom::bindings::codegen::InheritTypes::{EventCast, EventTargetCast};
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::error::{ErrorResult, Fallible};
@@ -14,8 +13,7 @@ use dom::bindings::refcounted::Trusted;
use dom::bindings::utils::{reflect_dom_object, Reflectable};
use dom::event::{EventHelpers, EventCancelable, EventBubbles};
use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId};
-use dom::blob::Blob;
-use dom::blob::BlobHelpers;
+use dom::blob::{Blob, BlobHelpers};
use dom::domexception::{DOMException, DOMErrorName};
use dom::progressevent::ProgressEvent;
use encoding::all::UTF_8;
@@ -229,33 +227,30 @@ impl FileReader {
fn perform_readastext(blob_body: BlobBody)
-> Result<Option<DOMString>, DOMErrorName> {
+ let blob_label = &blob_body.label;
+ let blob_type = &blob_body.blobtype;
+ let blob_bytes = &blob_body.bytes[..];
+
//https://w3c.github.io/FileAPI/#encoding-determination
// Steps 1 & 2 & 3
- let mut encoding = match blob_body.label {
- Some(e) => encoding_from_whatwg_label(&e),
- None => None
- };
+ let mut encoding = blob_label.as_ref()
+ .map(|string| &**string)
+ .and_then(encoding_from_whatwg_label);
// Step 4 & 5
- encoding = match encoding {
- Some(e) => Some(e),
- None => {
- let resultmime = blob_body.blobtype.parse::<Mime>().ok();
- resultmime.and_then(|Mime(_, _, ref parameters)| {
- parameters.iter()
- .find(|&&(ref k, _)| &Attr::Charset == k)
- .and_then(|&(_, ref v)| encoding_from_whatwg_label(&v.to_string()))
- })
- }
- };
+ encoding = encoding.or_else(|| {
+ let resultmime = blob_type.parse::<Mime>().ok();
+ resultmime.and_then(|Mime(_, _, ref parameters)| {
+ parameters.iter()
+ .find(|&&(ref k, _)| &Attr::Charset == k)
+ .and_then(|&(_, ref v)| encoding_from_whatwg_label(&v.to_string()))
+ })
+ });
// Step 6
- let enc = match encoding {
- Some(code) => code,
- None => UTF_8 as EncodingRef
- };
+ let enc = encoding.unwrap_or(UTF_8 as EncodingRef);
- let convert = &blob_body.bytes[..];
+ let convert = blob_bytes;
// Step 7
let output = enc.decode(convert, DecoderTrap::Replace).unwrap();
Ok(Some(output))
@@ -409,73 +404,51 @@ impl<'a> PrivateFileReaderHelpers for &'a FileReader {
}
#[derive(Clone)]
-pub enum Process {
+pub enum FileReaderEvent {
ProcessRead(TrustedFileReader, GenerationId),
ProcessReadData(TrustedFileReader, GenerationId, DOMString),
ProcessReadError(TrustedFileReader, GenerationId, DOMErrorName),
ProcessReadEOF(TrustedFileReader, GenerationId, Option<BlobBody>)
}
-impl Process {
- fn call(self, chan: &Box<ScriptChan + Send>) {
- let task = box FileReaderEvent::new(self);
- chan.send(ScriptMsg::RunnableMsg(task)).unwrap();
- }
-
- pub fn handle(process: Process) {
- match process {
- Process::ProcessRead(filereader, gen_id) => {
+impl Runnable for FileReaderEvent {
+ fn handler(self: Box<FileReaderEvent>) {
+ let file_reader_event = *self;
+ match file_reader_event {
+ FileReaderEvent::ProcessRead(filereader, gen_id) => {
FileReader::process_read(filereader, gen_id);
},
- Process::ProcessReadData(filereader, gen_id, _) => {
+ FileReaderEvent::ProcessReadData(filereader, gen_id, _) => {
FileReader::process_read_data(filereader, gen_id);
},
- Process::ProcessReadError(filereader, gen_id, error) => {
+ FileReaderEvent::ProcessReadError(filereader, gen_id, error) => {
FileReader::process_read_error(filereader, gen_id, error);
},
- Process::ProcessReadEOF(filereader, gen_id, blob_body) => {
+ FileReaderEvent::ProcessReadEOF(filereader, gen_id, blob_body) => {
FileReader::process_read_eof(filereader, gen_id, blob_body);
}
}
}
}
-pub struct FileReaderEvent {
- process: Process,
-}
-
-impl FileReaderEvent {
- pub fn new(process: Process) -> FileReaderEvent {
- FileReaderEvent {
- process: process,
- }
- }
-
-}
-
-impl Runnable for FileReaderEvent {
- fn handler(self: Box<FileReaderEvent>) {
- let this = *self;
- Process::handle(this.process);
- }
-}
-
-//https://w3c.github.io/FileAPI/#task-read-operation
+// https://w3c.github.io/FileAPI/#task-read-operation
fn perform_annotated_read_operation(gen_id: GenerationId, read_data: ReadData,
filereader: TrustedFileReader, script_chan: Box<ScriptChan + Send>) {
let chan = &script_chan;
// Step 4
- Process::ProcessRead(filereader.clone(),
- gen_id).call(chan);
+ let task = box FileReaderEvent::ProcessRead(filereader.clone(), gen_id);
+ chan.send(ScriptMsg::RunnableMsg(task)).unwrap();
- Process::ProcessReadData(filereader.clone(),
- gen_id, DOMString::new()).call(chan);
+ let task = box FileReaderEvent::ProcessReadData(filereader.clone(),
+ gen_id, DOMString::new());
+ chan.send(ScriptMsg::RunnableMsg(task)).unwrap();
let output = match read_data.bytes.recv() {
Ok(bytes) => bytes,
Err(_) => {
- Process::ProcessReadError(filereader,
- gen_id, DOMErrorName::NotFoundError).call(chan);
+ let task = box FileReaderEvent::ProcessReadError(filereader,
+ gen_id, DOMErrorName::NotFoundError);
+ chan.send(ScriptMsg::RunnableMsg(task)).unwrap();
return;
}
};
@@ -487,5 +460,6 @@ fn perform_annotated_read_operation(gen_id: GenerationId, read_data: ReadData,
BlobBody::new(bytes, blobtype, label, read_data.function)
});
- Process::ProcessReadEOF(filereader, gen_id, blob_body).call(chan);
+ let task = box FileReaderEvent::ProcessReadEOF(filereader, gen_id, blob_body);
+ chan.send(ScriptMsg::RunnableMsg(task)).unwrap();
}
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index a01a2c4fe26..3c52d99ea4f 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas_traits::CanvasMsg;
use dom::attr::Attr;
use dom::attr::AttrHelpers;
use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding;
@@ -27,12 +26,13 @@ use dom::webglrenderingcontext::{WebGLRenderingContext, LayoutCanvasWebGLRenderi
use util::str::{DOMString, parse_unsigned_integer};
use js::jsapi::{JSContext, HandleValue};
use offscreen_gl_context::GLContextAttributes;
+use canvas_traits::CanvasMsg;
+use ipc_channel::ipc::IpcSender;
use euclid::size::Size2D;
use std::cell::Cell;
use std::default::Default;
-use std::sync::mpsc::Sender;
const DEFAULT_WIDTH: u32 = 300;
const DEFAULT_HEIGHT: u32 = 150;
@@ -106,7 +106,9 @@ impl HTMLCanvasElement {
pub trait LayoutHTMLCanvasElementHelpers {
#[allow(unsafe_code)]
- unsafe fn get_renderer(&self) -> Option<Sender<CanvasMsg>>;
+ unsafe fn get_renderer_id(&self) -> Option<usize>;
+ #[allow(unsafe_code)]
+ unsafe fn get_ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>>;
#[allow(unsafe_code)]
unsafe fn get_canvas_width(&self) -> u32;
#[allow(unsafe_code)]
@@ -115,14 +117,25 @@ pub trait LayoutHTMLCanvasElementHelpers {
impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> {
#[allow(unsafe_code)]
- unsafe fn get_renderer(&self) -> Option<Sender<CanvasMsg>> {
+ unsafe fn get_renderer_id(&self) -> Option<usize> {
+ let ref canvas = *self.unsafe_get();
+ if let Some(context) = canvas.context.get() {
+ match context {
+ CanvasContext::Context2d(context) => Some(context.to_layout().get_renderer_id()),
+ CanvasContext::WebGL(context) => Some(context.to_layout().get_renderer_id()),
+ }
+ } else {
+ None
+ }
+ }
+
+ #[allow(unsafe_code)]
+ unsafe fn get_ipc_renderer(&self) -> Option<IpcSender<CanvasMsg>> {
let ref canvas = *self.unsafe_get();
if let Some(context) = canvas.context.get() {
match context {
- CanvasContext::Context2d(context)
- => Some(context.to_layout().get_renderer()),
- CanvasContext::WebGL(context)
- => Some(context.to_layout().get_renderer()),
+ CanvasContext::Context2d(context) => Some(context.to_layout().get_ipc_renderer()),
+ CanvasContext::WebGL(context) => Some(context.to_layout().get_ipc_renderer()),
}
} else {
None
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index 8bdbdb8759e..3329e0f0af9 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -27,7 +27,8 @@ use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::event::{Event, EventBubbles, EventCancelable, EventHelpers};
use dom::element::ElementTypeId;
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
-use dom::node::{Node, NodeHelpers, NodeTypeId, document_from_node, window_from_node, CloneChildrenFlag};
+use dom::node::{ChildrenMutation, CloneChildrenFlag, Node, NodeHelpers};
+use dom::node::{NodeTypeId, document_from_node, window_from_node};
use dom::servohtmlparser::ServoHTMLParserHelpers;
use dom::virtualmethods::VirtualMethods;
use dom::window::{WindowHelpers, ScriptHelpers};
@@ -564,9 +565,9 @@ impl<'a> VirtualMethods for &'a HTMLScriptElement {
}
}
- fn child_inserted(&self, child: &Node) {
+ fn children_changed(&self, mutation: &ChildrenMutation) {
if let Some(ref s) = self.super_type() {
- s.child_inserted(child);
+ s.children_changed(mutation);
}
let node = NodeCast::from_ref(*self);
if !self.parser_inserted.get() && node.is_in_doc() {
diff --git a/components/script/dom/htmlstyleelement.rs b/components/script/dom/htmlstyleelement.rs
index 7c1c06412ef..22c4c705ccb 100644
--- a/components/script/dom/htmlstyleelement.rs
+++ b/components/script/dom/htmlstyleelement.rs
@@ -11,7 +11,8 @@ use dom::document::Document;
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::element::{ElementTypeId, AttributeHandlers};
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
-use dom::node::{Node, NodeHelpers, NodeTypeId, window_from_node};
+use dom::node::{ChildrenMutation, Node, NodeHelpers, NodeTypeId};
+use dom::node::window_from_node;
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
use layout_interface::{LayoutChan, Msg};
@@ -86,11 +87,10 @@ impl<'a> VirtualMethods for &'a HTMLStyleElement {
Some(htmlelement as &VirtualMethods)
}
- fn child_inserted(&self, child: &Node) {
+ fn children_changed(&self, mutation: &ChildrenMutation) {
if let Some(ref s) = self.super_type() {
- s.child_inserted(child);
+ s.children_changed(mutation);
}
-
let node = NodeCast::from_ref(*self);
if node.is_in_doc() {
self.parse_own_css();
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index 17e646d71ed..22e843fa08f 100644
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -11,7 +11,7 @@ use dom::bindings::codegen::Bindings::HTMLTextAreaElementBinding::HTMLTextAreaEl
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementDerived, HTMLFieldSetElementDerived};
-use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, TextDerived};
+use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{LayoutJS, Root};
use dom::bindings::refcounted::Trusted;
@@ -23,8 +23,8 @@ use dom::element::ElementTypeId;
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
use dom::htmlformelement::FormControl;
use dom::keyboardevent::KeyboardEvent;
-use dom::node::{DisabledStateHelpers, Node, NodeHelpers, NodeDamage, NodeTypeId};
-use dom::node::{document_from_node, window_from_node};
+use dom::node::{ChildrenMutation, DisabledStateHelpers, Node, NodeDamage};
+use dom::node::{NodeHelpers, NodeTypeId, document_from_node, window_from_node};
use textinput::{TextInput, Lines, KeyReaction};
use dom::virtualmethods::VirtualMethods;
use dom::window::WindowHelpers;
@@ -330,12 +330,11 @@ impl<'a> VirtualMethods for &'a HTMLTextAreaElement {
}
}
- fn child_inserted(&self, child: &Node) {
- if let Some(s) = self.super_type() {
- s.child_inserted(child);
+ fn children_changed(&self, mutation: &ChildrenMutation) {
+ if let Some(ref s) = self.super_type() {
+ s.children_changed(mutation);
}
-
- if child.is_text() && !self.value_changed.get() {
+ if !self.value_changed.get() {
self.reset();
}
}
diff --git a/components/script/dom/htmltitleelement.rs b/components/script/dom/htmltitleelement.rs
index a6585bd17b4..e4f51b03629 100644
--- a/components/script/dom/htmltitleelement.rs
+++ b/components/script/dom/htmltitleelement.rs
@@ -13,7 +13,7 @@ use dom::document::{Document, DocumentHelpers};
use dom::eventtarget::{EventTarget, EventTargetTypeId};
use dom::element::ElementTypeId;
use dom::htmlelement::{HTMLElement, HTMLElementTypeId};
-use dom::node::{Node, NodeHelpers, NodeTypeId};
+use dom::node::{ChildrenMutation, Node, NodeHelpers, NodeTypeId};
use dom::text::Text;
use dom::virtualmethods::VirtualMethods;
use util::str::DOMString;
@@ -75,15 +75,13 @@ impl<'a> VirtualMethods for &'a HTMLTitleElement {
Some(htmlelement as &VirtualMethods)
}
- fn child_inserted(&self, child: &Node) {
+ fn children_changed(&self, mutation: &ChildrenMutation) {
if let Some(ref s) = self.super_type() {
- s.child_inserted(child);
+ s.children_changed(mutation);
}
-
let node = NodeCast::from_ref(*self);
if node.is_in_doc() {
- let document = node.owner_doc();
- document.r().title_changed();
+ node.owner_doc().title_changed();
}
}
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 0a06a5253c5..42ad7608580 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -67,6 +67,7 @@ use std::cell::{Cell, RefCell, Ref, RefMut};
use std::default::Default;
use std::iter::{FilterMap, Peekable};
use std::mem;
+use std::slice::ref_slice;
use std::sync::Arc;
use uuid;
use string_cache::{Atom, Namespace, QualName};
@@ -282,42 +283,11 @@ pub enum NodeTypeId {
}
trait PrivateNodeHelpers {
- fn node_inserted(self);
- fn node_removed(self, parent_in_doc: bool);
fn add_child(self, new_child: &Node, before: Option<&Node>);
fn remove_child(self, child: &Node);
}
impl<'a> PrivateNodeHelpers for &'a Node {
- // https://dom.spec.whatwg.org/#node-is-inserted
- fn node_inserted(self) {
- assert!(self.parent_node.get().is_some());
- let document = document_from_node(self);
- let is_in_doc = self.is_in_doc();
-
- for node in self.traverse_preorder() {
- vtable_for(&node.r()).bind_to_tree(is_in_doc);
- }
-
- let parent = self.parent_node.get().map(Root::from_rooted);
- parent.r().map(|parent| vtable_for(&parent).child_inserted(self));
- document.r().content_and_heritage_changed(self, NodeDamage::OtherNodeDamage);
- }
-
- // https://dom.spec.whatwg.org/#node-is-removed
- fn node_removed(self, parent_in_doc: bool) {
- assert!(self.parent_node.get().is_none());
- for node in self.traverse_preorder() {
- node.r().set_flag(IS_IN_DOC, false);
- vtable_for(&node.r()).unbind_from_tree(parent_in_doc);
- }
- self.layout_data.dispose(self);
- }
-
- //
- // Pointer stitching
- //
-
/// Adds a new child to the end of this node's list of children.
///
/// Fails unless `new_child` is disconnected from the tree.
@@ -358,6 +328,14 @@ impl<'a> PrivateNodeHelpers for &'a Node {
}
new_child.parent_node.set(Some(JS::from_ref(self)));
+
+ let parent_in_doc = self.is_in_doc();
+ for node in new_child.traverse_preorder() {
+ node.set_flag(IS_IN_DOC, parent_in_doc);
+ vtable_for(&&*node).bind_to_tree(parent_in_doc);
+ }
+ let document = new_child.owner_doc();
+ document.content_and_heritage_changed(new_child, NodeDamage::OtherNodeDamage);
}
/// Removes the given child from this node's list of children.
@@ -387,6 +365,15 @@ impl<'a> PrivateNodeHelpers for &'a Node {
child.prev_sibling.set(None);
child.next_sibling.set(None);
child.parent_node.set(None);
+
+ let parent_in_doc = self.is_in_doc();
+ for node in child.traverse_preorder() {
+ node.set_flag(IS_IN_DOC, false);
+ vtable_for(&&*node).unbind_from_tree(parent_in_doc);
+ }
+ child.layout_data.dispose(child);
+ let document = child.owner_doc();
+ document.content_and_heritage_changed(child, NodeDamage::OtherNodeDamage);
}
}
@@ -971,9 +958,8 @@ impl<'a> NodeHelpers for &'a Node {
}
fn remove_self(self) {
- match self.parent_node.get() {
- Some(parent) => parent.root().r().remove_child(self),
- None => ()
+ if let Some(ref parent) = self.GetParentNode() {
+ Node::remove(self, parent.r(), SuppressObserver::Unsuppressed);
}
}
@@ -1638,110 +1624,79 @@ impl Node {
parent: &Node,
child: Option<&Node>,
suppress_observers: SuppressObserver) {
- fn do_insert(node: &Node, parent: &Node, child: Option<&Node>) {
- parent.add_child(node, child);
- let is_in_doc = parent.is_in_doc();
- for kid in node.traverse_preorder() {
- let mut flags = kid.r().flags.get();
- if is_in_doc {
- flags.insert(IS_IN_DOC);
- } else {
- flags.remove(IS_IN_DOC);
- }
- kid.r().flags.set(flags);
- }
- }
+ debug_assert!(&*node.owner_doc() == &*parent.owner_doc());
+ debug_assert!(child.map_or(true, |child| Some(parent) == child.GetParentNode().r()));
- fn fire_observer_if_necessary(node: &Node, suppress_observers: SuppressObserver) {
- match suppress_observers {
- SuppressObserver::Unsuppressed => node.node_inserted(),
- SuppressObserver::Suppressed => ()
+ // Steps 1-2: ranges.
+ let mut new_nodes = RootedVec::new();
+ let new_nodes = if let NodeTypeId::DocumentFragment = node.type_id() {
+ // Step 3.
+ new_nodes.extend(node.children().map(|kid| JS::from_rooted(&kid)));
+ // Step 4: mutation observers.
+ // Step 5.
+ for kid in new_nodes.r() {
+ Node::remove(*kid, node, SuppressObserver::Suppressed);
}
- }
-
- // XXX assert owner_doc
- // Step 1-3: ranges.
-
- match node.type_id() {
- NodeTypeId::DocumentFragment => {
- // Step 4.
- // Step 5: DocumentFragment, mutation records.
- // Step 6: DocumentFragment.
- let kids: Vec<Root<Node>> = node.children().collect();
- for kid in &kids {
- Node::remove(kid.r(), node, SuppressObserver::Suppressed);
- }
-
- // Step 7: mutation records.
- // Step 8.
- for kid in &kids {
- do_insert(kid.r(), parent, child);
- }
-
- for kid in kids {
- fire_observer_if_necessary(kid.r(), suppress_observers);
+ vtable_for(&node).children_changed(&ChildrenMutation::replace_all(new_nodes.r(), &[]));
+ new_nodes.r()
+ } else {
+ // Step 3.
+ ref_slice(&node)
+ };
+ // Step 6: mutation observers.
+ let previous_sibling = match suppress_observers {
+ SuppressObserver::Unsuppressed => {
+ match child {
+ Some(child) => child.GetPreviousSibling(),
+ None => parent.GetLastChild(),
}
- }
- _ => {
- // Step 4.
- // Step 5: DocumentFragment, mutation records.
- // Step 6: DocumentFragment.
- // Step 7: mutation records.
- // Step 8.
- do_insert(node, parent, child);
- // Step 9.
- fire_observer_if_necessary(node, suppress_observers);
- }
+ },
+ SuppressObserver::Suppressed => None,
+ };
+ // Step 7.
+ for kid in new_nodes {
+ // Step 7.1.
+ parent.add_child(*kid, child);
+ // Step 7.2: insertion steps.
+ }
+ if let SuppressObserver::Unsuppressed = suppress_observers {
+ vtable_for(&parent).children_changed(
+ &ChildrenMutation::insert(previous_sibling.r(), new_nodes, child));
}
}
// https://dom.spec.whatwg.org/#concept-node-replace-all
pub fn replace_all(node: Option<&Node>, parent: &Node) {
// Step 1.
- match node {
- Some(node) => {
- let document = document_from_node(parent);
- Node::adopt(node, document.r());
- }
- None => (),
+ if let Some(node) = node {
+ Node::adopt(node, &*parent.owner_doc());
}
-
// Step 2.
- let mut removed_nodes: RootedVec<JS<Node>> = RootedVec::new();
- for child in parent.children() {
- removed_nodes.push(JS::from_rooted(&child));
- }
-
+ let mut removed_nodes = RootedVec::new();
+ removed_nodes.extend(parent.children().map(|child| JS::from_rooted(&child)));
// Step 3.
- let added_nodes = match node {
- None => vec!(),
- Some(node) => match node.type_id() {
- NodeTypeId::DocumentFragment => node.children().collect(),
- _ => vec!(Root::from_ref(node)),
- },
+ let mut added_nodes = RootedVec::new();
+ let added_nodes = if let Some(node) = node.as_ref() {
+ if let NodeTypeId::DocumentFragment = node.type_id() {
+ added_nodes.extend(node.children().map(|child| JS::from_rooted(&child)));
+ added_nodes.r()
+ } else {
+ ref_slice(node)
+ }
+ } else {
+ &[] as &[&Node]
};
-
// Step 4.
- for child in parent.children() {
- Node::remove(child.r(), parent, SuppressObserver::Suppressed);
+ for child in removed_nodes.r() {
+ Node::remove(*child, parent, SuppressObserver::Suppressed);
}
-
// Step 5.
- match node {
- Some(node) => Node::insert(node, parent, None, SuppressObserver::Suppressed),
- None => (),
- }
-
- // Step 6: mutation records.
-
- // Step 7.
- let parent_in_doc = parent.is_in_doc();
- for removed_node in removed_nodes.iter() {
- removed_node.root().r().node_removed(parent_in_doc);
- }
- for added_node in added_nodes {
- added_node.r().node_inserted();
+ if let Some(node) = node {
+ Node::insert(node, parent, None, SuppressObserver::Suppressed);
}
+ // Step 6: mutation observers.
+ vtable_for(&parent).children_changed(
+ &ChildrenMutation::replace_all(removed_nodes.r(), added_nodes));
}
// https://dom.spec.whatwg.org/#concept-node-pre-remove
@@ -1761,16 +1716,22 @@ impl Node {
}
// https://dom.spec.whatwg.org/#concept-node-remove
- fn remove(node: &Node, parent: &Node, _suppress_observers: SuppressObserver) {
+ fn remove(node: &Node, parent: &Node, suppress_observers: SuppressObserver) {
assert!(node.GetParentNode().map_or(false, |node_parent| node_parent.r() == parent));
// Step 1-5: ranges.
- // Step 6-7: mutation observers.
- // Step 8.
- parent.remove_child(node);
-
+ // Step 6.
+ let old_previous_sibling = node.GetPreviousSibling();
+ // Steps 7-8: mutation observers.
// Step 9.
- node.node_removed(parent.is_in_doc());
+ let old_next_sibling = node.GetNextSibling();
+ parent.remove_child(node);
+ if let SuppressObserver::Unsuppressed = suppress_observers {
+ vtable_for(&parent).children_changed(
+ &ChildrenMutation::replace(old_previous_sibling.r(),
+ &node, &[],
+ old_next_sibling.r()));
+ }
}
// https://dom.spec.whatwg.org/#concept-node-clone
@@ -1855,10 +1816,9 @@ impl Node {
copy_doc.set_quirks_mode(node_doc.quirks_mode());
},
NodeTypeId::Element(..) => {
- let node_elem: &Element = ElementCast::to_ref(node).unwrap();
- let copy_elem: &Element = ElementCast::to_ref(copy.r()).unwrap();
+ let node_elem = ElementCast::to_ref(node).unwrap();
+ let copy_elem = ElementCast::to_ref(copy.r()).unwrap();
- // FIXME: https://github.com/mozilla/servo/issues/1737
let window = document.r().window();
for ref attr in node_elem.attrs().iter() {
let attr = attr.root();
@@ -2275,36 +2235,31 @@ impl<'a> NodeMethods for &'a Node {
let document = document_from_node(self);
Node::adopt(node, document.r());
- // Step 12.
- let mut nodes: RootedVec<JS<Node>> = RootedVec::new();
- if node.type_id() == NodeTypeId::DocumentFragment {
- // Collect fragment children before Step 11,
- // because Node::insert removes a DocumentFragment's children,
- // and we need them in Step 13.
- // Issue filed against the spec:
- // https://www.w3.org/Bugs/Public/show_bug.cgi?id=28330
- for child_node in node.children() {
- nodes.push(JS::from_rooted(&child_node));
- }
- } else {
- nodes.push(JS::from_ref(node));
- }
+ // Step 10.
+ let previous_sibling = child.GetPreviousSibling();
- {
- // Step 10.
- Node::remove(child, self, SuppressObserver::Suppressed);
+ // Step 11.
+ Node::remove(child, self, SuppressObserver::Suppressed);
- // Step 11.
- Node::insert(node, self, reference_child, SuppressObserver::Suppressed);
- }
+ // Step 12.
+ let mut nodes = RootedVec::new();
+ let nodes = if node.type_id() == NodeTypeId::DocumentFragment {
+ nodes.extend(node.children().map(|node| JS::from_rooted(&node)));
+ nodes.r()
+ } else {
+ ref_slice(&node)
+ };
- // Step 13: mutation records.
- child.node_removed(self.is_in_doc());
- for child_node in &*nodes {
- child_node.root().r().node_inserted();
- }
+ // Step 13.
+ Node::insert(node, self, reference_child, SuppressObserver::Suppressed);
// Step 14.
+ vtable_for(&self).children_changed(
+ &ChildrenMutation::replace(previous_sibling.r(),
+ &child, nodes,
+ reference_child));
+
+ // Step 15.
Ok(Root::from_ref(child))
}
@@ -2322,14 +2277,14 @@ impl<'a> NodeMethods for &'a Node {
Some(text) => {
let characterdata: &CharacterData = CharacterDataCast::from_ref(text);
if characterdata.Length() == 0 {
- self.remove_child(child.r());
+ Node::remove(&*child, self, SuppressObserver::Unsuppressed);
} else {
match prev_text {
Some(ref text_node) => {
let prev_characterdata =
CharacterDataCast::from_ref(text_node.r());
prev_characterdata.append_data(&**characterdata.data());
- self.remove_child(child.r());
+ Node::remove(&*child, self, SuppressObserver::Unsuppressed);
},
None => prev_text = Some(Root::from_ref(text))
}
@@ -2635,3 +2590,61 @@ pub enum NodeDamage {
/// Other parts of a node changed; attributes, text content, etc.
OtherNodeDamage,
}
+
+pub enum ChildrenMutation<'a> {
+ Append { prev: &'a Node, added: &'a [&'a Node] },
+ Insert { prev: &'a Node, added: &'a [&'a Node], next: &'a Node },
+ Prepend { added: &'a [&'a Node], next: &'a Node },
+ Replace {
+ prev: Option<&'a Node>,
+ removed: &'a Node,
+ added: &'a [&'a Node],
+ next: Option<&'a Node>,
+ },
+ ReplaceAll { removed: &'a [&'a Node], added: &'a [&'a Node] },
+}
+
+impl<'a> ChildrenMutation<'a> {
+ fn insert(prev: Option<&'a Node>, added: &'a [&'a Node], next: Option<&'a Node>)
+ -> ChildrenMutation<'a> {
+ match (prev, next) {
+ (None, None) => {
+ ChildrenMutation::ReplaceAll { removed: &[], added: added }
+ },
+ (Some(prev), None) => {
+ ChildrenMutation::Append { prev: prev, added: added }
+ },
+ (None, Some(next)) => {
+ ChildrenMutation::Prepend { added: added, next: next }
+ },
+ (Some(prev), Some(next)) => {
+ ChildrenMutation::Insert { prev: prev, added: added, next: next }
+ },
+ }
+ }
+
+ fn replace(prev: Option<&'a Node>,
+ removed: &'a &'a Node,
+ added: &'a [&'a Node],
+ next: Option<&'a Node>)
+ -> ChildrenMutation<'a> {
+ if let (None, None) = (prev, next) {
+ ChildrenMutation::ReplaceAll {
+ removed: ref_slice(removed),
+ added: added,
+ }
+ } else {
+ ChildrenMutation::Replace {
+ prev: prev,
+ removed: *removed,
+ added: added,
+ next: next,
+ }
+ }
+ }
+
+ fn replace_all(removed: &'a [&'a Node], added: &'a [&'a Node])
+ -> ChildrenMutation<'a> {
+ ChildrenMutation::ReplaceAll { removed: removed, added: added }
+ }
+}
diff --git a/components/script/dom/storage.rs b/components/script/dom/storage.rs
index 42c564d9e2c..518d3c9c8f8 100644
--- a/components/script/dom/storage.rs
+++ b/components/script/dom/storage.rs
@@ -13,6 +13,7 @@ use dom::event::{EventHelpers, EventBubbles, EventCancelable};
use dom::storageevent::StorageEvent;
use dom::urlhelper::UrlHelper;
use dom::window::WindowHelpers;
+use ipc_channel::ipc;
use util::str::DOMString;
use page::IterablePage;
use net_traits::storage_task::{StorageTask, StorageTaskMsg, StorageType};
@@ -58,21 +59,21 @@ impl Storage {
impl<'a> StorageMethods for &'a Storage {
fn Length(self) -> u32 {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
self.get_storage_task().send(StorageTaskMsg::Length(sender, self.get_url(), self.storage_type)).unwrap();
receiver.recv().unwrap() as u32
}
fn Key(self, index: u32) -> Option<DOMString> {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
self.get_storage_task().send(StorageTaskMsg::Key(sender, self.get_url(), self.storage_type, index)).unwrap();
receiver.recv().unwrap()
}
fn GetItem(self, name: DOMString) -> Option<DOMString> {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
let msg = StorageTaskMsg::GetItem(sender, self.get_url(), self.storage_type, name);
self.get_storage_task().send(msg).unwrap();
@@ -86,7 +87,7 @@ impl<'a> StorageMethods for &'a Storage {
}
fn SetItem(self, name: DOMString, value: DOMString) {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
let msg = StorageTaskMsg::SetItem(sender, self.get_url(), self.storage_type, name.clone(), value.clone());
self.get_storage_task().send(msg).unwrap();
@@ -105,7 +106,7 @@ impl<'a> StorageMethods for &'a Storage {
}
fn RemoveItem(self, name: DOMString) {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
let msg = StorageTaskMsg::RemoveItem(sender, self.get_url(), self.storage_type, name.clone());
self.get_storage_task().send(msg).unwrap();
@@ -119,7 +120,7 @@ impl<'a> StorageMethods for &'a Storage {
}
fn Clear(self) {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
self.get_storage_task().send(StorageTaskMsg::Clear(sender, self.get_url(), self.storage_type)).unwrap();
if receiver.recv().unwrap() {
diff --git a/components/script/dom/virtualmethods.rs b/components/script/dom/virtualmethods.rs
index 8bb62637ac6..88cc024acd5 100644
--- a/components/script/dom/virtualmethods.rs
+++ b/components/script/dom/virtualmethods.rs
@@ -35,7 +35,8 @@ use dom::document::Document;
use dom::element::ElementTypeId;
use dom::event::Event;
use dom::htmlelement::HTMLElementTypeId;
-use dom::node::{Node, NodeHelpers, NodeTypeId, CloneChildrenFlag};
+use dom::node::{ChildrenMutation, CloneChildrenFlag, Node, NodeHelpers};
+use dom::node::NodeTypeId;
use util::str::DOMString;
@@ -97,10 +98,10 @@ pub trait VirtualMethods {
}
}
- /// Called on the parent when a node is added to its child list.
- fn child_inserted(&self, child: &Node) {
+ /// Called on the parent when its children are changed.
+ fn children_changed(&self, mutation: &ChildrenMutation) {
if let Some(ref s) = self.super_type() {
- s.child_inserted(child);
+ s.children_changed(mutation);
}
}
diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs
index 4970b577bb7..432caf6276c 100644
--- a/components/script/dom/webglbuffer.rs
+++ b/components/script/dom/webglbuffer.rs
@@ -10,7 +10,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::webglobject::WebGLObject;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
-use std::sync::mpsc::{channel, Sender};
+use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@@ -18,11 +18,11 @@ pub struct WebGLBuffer {
webgl_object: WebGLObject,
id: u32,
is_deleted: Cell<bool>,
- renderer: Sender<CanvasMsg>,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLBuffer {
- fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLBuffer {
+ fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLBuffer {
WebGLBuffer {
webgl_object: WebGLObject::new_inherited(),
id: id,
@@ -31,15 +31,16 @@ impl WebGLBuffer {
}
}
- pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLBuffer>> {
- let (sender, receiver) = channel();
+ pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
+ -> Option<Root<WebGLBuffer>> {
+ let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateBuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|buffer_id| WebGLBuffer::new(global, renderer, *buffer_id))
}
- pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLBuffer> {
+ pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32) -> Root<WebGLBuffer> {
reflect_dom_object(box WebGLBuffer::new_inherited(renderer, id), global, WebGLBufferBinding::Wrap)
}
}
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index 26773ca4b17..2a67bb4dbcb 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -10,7 +10,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::webglobject::WebGLObject;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLFramebufferBindingRequest};
-use std::sync::mpsc::{channel, Sender};
+use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@@ -18,11 +18,11 @@ pub struct WebGLFramebuffer {
webgl_object: WebGLObject,
id: u32,
is_deleted: Cell<bool>,
- renderer: Sender<CanvasMsg>,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLFramebuffer {
- fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLFramebuffer {
+ fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLFramebuffer {
WebGLFramebuffer {
webgl_object: WebGLObject::new_inherited(),
id: id,
@@ -31,15 +31,17 @@ impl WebGLFramebuffer {
}
}
- pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLFramebuffer>> {
- let (sender, receiver) = channel();
+ pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
+ -> Option<Root<WebGLFramebuffer>> {
+ let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateFramebuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|fb_id| WebGLFramebuffer::new(global, renderer, *fb_id))
}
- pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLFramebuffer> {
+ pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32)
+ -> Root<WebGLFramebuffer> {
reflect_dom_object(box WebGLFramebuffer::new_inherited(renderer, id), global, WebGLFramebufferBinding::Wrap)
}
}
diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs
index 71e0d2e6616..a61fc22c905 100644
--- a/components/script/dom/webglprogram.rs
+++ b/components/script/dom/webglprogram.rs
@@ -14,7 +14,7 @@ use dom::webglrenderingcontext::MAX_UNIFORM_AND_ATTRIBUTE_LEN;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLResult, WebGLError};
-use std::sync::mpsc::{channel, Sender};
+use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@@ -24,11 +24,11 @@ pub struct WebGLProgram {
is_deleted: Cell<bool>,
fragment_shader: MutNullableHeap<JS<WebGLShader>>,
vertex_shader: MutNullableHeap<JS<WebGLShader>>,
- renderer: Sender<CanvasMsg>,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLProgram {
- fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLProgram {
+ fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLProgram {
WebGLProgram {
webgl_object: WebGLObject::new_inherited(),
id: id,
@@ -39,15 +39,16 @@ impl WebGLProgram {
}
}
- pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLProgram>> {
- let (sender, receiver) = channel();
+ pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
+ -> Option<Root<WebGLProgram>> {
+ let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateProgram(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|program_id| WebGLProgram::new(global, renderer, *program_id))
}
- pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLProgram> {
+ pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32) -> Root<WebGLProgram> {
reflect_dom_object(box WebGLProgram::new_inherited(renderer, id), global, WebGLProgramBinding::Wrap)
}
}
@@ -112,7 +113,7 @@ impl<'a> WebGLProgramHelpers for &'a WebGLProgram {
return Ok(None);
}
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetAttribLocation(self.id, name, sender))).unwrap();
Ok(receiver.recv().unwrap())
}
@@ -128,7 +129,7 @@ impl<'a> WebGLProgramHelpers for &'a WebGLProgram {
return Ok(None);
}
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetUniformLocation(self.id, name, sender))).unwrap();
Ok(receiver.recv().unwrap())
}
diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs
index d7084564ec3..cfe3fb21261 100644
--- a/components/script/dom/webglrenderbuffer.rs
+++ b/components/script/dom/webglrenderbuffer.rs
@@ -10,7 +10,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::webglobject::WebGLObject;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
-use std::sync::mpsc::{channel, Sender};
+use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@@ -18,11 +18,11 @@ pub struct WebGLRenderbuffer {
webgl_object: WebGLObject,
id: u32,
is_deleted: Cell<bool>,
- renderer: Sender<CanvasMsg>,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLRenderbuffer {
- fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLRenderbuffer {
+ fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLRenderbuffer {
WebGLRenderbuffer {
webgl_object: WebGLObject::new_inherited(),
id: id,
@@ -31,15 +31,17 @@ impl WebGLRenderbuffer {
}
}
- pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLRenderbuffer>> {
- let (sender, receiver) = channel();
+ pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
+ -> Option<Root<WebGLRenderbuffer>> {
+ let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateRenderbuffer(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|renderbuffer_id| WebGLRenderbuffer::new(global, renderer, *renderbuffer_id))
}
- pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLRenderbuffer> {
+ pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32)
+ -> Root<WebGLRenderbuffer> {
reflect_dom_object(box WebGLRenderbuffer::new_inherited(renderer, id), global, WebGLRenderbufferBinding::Wrap)
}
}
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 123c1e200c3..4dcd1705782 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use canvas::webgl_paint_task::WebGLPaintTask;
use canvas_traits::
{CanvasMsg, CanvasWebGLMsg, CanvasCommonMsg, WebGLError,
WebGLShaderParameter, WebGLFramebufferBindingRequest};
@@ -23,14 +22,16 @@ use dom::webglshader::{WebGLShader, WebGLShaderHelpers};
use dom::webglprogram::{WebGLProgram, WebGLProgramHelpers};
use dom::webgluniformlocation::{WebGLUniformLocation, WebGLUniformLocationHelpers};
use euclid::size::Size2D;
+use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSObject, RootedValue};
use js::jsapi::{JS_GetFloat32ArrayData, JS_GetObjectAsArrayBufferView};
use js::jsval::{JSVal, UndefinedValue, NullValue, Int32Value, BooleanValue};
+use msg::constellation_msg::Msg as ConstellationMsg;
use std::cell::Cell;
use std::mem;
use std::ptr;
use std::slice;
-use std::sync::mpsc::{channel, Sender};
+use std::sync::mpsc::channel;
use util::str::DOMString;
use offscreen_gl_context::GLContextAttributes;
@@ -52,7 +53,8 @@ macro_rules! handle_potential_webgl_error {
pub struct WebGLRenderingContext {
reflector_: Reflector,
global: GlobalField,
- renderer: Sender<CanvasMsg>,
+ renderer_id: usize,
+ ipc_renderer: IpcSender<CanvasMsg>,
canvas: JS<HTMLCanvasElement>,
last_error: Cell<Option<WebGLError>>,
}
@@ -63,12 +65,17 @@ impl WebGLRenderingContext {
size: Size2D<i32>,
attrs: GLContextAttributes)
-> Result<WebGLRenderingContext, &'static str> {
- let chan = try!(WebGLPaintTask::start(size, attrs));
-
+ let (sender, receiver) = ipc::channel().unwrap();
+ let constellation_chan = global.constellation_chan();
+ constellation_chan.0
+ .send(ConstellationMsg::CreateWebGLPaintTask(size, attrs, sender))
+ .unwrap();
+ let (ipc_renderer, renderer_id) = receiver.recv().unwrap();
Ok(WebGLRenderingContext {
reflector_: Reflector::new(),
global: GlobalField::from_rooted(&global),
- renderer: chan,
+ renderer_id: renderer_id,
+ ipc_renderer: ipc_renderer,
last_error: Cell::new(None),
canvas: JS::from_ref(canvas),
})
@@ -87,13 +94,13 @@ impl WebGLRenderingContext {
}
pub fn recreate(&self, size: Size2D<i32>) {
- self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Recreate(size))).unwrap();
}
}
impl Drop for WebGLRenderingContext {
fn drop(&mut self) {
- self.renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::Common(CanvasCommonMsg::Close)).unwrap();
}
}
@@ -105,15 +112,19 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn DrawingBufferWidth(self) -> i32 {
- let (sender, receiver) = channel();
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferWidth(sender))).unwrap();
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferWidth(sender)))
+ .unwrap();
receiver.recv().unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.1
fn DrawingBufferHeight(self) -> i32 {
- let (sender, receiver) = channel();
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferHeight(sender))).unwrap();
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawingBufferHeight(sender)))
+ .unwrap();
receiver.recv().unwrap()
}
@@ -151,10 +162,11 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.2
fn GetContextAttributes(self) -> Option<WebGLContextAttributes> {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
// If the send does not succeed, assume context lost
- if let Err(_) = self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetContextAttributes(sender))) {
+ if let Err(_) = self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::GetContextAttributes(sender))) {
return None;
}
let attrs = receiver.recv().unwrap();
@@ -180,32 +192,36 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ActiveTexture(self, texture: u32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::ActiveTexture(texture))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::ActiveTexture(texture))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendColor(self, r: f32, g: f32, b: f32, a: f32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendColor(r, g, b, a))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendColor(r, g, b, a))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendEquation(self, mode: u32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquation(mode))).unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquation(mode))).unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendEquationSeparate(self, mode_rgb: u32, mode_alpha: u32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquationSeparate(mode_rgb, mode_alpha))).unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendEquationSeparate(mode_rgb, mode_alpha)))
+ .unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendFunc(self, src_factor: u32, dest_factor: u32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendFunc(src_factor, dest_factor))).unwrap();
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::BlendFunc(src_factor, dest_factor)))
+ .unwrap();
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn BlendFuncSeparate(self, src_rgb: u32, dest_rgb: u32, src_alpha: u32, dest_alpha: u32) {
- self.renderer.send(
+ self.ipc_renderer.send(
CanvasMsg::WebGL(CanvasWebGLMsg::BlendFuncSeparate(src_rgb, dest_rgb, src_alpha, dest_alpha))).unwrap();
}
@@ -224,7 +240,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
buffer.bind(target)
} else {
// Unbind the current buffer
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, 0))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::BindBuffer(target, 0)))
+ .unwrap()
}
}
@@ -235,7 +253,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
} else {
// Bind the default framebuffer
let cmd = CanvasWebGLMsg::BindFramebuffer(target, WebGLFramebufferBindingRequest::Default);
- self.renderer.send(CanvasMsg::WebGL(cmd)).unwrap();
+ self.ipc_renderer.send(CanvasMsg::WebGL(cmd)).unwrap();
}
}
@@ -245,7 +263,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
renderbuffer.bind(target)
} else {
// Unbind the currently bound renderbuffer
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, 0))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::BindRenderbuffer(target, 0)))
+ .unwrap()
}
}
@@ -274,17 +294,21 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
let data_vec_length = length / mem::size_of::<f32>() as u32;
slice::from_raw_parts(data_f32, data_vec_length as usize).to_vec()
};
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::BufferData(target, data_vec, usage))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::BufferData(target, data_vec, usage)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn Clear(self, mask: u32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Clear(mask))).unwrap()
+ self.ipc_renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Clear(mask))).unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3
fn ClearColor(self, red: f32, green: f32, blue: f32, alpha: f32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearColor(red, green, blue, alpha))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::ClearColor(red, green, blue, alpha)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@@ -298,34 +322,34 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// generated objects, either here or in the webgl task
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn CreateBuffer(self) -> Option<Root<WebGLBuffer>> {
- WebGLBuffer::maybe_new(self.global.root().r(), self.renderer.clone())
+ WebGLBuffer::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn CreateFramebuffer(self) -> Option<Root<WebGLFramebuffer>> {
- WebGLFramebuffer::maybe_new(self.global.root().r(), self.renderer.clone())
+ WebGLFramebuffer::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
fn CreateRenderbuffer(self) -> Option<Root<WebGLRenderbuffer>> {
- WebGLRenderbuffer::maybe_new(self.global.root().r(), self.renderer.clone())
+ WebGLRenderbuffer::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
fn CreateTexture(self) -> Option<Root<WebGLTexture>> {
- WebGLTexture::maybe_new(self.global.root().r(), self.renderer.clone())
+ WebGLTexture::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn CreateProgram(self) -> Option<Root<WebGLProgram>> {
- WebGLProgram::maybe_new(self.global.root().r(), self.renderer.clone())
+ WebGLProgram::maybe_new(self.global.root().r(), self.ipc_renderer.clone())
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
// TODO(ecoal95): Check if constants are cross-platform or if we must make a translation
// between WebGL constants and native ones.
fn CreateShader(self, shader_type: u32) -> Option<Root<WebGLShader>> {
- WebGLShader::maybe_new(self.global.root().r(), self.renderer.clone(), shader_type)
+ WebGLShader::maybe_new(self.global.root().r(), self.ipc_renderer.clone(), shader_type)
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
@@ -372,12 +396,16 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.11
fn DrawArrays(self, mode: u32, first: i32, count: i32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawArrays(mode, first, count))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::DrawArrays(mode, first, count)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn EnableVertexAttribArray(self, attrib_id: u32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::EnableVertexAttribArray(attrib_id))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::EnableVertexAttribArray(attrib_id)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@@ -466,7 +494,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
let data_f32 = JS_GetFloat32ArrayData(data, ptr::null());
slice::from_raw_parts(data_f32, 4).to_vec()
};
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Uniform4fv(uniform_id, data_vec))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::Uniform4fv(uniform_id, data_vec)))
+ .unwrap()
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@@ -483,7 +513,7 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
constants::FLOAT => {
let msg = CanvasMsg::WebGL(
CanvasWebGLMsg::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset));
- self.renderer.send(msg).unwrap()
+ self.ipc_renderer.send(msg).unwrap()
}
_ => panic!("VertexAttribPointer: Data Type not supported")
}
@@ -492,7 +522,9 @@ impl<'a> WebGLRenderingContextMethods for &'a WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.4
fn Viewport(self, x: i32, y: i32, width: i32, height: i32) {
- self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::Viewport(x, y, width, height))).unwrap()
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(CanvasWebGLMsg::Viewport(x, y, width, height)))
+ .unwrap()
}
}
@@ -512,12 +544,18 @@ impl<'a> WebGLRenderingContextHelpers for &'a WebGLRenderingContext {
pub trait LayoutCanvasWebGLRenderingContextHelpers {
#[allow(unsafe_code)]
- unsafe fn get_renderer(&self) -> Sender<CanvasMsg>;
+ unsafe fn get_renderer_id(&self) -> usize;
+ #[allow(unsafe_code)]
+ unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg>;
}
impl LayoutCanvasWebGLRenderingContextHelpers for LayoutJS<WebGLRenderingContext> {
#[allow(unsafe_code)]
- unsafe fn get_renderer(&self) -> Sender<CanvasMsg> {
- (*self.unsafe_get()).renderer.clone()
+ unsafe fn get_renderer_id(&self) -> usize {
+ (*self.unsafe_get()).renderer_id
+ }
+ #[allow(unsafe_code)]
+ unsafe fn get_ipc_renderer(&self) -> IpcSender<CanvasMsg> {
+ (*self.unsafe_get()).ipc_renderer.clone()
}
}
diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs
index f5d40b16699..40c26d40c90 100644
--- a/components/script/dom/webglshader.rs
+++ b/components/script/dom/webglshader.rs
@@ -12,7 +12,7 @@ use dom::webglobject::WebGLObject;
use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg, WebGLResult, WebGLError, WebGLShaderParameter};
-use std::sync::mpsc::{channel, Sender};
+use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
use std::cell::RefCell;
@@ -24,11 +24,11 @@ pub struct WebGLShader {
source: RefCell<Option<String>>,
is_deleted: Cell<bool>,
// TODO(ecoal95): Evaluate moving this to `WebGLObject`
- renderer: Sender<CanvasMsg>,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLShader {
- fn new_inherited(renderer: Sender<CanvasMsg>, id: u32, shader_type: u32) -> WebGLShader {
+ fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32, shader_type: u32) -> WebGLShader {
WebGLShader {
webgl_object: WebGLObject::new_inherited(),
id: id,
@@ -40,9 +40,9 @@ impl WebGLShader {
}
pub fn maybe_new(global: GlobalRef,
- renderer: Sender<CanvasMsg>,
+ renderer: IpcSender<CanvasMsg>,
shader_type: u32) -> Option<Root<WebGLShader>> {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateShader(shader_type, sender))).unwrap();
let result = receiver.recv().unwrap();
@@ -50,7 +50,7 @@ impl WebGLShader {
}
pub fn new(global: GlobalRef,
- renderer: Sender<CanvasMsg>,
+ renderer: IpcSender<CanvasMsg>,
id: u32,
shader_type: u32) -> Root<WebGLShader> {
reflect_dom_object(
@@ -95,7 +95,7 @@ impl<'a> WebGLShaderHelpers for &'a WebGLShader {
/// glGetShaderInfoLog
fn info_log(self) -> Option<String> {
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderInfoLog(self.id, sender))).unwrap();
receiver.recv().unwrap()
}
@@ -107,7 +107,7 @@ impl<'a> WebGLShaderHelpers for &'a WebGLShader {
_ => return Err(WebGLError::InvalidEnum),
}
- let (sender, receiver) = channel();
+ let (sender, receiver) = ipc::channel().unwrap();
self.renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::GetShaderParameter(self.id, param_id, sender))).unwrap();
Ok(receiver.recv().unwrap())
}
diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs
index ab934a5f47d..06664a01f3d 100644
--- a/components/script/dom/webgltexture.rs
+++ b/components/script/dom/webgltexture.rs
@@ -10,7 +10,7 @@ use dom::bindings::utils::reflect_dom_object;
use dom::webglobject::WebGLObject;
use canvas_traits::{CanvasMsg, CanvasWebGLMsg};
-use std::sync::mpsc::{channel, Sender};
+use ipc_channel::ipc::{self, IpcSender};
use std::cell::Cell;
#[dom_struct]
@@ -18,11 +18,11 @@ pub struct WebGLTexture {
webgl_object: WebGLObject,
id: u32,
is_deleted: Cell<bool>,
- renderer: Sender<CanvasMsg>,
+ renderer: IpcSender<CanvasMsg>,
}
impl WebGLTexture {
- fn new_inherited(renderer: Sender<CanvasMsg>, id: u32) -> WebGLTexture {
+ fn new_inherited(renderer: IpcSender<CanvasMsg>, id: u32) -> WebGLTexture {
WebGLTexture {
webgl_object: WebGLObject::new_inherited(),
id: id,
@@ -31,15 +31,16 @@ impl WebGLTexture {
}
}
- pub fn maybe_new(global: GlobalRef, renderer: Sender<CanvasMsg>) -> Option<Root<WebGLTexture>> {
- let (sender, receiver) = channel();
+ pub fn maybe_new(global: GlobalRef, renderer: IpcSender<CanvasMsg>)
+ -> Option<Root<WebGLTexture>> {
+ let (sender, receiver) = ipc::channel().unwrap();
renderer.send(CanvasMsg::WebGL(CanvasWebGLMsg::CreateTexture(sender))).unwrap();
let result = receiver.recv().unwrap();
result.map(|texture_id| WebGLTexture::new(global, renderer, *texture_id))
}
- pub fn new(global: GlobalRef, renderer: Sender<CanvasMsg>, id: u32) -> Root<WebGLTexture> {
+ pub fn new(global: GlobalRef, renderer: IpcSender<CanvasMsg>, id: u32) -> Root<WebGLTexture> {
reflect_dom_object(box WebGLTexture::new_inherited(renderer, id), global, WebGLTextureBinding::Wrap)
}
}
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index 257ecbdcef1..26fd1ff7421 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -70,6 +70,7 @@ impl Worker {
};
let resource_task = global.resource_task();
+ let constellation_chan = global.constellation_chan();
let (sender, receiver) = channel();
let worker = Worker::new(global, sender.clone());
@@ -91,7 +92,7 @@ impl Worker {
DedicatedWorkerGlobalScope::run_worker_scope(
worker_url, global.pipeline(), global.mem_profiler_chan(), global.devtools_chan(),
- worker_ref, resource_task, global.script_chan(), sender, receiver);
+ worker_ref, resource_task, constellation_chan, global.script_chan(), sender, receiver);
Ok(worker)
}
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index 260476859e9..8d473f6f081 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -22,7 +22,7 @@ use timers::{IsInterval, TimerId, TimerManager, TimerCallback};
use devtools_traits::DevtoolsControlChan;
-use msg::constellation_msg::{PipelineId, WorkerId};
+use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
use profile_traits::mem;
use net_traits::{load_whole_resource, ResourceTask};
use util::str::DOMString;
@@ -55,6 +55,7 @@ pub struct WorkerGlobalScope {
timers: TimerManager,
mem_profiler_chan: mem::ProfilerChan,
devtools_chan: Option<DevtoolsControlChan>,
+ constellation_chan: ConstellationChan,
}
impl WorkerGlobalScope {
@@ -63,7 +64,8 @@ impl WorkerGlobalScope {
runtime: Rc<Runtime>,
resource_task: ResourceTask,
mem_profiler_chan: mem::ProfilerChan,
- devtools_chan: Option<DevtoolsControlChan>) -> WorkerGlobalScope {
+ devtools_chan: Option<DevtoolsControlChan>,
+ constellation_chan: ConstellationChan) -> WorkerGlobalScope {
WorkerGlobalScope {
eventtarget: EventTarget::new_inherited(EventTargetTypeId::WorkerGlobalScope(type_id)),
next_worker_id: Cell::new(WorkerId(0)),
@@ -77,6 +79,7 @@ impl WorkerGlobalScope {
timers: TimerManager::new(),
mem_profiler_chan: mem_profiler_chan,
devtools_chan: devtools_chan,
+ constellation_chan: constellation_chan,
}
}
@@ -88,6 +91,10 @@ impl WorkerGlobalScope {
self.devtools_chan.clone()
}
+ pub fn constellation_chan(&self) -> ConstellationChan {
+ self.constellation_chan.clone()
+ }
+
#[inline]
pub fn eventtarget<'a>(&'a self) -> &'a EventTarget {
&self.eventtarget