mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Upgrade rust.
This commit is contained in:
parent
7ece5f92db
commit
31eee791dd
102 changed files with 724 additions and 839 deletions
|
@ -1 +1 @@
|
||||||
Subproject commit 68a4f7d9babb0c638f3425ced08e13f9fbfdcf56
|
Subproject commit aa39d755e3f9823b51cc57761c0c8c75759aca2e
|
|
@ -1,4 +1,4 @@
|
||||||
# If this file is modified, then rust will be forcibly cleaned and then rebuilt.
|
# If this file is modified, then rust will be forcibly cleaned and then rebuilt.
|
||||||
# The actual contents of this file do not matter, but to trigger a change on the
|
# The actual contents of this file do not matter, but to trigger a change on the
|
||||||
# build bots then the contents should be changed so git updates the mtime.
|
# build bots then the contents should be changed so git updates the mtime.
|
||||||
2014-02-24
|
2014-03-23
|
||||||
|
|
|
@ -43,6 +43,12 @@ impl Eq for BufferKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TotalEq for BufferKey {
|
||||||
|
fn equals(&self, other: &BufferKey) -> bool {
|
||||||
|
self.eq(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a key from a given size
|
/// Create a key from a given size
|
||||||
impl BufferKey {
|
impl BufferKey {
|
||||||
fn get(input: Size2D<uint>) -> BufferKey {
|
fn get(input: Size2D<uint>) -> BufferKey {
|
||||||
|
|
|
@ -25,7 +25,7 @@ use servo_util::range::Range;
|
||||||
use servo_util::smallvec::{SmallVec, SmallVec0, SmallVecIterator};
|
use servo_util::smallvec::{SmallVec, SmallVec0, SmallVecIterator};
|
||||||
use std::libc::uintptr_t;
|
use std::libc::uintptr_t;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::vec::Items;
|
use std::slice::Items;
|
||||||
use style::computed_values::border_style;
|
use style::computed_values::border_style;
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
|
@ -351,18 +351,18 @@ impl DisplayItem {
|
||||||
let text_run = text.text_run.get();
|
let text_run = text.text_run.get();
|
||||||
let font = render_context.font_ctx.get_font_by_descriptor(&text_run.font_descriptor).unwrap();
|
let font = render_context.font_ctx.get_font_by_descriptor(&text_run.font_descriptor).unwrap();
|
||||||
|
|
||||||
let font_metrics = font.borrow().with(|font| {
|
let font_metrics = {
|
||||||
font.metrics.clone()
|
font.borrow().metrics.clone()
|
||||||
});
|
};
|
||||||
let origin = text.base.bounds.origin;
|
let origin = text.base.bounds.origin;
|
||||||
let baseline_origin = Point2D(origin.x, origin.y + font_metrics.ascent);
|
let baseline_origin = Point2D(origin.x, origin.y + font_metrics.ascent);
|
||||||
font.borrow().with_mut(|font| {
|
{
|
||||||
font.draw_text_into_context(render_context,
|
font.borrow_mut().draw_text_into_context(render_context,
|
||||||
text.text_run.get(),
|
text.text_run.get(),
|
||||||
&text.range,
|
&text.range,
|
||||||
baseline_origin,
|
baseline_origin,
|
||||||
text.text_color);
|
text.text_color);
|
||||||
});
|
}
|
||||||
let width = text.base.bounds.size.width;
|
let width = text.base.bounds.size.width;
|
||||||
let underline_size = font_metrics.underline_size;
|
let underline_size = font_metrics.underline_size;
|
||||||
let underline_offset = font_metrics.underline_offset;
|
let underline_offset = font_metrics.underline_offset;
|
||||||
|
|
|
@ -166,9 +166,7 @@ impl FontGroup {
|
||||||
assert!(self.fonts.len() > 0);
|
assert!(self.fonts.len() > 0);
|
||||||
|
|
||||||
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
|
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
|
||||||
self.fonts[0].borrow().with_mut(|font| {
|
TextRun::new(&mut *self.fonts[0].borrow_mut(), text.clone(), decoration)
|
||||||
TextRun::new(font, text.clone(), decoration)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,11 @@
|
||||||
|
|
||||||
#[feature(globs, managed_boxes, macro_rules, phase)];
|
#[feature(globs, managed_boxes, macro_rules, phase)];
|
||||||
|
|
||||||
|
#[feature(phase)];
|
||||||
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
extern crate azure;
|
extern crate azure;
|
||||||
extern crate collections;
|
extern crate collections;
|
||||||
extern crate extra;
|
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
extern crate layers;
|
extern crate layers;
|
||||||
extern crate stb_image;
|
extern crate stb_image;
|
||||||
|
|
|
@ -76,7 +76,7 @@ impl FontHandleMethods for FontHandle {
|
||||||
buf: ~[u8],
|
buf: ~[u8],
|
||||||
style: &SpecifiedFontStyle)
|
style: &SpecifiedFontStyle)
|
||||||
-> Result<FontHandle, ()> {
|
-> Result<FontHandle, ()> {
|
||||||
let ft_ctx: FT_Library = fctx.ctx.borrow().ctx;
|
let ft_ctx: FT_Library = fctx.ctx.ctx;
|
||||||
if ft_ctx.is_null() { return Err(()); }
|
if ft_ctx.is_null() { return Err(()); }
|
||||||
|
|
||||||
let face_result = create_face_from_buffer(ft_ctx, buf.as_ptr(), buf.len(), style.pt_size);
|
let face_result = create_face_from_buffer(ft_ctx, buf.as_ptr(), buf.len(), style.pt_size);
|
||||||
|
@ -279,7 +279,7 @@ impl<'a> FontHandle {
|
||||||
pub fn new_from_file(fctx: &FontContextHandle, file: &str,
|
pub fn new_from_file(fctx: &FontContextHandle, file: &str,
|
||||||
style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
|
style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ft_ctx: FT_Library = fctx.ctx.borrow().ctx;
|
let ft_ctx: FT_Library = fctx.ctx.ctx;
|
||||||
if ft_ctx.is_null() { return Err(()); }
|
if ft_ctx.is_null() { return Err(()); }
|
||||||
|
|
||||||
let mut face: FT_Face = ptr::null();
|
let mut face: FT_Face = ptr::null();
|
||||||
|
@ -306,7 +306,7 @@ impl<'a> FontHandle {
|
||||||
pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str)
|
pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str)
|
||||||
-> Result<FontHandle, ()> {
|
-> Result<FontHandle, ()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ft_ctx: FT_Library = fctx.ctx.borrow().ctx;
|
let ft_ctx: FT_Library = fctx.ctx.ctx;
|
||||||
if ft_ctx.is_null() { return Err(()); }
|
if ft_ctx.is_null() { return Err(()); }
|
||||||
|
|
||||||
let mut face: FT_Face = ptr::null();
|
let mut face: FT_Face = ptr::null();
|
||||||
|
|
|
@ -29,7 +29,7 @@ use servo_util::time::{ProfilerChan, profile};
|
||||||
use servo_util::time;
|
use servo_util::time;
|
||||||
use servo_util::task::send_on_failure;
|
use servo_util::task::send_on_failure;
|
||||||
|
|
||||||
use std::comm::{Chan, Port};
|
use std::comm::{channel, Receiver, Sender};
|
||||||
use std::task;
|
use std::task;
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ pub enum Msg {
|
||||||
UnusedBufferMsg(~[~LayerBuffer]),
|
UnusedBufferMsg(~[~LayerBuffer]),
|
||||||
PaintPermissionGranted,
|
PaintPermissionGranted,
|
||||||
PaintPermissionRevoked,
|
PaintPermissionRevoked,
|
||||||
ExitMsg(Option<Chan<()>>),
|
ExitMsg(Option<Sender<()>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A request from the compositor to the renderer for tiles that need to be (re)displayed.
|
/// A request from the compositor to the renderer for tiles that need to be (re)displayed.
|
||||||
|
@ -75,7 +75,7 @@ pub fn BufferRequest(screen_rect: Rect<uint>, page_rect: Rect<f32>) -> BufferReq
|
||||||
|
|
||||||
// FIXME(#2005, pcwalton): This should be a newtype struct.
|
// FIXME(#2005, pcwalton): This should be a newtype struct.
|
||||||
pub struct RenderChan {
|
pub struct RenderChan {
|
||||||
chan: Chan<Msg>,
|
chan: Sender<Msg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clone for RenderChan {
|
impl Clone for RenderChan {
|
||||||
|
@ -87,8 +87,8 @@ impl Clone for RenderChan {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderChan {
|
impl RenderChan {
|
||||||
pub fn new() -> (Port<Msg>, RenderChan) {
|
pub fn new() -> (Receiver<Msg>, RenderChan) {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let render_chan = RenderChan {
|
let render_chan = RenderChan {
|
||||||
chan: chan,
|
chan: chan,
|
||||||
};
|
};
|
||||||
|
@ -113,7 +113,7 @@ enum GraphicsContext {
|
||||||
|
|
||||||
pub struct RenderTask<C> {
|
pub struct RenderTask<C> {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
compositor: C,
|
compositor: C,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
font_ctx: ~FontContext,
|
font_ctx: ~FontContext,
|
||||||
|
@ -167,13 +167,13 @@ fn initialize_layers<C:RenderListener>(
|
||||||
|
|
||||||
impl<C: RenderListener + Send> RenderTask<C> {
|
impl<C: RenderListener + Send> RenderTask<C> {
|
||||||
pub fn create(id: PipelineId,
|
pub fn create(id: PipelineId,
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
compositor: C,
|
compositor: C,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
failure_msg: Failure,
|
failure_msg: Failure,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
profiler_chan: ProfilerChan,
|
profiler_chan: ProfilerChan,
|
||||||
shutdown_chan: Chan<()>) {
|
shutdown_chan: Sender<()>) {
|
||||||
let mut builder = task::task().named("RenderTask");
|
let mut builder = task::task().named("RenderTask");
|
||||||
let ConstellationChan(c) = constellation_chan.clone();
|
let ConstellationChan(c) = constellation_chan.clone();
|
||||||
send_on_failure(&mut builder, FailureMsg(failure_msg), c);
|
send_on_failure(&mut builder, FailureMsg(failure_msg), c);
|
||||||
|
|
|
@ -11,7 +11,7 @@ use std::cmp::{Ord, Eq};
|
||||||
use std::num::NumCast;
|
use std::num::NumCast;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::u16;
|
use std::u16;
|
||||||
use std::vec;
|
use std::slice;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ impl<'a> GlyphStore {
|
||||||
assert!(length > 0);
|
assert!(length > 0);
|
||||||
|
|
||||||
GlyphStore {
|
GlyphStore {
|
||||||
entry_buffer: vec::from_elem(length, GlyphEntry::initial()),
|
entry_buffer: slice::from_elem(length, GlyphEntry::initial()),
|
||||||
detail_store: DetailedGlyphStore::new(),
|
detail_store: DetailedGlyphStore::new(),
|
||||||
is_whitespace: is_whitespace,
|
is_whitespace: is_whitespace,
|
||||||
}
|
}
|
||||||
|
@ -566,7 +566,7 @@ impl<'a> GlyphStore {
|
||||||
let entry = match first_glyph_data.is_missing {
|
let entry = match first_glyph_data.is_missing {
|
||||||
true => GlyphEntry::missing(glyph_count),
|
true => GlyphEntry::missing(glyph_count),
|
||||||
false => {
|
false => {
|
||||||
let glyphs_vec = vec::from_fn(glyph_count, |i| {
|
let glyphs_vec = slice::from_fn(glyph_count, |i| {
|
||||||
DetailedGlyph::new(data_for_glyphs[i].index,
|
DetailedGlyph::new(data_for_glyphs[i].index,
|
||||||
data_for_glyphs[i].advance,
|
data_for_glyphs[i].advance,
|
||||||
data_for_glyphs[i].offset)
|
data_for_glyphs[i].offset)
|
||||||
|
|
|
@ -42,7 +42,7 @@ use std::char;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::libc::{c_uint, c_int, c_void, c_char};
|
use std::libc::{c_uint, c_int, c_void, c_char};
|
||||||
use std::ptr::null;
|
use std::ptr::null;
|
||||||
use std::vec;
|
use std::slice;
|
||||||
|
|
||||||
static NO_GLYPH: i32 = -1;
|
static NO_GLYPH: i32 = -1;
|
||||||
static CONTINUATION_BYTE: i32 = -2;
|
static CONTINUATION_BYTE: i32 = -2;
|
||||||
|
@ -246,9 +246,9 @@ impl Shaper {
|
||||||
|
|
||||||
// fast path: all chars are single-byte.
|
// fast path: all chars are single-byte.
|
||||||
if byte_max == char_max {
|
if byte_max == char_max {
|
||||||
byteToGlyph = vec::from_elem(byte_max, NO_GLYPH);
|
byteToGlyph = slice::from_elem(byte_max, NO_GLYPH);
|
||||||
} else {
|
} else {
|
||||||
byteToGlyph = vec::from_elem(byte_max, CONTINUATION_BYTE);
|
byteToGlyph = slice::from_elem(byte_max, CONTINUATION_BYTE);
|
||||||
for (i, _) in text.char_indices() {
|
for (i, _) in text.char_indices() {
|
||||||
byteToGlyph[i] = NO_GLYPH;
|
byteToGlyph[i] = NO_GLYPH;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics};
|
use font::{Font, FontDescriptor, RunMetrics, FontStyle, FontMetrics};
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use servo_util::range::Range;
|
use servo_util::range::Range;
|
||||||
use std::vec::Items;
|
use std::slice::Items;
|
||||||
use style::computed_values::text_decoration;
|
use style::computed_values::text_decoration;
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
use text::glyph::GlyphStore;
|
use text::glyph::GlyphStore;
|
||||||
|
|
|
@ -34,8 +34,7 @@ use servo_msg::constellation_msg;
|
||||||
use servo_util::opts::Opts;
|
use servo_util::opts::Opts;
|
||||||
use servo_util::time::{profile, ProfilerChan, Timer};
|
use servo_util::time::{profile, ProfilerChan, Timer};
|
||||||
use servo_util::{time, url};
|
use servo_util::{time, url};
|
||||||
use std::cmp;
|
use std::comm::{Empty, Disconnected, Data, Sender, Receiver};
|
||||||
use std::comm::{Empty, Disconnected, Data, Port};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use time::precise_time_s;
|
use time::precise_time_s;
|
||||||
|
@ -46,7 +45,7 @@ pub struct IOCompositor {
|
||||||
window: Rc<Window>,
|
window: Rc<Window>,
|
||||||
|
|
||||||
/// The port on which we receive messages.
|
/// The port on which we receive messages.
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
|
|
||||||
/// The render context.
|
/// The render context.
|
||||||
context: RenderContext,
|
context: RenderContext,
|
||||||
|
@ -114,7 +113,7 @@ pub struct IOCompositor {
|
||||||
impl IOCompositor {
|
impl IOCompositor {
|
||||||
pub fn new(app: &Application,
|
pub fn new(app: &Application,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
profiler_chan: ProfilerChan) -> IOCompositor {
|
profiler_chan: ProfilerChan) -> IOCompositor {
|
||||||
let window: Rc<Window> = WindowMethods::new(app);
|
let window: Rc<Window> = WindowMethods::new(app);
|
||||||
|
@ -124,7 +123,7 @@ impl IOCompositor {
|
||||||
// TODO: There should be no initial layer tree until the renderer creates one from the display
|
// TODO: There should be no initial layer tree until the renderer creates one from the display
|
||||||
// list. This is only here because we don't have that logic in the renderer yet.
|
// list. This is only here because we don't have that logic in the renderer yet.
|
||||||
let root_layer = Rc::new(ContainerLayer());
|
let root_layer = Rc::new(ContainerLayer());
|
||||||
let window_size = window.borrow().size();
|
let window_size = window.size();
|
||||||
|
|
||||||
IOCompositor {
|
IOCompositor {
|
||||||
window: window,
|
window: window,
|
||||||
|
@ -154,7 +153,7 @@ impl IOCompositor {
|
||||||
|
|
||||||
pub fn create(app: &Application,
|
pub fn create(app: &Application,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
profiler_chan: ProfilerChan) {
|
profiler_chan: ProfilerChan) {
|
||||||
let mut compositor = IOCompositor::new(app,
|
let mut compositor = IOCompositor::new(app,
|
||||||
|
@ -187,7 +186,7 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for messages coming from the windowing system.
|
// Check for messages coming from the windowing system.
|
||||||
let msg = self.window.borrow().recv();
|
let msg = self.window.recv();
|
||||||
self.handle_window_message(msg);
|
self.handle_window_message(msg);
|
||||||
|
|
||||||
// If asked to recomposite and renderer has run at least once
|
// If asked to recomposite and renderer has run at least once
|
||||||
|
@ -247,7 +246,7 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
(Data(ChangeReadyState(ready_state)), false) => {
|
(Data(ChangeReadyState(ready_state)), false) => {
|
||||||
self.window.borrow().set_ready_state(ready_state);
|
self.window.set_ready_state(ready_state);
|
||||||
self.ready_state = ready_state;
|
self.ready_state = ready_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +319,7 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn change_render_state(&mut self, render_state: RenderState) {
|
fn change_render_state(&mut self, render_state: RenderState) {
|
||||||
self.window.borrow().set_render_state(render_state);
|
self.window.set_render_state(render_state);
|
||||||
if render_state == IdleRenderState {
|
if render_state == IdleRenderState {
|
||||||
self.composite_ready = true;
|
self.composite_ready = true;
|
||||||
}
|
}
|
||||||
|
@ -336,14 +335,14 @@ impl IOCompositor {
|
||||||
|
|
||||||
fn set_ids(&mut self,
|
fn set_ids(&mut self,
|
||||||
frame_tree: SendableFrameTree,
|
frame_tree: SendableFrameTree,
|
||||||
response_chan: Chan<()>,
|
response_chan: Sender<()>,
|
||||||
new_constellation_chan: ConstellationChan) {
|
new_constellation_chan: ConstellationChan) {
|
||||||
response_chan.send(());
|
response_chan.send(());
|
||||||
|
|
||||||
self.root_pipeline = Some(frame_tree.pipeline.clone());
|
self.root_pipeline = Some(frame_tree.pipeline.clone());
|
||||||
|
|
||||||
// Initialize the new constellation channel by sending it the root window size.
|
// Initialize the new constellation channel by sending it the root window size.
|
||||||
let window_size = self.window.borrow().size();
|
let window_size = self.window.size();
|
||||||
let window_size = Size2D(window_size.width as uint,
|
let window_size = Size2D(window_size.width as uint,
|
||||||
window_size.height as uint);
|
window_size.height as uint);
|
||||||
{
|
{
|
||||||
|
@ -378,13 +377,10 @@ impl IOCompositor {
|
||||||
self.opts.tile_size,
|
self.opts.tile_size,
|
||||||
self.opts.cpu_painting);
|
self.opts.cpu_painting);
|
||||||
|
|
||||||
{
|
match self.root_layer.first_child.get() {
|
||||||
let current_child = self.root_layer.borrow().first_child.borrow();
|
None => {}
|
||||||
match *current_child.get() {
|
Some(ref old_layer) => {
|
||||||
None => {}
|
ContainerLayer::remove_child(self.root_layer.clone(), old_layer.clone())
|
||||||
Some(ref old_layer) => {
|
|
||||||
ContainerLayer::remove_child(self.root_layer.clone(), old_layer.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,10 +681,12 @@ impl IOCompositor {
|
||||||
let window_size = &self.window_size;
|
let window_size = &self.window_size;
|
||||||
|
|
||||||
// Determine zoom amount
|
// Determine zoom amount
|
||||||
self.world_zoom = cmp::max(self.world_zoom * magnification, 1.0);
|
self.world_zoom = (self.world_zoom * magnification).max(1.0);
|
||||||
let world_zoom = self.world_zoom;
|
let world_zoom = self.world_zoom;
|
||||||
|
|
||||||
self.root_layer.borrow().common.with_mut(|common| common.set_transform(identity().scale(world_zoom, world_zoom, 1f32)));
|
{
|
||||||
|
self.root_layer.common.borrow_mut().set_transform(identity().scale(world_zoom, world_zoom, 1f32));
|
||||||
|
}
|
||||||
|
|
||||||
// Scroll as needed
|
// Scroll as needed
|
||||||
let page_delta = Point2D(window_size.width as f32 * (1.0 / world_zoom - 1.0 / old_world_zoom) * 0.5,
|
let page_delta = Point2D(window_size.width as f32 * (1.0 / world_zoom - 1.0 / old_world_zoom) * 0.5,
|
||||||
|
@ -736,7 +734,7 @@ impl IOCompositor {
|
||||||
profile(time::CompositingCategory, self.profiler_chan.clone(), || {
|
profile(time::CompositingCategory, self.profiler_chan.clone(), || {
|
||||||
debug!("compositor: compositing");
|
debug!("compositor: compositing");
|
||||||
// Adjust the layer dimensions as necessary to correspond to the size of the window.
|
// Adjust the layer dimensions as necessary to correspond to the size of the window.
|
||||||
self.scene.size = self.window.borrow().size();
|
self.scene.size = self.window.size();
|
||||||
// Render the scene.
|
// Render the scene.
|
||||||
match self.compositor_layer {
|
match self.compositor_layer {
|
||||||
Some(ref mut layer) => {
|
Some(ref mut layer) => {
|
||||||
|
@ -786,7 +784,7 @@ impl IOCompositor {
|
||||||
self.shutting_down = true;
|
self.shutting_down = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.window.borrow().present();
|
self.window.present();
|
||||||
|
|
||||||
let exit = self.opts.exit_after_load;
|
let exit = self.opts.exit_after_load;
|
||||||
if exit {
|
if exit {
|
||||||
|
|
|
@ -23,7 +23,6 @@ use script::script_task::{ScriptChan, SendEventMsg};
|
||||||
use servo_msg::compositor_msg::{Epoch, FixedPosition, LayerBuffer, LayerBufferSet, LayerId};
|
use servo_msg::compositor_msg::{Epoch, FixedPosition, LayerBuffer, LayerBufferSet, LayerId};
|
||||||
use servo_msg::compositor_msg::{ScrollPolicy, Tile};
|
use servo_msg::compositor_msg::{ScrollPolicy, Tile};
|
||||||
use servo_msg::constellation_msg::PipelineId;
|
use servo_msg::constellation_msg::PipelineId;
|
||||||
use std::cmp;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[cfg(target_os="macos")]
|
#[cfg(target_os="macos")]
|
||||||
|
@ -129,10 +128,9 @@ pub enum WantsScrollEventsFlag {
|
||||||
|
|
||||||
fn create_container_layer_from_rect(rect: Rect<f32>) -> Rc<ContainerLayer> {
|
fn create_container_layer_from_rect(rect: Rect<f32>) -> Rc<ContainerLayer> {
|
||||||
let container = Rc::new(ContainerLayer());
|
let container = Rc::new(ContainerLayer());
|
||||||
container.borrow().scissor.set(Some(rect));
|
container.scissor.set(Some(rect));
|
||||||
container.borrow().common.with_mut(|common| {
|
container.common.borrow_mut().transform =
|
||||||
common.transform = identity().translate(rect.origin.x, rect.origin.y, 0f32);
|
identity().translate(rect.origin.x, rect.origin.y, 0f32);
|
||||||
});
|
|
||||||
container
|
container
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,9 +303,7 @@ impl CompositorLayer {
|
||||||
// Allow children to scroll.
|
// Allow children to scroll.
|
||||||
let cursor = cursor - self.scroll_offset;
|
let cursor = cursor - self.scroll_offset;
|
||||||
for child in self.children.mut_iter() {
|
for child in self.children.mut_iter() {
|
||||||
// NOTE: work around borrowchk
|
match child.container.scissor.get() {
|
||||||
let tmp = child.container.borrow().scissor.borrow();
|
|
||||||
match *tmp.get() {
|
|
||||||
None => {
|
None => {
|
||||||
error!("CompositorLayer: unable to perform cursor hit test for layer");
|
error!("CompositorLayer: unable to perform cursor hit test for layer");
|
||||||
}
|
}
|
||||||
|
@ -333,9 +329,9 @@ impl CompositorLayer {
|
||||||
Some(size) => size,
|
Some(size) => size,
|
||||||
None => fail!("CompositorLayer: tried to scroll with no page size set"),
|
None => fail!("CompositorLayer: tried to scroll with no page size set"),
|
||||||
};
|
};
|
||||||
let min_x = cmp::min(window_size.width - page_size.width, 0.0);
|
let min_x = (window_size.width - page_size.width).min(0.0);
|
||||||
self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0);
|
self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0);
|
||||||
let min_y = cmp::min(window_size.height - page_size.height, 0.0);
|
let min_y = (window_size.height - page_size.height).min(0.0);
|
||||||
self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0);
|
self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0);
|
||||||
|
|
||||||
if old_origin - self.scroll_offset == Point2D(0f32, 0f32) {
|
if old_origin - self.scroll_offset == Point2D(0f32, 0f32) {
|
||||||
|
@ -347,11 +343,8 @@ impl CompositorLayer {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn dump_layer_tree(&self, layer: Rc<ContainerLayer>, indent: ~str) {
|
fn dump_layer_tree(&self, layer: Rc<ContainerLayer>, indent: ~str) {
|
||||||
{
|
println!("{}scissor {:?}", indent, layer.scissor.get());
|
||||||
let scissor = layer.borrow().scissor.borrow();
|
for kid in layer.children() {
|
||||||
println!("{}scissor {:?}", indent, *scissor.get());
|
|
||||||
}
|
|
||||||
for kid in layer.borrow().children() {
|
|
||||||
match kid {
|
match kid {
|
||||||
ContainerLayerKind(ref container_layer) => {
|
ContainerLayerKind(ref container_layer) => {
|
||||||
self.dump_layer_tree((*container_layer).clone(), indent + " ");
|
self.dump_layer_tree((*container_layer).clone(), indent + " ");
|
||||||
|
@ -373,14 +366,8 @@ impl CompositorLayer {
|
||||||
// Scroll this layer!
|
// Scroll this layer!
|
||||||
self.scroll_offset = scroll_offset;
|
self.scroll_offset = scroll_offset;
|
||||||
|
|
||||||
self.root_layer
|
self.root_layer.common.borrow_mut().set_transform(
|
||||||
.borrow()
|
identity().translate(self.scroll_offset.x, self.scroll_offset.y, 0.0));
|
||||||
.common
|
|
||||||
.with_mut(|common| {
|
|
||||||
common.set_transform(identity().translate(self.scroll_offset.x,
|
|
||||||
self.scroll_offset.y,
|
|
||||||
0.0))
|
|
||||||
});
|
|
||||||
|
|
||||||
result = true
|
result = true
|
||||||
}
|
}
|
||||||
|
@ -398,9 +385,7 @@ impl CompositorLayer {
|
||||||
pub fn send_mouse_event(&self, event: MouseWindowEvent, cursor: Point2D<f32>) {
|
pub fn send_mouse_event(&self, event: MouseWindowEvent, cursor: Point2D<f32>) {
|
||||||
let cursor = cursor - self.scroll_offset;
|
let cursor = cursor - self.scroll_offset;
|
||||||
for child in self.children.iter().filter(|&x| !x.child.hidden) {
|
for child in self.children.iter().filter(|&x| !x.child.hidden) {
|
||||||
// NOTE: work around borrowchk
|
match child.container.scissor.get() {
|
||||||
let tmp = child.container.borrow().scissor.borrow();
|
|
||||||
match *tmp.get() {
|
|
||||||
None => {
|
None => {
|
||||||
error!("CompositorLayer: unable to perform cursor hit test for layer");
|
error!("CompositorLayer: unable to perform cursor hit test for layer");
|
||||||
}
|
}
|
||||||
|
@ -465,9 +450,7 @@ impl CompositorLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let transform = |x: &mut CompositorLayerChild| -> bool {
|
let transform = |x: &mut CompositorLayerChild| -> bool {
|
||||||
// NOTE: work around borrowchk
|
match x.container.scissor.get() {
|
||||||
let tmp = x.container.borrow().scissor.borrow();
|
|
||||||
match *tmp.get() {
|
|
||||||
Some(scissor) => {
|
Some(scissor) => {
|
||||||
let mut new_rect = window_rect;
|
let mut new_rect = window_rect;
|
||||||
new_rect.origin.x = new_rect.origin.x - x.child.scroll_offset.x;
|
new_rect.origin.x = new_rect.origin.x - x.child.scroll_offset.x;
|
||||||
|
@ -512,17 +495,10 @@ impl CompositorLayer {
|
||||||
Some(i) => {
|
Some(i) => {
|
||||||
debug!("compositor_layer: node found for set_clipping_rect()");
|
debug!("compositor_layer: node found for set_clipping_rect()");
|
||||||
let child_node = &mut self.children[i];
|
let child_node = &mut self.children[i];
|
||||||
child_node.container.borrow().common.with_mut(|common|
|
child_node.container.common.borrow_mut().set_transform(
|
||||||
common.set_transform(identity().translate(new_rect.origin.x,
|
identity().translate(new_rect.origin.x, new_rect.origin.y, 0.0));
|
||||||
new_rect.origin.y,
|
let old_rect = child_node.container.scissor.get().clone();
|
||||||
0.0)));
|
child_node.container.scissor.set(Some(new_rect));
|
||||||
let old_rect = {
|
|
||||||
// NOTE: work around borrowchk
|
|
||||||
let tmp = child_node.container.borrow().scissor.borrow();
|
|
||||||
tmp.get().clone()
|
|
||||||
};
|
|
||||||
|
|
||||||
child_node.container.borrow().scissor.set(Some(new_rect));
|
|
||||||
match self.quadtree {
|
match self.quadtree {
|
||||||
NoTree(..) => {} // Nothing to do
|
NoTree(..) => {} // Nothing to do
|
||||||
Tree(ref mut quadtree) => {
|
Tree(ref mut quadtree) => {
|
||||||
|
@ -618,9 +594,9 @@ impl CompositorLayer {
|
||||||
Some(size) => size,
|
Some(size) => size,
|
||||||
None => fail!("CompositorLayer: tried to scroll with no page size set"),
|
None => fail!("CompositorLayer: tried to scroll with no page size set"),
|
||||||
};
|
};
|
||||||
let min_x = cmp::min(window_size.width - page_size.width, 0.0);
|
let min_x = (window_size.width - page_size.width).min(0.0);
|
||||||
self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0);
|
self.scroll_offset.x = self.scroll_offset.x.clamp(&min_x, &0.0);
|
||||||
let min_y = cmp::min(window_size.height - page_size.height, 0.0);
|
let min_y = (window_size.height - page_size.height).min(0.0);
|
||||||
self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0);
|
self.scroll_offset.y = self.scroll_offset.y.clamp(&min_y, &0.0);
|
||||||
|
|
||||||
// check to see if we scrolled
|
// check to see if we scrolled
|
||||||
|
@ -689,9 +665,7 @@ impl CompositorLayer {
|
||||||
max_mem))
|
max_mem))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NOTE: work around borrowchk
|
match child_node.container.scissor.get() {
|
||||||
let tmp = child_node.container.borrow().scissor.borrow();
|
|
||||||
match *tmp.get() {
|
|
||||||
Some(scissor) => {
|
Some(scissor) => {
|
||||||
// Call scroll for bounds checking if the page shrunk. Use (-1, -1) as the
|
// Call scroll for bounds checking if the page shrunk. Use (-1, -1) as the
|
||||||
// cursor position to make sure the scroll isn't propagated downwards.
|
// cursor position to make sure the scroll isn't propagated downwards.
|
||||||
|
@ -724,13 +698,7 @@ impl CompositorLayer {
|
||||||
// are not rebuilt directly from this method.
|
// are not rebuilt directly from this method.
|
||||||
pub fn build_layer_tree(&mut self, graphics_context: &NativeCompositingGraphicsContext) {
|
pub fn build_layer_tree(&mut self, graphics_context: &NativeCompositingGraphicsContext) {
|
||||||
// Iterate over the children of the container layer.
|
// Iterate over the children of the container layer.
|
||||||
let mut current_layer_child;
|
let mut current_layer_child = self.root_layer.first_child.get().clone();
|
||||||
|
|
||||||
// NOTE: work around borrowchk
|
|
||||||
{
|
|
||||||
let tmp = self.root_layer.borrow().first_child.borrow();
|
|
||||||
current_layer_child = tmp.get().clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete old layer.
|
// Delete old layer.
|
||||||
while current_layer_child.is_some() {
|
while current_layer_child.is_some() {
|
||||||
|
@ -784,7 +752,7 @@ impl CompositorLayer {
|
||||||
Some(TextureLayerKind(existing_texture_layer)) => {
|
Some(TextureLayerKind(existing_texture_layer)) => {
|
||||||
texture_layer = existing_texture_layer.clone();
|
texture_layer = existing_texture_layer.clone();
|
||||||
|
|
||||||
let texture = &existing_texture_layer.borrow().texture;
|
let texture = &existing_texture_layer.texture;
|
||||||
buffer.native_surface.bind_to_texture(graphics_context, texture, size);
|
buffer.native_surface.bind_to_texture(graphics_context, texture, size);
|
||||||
|
|
||||||
// Move on to the next sibling.
|
// Move on to the next sibling.
|
||||||
|
@ -799,18 +767,19 @@ impl CompositorLayer {
|
||||||
let rect = buffer.rect;
|
let rect = buffer.rect;
|
||||||
let transform = identity().translate(rect.origin.x, rect.origin.y, 0.0);
|
let transform = identity().translate(rect.origin.x, rect.origin.y, 0.0);
|
||||||
let transform = transform.scale(rect.size.width, rect.size.height, 1.0);
|
let transform = transform.scale(rect.size.width, rect.size.height, 1.0);
|
||||||
texture_layer.borrow().common.with_mut(|common| common.set_transform(transform));
|
texture_layer.common.borrow_mut().set_transform(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add child layers.
|
// Add child layers.
|
||||||
for child in self.children.mut_iter().filter(|x| !x.child.hidden) {
|
for child in self.children.mut_iter().filter(|x| !x.child.hidden) {
|
||||||
current_layer_child = match current_layer_child {
|
current_layer_child = match current_layer_child {
|
||||||
None => {
|
None => {
|
||||||
child.container.borrow().common.with_mut(|common| {
|
{
|
||||||
common.parent = None;
|
let mut common = child.container.common.borrow_mut();
|
||||||
common.prev_sibling = None;
|
(*common).parent = None;
|
||||||
common.next_sibling = None;
|
common.prev_sibling = None;
|
||||||
});
|
common.next_sibling = None;
|
||||||
|
}
|
||||||
ContainerLayer::add_child_end(self.root_layer.clone(),
|
ContainerLayer::add_child_end(self.root_layer.clone(),
|
||||||
ContainerLayerKind(child.container.clone()));
|
ContainerLayerKind(child.container.clone()));
|
||||||
None
|
None
|
||||||
|
@ -900,9 +869,7 @@ impl CompositorLayer {
|
||||||
match self.quadtree {
|
match self.quadtree {
|
||||||
NoTree(..) => {} // Nothing to do
|
NoTree(..) => {} // Nothing to do
|
||||||
Tree(ref mut quadtree) => {
|
Tree(ref mut quadtree) => {
|
||||||
// NOTE: work around borrowchk
|
match child.get_ref().container.scissor.get() {
|
||||||
let tmp = child.get_ref().container.borrow().scissor.borrow();
|
|
||||||
match *tmp.get() {
|
|
||||||
Some(rect) => {
|
Some(rect) => {
|
||||||
quadtree.set_status_page(rect, Normal, false); // Unhide this rect
|
quadtree.set_status_page(rect, Normal, false); // Unhide this rect
|
||||||
}
|
}
|
||||||
|
@ -952,9 +919,7 @@ impl CompositorLayer {
|
||||||
Tree(ref mut quadtree) => quadtree,
|
Tree(ref mut quadtree) => quadtree,
|
||||||
};
|
};
|
||||||
for child in self.children.iter().filter(|x| !x.child.hidden) {
|
for child in self.children.iter().filter(|x| !x.child.hidden) {
|
||||||
// NOTE: work around borrowchk
|
match child.container.scissor.get() {
|
||||||
let tmp = child.container.borrow().scissor.borrow();
|
|
||||||
match *tmp.get() {
|
|
||||||
None => {} // Nothing to do
|
None => {} // Nothing to do
|
||||||
Some(rect) => {
|
Some(rect) => {
|
||||||
quadtree.set_status_page(rect, Hidden, false);
|
quadtree.set_status_page(rect, Hidden, false);
|
||||||
|
|
|
@ -18,9 +18,9 @@ use servo_msg::compositor_msg::{RenderListener, RenderState, ScriptListener, Scr
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, PipelineId};
|
use servo_msg::constellation_msg::{ConstellationChan, PipelineId};
|
||||||
use servo_util::opts::Opts;
|
use servo_util::opts::Opts;
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
use std::comm::{Chan, Port};
|
use std::comm::{channel, Sender, Receiver};
|
||||||
|
|
||||||
use extra::url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[cfg(target_os="linux")]
|
#[cfg(target_os="linux")]
|
||||||
use azure::azure_hl;
|
use azure::azure_hl;
|
||||||
|
@ -35,7 +35,7 @@ mod headless;
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct CompositorChan {
|
pub struct CompositorChan {
|
||||||
/// A channel on which messages can be sent to the compositor.
|
/// A channel on which messages can be sent to the compositor.
|
||||||
chan: Chan<Msg>,
|
chan: Sender<Msg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of the abstract `ScriptListener` interface.
|
/// Implementation of the abstract `ScriptListener` interface.
|
||||||
|
@ -57,7 +57,7 @@ impl ScriptListener for CompositorChan {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(&self) {
|
fn close(&self) {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
self.chan.send(Exit(chan));
|
self.chan.send(Exit(chan));
|
||||||
port.recv();
|
port.recv();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ impl ScriptListener for CompositorChan {
|
||||||
/// Implementation of the abstract `RenderListener` interface.
|
/// Implementation of the abstract `RenderListener` interface.
|
||||||
impl RenderListener for CompositorChan {
|
impl RenderListener for CompositorChan {
|
||||||
fn get_graphics_metadata(&self) -> Option<NativeGraphicsMetadata> {
|
fn get_graphics_metadata(&self) -> Option<NativeGraphicsMetadata> {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
self.chan.send(GetGraphicsMetadata(chan));
|
self.chan.send(GetGraphicsMetadata(chan));
|
||||||
port.recv()
|
port.recv()
|
||||||
}
|
}
|
||||||
|
@ -145,8 +145,8 @@ impl RenderListener for CompositorChan {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompositorChan {
|
impl CompositorChan {
|
||||||
pub fn new() -> (Port<Msg>, CompositorChan) {
|
pub fn new() -> (Receiver<Msg>, CompositorChan) {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let compositor_chan = CompositorChan {
|
let compositor_chan = CompositorChan {
|
||||||
chan: chan,
|
chan: chan,
|
||||||
};
|
};
|
||||||
|
@ -160,7 +160,7 @@ impl CompositorChan {
|
||||||
/// Messages from the painting task and the constellation task to the compositor task.
|
/// Messages from the painting task and the constellation task to the compositor task.
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
/// Requests that the compositor shut down.
|
/// Requests that the compositor shut down.
|
||||||
Exit(Chan<()>),
|
Exit(Sender<()>),
|
||||||
|
|
||||||
/// Informs the compositor that the constellation has completed shutdown.
|
/// Informs the compositor that the constellation has completed shutdown.
|
||||||
/// Required because the constellation can have pending calls to make (e.g. SetIds)
|
/// Required because the constellation can have pending calls to make (e.g. SetIds)
|
||||||
|
@ -172,7 +172,7 @@ pub enum Msg {
|
||||||
/// is the pixel format.
|
/// is the pixel format.
|
||||||
///
|
///
|
||||||
/// The headless compositor returns `None`.
|
/// The headless compositor returns `None`.
|
||||||
GetGraphicsMetadata(Chan<Option<NativeGraphicsMetadata>>),
|
GetGraphicsMetadata(Sender<Option<NativeGraphicsMetadata>>),
|
||||||
|
|
||||||
/// Tells the compositor to create the root layer for a pipeline if necessary (i.e. if no layer
|
/// Tells the compositor to create the root layer for a pipeline if necessary (i.e. if no layer
|
||||||
/// with that ID exists).
|
/// with that ID exists).
|
||||||
|
@ -197,7 +197,7 @@ pub enum Msg {
|
||||||
/// Alerts the compositor to the current status of rendering.
|
/// Alerts the compositor to the current status of rendering.
|
||||||
ChangeRenderState(RenderState),
|
ChangeRenderState(RenderState),
|
||||||
/// Sets the channel to the current layout and render tasks, along with their id
|
/// Sets the channel to the current layout and render tasks, along with their id
|
||||||
SetIds(SendableFrameTree, Chan<()>, ConstellationChan),
|
SetIds(SendableFrameTree, Sender<()>, ConstellationChan),
|
||||||
/// Sets the color of unrendered content for a layer.
|
/// Sets the color of unrendered content for a layer.
|
||||||
SetUnRenderedColor(PipelineId, LayerId, Color),
|
SetUnRenderedColor(PipelineId, LayerId, Color),
|
||||||
/// The load of a page for a given URL has completed.
|
/// The load of a page for a given URL has completed.
|
||||||
|
@ -239,7 +239,7 @@ impl CompositorTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create(opts: Opts,
|
pub fn create(opts: Opts,
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
profiler_chan: ProfilerChan) {
|
profiler_chan: ProfilerChan) {
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use compositing::*;
|
||||||
|
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg};
|
use servo_msg::constellation_msg::{ConstellationChan, ExitMsg, ResizedWindowMsg};
|
||||||
use std::comm::{Empty, Disconnected, Data, Port};
|
use std::comm::{Empty, Disconnected, Data, Receiver};
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
use servo_util::time;
|
use servo_util::time;
|
||||||
|
|
||||||
|
@ -16,17 +16,17 @@ use servo_util::time;
|
||||||
/// It's intended for headless testing.
|
/// It's intended for headless testing.
|
||||||
pub struct NullCompositor {
|
pub struct NullCompositor {
|
||||||
/// The port on which we receive messages.
|
/// The port on which we receive messages.
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NullCompositor {
|
impl NullCompositor {
|
||||||
fn new(port: Port<Msg>) -> NullCompositor {
|
fn new(port: Receiver<Msg>) -> NullCompositor {
|
||||||
NullCompositor {
|
NullCompositor {
|
||||||
port: port,
|
port: port,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create(port: Port<Msg>,
|
pub fn create(port: Receiver<Msg>,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
profiler_chan: ProfilerChan) {
|
profiler_chan: ProfilerChan) {
|
||||||
let compositor = NullCompositor::new(port);
|
let compositor = NullCompositor::new(port);
|
||||||
|
|
|
@ -10,10 +10,10 @@ use geom::size::Size2D;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use gfx::render_task::BufferRequest;
|
use gfx::render_task::BufferRequest;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::num::next_power_of_two;
|
|
||||||
use std::vec;
|
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::vec::build;
|
use std::num::next_power_of_two;
|
||||||
|
use std::slice;
|
||||||
|
use std::slice::build;
|
||||||
use servo_msg::compositor_msg::Tile;
|
use servo_msg::compositor_msg::Tile;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -355,8 +355,8 @@ impl<T: Tile> QuadtreeNode<T> {
|
||||||
if self.size <= tile_size {
|
if self.size <= tile_size {
|
||||||
let pix_x = (self.origin.x * scale).ceil() as uint;
|
let pix_x = (self.origin.x * scale).ceil() as uint;
|
||||||
let pix_y = (self.origin.y * scale).ceil() as uint;
|
let pix_y = (self.origin.y * scale).ceil() as uint;
|
||||||
let page_width = cmp::min(clip_x - self.origin.x, self.size);
|
let page_width = self.size.min(clip_x - self.origin.x);
|
||||||
let page_height = cmp::min(clip_y - self.origin.y, self.size);
|
let page_height = self.size.min(clip_y - self.origin.y);
|
||||||
let pix_width = (page_width * scale).ceil() as uint;
|
let pix_width = (page_width * scale).ceil() as uint;
|
||||||
let pix_height = (page_height * scale).ceil() as uint;
|
let pix_height = (page_height * scale).ceil() as uint;
|
||||||
self.status = Rendering;
|
self.status = Rendering;
|
||||||
|
@ -483,8 +483,8 @@ impl<T: Tile> QuadtreeNode<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip window to visible region
|
// clip window to visible region
|
||||||
let w_width = cmp::min(clip.width - w_x, w_width);
|
let w_width = w_width.min(clip.width - w_x);
|
||||||
let w_height = cmp::min(clip.height - w_y, w_height);
|
let w_height = w_height.min(clip.height - w_y);
|
||||||
|
|
||||||
if s_size <= tile_size { // We are the child
|
if s_size <= tile_size { // We are the child
|
||||||
return match self.tile {
|
return match self.tile {
|
||||||
|
@ -546,7 +546,7 @@ impl<T: Tile> QuadtreeNode<T> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let quads_to_check = vec::build(Some(4), builder);
|
let quads_to_check = slice::build(Some(4), builder);
|
||||||
|
|
||||||
let mut request = ~[];
|
let mut request = ~[];
|
||||||
let mut unused = ~[];
|
let mut unused = ~[];
|
||||||
|
@ -556,20 +556,20 @@ impl<T: Tile> QuadtreeNode<T> {
|
||||||
// Recurse into child
|
// Recurse into child
|
||||||
let new_window = match *quad {
|
let new_window = match *quad {
|
||||||
TL => Rect(window.origin,
|
TL => Rect(window.origin,
|
||||||
Size2D(cmp::min(w_width, s_x + s_size / 2.0 - w_x),
|
Size2D(w_width.min(s_x + s_size / 2.0 - w_x),
|
||||||
cmp::min(w_height, (s_y + s_size / 2.0 - w_y)))),
|
w_height.min(s_y + s_size / 2.0 - w_y))),
|
||||||
TR => Rect(Point2D(cmp::max(w_x, s_x + s_size / 2.0),
|
TR => Rect(Point2D(w_x.max(s_x + s_size / 2.0),
|
||||||
w_y),
|
w_y),
|
||||||
Size2D(cmp::min(w_width, w_x + w_width - (s_x + s_size / 2.0)),
|
Size2D(w_width.min(w_x + w_width - (s_x + s_size / 2.0)),
|
||||||
cmp::min(w_height, s_y + s_size / 2.0 - w_y))),
|
w_height.min(s_y + s_size / 2.0 - w_y))),
|
||||||
BL => Rect(Point2D(w_x,
|
BL => Rect(Point2D(w_x,
|
||||||
cmp::max(w_y, s_y + s_size / 2.0)),
|
w_y.max(s_y + s_size / 2.0)),
|
||||||
Size2D(cmp::min(w_width, s_x + s_size / 2.0 - w_x),
|
Size2D(w_width.min(s_x + s_size / 2.0 - w_x),
|
||||||
cmp::min(w_height, w_y + w_height - (s_y + s_size / 2.0)))),
|
w_height.min(w_y + w_height - (s_y + s_size / 2.0)))),
|
||||||
BR => Rect(Point2D(cmp::max(w_x, s_x + s_size / 2.0),
|
BR => Rect(Point2D(w_x.max(s_x + s_size / 2.0),
|
||||||
cmp::max(w_y, s_y + s_size / 2.0)),
|
w_y.max(s_y + s_size / 2.0)),
|
||||||
Size2D(cmp::min(w_width, w_x + w_width - (s_x + s_size / 2.0)),
|
Size2D(w_width.min(w_x + w_width - (s_x + s_size / 2.0)),
|
||||||
cmp::min(w_height, w_y + w_height - (s_y + s_size / 2.0)))),
|
w_height.min(w_y + w_height - (s_y + s_size / 2.0)))),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete};
|
use compositing::{CompositorChan, LoadComplete, SetIds, SetLayerClipRect, ShutdownComplete};
|
||||||
|
|
||||||
use collections::hashmap::{HashMap, HashSet};
|
use collections::hashmap::{HashMap, HashSet};
|
||||||
use extra::url::Url;
|
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use gfx::render_task;
|
use gfx::render_task;
|
||||||
|
@ -33,11 +32,12 @@ use std::mem::replace;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::libc;
|
use std::libc;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
/// Maintains the pipelines and navigation context and grants permission to composite
|
/// Maintains the pipelines and navigation context and grants permission to composite
|
||||||
pub struct Constellation {
|
pub struct Constellation {
|
||||||
chan: ConstellationChan,
|
chan: ConstellationChan,
|
||||||
request_port: Port<Msg>,
|
request_port: Receiver<Msg>,
|
||||||
compositor_chan: CompositorChan,
|
compositor_chan: CompositorChan,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
image_cache_task: ImageCacheTask,
|
image_cache_task: ImageCacheTask,
|
||||||
|
@ -61,14 +61,15 @@ struct FrameTree {
|
||||||
// Need to clone the FrameTrees, but _not_ the Pipelines
|
// Need to clone the FrameTrees, but _not_ the Pipelines
|
||||||
impl Clone for FrameTree {
|
impl Clone for FrameTree {
|
||||||
fn clone(&self) -> FrameTree {
|
fn clone(&self) -> FrameTree {
|
||||||
let children = self.children.borrow();
|
let children = self.children
|
||||||
let mut children = children.get().iter().map(|child_frame_tree| {
|
.get()
|
||||||
child_frame_tree.clone()
|
.iter()
|
||||||
});
|
.map(|child_frame_tree| child_frame_tree.clone())
|
||||||
|
.collect();
|
||||||
FrameTree {
|
FrameTree {
|
||||||
pipeline: self.pipeline.clone(),
|
pipeline: self.pipeline.clone(),
|
||||||
parent: self.parent.clone(),
|
parent: self.parent.clone(),
|
||||||
children: RefCell::new(children.collect()),
|
children: RefCell::new(children),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,40 +107,23 @@ enum ReplaceResult {
|
||||||
|
|
||||||
impl FrameTree {
|
impl FrameTree {
|
||||||
fn contains(&self, id: PipelineId) -> bool {
|
fn contains(&self, id: PipelineId) -> bool {
|
||||||
self.iter().any(|frame_tree| {
|
self.iter().any(|frame_tree| id == frame_tree.pipeline.get().id)
|
||||||
// NOTE: work around borrowchk issue
|
|
||||||
let tmp = frame_tree.borrow().pipeline.borrow();
|
|
||||||
id == tmp.get().borrow().id
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the frame tree whose key is id
|
/// Returns the frame tree whose key is id
|
||||||
fn find(&self, id: PipelineId) -> Option<Rc<FrameTree>> {
|
fn find(&self, id: PipelineId) -> Option<Rc<FrameTree>> {
|
||||||
self.iter().find(|frame_tree| {
|
self.iter().find(|frame_tree| id == frame_tree.pipeline.get().id)
|
||||||
// NOTE: work around borrowchk issue
|
|
||||||
let tmp = frame_tree.borrow().pipeline.borrow();
|
|
||||||
id == tmp.get().borrow().id
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replaces a node of the frame tree in place. Returns the node that was removed or the original node
|
/// Replaces a node of the frame tree in place. Returns the node that was removed or the original node
|
||||||
/// if the node to replace could not be found.
|
/// if the node to replace could not be found.
|
||||||
fn replace_child(&self, id: PipelineId, new_child: Rc<FrameTree>) -> ReplaceResult {
|
fn replace_child(&self, id: PipelineId, new_child: Rc<FrameTree>) -> ReplaceResult {
|
||||||
for frame_tree in self.iter() {
|
for frame_tree in self.iter() {
|
||||||
// NOTE: work around mutability issue
|
let mut children = frame_tree.children.get();
|
||||||
let mut children = frame_tree.borrow().children.borrow_mut();
|
let mut child = children.mut_iter()
|
||||||
let mut child = children.get().mut_iter()
|
.find(|child| child.frame_tree.pipeline.get().id == id);
|
||||||
.find(|child| {
|
|
||||||
// NOTE: work around borrowchk issue
|
|
||||||
let tmp = child.frame_tree.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().id == id
|
|
||||||
});
|
|
||||||
for child in child.mut_iter() {
|
for child in child.mut_iter() {
|
||||||
// NOTE: work around lifetime issues
|
new_child.parent.set(child.frame_tree.parent.get().clone());
|
||||||
{
|
|
||||||
let tmp = child.frame_tree.borrow().parent.borrow();
|
|
||||||
new_child.borrow().parent.set(tmp.get().clone());
|
|
||||||
}
|
|
||||||
return ReplacedNode(replace(&mut child.frame_tree, new_child));
|
return ReplacedNode(replace(&mut child.frame_tree, new_child));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,16 +132,8 @@ impl FrameTree {
|
||||||
|
|
||||||
fn to_sendable(&self) -> SendableFrameTree {
|
fn to_sendable(&self) -> SendableFrameTree {
|
||||||
let sendable_frame_tree = SendableFrameTree {
|
let sendable_frame_tree = SendableFrameTree {
|
||||||
pipeline: {
|
pipeline: self.pipeline.get().to_sendable(),
|
||||||
// NOTE: work around borrowchk issues
|
children: self.children.get().iter().map(|frame_tree| frame_tree.to_sendable()).collect(),
|
||||||
let tmp = self.pipeline.borrow();
|
|
||||||
tmp.get().borrow().to_sendable()
|
|
||||||
},
|
|
||||||
children: {
|
|
||||||
// NOTE: work around borrowchk issues
|
|
||||||
let tmp = self.children.borrow();
|
|
||||||
tmp.get().iter().map(|frame_tree| frame_tree.to_sendable()).collect()
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
sendable_frame_tree
|
sendable_frame_tree
|
||||||
}
|
}
|
||||||
|
@ -172,7 +148,7 @@ impl FrameTree {
|
||||||
impl ChildFrameTree {
|
impl ChildFrameTree {
|
||||||
fn to_sendable(&self) -> SendableChildFrameTree {
|
fn to_sendable(&self) -> SendableChildFrameTree {
|
||||||
SendableChildFrameTree {
|
SendableChildFrameTree {
|
||||||
frame_tree: self.frame_tree.borrow().to_sendable(),
|
frame_tree: self.frame_tree.to_sendable(),
|
||||||
rect: self.rect,
|
rect: self.rect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,12 +165,8 @@ impl Iterator<Rc<FrameTree>> for FrameTreeIterator {
|
||||||
fn next(&mut self) -> Option<Rc<FrameTree>> {
|
fn next(&mut self) -> Option<Rc<FrameTree>> {
|
||||||
if !self.stack.is_empty() {
|
if !self.stack.is_empty() {
|
||||||
let next = self.stack.pop();
|
let next = self.stack.pop();
|
||||||
{
|
for cft in next.get_ref().children.get().rev_iter() {
|
||||||
// NOTE: work around borrowchk issues
|
self.stack.push(cft.frame_tree.clone());
|
||||||
let tmp = next.get_ref().borrow().children.borrow();
|
|
||||||
for cft in tmp.get().rev_iter() {
|
|
||||||
self.stack.push(cft.frame_tree.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Some(next.unwrap())
|
Some(next.unwrap())
|
||||||
} else {
|
} else {
|
||||||
|
@ -245,11 +217,7 @@ impl NavigationContext {
|
||||||
|
|
||||||
/// Loads a new set of page frames, returning all evicted frame trees
|
/// Loads a new set of page frames, returning all evicted frame trees
|
||||||
pub fn load(&mut self, frame_tree: Rc<FrameTree>) -> ~[Rc<FrameTree>] {
|
pub fn load(&mut self, frame_tree: Rc<FrameTree>) -> ~[Rc<FrameTree>] {
|
||||||
debug!("navigating to {:?}", {
|
debug!("navigating to {:?}", frame_tree.pipeline.get().id);
|
||||||
// NOTE: work around borrowchk issues
|
|
||||||
let tmp = frame_tree.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().id
|
|
||||||
});
|
|
||||||
let evicted = replace(&mut self.next, ~[]);
|
let evicted = replace(&mut self.next, ~[]);
|
||||||
if self.current.is_some() {
|
if self.current.is_some() {
|
||||||
self.previous.push(self.current.take_unwrap());
|
self.previous.push(self.current.take_unwrap());
|
||||||
|
@ -261,13 +229,13 @@ impl NavigationContext {
|
||||||
/// Returns the frame trees whose keys are pipeline_id.
|
/// Returns the frame trees whose keys are pipeline_id.
|
||||||
pub fn find_all(&mut self, pipeline_id: PipelineId) -> ~[Rc<FrameTree>] {
|
pub fn find_all(&mut self, pipeline_id: PipelineId) -> ~[Rc<FrameTree>] {
|
||||||
let from_current = self.current.iter().filter_map(|frame_tree| {
|
let from_current = self.current.iter().filter_map(|frame_tree| {
|
||||||
frame_tree.borrow().find(pipeline_id)
|
frame_tree.find(pipeline_id)
|
||||||
});
|
});
|
||||||
let from_next = self.next.iter().filter_map(|frame_tree| {
|
let from_next = self.next.iter().filter_map(|frame_tree| {
|
||||||
frame_tree.borrow().find(pipeline_id)
|
frame_tree.find(pipeline_id)
|
||||||
});
|
});
|
||||||
let from_prev = self.previous.iter().filter_map(|frame_tree| {
|
let from_prev = self.previous.iter().filter_map(|frame_tree| {
|
||||||
frame_tree.borrow().find(pipeline_id)
|
frame_tree.find(pipeline_id)
|
||||||
});
|
});
|
||||||
from_prev.chain(from_current).chain(from_next).collect()
|
from_prev.chain(from_current).chain(from_next).collect()
|
||||||
}
|
}
|
||||||
|
@ -279,7 +247,7 @@ impl NavigationContext {
|
||||||
|
|
||||||
let mut all_contained = from_prev.chain(from_current).chain(from_next);
|
let mut all_contained = from_prev.chain(from_current).chain(from_next);
|
||||||
all_contained.any(|frame_tree| {
|
all_contained.any(|frame_tree| {
|
||||||
frame_tree.borrow().contains(pipeline_id)
|
frame_tree.contains(pipeline_id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,7 +310,7 @@ impl Constellation {
|
||||||
pub fn find_all(&mut self, pipeline_id: PipelineId) -> ~[Rc<FrameTree>] {
|
pub fn find_all(&mut self, pipeline_id: PipelineId) -> ~[Rc<FrameTree>] {
|
||||||
let matching_navi_frames = self.navigation_context.find_all(pipeline_id);
|
let matching_navi_frames = self.navigation_context.find_all(pipeline_id);
|
||||||
let matching_pending_frames = self.pending_frames.iter().filter_map(|frame_change| {
|
let matching_pending_frames = self.pending_frames.iter().filter_map(|frame_change| {
|
||||||
frame_change.after.borrow().find(pipeline_id)
|
frame_change.after.find(pipeline_id)
|
||||||
});
|
});
|
||||||
matching_navi_frames.move_iter().chain(matching_pending_frames).collect()
|
matching_navi_frames.move_iter().chain(matching_pending_frames).collect()
|
||||||
}
|
}
|
||||||
|
@ -406,7 +374,7 @@ impl Constellation {
|
||||||
|
|
||||||
fn handle_exit(&self) {
|
fn handle_exit(&self) {
|
||||||
for (_id, ref pipeline) in self.pipelines.iter() {
|
for (_id, ref pipeline) in self.pipelines.iter() {
|
||||||
pipeline.borrow().exit();
|
pipeline.exit();
|
||||||
}
|
}
|
||||||
self.image_cache_task.exit();
|
self.image_cache_task.exit();
|
||||||
self.resource_task.send(resource_task::Exit);
|
self.resource_task.send(resource_task::Exit);
|
||||||
|
@ -430,10 +398,10 @@ impl Constellation {
|
||||||
Some(id) => id.clone()
|
Some(id) => id.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let ScriptChan(ref old_script) = old_pipeline.borrow().script_chan;
|
let ScriptChan(ref old_script) = old_pipeline.script_chan;
|
||||||
old_script.try_send(ExitPipelineMsg(pipeline_id));
|
old_script.try_send(ExitPipelineMsg(pipeline_id));
|
||||||
old_pipeline.borrow().render_chan.chan.try_send(render_task::ExitMsg(None));
|
old_pipeline.render_chan.chan.try_send(render_task::ExitMsg(None));
|
||||||
let LayoutChan(ref old_layout) = old_pipeline.borrow().layout_chan;
|
let LayoutChan(ref old_layout) = old_pipeline.layout_chan;
|
||||||
old_layout.try_send(layout_interface::ExitNowMsg);
|
old_layout.try_send(layout_interface::ExitNowMsg);
|
||||||
self.pipelines.remove(&pipeline_id);
|
self.pipelines.remove(&pipeline_id);
|
||||||
|
|
||||||
|
@ -486,7 +454,7 @@ impl Constellation {
|
||||||
}),
|
}),
|
||||||
navigation_type: constellation_msg::Load,
|
navigation_type: constellation_msg::Load,
|
||||||
});
|
});
|
||||||
self.pipelines.insert(pipeline_wrapped.borrow().id, pipeline_wrapped);
|
self.pipelines.insert(pipeline_wrapped.id, pipeline_wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId, rect: Rect<f32>) {
|
fn handle_frame_rect_msg(&mut self, pipeline_id: PipelineId, subpage_id: SubpageId, rect: Rect<f32>) {
|
||||||
|
@ -495,9 +463,7 @@ impl Constellation {
|
||||||
|
|
||||||
// Returns true if a child frame tree's subpage id matches the given subpage id
|
// Returns true if a child frame tree's subpage id matches the given subpage id
|
||||||
let subpage_eq = |child_frame_tree: & &mut ChildFrameTree| {
|
let subpage_eq = |child_frame_tree: & &mut ChildFrameTree| {
|
||||||
// NOTE: work around borrowchk issues
|
child_frame_tree.frame_tree.pipeline.get().
|
||||||
let tmp = child_frame_tree.frame_tree.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().
|
|
||||||
subpage_id.expect("Constellation:
|
subpage_id.expect("Constellation:
|
||||||
child frame does not have a subpage id. This should not be possible.")
|
child frame does not have a subpage id. This should not be possible.")
|
||||||
== subpage_id
|
== subpage_id
|
||||||
|
@ -512,11 +478,11 @@ impl Constellation {
|
||||||
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
|
let update_child_rect = |child_frame_tree: &mut ChildFrameTree, is_active: bool| {
|
||||||
child_frame_tree.rect = Some(rect.clone());
|
child_frame_tree.rect = Some(rect.clone());
|
||||||
// NOTE: work around borrowchk issues
|
// NOTE: work around borrowchk issues
|
||||||
let pipeline = &child_frame_tree.frame_tree.borrow().pipeline.borrow();
|
let pipeline = &child_frame_tree.frame_tree.pipeline;
|
||||||
if !already_sent.contains(&pipeline.get().borrow().id) {
|
if !already_sent.contains(&pipeline.get().id) {
|
||||||
let Size2D { width, height } = rect.size;
|
let Size2D { width, height } = rect.size;
|
||||||
if is_active {
|
if is_active {
|
||||||
let pipeline = pipeline.get().borrow();
|
let pipeline = pipeline.get();
|
||||||
let ScriptChan(ref script_chan) = pipeline.script_chan;
|
let ScriptChan(ref script_chan) = pipeline.script_chan;
|
||||||
script_chan.send(ResizeMsg(pipeline.id, Size2D {
|
script_chan.send(ResizeMsg(pipeline.id, Size2D {
|
||||||
width: width as uint,
|
width: width as uint,
|
||||||
|
@ -526,8 +492,7 @@ impl Constellation {
|
||||||
LayerId::null(),
|
LayerId::null(),
|
||||||
rect));
|
rect));
|
||||||
} else {
|
} else {
|
||||||
let pipeline = pipeline.get().borrow();
|
already_sent.insert(pipeline.get().id);
|
||||||
already_sent.insert(pipeline.id);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -535,20 +500,18 @@ impl Constellation {
|
||||||
// If the subframe is in the current frame tree, the compositor needs the new size
|
// If the subframe is in the current frame tree, the compositor needs the new size
|
||||||
for current_frame in self.current_frame().iter() {
|
for current_frame in self.current_frame().iter() {
|
||||||
debug!("Constellation: Sending size for frame in current frame tree.");
|
debug!("Constellation: Sending size for frame in current frame tree.");
|
||||||
let source_frame = current_frame.borrow().find(pipeline_id);
|
let source_frame = current_frame.find(pipeline_id);
|
||||||
for source_frame in source_frame.iter() {
|
for source_frame in source_frame.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
let mut children = source_frame.children.get();
|
||||||
let mut tmp = source_frame.borrow().children.borrow_mut();
|
let found_child = children.mut_iter().find(|child| subpage_eq(child));
|
||||||
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child));
|
|
||||||
found_child.map(|child| update_child_rect(child, true));
|
found_child.map(|child| update_child_rect(child, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update all frames with matching pipeline- and subpage-ids
|
// Update all frames with matching pipeline- and subpage-ids
|
||||||
for frame_tree in frames.iter() {
|
for frame_tree in frames.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
let mut children = frame_tree.children.get();
|
||||||
let mut tmp = frame_tree.borrow().children.borrow_mut();
|
let found_child = children.mut_iter().find(|child| subpage_eq(child));
|
||||||
let found_child = tmp.get().mut_iter().find(|child| subpage_eq(child));
|
|
||||||
found_child.map(|child| update_child_rect(child, false));
|
found_child.map(|child| update_child_rect(child, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -575,7 +538,7 @@ impl Constellation {
|
||||||
let frame_trees: ~[Rc<FrameTree>] = {
|
let frame_trees: ~[Rc<FrameTree>] = {
|
||||||
let matching_navi_frames = self.navigation_context.find_all(source_pipeline_id);
|
let matching_navi_frames = self.navigation_context.find_all(source_pipeline_id);
|
||||||
let matching_pending_frames = self.pending_frames.iter().filter_map(|frame_change| {
|
let matching_pending_frames = self.pending_frames.iter().filter_map(|frame_change| {
|
||||||
frame_change.after.borrow().find(source_pipeline_id)
|
frame_change.after.find(source_pipeline_id)
|
||||||
});
|
});
|
||||||
matching_navi_frames.move_iter().chain(matching_pending_frames).collect()
|
matching_navi_frames.move_iter().chain(matching_pending_frames).collect()
|
||||||
};
|
};
|
||||||
|
@ -594,7 +557,7 @@ impl Constellation {
|
||||||
source Id of LoadIframeUrlMsg does have an associated pipeline in
|
source Id of LoadIframeUrlMsg does have an associated pipeline in
|
||||||
constellation. This should be impossible.").clone();
|
constellation. This should be impossible.").clone();
|
||||||
|
|
||||||
let source_url = source_pipeline.borrow().url.get().clone().expect("Constellation: LoadUrlIframeMsg's
|
let source_url = source_pipeline.url.get().clone().expect("Constellation: LoadUrlIframeMsg's
|
||||||
source's Url is None. There should never be a LoadUrlIframeMsg from a pipeline
|
source's Url is None. There should never be a LoadUrlIframeMsg from a pipeline
|
||||||
that was never given a url to load.");
|
that was never given a url to load.");
|
||||||
|
|
||||||
|
@ -631,9 +594,7 @@ impl Constellation {
|
||||||
let pipeline_wrapped = Rc::new(pipeline);
|
let pipeline_wrapped = Rc::new(pipeline);
|
||||||
let rect = self.pending_sizes.pop(&(source_pipeline_id, subpage_id));
|
let rect = self.pending_sizes.pop(&(source_pipeline_id, subpage_id));
|
||||||
for frame_tree in frame_trees.iter() {
|
for frame_tree in frame_trees.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
frame_tree.children.get().push(ChildFrameTree {
|
||||||
let mut tmp = frame_tree.borrow().children.borrow_mut();
|
|
||||||
tmp.get().push(ChildFrameTree {
|
|
||||||
frame_tree: Rc::new(FrameTree {
|
frame_tree: Rc::new(FrameTree {
|
||||||
pipeline: RefCell::new(pipeline_wrapped.clone()),
|
pipeline: RefCell::new(pipeline_wrapped.clone()),
|
||||||
parent: RefCell::new(Some(source_pipeline.clone())),
|
parent: RefCell::new(Some(source_pipeline.clone())),
|
||||||
|
@ -642,13 +603,13 @@ impl Constellation {
|
||||||
rect: rect,
|
rect: rect,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.pipelines.insert(pipeline_wrapped.borrow().id, pipeline_wrapped);
|
self.pipelines.insert(pipeline_wrapped.id, pipeline_wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_load_url_msg(&mut self, source_id: PipelineId, url: Url) {
|
fn handle_load_url_msg(&mut self, source_id: PipelineId, url: Url) {
|
||||||
debug!("Constellation: received message to load {:s}", url.to_str());
|
debug!("Constellation: received message to load {:s}", url.to_str());
|
||||||
// Make sure no pending page would be overridden.
|
// Make sure no pending page would be overridden.
|
||||||
let source_frame = self.current_frame().get_ref().borrow().find(source_id).expect(
|
let source_frame = self.current_frame().get_ref().find(source_id).expect(
|
||||||
"Constellation: received a LoadUrlMsg from a pipeline_id associated
|
"Constellation: received a LoadUrlMsg from a pipeline_id associated
|
||||||
with a pipeline not in the active frame tree. This should be
|
with a pipeline not in the active frame tree. This should be
|
||||||
impossible.");
|
impossible.");
|
||||||
|
@ -657,10 +618,10 @@ impl Constellation {
|
||||||
let old_id = frame_change.before.expect("Constellation: Received load msg
|
let old_id = frame_change.before.expect("Constellation: Received load msg
|
||||||
from pipeline, but there is no currently active page. This should
|
from pipeline, but there is no currently active page. This should
|
||||||
be impossible.");
|
be impossible.");
|
||||||
let changing_frame = self.current_frame().get_ref().borrow().find(old_id).expect("Constellation:
|
let changing_frame = self.current_frame().get_ref().find(old_id).expect("Constellation:
|
||||||
Pending change has non-active source pipeline. This should be
|
Pending change has non-active source pipeline. This should be
|
||||||
impossible.");
|
impossible.");
|
||||||
if changing_frame.borrow().contains(source_id) || source_frame.borrow().contains(old_id) {
|
if changing_frame.contains(source_id) || source_frame.contains(old_id) {
|
||||||
// id that sent load msg is being changed already; abort
|
// id that sent load msg is being changed already; abort
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -668,10 +629,8 @@ impl Constellation {
|
||||||
// Being here means either there are no pending frames, or none of the pending
|
// Being here means either there are no pending frames, or none of the pending
|
||||||
// changes would be overriden by changing the subframe associated with source_id.
|
// changes would be overriden by changing the subframe associated with source_id.
|
||||||
|
|
||||||
let parent = source_frame.borrow().parent.clone();
|
let parent = source_frame.parent.clone();
|
||||||
// NOTE: work around borrowchk issues
|
let subpage_id = source_frame.pipeline.get().subpage_id;
|
||||||
let tmp = source_frame.borrow().pipeline.borrow();
|
|
||||||
let subpage_id = tmp.get().borrow().subpage_id;
|
|
||||||
let next_pipeline_id = self.get_next_pipeline_id();
|
let next_pipeline_id = self.get_next_pipeline_id();
|
||||||
|
|
||||||
let pipeline = Pipeline::create(next_pipeline_id,
|
let pipeline = Pipeline::create(next_pipeline_id,
|
||||||
|
@ -696,7 +655,7 @@ impl Constellation {
|
||||||
}),
|
}),
|
||||||
navigation_type: constellation_msg::Load,
|
navigation_type: constellation_msg::Load,
|
||||||
});
|
});
|
||||||
self.pipelines.insert(pipeline_wrapped.borrow().id, pipeline_wrapped);
|
self.pipelines.insert(pipeline_wrapped.id, pipeline_wrapped);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_navigate_msg(&mut self, direction: constellation_msg::NavigationDirection) {
|
fn handle_navigate_msg(&mut self, direction: constellation_msg::NavigationDirection) {
|
||||||
|
@ -713,10 +672,8 @@ impl Constellation {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
let old = self.current_frame().get_ref();
|
let old = self.current_frame().get_ref();
|
||||||
for frame in old.borrow().iter() {
|
for frame in old.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
frame.pipeline.get().revoke_paint_permission();
|
||||||
let tmp = frame.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().revoke_paint_permission();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.navigation_context.forward()
|
self.navigation_context.forward()
|
||||||
|
@ -727,20 +684,16 @@ impl Constellation {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
let old = self.current_frame().get_ref();
|
let old = self.current_frame().get_ref();
|
||||||
for frame in old.borrow().iter() {
|
for frame in old.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
frame.pipeline.get().revoke_paint_permission();
|
||||||
let tmp = frame.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().revoke_paint_permission();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.navigation_context.back()
|
self.navigation_context.back()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for frame in destination_frame.borrow().iter() {
|
for frame in destination_frame.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
frame.pipeline.get().reload();
|
||||||
let pipeline = &frame.borrow().pipeline.borrow();
|
|
||||||
pipeline.get().borrow().reload();
|
|
||||||
}
|
}
|
||||||
self.grant_paint_permission(destination_frame, constellation_msg::Navigate);
|
self.grant_paint_permission(destination_frame, constellation_msg::Navigate);
|
||||||
|
|
||||||
|
@ -756,11 +709,9 @@ impl Constellation {
|
||||||
// Messages originating in the current frame are not navigations;
|
// Messages originating in the current frame are not navigations;
|
||||||
// TODO(tkuehn): In fact, this kind of message might be provably
|
// TODO(tkuehn): In fact, this kind of message might be provably
|
||||||
// impossible to occur.
|
// impossible to occur.
|
||||||
if current_frame.borrow().contains(pipeline_id) {
|
if current_frame.contains(pipeline_id) {
|
||||||
for frame in current_frame.borrow().iter() {
|
for frame in current_frame.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
frame.pipeline.get().grant_paint_permission();
|
||||||
let tmp = frame.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().grant_paint_permission();
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -770,18 +721,15 @@ impl Constellation {
|
||||||
// If it is not found, it simply means that this pipeline will not receive
|
// If it is not found, it simply means that this pipeline will not receive
|
||||||
// permission to paint.
|
// permission to paint.
|
||||||
let pending_index = self.pending_frames.iter().rposition(|frame_change| {
|
let pending_index = self.pending_frames.iter().rposition(|frame_change| {
|
||||||
// NOTE: work around borrowchk issues
|
frame_change.after.pipeline.get().id == pipeline_id
|
||||||
let tmp = frame_change.after.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().id == pipeline_id
|
|
||||||
});
|
});
|
||||||
for &pending_index in pending_index.iter() {
|
for &pending_index in pending_index.iter() {
|
||||||
let frame_change = self.pending_frames.swap_remove(pending_index);
|
let frame_change = self.pending_frames.swap_remove(pending_index).unwrap();
|
||||||
let to_add = frame_change.after.clone();
|
let to_add = frame_change.after.clone();
|
||||||
|
|
||||||
// Create the next frame tree that will be given to the compositor
|
// Create the next frame tree that will be given to the compositor
|
||||||
// NOTE: work around borrowchk issues
|
// NOTE: work around borrowchk issues
|
||||||
let tmp = to_add.borrow().parent.clone();
|
let tmp = to_add.parent.clone();
|
||||||
let tmp = tmp.borrow();
|
|
||||||
let next_frame_tree = if tmp.get().is_some() {
|
let next_frame_tree = if tmp.get().is_some() {
|
||||||
// NOTE: work around borrowchk issues
|
// NOTE: work around borrowchk issues
|
||||||
let tmp = self.current_frame().get_ref();
|
let tmp = self.current_frame().get_ref();
|
||||||
|
@ -796,14 +744,12 @@ impl Constellation {
|
||||||
debug!("Constellation: revoking permission from {:?}", revoke_id);
|
debug!("Constellation: revoking permission from {:?}", revoke_id);
|
||||||
let current_frame = self.current_frame().get_ref();
|
let current_frame = self.current_frame().get_ref();
|
||||||
|
|
||||||
let to_revoke = current_frame.borrow().find(revoke_id).expect(
|
let to_revoke = current_frame.find(revoke_id).expect(
|
||||||
"Constellation: pending frame change refers to an old
|
"Constellation: pending frame change refers to an old
|
||||||
frame not contained in the current frame. This is a bug");
|
frame not contained in the current frame. This is a bug");
|
||||||
|
|
||||||
for frame in to_revoke.borrow().iter() {
|
for frame in to_revoke.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
frame.pipeline.get().revoke_paint_permission();
|
||||||
let tmp = frame.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().revoke_paint_permission();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If to_add is not the root frame, then replace revoked_frame with it.
|
// If to_add is not the root frame, then replace revoked_frame with it.
|
||||||
|
@ -811,45 +757,30 @@ impl Constellation {
|
||||||
// NOTE: work around borrowchk issue
|
// NOTE: work around borrowchk issue
|
||||||
let mut flag = false;
|
let mut flag = false;
|
||||||
{
|
{
|
||||||
// NOTE: work around borrowchk issue
|
if to_add.parent.get().is_some() {
|
||||||
let tmp = to_add.borrow().parent.borrow();
|
|
||||||
if tmp.get().is_some() {
|
|
||||||
debug!("Constellation: replacing {:?} with {:?} in {:?}",
|
debug!("Constellation: replacing {:?} with {:?} in {:?}",
|
||||||
revoke_id, {
|
revoke_id, to_add.pipeline.get().id,
|
||||||
// NOTE: work around borrowchk issues
|
next_frame_tree.pipeline.get().id);
|
||||||
let tmp = to_add.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().id
|
|
||||||
}, {
|
|
||||||
// NOTE: work around borrowchk issues
|
|
||||||
let tmp = next_frame_tree.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().id
|
|
||||||
});
|
|
||||||
flag = true;
|
flag = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if flag {
|
if flag {
|
||||||
next_frame_tree.borrow().replace_child(revoke_id, to_add);
|
next_frame_tree.replace_child(revoke_id, to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None => {
|
None => {
|
||||||
// Add to_add to parent's children, if it is not the root
|
// Add to_add to parent's children, if it is not the root
|
||||||
let parent = &to_add.borrow().parent;
|
let parent = &to_add.parent;
|
||||||
// NOTE: work around borrowchk issue
|
for parent in parent.get().iter() {
|
||||||
let tmp = parent.borrow();
|
let subpage_id = to_add.pipeline.get().subpage_id
|
||||||
for parent in tmp.get().iter() {
|
|
||||||
// NOTE: work around borrowchk issues
|
|
||||||
let tmp = to_add.borrow().pipeline.borrow();
|
|
||||||
let subpage_id = tmp.get().borrow().subpage_id
|
|
||||||
.expect("Constellation:
|
.expect("Constellation:
|
||||||
Child frame's subpage id is None. This should be impossible.");
|
Child frame's subpage id is None. This should be impossible.");
|
||||||
let rect = self.pending_sizes.pop(&(parent.borrow().id, subpage_id));
|
let rect = self.pending_sizes.pop(&(parent.id, subpage_id));
|
||||||
let parent = next_frame_tree.borrow().find(parent.borrow().id).expect(
|
let parent = next_frame_tree.find(parent.id).expect(
|
||||||
"Constellation: pending frame has a parent frame that is not
|
"Constellation: pending frame has a parent frame that is not
|
||||||
active. This is a bug.");
|
active. This is a bug.");
|
||||||
// NOTE: work around borrowchk issue
|
parent.children.get().push(ChildFrameTree {
|
||||||
let mut tmp = parent.borrow().children.borrow_mut();
|
|
||||||
tmp.get().push(ChildFrameTree {
|
|
||||||
frame_tree: to_add.clone(),
|
frame_tree: to_add.clone(),
|
||||||
rect: rect,
|
rect: rect,
|
||||||
});
|
});
|
||||||
|
@ -866,18 +797,14 @@ impl Constellation {
|
||||||
let mut already_seen = HashSet::new();
|
let mut already_seen = HashSet::new();
|
||||||
for frame_tree in self.current_frame().iter() {
|
for frame_tree in self.current_frame().iter() {
|
||||||
debug!("constellation sending resize message to active frame");
|
debug!("constellation sending resize message to active frame");
|
||||||
// NOTE: work around borrowchk issues
|
let pipeline = &frame_tree.pipeline.get();
|
||||||
let tmp = frame_tree.borrow().pipeline.borrow();
|
|
||||||
let pipeline = tmp.get().borrow();
|
|
||||||
let ScriptChan(ref chan) = pipeline.script_chan;
|
let ScriptChan(ref chan) = pipeline.script_chan;
|
||||||
chan.try_send(ResizeMsg(pipeline.id, new_size));
|
chan.try_send(ResizeMsg(pipeline.id, new_size));
|
||||||
already_seen.insert(pipeline.id);
|
already_seen.insert(pipeline.id);
|
||||||
}
|
}
|
||||||
for frame_tree in self.navigation_context.previous.iter()
|
for frame_tree in self.navigation_context.previous.iter()
|
||||||
.chain(self.navigation_context.next.iter()) {
|
.chain(self.navigation_context.next.iter()) {
|
||||||
// NOTE: work around borrowchk issues
|
let pipeline = &frame_tree.pipeline.get();
|
||||||
let tmp = frame_tree.borrow().pipeline.borrow();
|
|
||||||
let pipeline = &tmp.get().borrow();
|
|
||||||
if !already_seen.contains(&pipeline.id) {
|
if !already_seen.contains(&pipeline.id) {
|
||||||
debug!("constellation sending resize message to inactive frame");
|
debug!("constellation sending resize message to inactive frame");
|
||||||
let ScriptChan(ref chan) = pipeline.script_chan;
|
let ScriptChan(ref chan) = pipeline.script_chan;
|
||||||
|
@ -889,14 +816,10 @@ impl Constellation {
|
||||||
// If there are any pending outermost frames, then tell them to resize. (This is how the
|
// If there are any pending outermost frames, then tell them to resize. (This is how the
|
||||||
// initial window size gets sent to the first page loaded, giving it permission to reflow.)
|
// initial window size gets sent to the first page loaded, giving it permission to reflow.)
|
||||||
for change in self.pending_frames.iter() {
|
for change in self.pending_frames.iter() {
|
||||||
let frame_tree = change.after.borrow();
|
let frame_tree = &change.after;
|
||||||
// NOTE: work around borrowchk issue
|
if frame_tree.parent.get().is_none() {
|
||||||
let tmp = frame_tree.parent.borrow();
|
|
||||||
if tmp.get().is_none() {
|
|
||||||
debug!("constellation sending resize message to pending outer frame");
|
debug!("constellation sending resize message to pending outer frame");
|
||||||
// NOTE: work around borrowchk issues
|
let pipeline = frame_tree.pipeline.get();
|
||||||
let tmp = frame_tree.pipeline.borrow();
|
|
||||||
let pipeline = tmp.get().borrow();
|
|
||||||
let ScriptChan(ref chan) = pipeline.script_chan;
|
let ScriptChan(ref chan) = pipeline.script_chan;
|
||||||
chan.send(ResizeMsg(pipeline.id, new_size))
|
chan.send(ResizeMsg(pipeline.id, new_size))
|
||||||
}
|
}
|
||||||
|
@ -909,10 +832,8 @@ impl Constellation {
|
||||||
fn close_pipelines(&mut self, frame_tree: Rc<FrameTree>) {
|
fn close_pipelines(&mut self, frame_tree: Rc<FrameTree>) {
|
||||||
// TODO(tkuehn): should only exit once per unique script task,
|
// TODO(tkuehn): should only exit once per unique script task,
|
||||||
// and then that script task will handle sub-exits
|
// and then that script task will handle sub-exits
|
||||||
for frame_tree in frame_tree.borrow().iter() {
|
for frame_tree in frame_tree.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
let pipeline = frame_tree.pipeline.get();
|
||||||
let tmp = frame_tree.borrow().pipeline.borrow();
|
|
||||||
let pipeline = tmp.get().borrow();
|
|
||||||
pipeline.exit();
|
pipeline.exit();
|
||||||
self.pipelines.remove(&pipeline.id);
|
self.pipelines.remove(&pipeline.id);
|
||||||
}
|
}
|
||||||
|
@ -920,16 +841,12 @@ impl Constellation {
|
||||||
|
|
||||||
fn handle_evicted_frames(&mut self, evicted: ~[Rc<FrameTree>]) {
|
fn handle_evicted_frames(&mut self, evicted: ~[Rc<FrameTree>]) {
|
||||||
for frame_tree in evicted.iter() {
|
for frame_tree in evicted.iter() {
|
||||||
// NOTE: work around borrowchk issues
|
if !self.navigation_context.contains(frame_tree.pipeline.get().id) {
|
||||||
let tmp = frame_tree.borrow().pipeline.borrow();
|
|
||||||
if !self.navigation_context.contains(tmp.get().borrow().id) {
|
|
||||||
self.close_pipelines(frame_tree.clone());
|
self.close_pipelines(frame_tree.clone());
|
||||||
} else {
|
} else {
|
||||||
// NOTE: work around borrowchk issue
|
let frames = frame_tree.children.get().iter()
|
||||||
let tmp = frame_tree.borrow().children.borrow();
|
.map(|child| child.frame_tree.clone()).collect();
|
||||||
let mut frames = tmp.get().iter()
|
self.handle_evicted_frames(frames);
|
||||||
.map(|child| child.frame_tree.clone());
|
|
||||||
self.handle_evicted_frames(frames.collect());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -951,16 +868,14 @@ impl Constellation {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_ids(&self, frame_tree: &Rc<FrameTree>) {
|
fn set_ids(&self, frame_tree: &Rc<FrameTree>) {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
debug!("Constellation sending SetIds");
|
debug!("Constellation sending SetIds");
|
||||||
self.compositor_chan.send(SetIds(frame_tree.borrow().to_sendable(), chan, self.chan.clone()));
|
self.compositor_chan.send(SetIds(frame_tree.to_sendable(), chan, self.chan.clone()));
|
||||||
match port.recv_opt() {
|
match port.recv_opt() {
|
||||||
Some(()) => {
|
Some(()) => {
|
||||||
let mut iter = frame_tree.borrow().iter();
|
let mut iter = frame_tree.iter();
|
||||||
for frame in iter {
|
for frame in iter {
|
||||||
// NOTE: work around borrowchk issues
|
frame.pipeline.get().grant_paint_permission();
|
||||||
let tmp = frame.borrow().pipeline.borrow();
|
|
||||||
tmp.get().borrow().grant_paint_permission();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {} // message has been discarded, probably shutting down
|
None => {} // message has been discarded, probably shutting down
|
||||||
|
|
|
@ -18,7 +18,7 @@ use servo_util::smallvec::{SmallVec, SmallVec0, SmallVec16};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::hash::{Hash, sip};
|
use std::hash::{Hash, sip};
|
||||||
use std::vec::Items;
|
use std::slice::Items;
|
||||||
use style::{After, Before, ComputedValues, MatchedProperty, Stylist, TElement, TNode, cascade};
|
use style::{After, Before, ComputedValues, MatchedProperty, Stylist, TElement, TNode, cascade};
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
|
@ -458,13 +458,8 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
||||||
Some(shared_style) => {
|
Some(shared_style) => {
|
||||||
// Yay, cache hit. Share the style.
|
// Yay, cache hit. Share the style.
|
||||||
let mut layout_data_ref = self.mutate_layout_data();
|
let mut layout_data_ref = self.mutate_layout_data();
|
||||||
match *layout_data_ref.get() {
|
layout_data_ref.get_mut_ref().data.style = Some(shared_style);
|
||||||
None => fail!(),
|
return StyleWasShared(i)
|
||||||
Some(ref mut layout_data_ref) => {
|
|
||||||
layout_data_ref.data.style = Some(shared_style);
|
|
||||||
return StyleWasShared(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
@ -558,9 +553,9 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut layout_data_ref = self.mutate_layout_data();
|
let mut layout_data_ref = self.mutate_layout_data();
|
||||||
match *layout_data_ref.get() {
|
match &mut *layout_data_ref {
|
||||||
None => fail!("no layout data"),
|
&None => fail!("no layout data"),
|
||||||
Some(ref mut layout_data) => {
|
&Some(ref mut layout_data) => {
|
||||||
self.cascade_node_pseudo_element(parent_style,
|
self.cascade_node_pseudo_element(parent_style,
|
||||||
applicable_declarations.normal.as_slice(),
|
applicable_declarations.normal.as_slice(),
|
||||||
&mut layout_data.data.style,
|
&mut layout_data.data.style,
|
||||||
|
|
|
@ -27,8 +27,7 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
|
||||||
let layout_data_ref = self.borrow_layout_data();
|
let layout_data_ref = self.borrow_layout_data();
|
||||||
match self.get_element_type() {
|
match self.get_element_type() {
|
||||||
Before | BeforeBlock => {
|
Before | BeforeBlock => {
|
||||||
cast::transmute_region(layout_data_ref.get()
|
cast::transmute_region(layout_data_ref.as_ref()
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.data
|
.data
|
||||||
.before_style
|
.before_style
|
||||||
|
@ -36,8 +35,7 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
|
||||||
.unwrap())
|
.unwrap())
|
||||||
}
|
}
|
||||||
After | AfterBlock => {
|
After | AfterBlock => {
|
||||||
cast::transmute_region(layout_data_ref.get()
|
cast::transmute_region(layout_data_ref.as_ref()
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.data
|
.data
|
||||||
.after_style
|
.after_style
|
||||||
|
@ -45,8 +43,7 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
|
||||||
.unwrap())
|
.unwrap())
|
||||||
}
|
}
|
||||||
Normal => {
|
Normal => {
|
||||||
cast::transmute_region(layout_data_ref.get()
|
cast::transmute_region(layout_data_ref.as_ref()
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.data
|
.data
|
||||||
.style
|
.style
|
||||||
|
@ -60,7 +57,7 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
|
||||||
/// Does this node have a computed style yet?
|
/// Does this node have a computed style yet?
|
||||||
fn have_css_select_results(&self) -> bool {
|
fn have_css_select_results(&self) -> bool {
|
||||||
let layout_data_ref = self.borrow_layout_data();
|
let layout_data_ref = self.borrow_layout_data();
|
||||||
layout_data_ref.get().get_ref().data.style.is_some()
|
layout_data_ref.get_ref().data.style.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the description of how to account for recent style changes.
|
/// Get the description of how to account for recent style changes.
|
||||||
|
@ -76,7 +73,6 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
|
||||||
|
|
||||||
let layout_data_ref = self.borrow_layout_data();
|
let layout_data_ref = self.borrow_layout_data();
|
||||||
layout_data_ref
|
layout_data_ref
|
||||||
.get()
|
|
||||||
.get_ref()
|
.get_ref()
|
||||||
.data
|
.data
|
||||||
.restyle_damage
|
.restyle_damage
|
||||||
|
@ -87,8 +83,8 @@ impl<'ln> NodeUtil for ThreadSafeLayoutNode<'ln> {
|
||||||
/// Set the restyle damage field.
|
/// Set the restyle damage field.
|
||||||
fn set_restyle_damage(&self, damage: RestyleDamage) {
|
fn set_restyle_damage(&self, damage: RestyleDamage) {
|
||||||
let mut layout_data_ref = self.mutate_layout_data();
|
let mut layout_data_ref = self.mutate_layout_data();
|
||||||
match *layout_data_ref.get() {
|
match &mut *layout_data_ref {
|
||||||
Some(ref mut layout_data) => layout_data.data.restyle_damage = Some(damage.to_int()),
|
&Some(ref mut layout_data) => layout_data.data.restyle_damage = Some(damage.to_int()),
|
||||||
_ => fail!("no layout data for this node"),
|
_ => fail!("no layout data for this node"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use style::{Stylesheet, Stylist, UserAgentOrigin, with_errors_silenced};
|
use style::{Stylesheet, Stylist, UserAgentOrigin, with_errors_silenced};
|
||||||
use extra::url;
|
use url;
|
||||||
|
|
||||||
|
|
||||||
pub fn new_stylist() -> Stylist {
|
pub fn new_stylist() -> Stylist {
|
||||||
|
|
|
@ -755,7 +755,7 @@ impl BlockFlow {
|
||||||
// Consume all the static y-offsets bubbled up by kid.
|
// Consume all the static y-offsets bubbled up by kid.
|
||||||
for y_offset in kid_base.abs_descendants.static_y_offsets.move_iter() {
|
for y_offset in kid_base.abs_descendants.static_y_offsets.move_iter() {
|
||||||
// The offsets are wrt the kid flow box. Translate them to current flow.
|
// The offsets are wrt the kid flow box. Translate them to current flow.
|
||||||
y_offset = y_offset + kid_base.position.origin.y;
|
let y_offset = y_offset + kid_base.position.origin.y;
|
||||||
abs_descendant_y_offsets.push(y_offset);
|
abs_descendant_y_offsets.push(y_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1533,10 +1533,6 @@ impl Flow for BlockFlow {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_store_overflow_delayed(&mut self) -> bool {
|
|
||||||
self.is_absolutely_positioned()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Recursively (bottom-up) determine the context's preferred and
|
/* Recursively (bottom-up) determine the context's preferred and
|
||||||
minimum widths. When called on this context, all child contexts
|
minimum widths. When called on this context, all child contexts
|
||||||
have had their min/pref widths set. This function must decide
|
have had their min/pref widths set. This function must decide
|
||||||
|
@ -1897,10 +1893,10 @@ pub trait WidthAndMarginsComputer {
|
||||||
// The associated box is the border box of this flow.
|
// The associated box is the border box of this flow.
|
||||||
let mut position_ref = box_.border_box.borrow_mut();
|
let mut position_ref = box_.border_box.borrow_mut();
|
||||||
// Left border edge.
|
// Left border edge.
|
||||||
position_ref.get().origin.x = box_.margin.get().left;
|
position_ref.origin.x = box_.margin.borrow().left;
|
||||||
|
|
||||||
// Border box width
|
// Border box width
|
||||||
position_ref.get().size.width = solution.width + box_.noncontent_width();
|
position_ref.size.width = solution.width + box_.noncontent_width();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the x coordinate of the given flow if it is absolutely positioned.
|
/// Set the x coordinate of the given flow if it is absolutely positioned.
|
||||||
|
|
|
@ -16,7 +16,6 @@ use layout::model;
|
||||||
use layout::util::OpaqueNodeMethods;
|
use layout::util::OpaqueNodeMethods;
|
||||||
use layout::wrapper::{TLayoutNode, ThreadSafeLayoutNode};
|
use layout::wrapper::{TLayoutNode, ThreadSafeLayoutNode};
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use sync::{MutexArc, Arc};
|
use sync::{MutexArc, Arc};
|
||||||
use geom::{Point2D, Rect, Size2D, SideOffsets2D};
|
use geom::{Point2D, Rect, Size2D, SideOffsets2D};
|
||||||
use geom::approxeq::ApproxEq;
|
use geom::approxeq::ApproxEq;
|
||||||
|
@ -40,12 +39,14 @@ use servo_util::smallvec::{SmallVec, SmallVec0};
|
||||||
use servo_util::str::is_whitespace;
|
use servo_util::str::is_whitespace;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::from_str::FromStr;
|
||||||
use std::num::Zero;
|
use std::num::Zero;
|
||||||
use style::{ComputedValues, TElement, TNode, cascade, initial_values};
|
use style::{ComputedValues, TElement, TNode, cascade, initial_values};
|
||||||
use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto, overflow, LPA_Auto};
|
use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto, overflow, LPA_Auto};
|
||||||
use style::computed_values::{background_attachment, background_repeat, border_style, clear};
|
use style::computed_values::{background_attachment, background_repeat, border_style, clear};
|
||||||
use style::computed_values::{font_family, line_height, position, text_align, text_decoration};
|
use style::computed_values::{font_family, line_height, position, text_align, text_decoration};
|
||||||
use style::computed_values::{vertical_align, visibility, white_space};
|
use style::computed_values::{vertical_align, visibility, white_space};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
/// Boxes (`struct Box`) are the leaves of the layout tree. They cannot position themselves. In
|
/// Boxes (`struct Box`) are the leaves of the layout tree. They cannot position themselves. In
|
||||||
/// general, boxes do not have a simple correspondence with CSS boxes in the specification:
|
/// general, boxes do not have a simple correspondence with CSS boxes in the specification:
|
||||||
|
@ -157,7 +158,7 @@ impl ImageBoxInfo {
|
||||||
|
|
||||||
/// Returns the calculated width of the image, accounting for the width attribute.
|
/// Returns the calculated width of the image, accounting for the width attribute.
|
||||||
pub fn computed_width(&self) -> Au {
|
pub fn computed_width(&self) -> Au {
|
||||||
match self.computed_width.borrow().get() {
|
match &*self.computed_width.borrow() {
|
||||||
&Some(width) => {
|
&Some(width) => {
|
||||||
width
|
width
|
||||||
},
|
},
|
||||||
|
@ -169,7 +170,7 @@ impl ImageBoxInfo {
|
||||||
/// Returns width of image(just original width)
|
/// Returns width of image(just original width)
|
||||||
pub fn image_width(&self) -> Au {
|
pub fn image_width(&self) -> Au {
|
||||||
let mut image_ref = self.image.borrow_mut();
|
let mut image_ref = self.image.borrow_mut();
|
||||||
Au::from_px(image_ref.get().get_size().unwrap_or(Size2D(0,0)).width)
|
Au::from_px(image_ref.get_size().unwrap_or(Size2D(0,0)).width)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return used value for width or height.
|
// Return used value for width or height.
|
||||||
|
@ -193,7 +194,7 @@ impl ImageBoxInfo {
|
||||||
}
|
}
|
||||||
/// Returns the calculated height of the image, accounting for the height attribute.
|
/// Returns the calculated height of the image, accounting for the height attribute.
|
||||||
pub fn computed_height(&self) -> Au {
|
pub fn computed_height(&self) -> Au {
|
||||||
match self.computed_height.borrow().get() {
|
match &*self.computed_height.borrow() {
|
||||||
&Some(height) => {
|
&Some(height) => {
|
||||||
height
|
height
|
||||||
},
|
},
|
||||||
|
@ -206,7 +207,7 @@ impl ImageBoxInfo {
|
||||||
/// Returns height of image(just original height)
|
/// Returns height of image(just original height)
|
||||||
pub fn image_height(&self) -> Au {
|
pub fn image_height(&self) -> Au {
|
||||||
let mut image_ref = self.image.borrow_mut();
|
let mut image_ref = self.image.borrow_mut();
|
||||||
Au::from_px(image_ref.get().get_size().unwrap_or(Size2D(0,0)).height)
|
Au::from_px(image_ref.get_size().unwrap_or(Size2D(0,0)).height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +354,7 @@ macro_rules! def_noncontent( ($side:ident, $get:ident, $inline_get:ident) => (
|
||||||
pub fn $inline_get(&self) -> Au {
|
pub fn $inline_get(&self) -> Au {
|
||||||
let mut val = Au::new(0);
|
let mut val = Au::new(0);
|
||||||
let info = self.inline_info.borrow();
|
let info = self.inline_info.borrow();
|
||||||
match info.get() {
|
match &*info {
|
||||||
&Some(ref info) => {
|
&Some(ref info) => {
|
||||||
for info in info.parent_info.iter() {
|
for info in info.parent_info.iter() {
|
||||||
val = val + info.border.$side + info.padding.$side;
|
val = val + info.border.$side + info.padding.$side;
|
||||||
|
@ -372,9 +373,9 @@ macro_rules! def_noncontent_horiz( ($side:ident, $merge:ident, $clear:ident) =>
|
||||||
let mut info = self.inline_info.borrow_mut();
|
let mut info = self.inline_info.borrow_mut();
|
||||||
let other_info = other_box.inline_info.borrow();
|
let other_info = other_box.inline_info.borrow();
|
||||||
|
|
||||||
match other_info.get() {
|
match &*other_info {
|
||||||
&Some(ref other_info) => {
|
&Some(ref other_info) => {
|
||||||
match info.get() {
|
match &mut *info {
|
||||||
&Some(ref mut info) => {
|
&Some(ref mut info) => {
|
||||||
for other_item in other_info.parent_info.iter() {
|
for other_item in other_info.parent_info.iter() {
|
||||||
for item in info.parent_info.mut_iter() {
|
for item in info.parent_info.mut_iter() {
|
||||||
|
@ -396,7 +397,7 @@ macro_rules! def_noncontent_horiz( ($side:ident, $merge:ident, $clear:ident) =>
|
||||||
|
|
||||||
pub fn $clear(&self) {
|
pub fn $clear(&self) {
|
||||||
let mut info = self.inline_info.borrow_mut();
|
let mut info = self.inline_info.borrow_mut();
|
||||||
match info.get() {
|
match &mut *info {
|
||||||
&Some(ref mut info) => {
|
&Some(ref mut info) => {
|
||||||
for item in info.parent_info.mut_iter() {
|
for item in info.parent_info.mut_iter() {
|
||||||
item.border.$side = Au::new(0);
|
item.border.$side = Au::new(0);
|
||||||
|
@ -807,7 +808,7 @@ impl Box {
|
||||||
|
|
||||||
// Go over the ancestor boxes and add all relative offsets (if any).
|
// Go over the ancestor boxes and add all relative offsets (if any).
|
||||||
let info = self.inline_info.borrow();
|
let info = self.inline_info.borrow();
|
||||||
match info.get() {
|
match &*info {
|
||||||
&Some(ref info) => {
|
&Some(ref info) => {
|
||||||
for info in info.parent_info.iter() {
|
for info in info.parent_info.iter() {
|
||||||
if info.style.get().Box.get().position == position::relative {
|
if info.style.get().Box.get().position == position::relative {
|
||||||
|
@ -959,7 +960,7 @@ impl Box {
|
||||||
// inefficient. What we really want is something like "nearest ancestor element that
|
// inefficient. What we really want is something like "nearest ancestor element that
|
||||||
// doesn't have a box".
|
// doesn't have a box".
|
||||||
let info = self.inline_info.borrow();
|
let info = self.inline_info.borrow();
|
||||||
match info.get() {
|
match &*info {
|
||||||
&Some(ref box_info) => {
|
&Some(ref box_info) => {
|
||||||
let mut bg_rect = absolute_bounds.clone();
|
let mut bg_rect = absolute_bounds.clone();
|
||||||
for info in box_info.parent_info.as_slice().rev_iter() {
|
for info in box_info.parent_info.as_slice().rev_iter() {
|
||||||
|
@ -972,10 +973,10 @@ impl Box {
|
||||||
if !background_color.alpha.approx_eq(&0.0) {
|
if !background_color.alpha.approx_eq(&0.0) {
|
||||||
let solid_color_display_item = ~SolidColorDisplayItem {
|
let solid_color_display_item = ~SolidColorDisplayItem {
|
||||||
base: BaseDisplayItem {
|
base: BaseDisplayItem {
|
||||||
bounds: bg_rect.clone(),
|
bounds: bg_rect.clone(),
|
||||||
node: self.node,
|
node: self.node,
|
||||||
},
|
},
|
||||||
color: background_color.to_gfx_color(),
|
color: background_color.to_gfx_color(),
|
||||||
};
|
};
|
||||||
|
|
||||||
list.push(SolidColorDisplayItemClass(solid_color_display_item))
|
list.push(SolidColorDisplayItemClass(solid_color_display_item))
|
||||||
|
@ -1312,7 +1313,7 @@ impl Box {
|
||||||
let mut flow_flags = flow::base(flow).flags_info.clone();
|
let mut flow_flags = flow::base(flow).flags_info.clone();
|
||||||
|
|
||||||
let inline_info = self.inline_info.borrow();
|
let inline_info = self.inline_info.borrow();
|
||||||
match inline_info.get() {
|
match &*inline_info {
|
||||||
&Some(ref info) => {
|
&Some(ref info) => {
|
||||||
for data in info.parent_info.as_slice().rev_iter() {
|
for data in info.parent_info.as_slice().rev_iter() {
|
||||||
let parent_info = FlowFlagsInfo::new(data.style.get());
|
let parent_info = FlowFlagsInfo::new(data.style.get());
|
||||||
|
@ -1385,7 +1386,7 @@ impl Box {
|
||||||
- self.noncontent_inline_right();
|
- self.noncontent_inline_right();
|
||||||
bounds.size.height = bounds.size.height - self.noncontent_height();
|
bounds.size.height = bounds.size.height - self.noncontent_height();
|
||||||
|
|
||||||
match image_ref.get().get_image() {
|
match image_ref.get_image() {
|
||||||
Some(image) => {
|
Some(image) => {
|
||||||
debug!("(building display list) building image box");
|
debug!("(building display list) building image box");
|
||||||
|
|
||||||
|
@ -1716,7 +1717,7 @@ impl Box {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut position = self.border_box.borrow_mut();
|
let mut position = self.border_box.borrow_mut();
|
||||||
position.get().size.width = width + self.noncontent_width() +
|
position.size.width = width + self.noncontent_width() +
|
||||||
self.noncontent_inline_left() + self.noncontent_inline_right();
|
self.noncontent_inline_left() + self.noncontent_inline_right();
|
||||||
image_box_info.computed_width.set(Some(width));
|
image_box_info.computed_width.set(Some(width));
|
||||||
}
|
}
|
||||||
|
@ -1724,7 +1725,7 @@ impl Box {
|
||||||
// Scanned text boxes will have already had their
|
// Scanned text boxes will have already had their
|
||||||
// content_widths assigned by this point.
|
// content_widths assigned by this point.
|
||||||
let mut position = self.border_box.borrow_mut();
|
let mut position = self.border_box.borrow_mut();
|
||||||
position.get().size.width = position.get().size.width + self.noncontent_width() +
|
position.size.width = position.size.width + self.noncontent_width() +
|
||||||
self.noncontent_inline_left() + self.noncontent_inline_right();
|
self.noncontent_inline_left() + self.noncontent_inline_right();
|
||||||
}
|
}
|
||||||
TableColumnBox(_) => fail!("Table column boxes do not have width"),
|
TableColumnBox(_) => fail!("Table column boxes do not have width"),
|
||||||
|
@ -1766,15 +1767,15 @@ impl Box {
|
||||||
|
|
||||||
let mut position = self.border_box.borrow_mut();
|
let mut position = self.border_box.borrow_mut();
|
||||||
image_box_info.computed_height.set(Some(height));
|
image_box_info.computed_height.set(Some(height));
|
||||||
position.get().size.height = height + self.noncontent_height()
|
position.size.height = height + self.noncontent_height()
|
||||||
}
|
}
|
||||||
ScannedTextBox(_) => {
|
ScannedTextBox(_) => {
|
||||||
// Scanned text boxes will have already had their widths assigned by this point
|
// Scanned text boxes will have already had their widths assigned by this point
|
||||||
let mut position = self.border_box.borrow_mut();
|
let mut position = self.border_box.borrow_mut();
|
||||||
// Scanned text boxes' content heights are calculated by the
|
// Scanned text boxes' content heights are calculated by the
|
||||||
// text run scanner during Flow construction.
|
// text run scanner during Flow construction.
|
||||||
position.get().size.height
|
position.size.height
|
||||||
= position.get().size.height + self.noncontent_height()
|
= position.size.height + self.noncontent_height()
|
||||||
}
|
}
|
||||||
TableColumnBox(_) => fail!("Table column boxes do not have height"),
|
TableColumnBox(_) => fail!("Table column boxes do not have height"),
|
||||||
UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"),
|
UnscannedTextBox(_) => fail!("Unscanned text boxes should have been scanned by now!"),
|
||||||
|
|
|
@ -44,7 +44,6 @@ use layout::util::{LayoutDataAccess, OpaqueNodeMethods};
|
||||||
use layout::wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
|
use layout::wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
|
||||||
use layout::wrapper::{Before, BeforeBlock, After, AfterBlock, Normal};
|
use layout::wrapper::{Before, BeforeBlock, After, AfterBlock, Normal};
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use gfx::display_list::OpaqueNode;
|
use gfx::display_list::OpaqueNode;
|
||||||
use gfx::font_context::FontContext;
|
use gfx::font_context::FontContext;
|
||||||
use script::dom::bindings::codegen::InheritTypes::TextCast;
|
use script::dom::bindings::codegen::InheritTypes::TextCast;
|
||||||
|
@ -68,6 +67,7 @@ use std::num::Zero;
|
||||||
use style::ComputedValues;
|
use style::ComputedValues;
|
||||||
use style::computed_values::{display, position, float, white_space};
|
use style::computed_values::{display, position, float, white_space};
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
/// The results of flow construction for a DOM node.
|
/// The results of flow construction for a DOM node.
|
||||||
pub enum ConstructionResult {
|
pub enum ConstructionResult {
|
||||||
|
@ -683,11 +683,11 @@ impl<'a> FlowConstructor<'a> {
|
||||||
let parent_box = Box::new(self, parent_node);
|
let parent_box = Box::new(self, parent_node);
|
||||||
let font_style = parent_box.font_style();
|
let font_style = parent_box.font_style();
|
||||||
let font_group = self.font_context().get_resolved_font_for_style(&font_style);
|
let font_group = self.font_context().get_resolved_font_for_style(&font_style);
|
||||||
let (font_ascent,font_descent) = font_group.borrow().with_mut( |fg| {
|
let (font_ascent,font_descent) = {
|
||||||
fg.fonts[0].borrow().with_mut( |font| {
|
let fg = font_group.borrow();
|
||||||
(font.metrics.ascent,font.metrics.descent)
|
let font = fg.fonts[0].borrow();
|
||||||
})
|
(font.metrics.ascent,font.metrics.descent)
|
||||||
});
|
};
|
||||||
|
|
||||||
let boxes_len = boxes.len();
|
let boxes_len = boxes.len();
|
||||||
parent_box.compute_borders(parent_box.style());
|
parent_box.compute_borders(parent_box.style());
|
||||||
|
@ -697,8 +697,9 @@ impl<'a> FlowConstructor<'a> {
|
||||||
parent_box.compute_padding(parent_box.style(), Au(0));
|
parent_box.compute_padding(parent_box.style(), Au(0));
|
||||||
|
|
||||||
for (i, box_) in boxes.iter().enumerate() {
|
for (i, box_) in boxes.iter().enumerate() {
|
||||||
if box_.inline_info.with( |data| data.is_none() ) {
|
let mut info = box_.inline_info.borrow_mut();
|
||||||
box_.inline_info.set(Some(InlineInfo::new()));
|
if info.is_none() {
|
||||||
|
*info = Some(InlineInfo::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut border = parent_box.border.get();
|
let mut border = parent_box.border.get();
|
||||||
|
@ -712,8 +713,7 @@ impl<'a> FlowConstructor<'a> {
|
||||||
padding.right = Zero::zero()
|
padding.right = Zero::zero()
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut info = box_.inline_info.borrow_mut();
|
match &mut *info {
|
||||||
match info.get() {
|
|
||||||
&Some(ref mut info) => {
|
&Some(ref mut info) => {
|
||||||
// TODO(ksh8281): Compute margins.
|
// TODO(ksh8281): Compute margins.
|
||||||
info.parent_info.push(InlineParentInfo {
|
info.parent_info.push(InlineParentInfo {
|
||||||
|
@ -1122,8 +1122,8 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_flow_construction_result(&self, result: ConstructionResult) {
|
fn set_flow_construction_result(&self, result: ConstructionResult) {
|
||||||
let mut layout_data_ref = self.mutate_layout_data();
|
let mut layout_data_ref = self.mutate_layout_data();
|
||||||
match *layout_data_ref.get() {
|
match &mut *layout_data_ref {
|
||||||
Some(ref mut layout_data) =>{
|
&Some(ref mut layout_data) =>{
|
||||||
match self.get_element_type() {
|
match self.get_element_type() {
|
||||||
Before | BeforeBlock => {
|
Before | BeforeBlock => {
|
||||||
layout_data.data.before_flow_construction_result = result
|
layout_data.data.before_flow_construction_result = result
|
||||||
|
@ -1134,15 +1134,15 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
|
||||||
Normal => layout_data.data.flow_construction_result = result,
|
Normal => layout_data.data.flow_construction_result = result,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => fail!("no layout data"),
|
&None => fail!("no layout data"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn swap_out_construction_result(&self) -> ConstructionResult {
|
fn swap_out_construction_result(&self) -> ConstructionResult {
|
||||||
let mut layout_data_ref = self.mutate_layout_data();
|
let mut layout_data_ref = self.mutate_layout_data();
|
||||||
match *layout_data_ref.get() {
|
match &mut *layout_data_ref {
|
||||||
Some(ref mut layout_data) => {
|
&Some(ref mut layout_data) => {
|
||||||
match self.get_element_type() {
|
match self.get_element_type() {
|
||||||
Before | BeforeBlock => {
|
Before | BeforeBlock => {
|
||||||
mem::replace(&mut layout_data.data.before_flow_construction_result,
|
mem::replace(&mut layout_data.data.before_flow_construction_result,
|
||||||
|
@ -1158,7 +1158,7 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => fail!("no layout data"),
|
&None => fail!("no layout data"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
|
use css::matching::{ApplicableDeclarationsCache, StyleSharingCandidateCache};
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use gfx::display_list::OpaqueNode;
|
use gfx::display_list::OpaqueNode;
|
||||||
use gfx::font_context::{FontContext, FontContextInfo};
|
use gfx::font_context::{FontContext, FontContextInfo};
|
||||||
|
@ -23,6 +22,7 @@ use std::rt::local::Local;
|
||||||
use std::rt::task::Task;
|
use std::rt::task::Task;
|
||||||
use style::{ComputedValues, Stylist};
|
use style::{ComputedValues, Stylist};
|
||||||
use sync::{Arc, MutexArc};
|
use sync::{Arc, MutexArc};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[thread_local]
|
#[thread_local]
|
||||||
static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext;
|
static mut FONT_CONTEXT: *mut FontContext = 0 as *mut FontContext;
|
||||||
|
|
|
@ -20,9 +20,9 @@ impl<'ln> LayoutAuxMethods for LayoutNode<'ln> {
|
||||||
/// FIXME(pcwalton): Do this as part of box building instead of in a traversal.
|
/// FIXME(pcwalton): Do this as part of box building instead of in a traversal.
|
||||||
fn initialize_layout_data(&self, chan: LayoutChan) {
|
fn initialize_layout_data(&self, chan: LayoutChan) {
|
||||||
let mut layout_data_ref = self.mutate_layout_data();
|
let mut layout_data_ref = self.mutate_layout_data();
|
||||||
match *layout_data_ref.get() {
|
match *layout_data_ref {
|
||||||
None => {
|
None => {
|
||||||
*layout_data_ref.get() = Some(LayoutDataWrapper {
|
*layout_data_ref = Some(LayoutDataWrapper {
|
||||||
chan: Some(chan),
|
chan: Some(chan),
|
||||||
data: ~PrivateLayoutData::new(),
|
data: ~PrivateLayoutData::new(),
|
||||||
});
|
});
|
||||||
|
|
|
@ -59,7 +59,7 @@ use servo_util::smallvec::{SmallVec, SmallVec0};
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::iter::Zip;
|
use std::iter::Zip;
|
||||||
use std::sync::atomics::Relaxed;
|
use std::sync::atomics::Relaxed;
|
||||||
use std::vec::MutItems;
|
use std::slice::MutItems;
|
||||||
use style::ComputedValues;
|
use style::ComputedValues;
|
||||||
use style::computed_values::{clear, position, text_align};
|
use style::computed_values::{clear, position, text_align};
|
||||||
|
|
||||||
|
|
|
@ -821,7 +821,7 @@ impl Flow for InlineFlow {
|
||||||
bottommost = bottom_from_base;
|
bottommost = bottom_from_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_box.border_box.borrow_mut().get().origin.y = line.bounds.origin.y + offset + top;
|
cur_box.border_box.borrow_mut().origin.y = line.bounds.origin.y + offset + top;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the distance from baseline to the top of the biggest box with 'bottom'
|
// Calculate the distance from baseline to the top of the biggest box with 'bottom'
|
||||||
|
@ -850,21 +850,19 @@ impl Flow for InlineFlow {
|
||||||
_ => baseline_offset,
|
_ => baseline_offset,
|
||||||
};
|
};
|
||||||
|
|
||||||
cur_box.border_box.borrow_mut().get().origin.y = cur_box.border_box.get().origin.y +
|
cur_box.border_box.borrow_mut().origin.y = cur_box.border_box.get().origin.y +
|
||||||
adjust_offset;
|
adjust_offset;
|
||||||
|
|
||||||
if cur_box.inline_info.with(|info| info.is_none()) {
|
if { cur_box.inline_info.borrow().is_none() } {
|
||||||
cur_box.inline_info.set(Some(InlineInfo::new()));
|
cur_box.inline_info.set(Some(InlineInfo::new()));
|
||||||
}
|
}
|
||||||
cur_box.inline_info.with_mut( |info| {
|
match &mut *cur_box.inline_info.borrow_mut() {
|
||||||
match info {
|
&Some(ref mut info) => {
|
||||||
&Some(ref mut info) => {
|
// TODO (ksh8281) compute vertical-align, line-height
|
||||||
// TODO (ksh8281) compute vertical-align, line-height
|
info.baseline = line.bounds.origin.y + baseline_offset;
|
||||||
info.baseline = line.bounds.origin.y + baseline_offset;
|
},
|
||||||
},
|
&None => {}
|
||||||
&None => {}
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is used to set the top y position of the next linebox in the next loop.
|
// This is used to set the top y position of the next linebox in the next loop.
|
||||||
|
|
|
@ -21,7 +21,6 @@ use layout::parallel;
|
||||||
use layout::util::{LayoutDataAccess, LayoutDataWrapper, OpaqueNodeMethods};
|
use layout::util::{LayoutDataAccess, LayoutDataWrapper, OpaqueNodeMethods};
|
||||||
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
|
use layout::wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
|
@ -55,13 +54,14 @@ use servo_util::task::send_on_failure;
|
||||||
use servo_util::workqueue::WorkQueue;
|
use servo_util::workqueue::WorkQueue;
|
||||||
use std::cast::transmute;
|
use std::cast::transmute;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::comm::Port;
|
use std::comm::{channel, Sender, Receiver};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::task;
|
use std::task;
|
||||||
use style::{AuthorOrigin, ComputedValues, Stylesheet, Stylist};
|
use style::{AuthorOrigin, ComputedValues, Stylesheet, Stylist};
|
||||||
use style;
|
use style;
|
||||||
use sync::{Arc, MutexArc};
|
use sync::{Arc, MutexArc};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
/// Information needed by the layout task.
|
/// Information needed by the layout task.
|
||||||
pub struct LayoutTask {
|
pub struct LayoutTask {
|
||||||
|
@ -69,7 +69,7 @@ pub struct LayoutTask {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
|
|
||||||
/// The port on which we receive messages.
|
/// The port on which we receive messages.
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
|
|
||||||
//// The channel to send messages to ourself.
|
//// The channel to send messages to ourself.
|
||||||
chan: LayoutChan,
|
chan: LayoutChan,
|
||||||
|
@ -248,7 +248,7 @@ impl ImageResponder for LayoutImageResponder {
|
||||||
impl LayoutTask {
|
impl LayoutTask {
|
||||||
/// Spawns a new layout task.
|
/// Spawns a new layout task.
|
||||||
pub fn create(id: PipelineId,
|
pub fn create(id: PipelineId,
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
chan: LayoutChan,
|
chan: LayoutChan,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
failure_msg: Failure,
|
failure_msg: Failure,
|
||||||
|
@ -257,7 +257,7 @@ impl LayoutTask {
|
||||||
img_cache_task: ImageCacheTask,
|
img_cache_task: ImageCacheTask,
|
||||||
opts: Opts,
|
opts: Opts,
|
||||||
profiler_chan: ProfilerChan,
|
profiler_chan: ProfilerChan,
|
||||||
shutdown_chan: Chan<()>) {
|
shutdown_chan: Sender<()>) {
|
||||||
let mut builder = task::task().named("LayoutTask");
|
let mut builder = task::task().named("LayoutTask");
|
||||||
let ConstellationChan(con_chan) = constellation_chan.clone();
|
let ConstellationChan(con_chan) = constellation_chan.clone();
|
||||||
send_on_failure(&mut builder, FailureMsg(failure_msg), con_chan);
|
send_on_failure(&mut builder, FailureMsg(failure_msg), con_chan);
|
||||||
|
@ -280,7 +280,7 @@ impl LayoutTask {
|
||||||
|
|
||||||
/// Creates a new `LayoutTask` structure.
|
/// Creates a new `LayoutTask` structure.
|
||||||
fn new(id: PipelineId,
|
fn new(id: PipelineId,
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
chan: LayoutChan,
|
chan: LayoutChan,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
|
@ -384,7 +384,7 @@ impl LayoutTask {
|
||||||
/// Enters a quiescent state in which no new messages except for `ReapLayoutDataMsg` will be
|
/// Enters a quiescent state in which no new messages except for `ReapLayoutDataMsg` will be
|
||||||
/// processed until an `ExitNowMsg` is received. A pong is immediately sent on the given
|
/// processed until an `ExitNowMsg` is received. A pong is immediately sent on the given
|
||||||
/// response channel.
|
/// response channel.
|
||||||
fn prepare_to_exit(&mut self, response_chan: Chan<()>) {
|
fn prepare_to_exit(&mut self, response_chan: Sender<()>) {
|
||||||
response_chan.send(());
|
response_chan.send(());
|
||||||
loop {
|
loop {
|
||||||
match self.port.recv() {
|
match self.port.recv() {
|
||||||
|
@ -409,7 +409,7 @@ impl LayoutTask {
|
||||||
/// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely)
|
/// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely)
|
||||||
/// crash.
|
/// crash.
|
||||||
fn exit_now(&mut self) {
|
fn exit_now(&mut self) {
|
||||||
let (response_port, response_chan) = Chan::new();
|
let (response_chan, response_port) = channel();
|
||||||
|
|
||||||
match self.parallel_traversal {
|
match self.parallel_traversal {
|
||||||
None => {}
|
None => {}
|
||||||
|
@ -427,11 +427,11 @@ impl LayoutTask {
|
||||||
/// Retrieves the flow tree root from the root node.
|
/// Retrieves the flow tree root from the root node.
|
||||||
fn get_layout_root(&self, node: LayoutNode) -> ~Flow {
|
fn get_layout_root(&self, node: LayoutNode) -> ~Flow {
|
||||||
let mut layout_data_ref = node.mutate_layout_data();
|
let mut layout_data_ref = node.mutate_layout_data();
|
||||||
let result = match *layout_data_ref.get() {
|
let result = match &mut *layout_data_ref {
|
||||||
Some(ref mut layout_data) => {
|
&Some(ref mut layout_data) => {
|
||||||
mem::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult)
|
mem::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult)
|
||||||
}
|
}
|
||||||
None => fail!("no layout data for root node"),
|
&None => fail!("no layout data for root node"),
|
||||||
};
|
};
|
||||||
let mut flow = match result {
|
let mut flow = match result {
|
||||||
FlowConstructionResult(mut flow, abs_descendants) => {
|
FlowConstructionResult(mut flow, abs_descendants) => {
|
||||||
|
@ -893,6 +893,6 @@ impl LayoutTask {
|
||||||
unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) {
|
unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) {
|
||||||
let mut layout_data_ref = layout_data.borrow_mut();
|
let mut layout_data_ref = layout_data.borrow_mut();
|
||||||
let _: Option<LayoutDataWrapper> = cast::transmute(
|
let _: Option<LayoutDataWrapper> = cast::transmute(
|
||||||
mem::replace(layout_data_ref.get(), None));
|
mem::replace(&mut *layout_data_ref, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,11 +289,11 @@ fn recalc_style_for_node(unsafe_layout_node: UnsafeLayoutNode,
|
||||||
}
|
}
|
||||||
if child_count != 0 {
|
if child_count != 0 {
|
||||||
let mut layout_data_ref = node.mutate_layout_data();
|
let mut layout_data_ref = node.mutate_layout_data();
|
||||||
match *layout_data_ref.get() {
|
match &mut *layout_data_ref {
|
||||||
Some(ref mut layout_data) => {
|
&Some(ref mut layout_data) => {
|
||||||
layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
|
layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
|
||||||
}
|
}
|
||||||
None => fail!("no layout data"),
|
&None => fail!("no layout data"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enqueue kids.
|
// Enqueue kids.
|
||||||
|
@ -338,11 +338,11 @@ fn construct_flows(mut unsafe_layout_node: UnsafeLayoutNode,
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
let mut layout_data_ref = node.mutate_layout_data();
|
let mut layout_data_ref = node.mutate_layout_data();
|
||||||
match *layout_data_ref.get() {
|
match &mut *layout_data_ref {
|
||||||
Some(ref mut layout_data) => {
|
&Some(ref mut layout_data) => {
|
||||||
layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
|
layout_data.data.parallel.children_count.store(child_count as int, Relaxed)
|
||||||
}
|
}
|
||||||
None => fail!("no layout data"),
|
&None => fail!("no layout data"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl TableRowFlow {
|
||||||
fn assign_height_table_row_base(&mut self, layout_context: &mut LayoutContext, inorder: bool) {
|
fn assign_height_table_row_base(&mut self, layout_context: &mut LayoutContext, inorder: bool) {
|
||||||
let (top_offset, _, _) = self.initialize_offsets();
|
let (top_offset, _, _) = self.initialize_offsets();
|
||||||
|
|
||||||
let mut cur_y = top_offset;
|
let /* mut */ cur_y = top_offset;
|
||||||
|
|
||||||
// Per CSS 2.1 § 17.5.3, find max_y = max( computed `height`, minimum height of all cells )
|
// Per CSS 2.1 § 17.5.3, find max_y = max( computed `height`, minimum height of all cells )
|
||||||
let mut max_y = Au::new(0);
|
let mut max_y = Au::new(0);
|
||||||
|
@ -112,7 +112,7 @@ impl TableRowFlow {
|
||||||
Specified(value) => geometry::max(value, height)
|
Specified(value) => geometry::max(value, height)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
cur_y = cur_y + height;
|
// cur_y = cur_y + height;
|
||||||
|
|
||||||
// Assign the height of own box
|
// Assign the height of own box
|
||||||
//
|
//
|
||||||
|
|
|
@ -11,7 +11,7 @@ use gfx::font_context::FontContext;
|
||||||
use gfx::text::text_run::TextRun;
|
use gfx::text::text_run::TextRun;
|
||||||
use gfx::text::util::{CompressWhitespaceNewline, transform_text, CompressNone};
|
use gfx::text::util::{CompressWhitespaceNewline, transform_text, CompressNone};
|
||||||
use servo_util::range::Range;
|
use servo_util::range::Range;
|
||||||
use std::vec;
|
use std::slice;
|
||||||
use style::computed_values::white_space;
|
use style::computed_values::white_space;
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ impl TextRunScanner {
|
||||||
// font group fonts. This is probably achieved by creating the font group above
|
// font group fonts. This is probably achieved by creating the font group above
|
||||||
// and then letting `FontGroup` decide which `Font` to stick into the text run.
|
// and then letting `FontGroup` decide which `Font` to stick into the text run.
|
||||||
let fontgroup = font_context.get_resolved_font_for_style(&font_style);
|
let fontgroup = font_context.get_resolved_font_for_style(&font_style);
|
||||||
let run = ~fontgroup.borrow().with(|fg| fg.create_textrun(transformed_text.clone(), decoration));
|
let run = ~fontgroup.borrow().create_textrun(transformed_text.clone(), decoration);
|
||||||
|
|
||||||
debug!("TextRunScanner: pushing single text box in range: {} ({})",
|
debug!("TextRunScanner: pushing single text box in range: {} ({})",
|
||||||
self.clump,
|
self.clump,
|
||||||
|
@ -180,7 +180,7 @@ impl TextRunScanner {
|
||||||
|
|
||||||
// First, transform/compress text of all the nodes.
|
// First, transform/compress text of all the nodes.
|
||||||
let mut last_whitespace_in_clump = new_whitespace;
|
let mut last_whitespace_in_clump = new_whitespace;
|
||||||
let transformed_strs: ~[~str] = vec::from_fn(self.clump.length(), |i| {
|
let transformed_strs: ~[~str] = slice::from_fn(self.clump.length(), |i| {
|
||||||
// TODO(#113): We should be passing the compression context between calls to
|
// TODO(#113): We should be passing the compression context between calls to
|
||||||
// `transform_text`, so that boxes starting and/or ending with whitespace can
|
// `transform_text`, so that boxes starting and/or ending with whitespace can
|
||||||
// be compressed correctly with respect to the text run.
|
// be compressed correctly with respect to the text run.
|
||||||
|
@ -220,11 +220,8 @@ impl TextRunScanner {
|
||||||
// sequence. If no clump takes ownership, however, it will leak.
|
// sequence. If no clump takes ownership, however, it will leak.
|
||||||
let clump = self.clump;
|
let clump = self.clump;
|
||||||
let run = if clump.length() != 0 && run_str.len() > 0 {
|
let run = if clump.length() != 0 && run_str.len() > 0 {
|
||||||
fontgroup.borrow().with(|fg| {
|
Some(Arc::new(~TextRun::new(&mut *fontgroup.borrow().fonts[0].borrow_mut(),
|
||||||
fg.fonts[0].borrow().with_mut(|font| {
|
run_str.clone(), decoration)))
|
||||||
Some(Arc::new(~TextRun::new(font, run_str.clone(), decoration)))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ use std::cast;
|
||||||
use std::cell::{Ref, RefMut};
|
use std::cell::{Ref, RefMut};
|
||||||
use std::iter::Enumerate;
|
use std::iter::Enumerate;
|
||||||
use std::libc::uintptr_t;
|
use std::libc::uintptr_t;
|
||||||
use std::vec::Items;
|
use std::slice::Items;
|
||||||
use style::ComputedValues;
|
use style::ComputedValues;
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
//! o Instead of `html_element_in_html_document()`, use
|
//! o Instead of `html_element_in_html_document()`, use
|
||||||
//! `html_element_in_html_document_for_layout()`.
|
//! `html_element_in_html_document_for_layout()`.
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use script::dom::bindings::codegen::InheritTypes::{HTMLIFrameElementDerived};
|
use script::dom::bindings::codegen::InheritTypes::{HTMLIFrameElementDerived};
|
||||||
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementDerived, TextDerived};
|
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementDerived, TextDerived};
|
||||||
use script::dom::bindings::js::JS;
|
use script::dom::bindings::js::JS;
|
||||||
|
@ -52,6 +51,7 @@ use style::{PropertyDeclarationBlock, TElement, TNode, AttrSelector, SpecificNam
|
||||||
use style::{AnyNamespace};
|
use style::{AnyNamespace};
|
||||||
use style::computed_values::{content, display};
|
use style::computed_values::{content, display};
|
||||||
use layout::util::LayoutDataWrapper;
|
use layout::util::LayoutDataWrapper;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
/// Allows some convenience methods on generic layout nodes.
|
/// Allows some convenience methods on generic layout nodes.
|
||||||
pub trait TLayoutNode {
|
pub trait TLayoutNode {
|
||||||
|
@ -465,7 +465,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
|
||||||
fn text(&self) -> ~str {
|
fn text(&self) -> ~str {
|
||||||
if self.pseudo == Before || self.pseudo == After {
|
if self.pseudo == Before || self.pseudo == After {
|
||||||
let layout_data_ref = self.borrow_layout_data();
|
let layout_data_ref = self.borrow_layout_data();
|
||||||
let node_layout_data_wrapper = layout_data_ref.get().get_ref();
|
let node_layout_data_wrapper = layout_data_ref.get_ref();
|
||||||
|
|
||||||
if self.pseudo == Before {
|
if self.pseudo == Before {
|
||||||
let before_style = node_layout_data_wrapper.data.before_style.get_ref();
|
let before_style = node_layout_data_wrapper.data.before_style.get_ref();
|
||||||
|
@ -557,7 +557,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||||
|
|
||||||
pub fn is_block(&self, kind: ElementType) -> bool {
|
pub fn is_block(&self, kind: ElementType) -> bool {
|
||||||
let mut layout_data_ref = self.mutate_layout_data();
|
let mut layout_data_ref = self.mutate_layout_data();
|
||||||
let node_layout_data_wrapper = layout_data_ref.get().get_mut_ref();
|
let node_layout_data_wrapper = layout_data_ref.get_mut_ref();
|
||||||
|
|
||||||
let display = match kind {
|
let display = match kind {
|
||||||
Before | BeforeBlock => {
|
Before | BeforeBlock => {
|
||||||
|
@ -579,13 +579,13 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
|
||||||
|
|
||||||
pub fn has_before_pseudo(&self) -> bool {
|
pub fn has_before_pseudo(&self) -> bool {
|
||||||
let layout_data_wrapper = self.borrow_layout_data();
|
let layout_data_wrapper = self.borrow_layout_data();
|
||||||
let layout_data_wrapper_ref = layout_data_wrapper.get().get_ref();
|
let layout_data_wrapper_ref = layout_data_wrapper.get_ref();
|
||||||
layout_data_wrapper_ref.data.before_style.is_some()
|
layout_data_wrapper_ref.data.before_style.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_after_pseudo(&self) -> bool {
|
pub fn has_after_pseudo(&self) -> bool {
|
||||||
let layout_data_wrapper = self.borrow_layout_data();
|
let layout_data_wrapper = self.borrow_layout_data();
|
||||||
let layout_data_wrapper_ref = layout_data_wrapper.get().get_ref();
|
let layout_data_wrapper_ref = layout_data_wrapper.get_ref();
|
||||||
layout_data_wrapper_ref.data.after_style.is_some()
|
layout_data_wrapper_ref.data.after_style.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
use compositing::CompositorChan;
|
use compositing::CompositorChan;
|
||||||
use layout::layout_task::LayoutTask;
|
use layout::layout_task::LayoutTask;
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use gfx::render_task::{PaintPermissionGranted, PaintPermissionRevoked};
|
use gfx::render_task::{PaintPermissionGranted, PaintPermissionRevoked};
|
||||||
use gfx::render_task::{RenderChan, RenderTask};
|
use gfx::render_task::{RenderChan, RenderTask};
|
||||||
|
@ -20,6 +19,7 @@ use servo_util::opts::Opts;
|
||||||
use servo_util::time::ProfilerChan;
|
use servo_util::time::ProfilerChan;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
/// A uniquely-identifiable pipeline of script task, layout task, and render task.
|
/// A uniquely-identifiable pipeline of script task, layout task, and render task.
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
|
@ -28,8 +28,8 @@ pub struct Pipeline {
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
render_chan: RenderChan,
|
render_chan: RenderChan,
|
||||||
layout_shutdown_port: Port<()>,
|
layout_shutdown_port: Receiver<()>,
|
||||||
render_shutdown_port: Port<()>,
|
render_shutdown_port: Receiver<()>,
|
||||||
/// The most recently loaded url
|
/// The most recently loaded url
|
||||||
url: RefCell<Option<Url>>,
|
url: RefCell<Option<Url>>,
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ impl Pipeline {
|
||||||
-> Pipeline {
|
-> Pipeline {
|
||||||
let (layout_port, layout_chan) = LayoutChan::new();
|
let (layout_port, layout_chan) = LayoutChan::new();
|
||||||
let (render_port, render_chan) = RenderChan::new();
|
let (render_port, render_chan) = RenderChan::new();
|
||||||
let (render_shutdown_port, render_shutdown_chan) = Chan::new();
|
let (render_shutdown_chan, render_shutdown_port) = channel();
|
||||||
let (layout_shutdown_port, layout_shutdown_chan) = Chan::new();
|
let (layout_shutdown_chan, layout_shutdown_port) = channel();
|
||||||
|
|
||||||
let failure = Failure {
|
let failure = Failure {
|
||||||
pipeline_id: id,
|
pipeline_id: id,
|
||||||
|
@ -78,7 +78,7 @@ impl Pipeline {
|
||||||
layout_chan.clone(),
|
layout_chan.clone(),
|
||||||
constellation_chan,
|
constellation_chan,
|
||||||
failure,
|
failure,
|
||||||
script_pipeline.borrow().script_chan.clone(),
|
script_pipeline.script_chan.clone(),
|
||||||
render_chan.clone(),
|
render_chan.clone(),
|
||||||
image_cache_task.clone(),
|
image_cache_task.clone(),
|
||||||
opts.clone(),
|
opts.clone(),
|
||||||
|
@ -86,17 +86,17 @@ impl Pipeline {
|
||||||
layout_shutdown_chan);
|
layout_shutdown_chan);
|
||||||
|
|
||||||
let new_layout_info = NewLayoutInfo {
|
let new_layout_info = NewLayoutInfo {
|
||||||
old_id: script_pipeline.borrow().id.clone(),
|
old_id: script_pipeline.id.clone(),
|
||||||
new_id: id,
|
new_id: id,
|
||||||
layout_chan: layout_chan.clone(),
|
layout_chan: layout_chan.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ScriptChan(ref chan) = script_pipeline.borrow().script_chan;
|
let ScriptChan(ref chan) = script_pipeline.script_chan;
|
||||||
chan.send(AttachLayoutMsg(new_layout_info));
|
chan.send(AttachLayoutMsg(new_layout_info));
|
||||||
|
|
||||||
Pipeline::new(id,
|
Pipeline::new(id,
|
||||||
subpage_id,
|
subpage_id,
|
||||||
script_pipeline.borrow().script_chan.clone(),
|
script_pipeline.script_chan.clone(),
|
||||||
layout_chan,
|
layout_chan,
|
||||||
render_chan,
|
render_chan,
|
||||||
layout_shutdown_port,
|
layout_shutdown_port,
|
||||||
|
@ -116,8 +116,8 @@ impl Pipeline {
|
||||||
let (script_port, script_chan) = ScriptChan::new();
|
let (script_port, script_chan) = ScriptChan::new();
|
||||||
let (layout_port, layout_chan) = LayoutChan::new();
|
let (layout_port, layout_chan) = LayoutChan::new();
|
||||||
let (render_port, render_chan) = RenderChan::new();
|
let (render_port, render_chan) = RenderChan::new();
|
||||||
let (render_shutdown_port, render_shutdown_chan) = Chan::new();
|
let (render_shutdown_chan, render_shutdown_port) = channel();
|
||||||
let (layout_shutdown_port, layout_shutdown_chan) = Chan::new();
|
let (layout_shutdown_chan, layout_shutdown_port) = channel();
|
||||||
let pipeline = Pipeline::new(id,
|
let pipeline = Pipeline::new(id,
|
||||||
subpage_id,
|
subpage_id,
|
||||||
script_chan.clone(),
|
script_chan.clone(),
|
||||||
|
@ -171,8 +171,8 @@ impl Pipeline {
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
render_chan: RenderChan,
|
render_chan: RenderChan,
|
||||||
layout_shutdown_port: Port<()>,
|
layout_shutdown_port: Receiver<()>,
|
||||||
render_shutdown_port: Port<()>)
|
render_shutdown_port: Receiver<()>)
|
||||||
-> Pipeline {
|
-> Pipeline {
|
||||||
Pipeline {
|
Pipeline {
|
||||||
id: id,
|
id: id,
|
||||||
|
|
|
@ -144,8 +144,11 @@ impl WindowMethods<Application> for Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recv(&self) -> WindowEvent {
|
fn recv(&self) -> WindowEvent {
|
||||||
if !self.event_queue.with_mut(|queue| queue.is_empty()) {
|
{
|
||||||
return self.event_queue.with_mut(|queue| queue.shift().unwrap())
|
let mut event_queue = self.event_queue.borrow_mut();
|
||||||
|
if !event_queue.is_empty() {
|
||||||
|
return event_queue.shift().unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glfw::poll_events();
|
glfw::poll_events();
|
||||||
|
@ -155,10 +158,8 @@ impl WindowMethods<Application> for Window {
|
||||||
|
|
||||||
if self.glfw_window.should_close() {
|
if self.glfw_window.should_close() {
|
||||||
QuitWindowEvent
|
QuitWindowEvent
|
||||||
} else if !self.event_queue.with_mut(|queue| queue.is_empty()) {
|
|
||||||
self.event_queue.with_mut(|queue| queue.shift().unwrap())
|
|
||||||
} else {
|
} else {
|
||||||
IdleWindowEvent
|
self.event_queue.borrow_mut().shift().unwrap_or(IdleWindowEvent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +175,7 @@ impl WindowMethods<Application> for Window {
|
||||||
self.render_state.get() == RenderingRenderState &&
|
self.render_state.get() == RenderingRenderState &&
|
||||||
render_state == IdleRenderState {
|
render_state == IdleRenderState {
|
||||||
// page loaded
|
// page loaded
|
||||||
self.event_queue.with_mut(|queue| queue.push(FinishedWindowEvent));
|
self.event_queue.borrow_mut().push(FinishedWindowEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.render_state.set(render_state);
|
self.render_state.set(render_state);
|
||||||
|
@ -197,10 +198,10 @@ impl Window {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
glfw::FramebufferSizeEvent(width, height) => {
|
glfw::FramebufferSizeEvent(width, height) => {
|
||||||
self.event_queue.with_mut(|queue| queue.push(ResizeWindowEvent(width as uint, height as uint)));
|
self.event_queue.borrow_mut().push(ResizeWindowEvent(width as uint, height as uint));
|
||||||
},
|
},
|
||||||
glfw::RefreshEvent => {
|
glfw::RefreshEvent => {
|
||||||
self.event_queue.with_mut(|queue| queue.push(RefreshWindowEvent));
|
self.event_queue.borrow_mut().push(RefreshWindowEvent);
|
||||||
},
|
},
|
||||||
glfw::MouseButtonEvent(button, action, _mods) => {
|
glfw::MouseButtonEvent(button, action, _mods) => {
|
||||||
let (x, y) = window.get_cursor_pos();
|
let (x, y) = window.get_cursor_pos();
|
||||||
|
@ -215,7 +216,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
glfw::CursorPosEvent(xpos, ypos) => {
|
glfw::CursorPosEvent(xpos, ypos) => {
|
||||||
self.event_queue.with_mut(|queue| queue.push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32))));
|
self.event_queue.borrow_mut().push(MouseWindowMoveEventClass(Point2D(xpos as f32, ypos as f32)));
|
||||||
},
|
},
|
||||||
glfw::ScrollEvent(xpos, ypos) => {
|
glfw::ScrollEvent(xpos, ypos) => {
|
||||||
let dx = (xpos as f32) * 30.0;
|
let dx = (xpos as f32) * 30.0;
|
||||||
|
@ -229,7 +230,7 @@ impl Window {
|
||||||
let x = x as f32 * hidpi;
|
let x = x as f32 * hidpi;
|
||||||
let y = y as f32 * hidpi;
|
let y = y as f32 * hidpi;
|
||||||
|
|
||||||
self.event_queue.with_mut(|queue| queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32))));
|
self.event_queue.borrow_mut().push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32)));
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -272,16 +273,16 @@ impl Window {
|
||||||
glfw::KeyEscape => self.glfw_window.set_should_close(true),
|
glfw::KeyEscape => self.glfw_window.set_should_close(true),
|
||||||
glfw::KeyL if mods.contains(glfw::Control) => self.load_url(), // Ctrl+L
|
glfw::KeyL if mods.contains(glfw::Control) => self.load_url(), // Ctrl+L
|
||||||
glfw::KeyEqual if mods.contains(glfw::Control) => { // Ctrl-+
|
glfw::KeyEqual if mods.contains(glfw::Control) => { // Ctrl-+
|
||||||
self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(1.1)));
|
self.event_queue.borrow_mut().push(ZoomWindowEvent(1.1));
|
||||||
}
|
}
|
||||||
glfw::KeyMinus if mods.contains(glfw::Control) => { // Ctrl--
|
glfw::KeyMinus if mods.contains(glfw::Control) => { // Ctrl--
|
||||||
self.event_queue.with_mut(|queue| queue.push(ZoomWindowEvent(0.90909090909)));
|
self.event_queue.borrow_mut().push(ZoomWindowEvent(0.90909090909));
|
||||||
}
|
}
|
||||||
glfw::KeyBackspace if mods.contains(glfw::Shift) => { // Shift-Backspace
|
glfw::KeyBackspace if mods.contains(glfw::Shift) => { // Shift-Backspace
|
||||||
self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Forward)));
|
self.event_queue.borrow_mut().push(NavigationWindowEvent(Forward));
|
||||||
}
|
}
|
||||||
glfw::KeyBackspace => { // Backspace
|
glfw::KeyBackspace => { // Backspace
|
||||||
self.event_queue.with_mut(|queue| queue.push(NavigationWindowEvent(Back)));
|
self.event_queue.borrow_mut().push(NavigationWindowEvent(Back));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -307,7 +308,7 @@ impl Window {
|
||||||
if pixel_dist < max_pixel_dist {
|
if pixel_dist < max_pixel_dist {
|
||||||
let click_event = MouseWindowClickEvent(button as uint,
|
let click_event = MouseWindowClickEvent(button as uint,
|
||||||
Point2D(x as f32, y as f32));
|
Point2D(x as f32, y as f32));
|
||||||
self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(click_event)));
|
self.event_queue.borrow_mut().push(MouseWindowEventClass(click_event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(_) => (),
|
Some(_) => (),
|
||||||
|
@ -316,7 +317,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
_ => fail!("I cannot recognize the type of mouse action that occured. :-(")
|
_ => fail!("I cannot recognize the type of mouse action that occured. :-(")
|
||||||
};
|
};
|
||||||
self.event_queue.with_mut(|queue| queue.push(MouseWindowEventClass(event)));
|
self.event_queue.borrow_mut().push(MouseWindowEventClass(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function to pop up an alert box prompting the user to load a URL.
|
/// Helper function to pop up an alert box prompting the user to load a URL.
|
||||||
|
@ -326,9 +327,9 @@ impl Window {
|
||||||
alert.run();
|
alert.run();
|
||||||
let value = alert.prompt_value();
|
let value = alert.prompt_value();
|
||||||
if "" == value { // To avoid crashing on Linux.
|
if "" == value { // To avoid crashing on Linux.
|
||||||
self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(~"http://purple.com/")))
|
self.event_queue.borrow_mut().push(LoadUrlWindowEvent(~"http://purple.com/"))
|
||||||
} else {
|
} else {
|
||||||
self.event_queue.with_mut(|queue| queue.push(LoadUrlWindowEvent(value.clone())))
|
self.event_queue.borrow_mut().push(LoadUrlWindowEvent(value.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@
|
||||||
|
|
||||||
#[feature(globs, macro_rules, managed_boxes, phase, thread_local)];
|
#[feature(globs, macro_rules, managed_boxes, phase, thread_local)];
|
||||||
|
|
||||||
|
#[feature(phase)];
|
||||||
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
extern crate alert;
|
extern crate alert;
|
||||||
extern crate azure;
|
extern crate azure;
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
|
@ -20,7 +23,6 @@ extern crate js;
|
||||||
extern crate layers;
|
extern crate layers;
|
||||||
extern crate opengles;
|
extern crate opengles;
|
||||||
extern crate png;
|
extern crate png;
|
||||||
#[cfg(target_os="android")]
|
|
||||||
extern crate rustuv;
|
extern crate rustuv;
|
||||||
extern crate script;
|
extern crate script;
|
||||||
#[phase(syntax)]
|
#[phase(syntax)]
|
||||||
|
@ -33,12 +35,12 @@ extern crate sharegl;
|
||||||
extern crate stb_image;
|
extern crate stb_image;
|
||||||
|
|
||||||
extern crate collections;
|
extern crate collections;
|
||||||
extern crate extra;
|
|
||||||
extern crate green;
|
extern crate green;
|
||||||
extern crate native;
|
extern crate native;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
extern crate url;
|
||||||
|
|
||||||
#[cfg(target_os="macos")]
|
#[cfg(target_os="macos")]
|
||||||
extern crate core_graphics;
|
extern crate core_graphics;
|
||||||
|
@ -66,12 +68,12 @@ use servo_util::url::parse_url;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use std::os;
|
use std::os;
|
||||||
#[cfg(not(test))]
|
|
||||||
use extra::url::Url;
|
|
||||||
#[cfg(not(test), target_os="android")]
|
#[cfg(not(test), target_os="android")]
|
||||||
use std::str;
|
use std::str;
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use std::task::TaskOpts;
|
use std::task::TaskOpts;
|
||||||
|
#[cfg(not(test))]
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
|
||||||
#[path="compositing/compositor_task.rs"]
|
#[path="compositing/compositor_task.rs"]
|
||||||
|
@ -153,7 +155,7 @@ fn run(opts: opts::Opts) {
|
||||||
let opts_clone = opts.clone();
|
let opts_clone = opts.clone();
|
||||||
let profiler_chan_clone = profiler_chan.clone();
|
let profiler_chan_clone = profiler_chan.clone();
|
||||||
|
|
||||||
let (result_port, result_chan) = Chan::new();
|
let (result_chan, result_port) = channel();
|
||||||
pool.spawn(TaskOpts::new(), proc() {
|
pool.spawn(TaskOpts::new(), proc() {
|
||||||
let opts = &opts_clone;
|
let opts = &opts_clone;
|
||||||
// Create a Servo instance.
|
// Create a Servo instance.
|
||||||
|
@ -178,7 +180,7 @@ fn run(opts: opts::Opts) {
|
||||||
// As a hack for easier command-line testing,
|
// As a hack for easier command-line testing,
|
||||||
// assume that data URLs are not URL-encoded.
|
// assume that data URLs are not URL-encoded.
|
||||||
Url::new(~"data", None, ~"", None,
|
Url::new(~"data", None, ~"", None,
|
||||||
filename.slice_from(5).to_owned(), ~[], None)
|
filename.slice_from(5).to_owned(), Vec::new(), None)
|
||||||
} else {
|
} else {
|
||||||
parse_url(*filename, None)
|
parse_url(*filename, None)
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,17 +5,17 @@
|
||||||
//! The high-level interface from script to constellation. Using this abstract interface helps reduce
|
//! The high-level interface from script to constellation. Using this abstract interface helps reduce
|
||||||
/// coupling between these two components
|
/// coupling between these two components
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use std::comm::Chan;
|
use std::comm::{channel, Sender, Receiver};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct ConstellationChan(Chan<Msg>);
|
pub struct ConstellationChan(Sender<Msg>);
|
||||||
|
|
||||||
impl ConstellationChan {
|
impl ConstellationChan {
|
||||||
pub fn new() -> (Port<Msg>, ConstellationChan) {
|
pub fn new() -> (Receiver<Msg>, ConstellationChan) {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
(port, ConstellationChan(chan))
|
(port, ConstellationChan(chan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,8 @@ pub enum NavigationDirection {
|
||||||
Back,
|
Back,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq, Hash, Encodable)]
|
#[deriving(Clone, Eq, TotalEq, Hash, Encodable)]
|
||||||
pub struct PipelineId(uint);
|
pub struct PipelineId(uint);
|
||||||
|
|
||||||
#[deriving(Clone, Eq, Hash, Encodable)]
|
#[deriving(Clone, Eq, TotalEq, Hash, Encodable)]
|
||||||
pub struct SubpageId(uint);
|
pub struct SubpageId(uint);
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
#[feature(managed_boxes)];
|
#[feature(managed_boxes)];
|
||||||
|
|
||||||
extern crate azure;
|
extern crate azure;
|
||||||
extern crate extra;
|
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
extern crate layers;
|
extern crate layers;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate std;
|
extern crate std;
|
||||||
|
extern crate url;
|
||||||
|
|
||||||
#[cfg(target_os="macos")]
|
#[cfg(target_os="macos")]
|
||||||
extern crate core_foundation;
|
extern crate core_foundation;
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
use resource_task::{Done, Payload, Metadata, LoadResponse, LoaderTask, start_sending};
|
use resource_task::{Done, Payload, Metadata, LoadResponse, LoaderTask, start_sending};
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use serialize::base64::FromBase64;
|
use serialize::base64::FromBase64;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use http::headers::test_utils::from_stream_with_str;
|
use http::headers::test_utils::from_stream_with_str;
|
||||||
use http::headers::content_type::MediaType;
|
use http::headers::content_type::MediaType;
|
||||||
|
@ -19,7 +19,7 @@ pub fn factory() -> LoaderTask {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(url: Url, start_chan: Chan<LoadResponse>) {
|
fn load(url: Url, start_chan: Sender<LoadResponse>) {
|
||||||
assert!("data" == url.scheme);
|
assert!("data" == url.scheme);
|
||||||
|
|
||||||
let mut metadata = Metadata::default(url.clone());
|
let mut metadata = Metadata::default(url.clone());
|
||||||
|
|
|
@ -11,11 +11,11 @@ use servo_util::task::spawn_named;
|
||||||
//FIXME: https://github.com/mozilla/rust/issues/12892
|
//FIXME: https://github.com/mozilla/rust/issues/12892
|
||||||
static READ_SIZE: uint = 1;
|
static READ_SIZE: uint = 1;
|
||||||
|
|
||||||
fn read_all(reader: &mut io::Stream, progress_chan: &Chan<ProgressMsg>)
|
fn read_all(reader: &mut io::Stream, progress_chan: &Sender<ProgressMsg>)
|
||||||
-> Result<(), ()> {
|
-> Result<(), ()> {
|
||||||
loop {
|
loop {
|
||||||
let mut buf = ~[];
|
let mut buf = ~[];
|
||||||
match reader.push_bytes(&mut buf, READ_SIZE) {
|
match reader.push_exact(&mut buf, READ_SIZE) {
|
||||||
Ok(_) => progress_chan.send(Payload(buf)),
|
Ok(_) => progress_chan.send(Payload(buf)),
|
||||||
Err(e) => match e.kind {
|
Err(e) => match e.kind {
|
||||||
io::EndOfFile => return Ok(()),
|
io::EndOfFile => return Ok(()),
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
use resource_task::{Metadata, Payload, Done, LoadResponse, LoaderTask, start_sending};
|
use resource_task::{Metadata, Payload, Done, LoadResponse, LoaderTask, start_sending};
|
||||||
|
|
||||||
use std::vec;
|
|
||||||
use collections::hashmap::HashSet;
|
use collections::hashmap::HashSet;
|
||||||
use extra::url::Url;
|
|
||||||
use http::client::RequestWriter;
|
use http::client::RequestWriter;
|
||||||
use http::method::Get;
|
use http::method::Get;
|
||||||
use http::headers::HeaderEnum;
|
use http::headers::HeaderEnum;
|
||||||
use std::io::Reader;
|
use std::io::Reader;
|
||||||
use std::io::net::tcp::TcpStream;
|
use std::io::net::tcp::TcpStream;
|
||||||
|
use std::slice;
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::spawn_named;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
pub fn factory() -> LoaderTask {
|
pub fn factory() -> LoaderTask {
|
||||||
let f: LoaderTask = proc(url, start_chan) {
|
let f: LoaderTask = proc(url, start_chan) {
|
||||||
|
@ -21,11 +21,11 @@ pub fn factory() -> LoaderTask {
|
||||||
f
|
f
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_error(url: Url, start_chan: Chan<LoadResponse>) {
|
fn send_error(url: Url, start_chan: Sender<LoadResponse>) {
|
||||||
start_sending(start_chan, Metadata::default(url)).send(Done(Err(())));
|
start_sending(start_chan, Metadata::default(url)).send(Done(Err(())));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
|
fn load(mut url: Url, start_chan: Sender<LoadResponse>) {
|
||||||
// FIXME: At the time of writing this FIXME, servo didn't have any central
|
// FIXME: At the time of writing this FIXME, servo didn't have any central
|
||||||
// location for configuration. If you're reading this and such a
|
// location for configuration. If you're reading this and such a
|
||||||
// repository DOES exist, please update this constant to use it.
|
// repository DOES exist, please update this constant to use it.
|
||||||
|
@ -95,7 +95,7 @@ fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
|
||||||
|
|
||||||
let progress_chan = start_sending(start_chan, metadata);
|
let progress_chan = start_sending(start_chan, metadata);
|
||||||
loop {
|
loop {
|
||||||
let mut buf = vec::with_capacity(1024);
|
let mut buf = slice::with_capacity(1024);
|
||||||
|
|
||||||
unsafe { buf.set_len(1024); }
|
unsafe { buf.set_len(1024); }
|
||||||
match response.read(buf) {
|
match response.read(buf) {
|
||||||
|
|
|
@ -7,9 +7,9 @@ use image_cache_task::{ImageReady, ImageNotReady, ImageFailed};
|
||||||
use local_image_cache::LocalImageCache;
|
use local_image_cache::LocalImageCache;
|
||||||
|
|
||||||
use sync::{Arc, MutexArc};
|
use sync::{Arc, MutexArc};
|
||||||
use extra::url::Url;
|
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
// FIXME: Nasty coupling here This will be a problem if we want to factor out image handling from
|
// FIXME: Nasty coupling here This will be a problem if we want to factor out image handling from
|
||||||
// the network stack. This should probably be factored out into an interface and use dependency
|
// the network stack. This should probably be factored out into an interface and use dependency
|
||||||
|
|
|
@ -7,14 +7,14 @@ use resource_task;
|
||||||
use resource_task::ResourceTask;
|
use resource_task::ResourceTask;
|
||||||
use servo_util::url::{UrlMap, url_map};
|
use servo_util::url::{UrlMap, url_map};
|
||||||
|
|
||||||
use std::comm::{Chan, Port};
|
use std::comm::{channel, Receiver, Sender};
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::task::spawn;
|
use std::task::spawn;
|
||||||
use std::to_str::ToStr;
|
use std::to_str::ToStr;
|
||||||
use std::result;
|
use std::result;
|
||||||
use sync::{Arc,MutexArc};
|
use sync::{Arc,MutexArc};
|
||||||
use extra::url::Url;
|
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
/// Tell the cache that we may need a particular image soon. Must be posted
|
/// Tell the cache that we may need a particular image soon. Must be posted
|
||||||
|
@ -35,21 +35,21 @@ pub enum Msg {
|
||||||
|
|
||||||
/// Request an Image object for a URL. If the image is not is not immediately
|
/// Request an Image object for a URL. If the image is not is not immediately
|
||||||
/// available then ImageNotReady is returned.
|
/// available then ImageNotReady is returned.
|
||||||
GetImage(Url, Chan<ImageResponseMsg>),
|
GetImage(Url, Sender<ImageResponseMsg>),
|
||||||
|
|
||||||
/// Wait for an image to become available (or fail to load).
|
/// Wait for an image to become available (or fail to load).
|
||||||
WaitForImage(Url, Chan<ImageResponseMsg>),
|
WaitForImage(Url, Sender<ImageResponseMsg>),
|
||||||
|
|
||||||
/// Clients must wait for a response before shutting down the ResourceTask
|
/// Clients must wait for a response before shutting down the ResourceTask
|
||||||
Exit(Chan<()>),
|
Exit(Sender<()>),
|
||||||
|
|
||||||
/// For testing
|
/// For testing
|
||||||
// FIXME: make this priv after visibility rules change
|
// FIXME: make this priv after visibility rules change
|
||||||
WaitForStore(Chan<()>),
|
WaitForStore(Sender<()>),
|
||||||
|
|
||||||
/// For testing
|
/// For testing
|
||||||
// FIXME: make this priv after visibility rules change
|
// FIXME: make this priv after visibility rules change
|
||||||
WaitForStorePrefetched(Chan<()>),
|
WaitForStorePrefetched(Sender<()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
|
@ -78,7 +78,7 @@ impl Eq for ImageResponseMsg {
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct ImageCacheTask {
|
pub struct ImageCacheTask {
|
||||||
chan: Chan<Msg>,
|
chan: Sender<Msg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Encoder> Encodable<S> for ImageCacheTask {
|
impl<S: Encoder> Encodable<S> for ImageCacheTask {
|
||||||
|
@ -89,7 +89,7 @@ impl<S: Encoder> Encodable<S> for ImageCacheTask {
|
||||||
type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>;
|
type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>;
|
||||||
|
|
||||||
pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let chan_clone = chan.clone();
|
let chan_clone = chan.clone();
|
||||||
|
|
||||||
spawn(proc() {
|
spawn(proc() {
|
||||||
|
@ -111,7 +111,7 @@ pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||||
|
|
||||||
// FIXME: make this priv after visibility rules change
|
// FIXME: make this priv after visibility rules change
|
||||||
pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
|
|
||||||
spawn(proc() {
|
spawn(proc() {
|
||||||
let inner_cache = ImageCacheTask(resource_task.clone());
|
let inner_cache = ImageCacheTask(resource_task.clone());
|
||||||
|
@ -141,14 +141,14 @@ struct ImageCache {
|
||||||
/// A handle to the resource task for fetching the image binaries
|
/// A handle to the resource task for fetching the image binaries
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
/// The port on which we'll receive client requests
|
/// The port on which we'll receive client requests
|
||||||
port: Port<Msg>,
|
port: Receiver<Msg>,
|
||||||
/// A copy of the shared chan to give to child tasks
|
/// A copy of the shared chan to give to child tasks
|
||||||
chan: Chan<Msg>,
|
chan: Sender<Msg>,
|
||||||
/// The state of processsing an image for a URL
|
/// The state of processsing an image for a URL
|
||||||
state_map: UrlMap<ImageState>,
|
state_map: UrlMap<ImageState>,
|
||||||
/// List of clients waiting on a WaitForImage response
|
/// List of clients waiting on a WaitForImage response
|
||||||
wait_map: UrlMap<MutexArc<~[Chan<ImageResponseMsg>]>>,
|
wait_map: UrlMap<MutexArc<~[Sender<ImageResponseMsg>]>>,
|
||||||
need_exit: Option<Chan<()>>,
|
need_exit: Option<Sender<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
|
@ -169,8 +169,8 @@ enum AfterPrefetch {
|
||||||
|
|
||||||
impl ImageCache {
|
impl ImageCache {
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
let mut store_chan: Option<Chan<()>> = None;
|
let mut store_chan: Option<Sender<()>> = None;
|
||||||
let mut store_prefetched_chan: Option<Chan<()>> = None;
|
let mut store_prefetched_chan: Option<Sender<()>> = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let msg = self.port.recv();
|
let msg = self.port.recv();
|
||||||
|
@ -385,7 +385,7 @@ impl ImageCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_image(&self, url: Url, response: Chan<ImageResponseMsg>) {
|
fn get_image(&self, url: Url, response: Sender<ImageResponseMsg>) {
|
||||||
match self.get_state(url.clone()) {
|
match self.get_state(url.clone()) {
|
||||||
Init => fail!(~"request for image before prefetch"),
|
Init => fail!(~"request for image before prefetch"),
|
||||||
Prefetching(DoDecode) => response.send(ImageNotReady),
|
Prefetching(DoDecode) => response.send(ImageNotReady),
|
||||||
|
@ -396,7 +396,7 @@ impl ImageCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wait_for_image(&mut self, url: Url, response: Chan<ImageResponseMsg>) {
|
fn wait_for_image(&mut self, url: Url, response: Sender<ImageResponseMsg>) {
|
||||||
match self.get_state(url.clone()) {
|
match self.get_state(url.clone()) {
|
||||||
Init => fail!(~"request for image before prefetch"),
|
Init => fail!(~"request for image before prefetch"),
|
||||||
|
|
||||||
|
@ -432,7 +432,7 @@ pub trait ImageCacheTaskClient {
|
||||||
|
|
||||||
impl ImageCacheTaskClient for ImageCacheTask {
|
impl ImageCacheTaskClient for ImageCacheTask {
|
||||||
fn exit(&self) {
|
fn exit(&self) {
|
||||||
let (response_port, response_chan) = Chan::new();
|
let (response_chan, response_port) = channel();
|
||||||
self.send(Exit(response_chan));
|
self.send(Exit(response_chan));
|
||||||
response_port.recv();
|
response_port.recv();
|
||||||
}
|
}
|
||||||
|
@ -444,22 +444,22 @@ impl ImageCacheTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn wait_for_store(&self) -> Port<()> {
|
fn wait_for_store(&self) -> Receiver<()> {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
self.send(WaitForStore(chan));
|
self.send(WaitForStore(chan));
|
||||||
port
|
port
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn wait_for_store_prefetched(&self) -> Port<()> {
|
fn wait_for_store_prefetched(&self) -> Receiver<()> {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
self.send(WaitForStorePrefetched(chan));
|
self.send(WaitForStorePrefetched(chan));
|
||||||
port
|
port
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
|
fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
|
||||||
let (response_port, response_chan) = Chan::new();
|
let (response_chan, response_port) = channel();
|
||||||
resource_task.send(resource_task::Load(url, response_chan));
|
resource_task.send(resource_task::Load(url, response_chan));
|
||||||
|
|
||||||
let mut image_data = ~[];
|
let mut image_data = ~[];
|
||||||
|
@ -481,11 +481,11 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn spawn_listener<A: Send>(f: proc(Port<A>)) -> Chan<A> {
|
pub fn spawn_listener<A: Send>(f: proc(Receiver<A>)) -> Sender<A> {
|
||||||
let (setup_port, setup_chan) = Chan::new();
|
let (setup_chan, setup_port) = channel();
|
||||||
|
|
||||||
spawn(proc() {
|
spawn(proc() {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
setup_chan.send(chan);
|
setup_chan.send(chan);
|
||||||
f(port);
|
f(port);
|
||||||
});
|
});
|
||||||
|
@ -503,8 +503,8 @@ mod tests {
|
||||||
use servo_util::url::parse_url;
|
use servo_util::url::parse_url;
|
||||||
use std::comm::{Empty, Data, Disconnected};
|
use std::comm::{Empty, Data, Disconnected};
|
||||||
|
|
||||||
fn mock_resource_task(on_load: proc(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
|
fn mock_resource_task(on_load: proc(resource: Sender<resource_task::ProgressMsg>)) -> ResourceTask {
|
||||||
spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
|
spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) {
|
||||||
loop {
|
loop {
|
||||||
match port.recv() {
|
match port.recv() {
|
||||||
resource_task::Load(_, response) => {
|
resource_task::Load(_, response) => {
|
||||||
|
@ -536,14 +536,14 @@ mod tests {
|
||||||
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
|
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
|
||||||
let url = parse_url("file", None);
|
let url = parse_url("file", None);
|
||||||
|
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
image_cache_task.send(GetImage(url, chan));
|
image_cache_task.send(GetImage(url, chan));
|
||||||
port.recv();
|
port.recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_request_url_from_resource_task_on_prefetch() {
|
fn should_request_url_from_resource_task_on_prefetch() {
|
||||||
let (url_requested, url_requested_chan) = Chan::new();
|
let (url_requested_chan, url_requested) = channel();
|
||||||
|
|
||||||
let mock_resource_task = mock_resource_task(proc(response) {
|
let mock_resource_task = mock_resource_task(proc(response) {
|
||||||
url_requested_chan.send(());
|
url_requested_chan.send(());
|
||||||
|
@ -673,7 +673,7 @@ mod tests {
|
||||||
|
|
||||||
let (resource_task_exited, resource_task_exited_chan) = Chan::new();
|
let (resource_task_exited, resource_task_exited_chan) = Chan::new();
|
||||||
|
|
||||||
let mock_resource_task = spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
|
let mock_resource_task = spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) {
|
||||||
loop {
|
loop {
|
||||||
match port.recv() {
|
match port.recv() {
|
||||||
resource_task::Load(_, response) => {
|
resource_task::Load(_, response) => {
|
||||||
|
@ -719,7 +719,7 @@ mod tests {
|
||||||
|
|
||||||
let (resource_task_exited, resource_task_exited_chan) = Chan::new();
|
let (resource_task_exited, resource_task_exited_chan) = Chan::new();
|
||||||
|
|
||||||
let mock_resource_task = spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
|
let mock_resource_task = spawn_listener(proc(port: Receiver<resource_task::ControlMsg>) {
|
||||||
loop {
|
loop {
|
||||||
match port.recv() {
|
match port.recv() {
|
||||||
resource_task::Load(_, response) => {
|
resource_task::Load(_, response) => {
|
||||||
|
|
|
@ -11,10 +11,10 @@ multiple times and thus triggering reflows multiple times.
|
||||||
use image_cache_task::{Decode, GetImage, ImageCacheTask, ImageFailed, ImageNotReady, ImageReady};
|
use image_cache_task::{Decode, GetImage, ImageCacheTask, ImageFailed, ImageNotReady, ImageReady};
|
||||||
use image_cache_task::{ImageResponseMsg, Prefetch, WaitForImage};
|
use image_cache_task::{ImageResponseMsg, Prefetch, WaitForImage};
|
||||||
|
|
||||||
use std::comm::Port;
|
use std::comm::{Receiver, channel};
|
||||||
use servo_util::url::{UrlMap, url_map};
|
use servo_util::url::{UrlMap, url_map};
|
||||||
use extra::url::Url;
|
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::spawn_named;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
pub trait ImageResponder {
|
pub trait ImageResponder {
|
||||||
fn respond(&self) -> proc(ImageResponseMsg);
|
fn respond(&self) -> proc(ImageResponseMsg);
|
||||||
|
@ -78,7 +78,7 @@ impl LocalImageCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Should return a Future
|
// FIXME: Should return a Future
|
||||||
pub fn get_image(&mut self, url: &Url) -> Port<ImageResponseMsg> {
|
pub fn get_image(&mut self, url: &Url) -> Receiver<ImageResponseMsg> {
|
||||||
{
|
{
|
||||||
let state = self.get_state(url);
|
let state = self.get_state(url);
|
||||||
|
|
||||||
|
@ -89,13 +89,13 @@ impl LocalImageCache {
|
||||||
|
|
||||||
match state.last_response {
|
match state.last_response {
|
||||||
ImageReady(ref image) => {
|
ImageReady(ref image) => {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
chan.send(ImageReady(image.clone()));
|
chan.send(ImageReady(image.clone()));
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
ImageNotReady => {
|
ImageNotReady => {
|
||||||
if last_round == self.round_number {
|
if last_round == self.round_number {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
chan.send(ImageNotReady);
|
chan.send(ImageNotReady);
|
||||||
return port;
|
return port;
|
||||||
} else {
|
} else {
|
||||||
|
@ -104,14 +104,14 @@ impl LocalImageCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImageFailed => {
|
ImageFailed => {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
chan.send(ImageFailed);
|
chan.send(ImageFailed);
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (response_port, response_chan) = Chan::new();
|
let (response_chan, response_port) = channel();
|
||||||
self.image_cache_task.send(GetImage((*url).clone(), response_chan));
|
self.image_cache_task.send(GetImage((*url).clone(), response_chan));
|
||||||
|
|
||||||
let response = response_port.recv();
|
let response = response_port.recv();
|
||||||
|
@ -127,7 +127,7 @@ impl LocalImageCache {
|
||||||
let on_image_available = self.on_image_available.as_ref().unwrap().respond();
|
let on_image_available = self.on_image_available.as_ref().unwrap().respond();
|
||||||
let url = (*url).clone();
|
let url = (*url).clone();
|
||||||
spawn_named("LocalImageCache", proc() {
|
spawn_named("LocalImageCache", proc() {
|
||||||
let (response_port, response_chan) = Chan::new();
|
let (response_chan, response_port) = channel();
|
||||||
image_cache_task.send(WaitForImage(url.clone(), response_chan));
|
image_cache_task.send(WaitForImage(url.clone(), response_chan));
|
||||||
on_image_available(response_port.recv());
|
on_image_available(response_port.recv());
|
||||||
});
|
});
|
||||||
|
@ -143,7 +143,7 @@ impl LocalImageCache {
|
||||||
};
|
};
|
||||||
self.get_state(url).last_response = response_copy;
|
self.get_state(url).last_response = response_copy;
|
||||||
|
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
chan.send(response);
|
chan.send(response);
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,18 @@
|
||||||
|
|
||||||
#[feature(globs, managed_boxes)];
|
#[feature(globs, managed_boxes)];
|
||||||
|
|
||||||
|
#[feature(phase)];
|
||||||
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
extern crate collections;
|
extern crate collections;
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
extern crate http;
|
extern crate http;
|
||||||
extern crate servo_util = "util";
|
extern crate servo_util = "util";
|
||||||
extern crate stb_image;
|
extern crate stb_image;
|
||||||
extern crate extra;
|
|
||||||
extern crate png;
|
extern crate png;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
|
extern crate url;
|
||||||
|
|
||||||
/// Image handling.
|
/// Image handling.
|
||||||
///
|
///
|
||||||
|
|
|
@ -8,17 +8,17 @@ use file_loader;
|
||||||
use http_loader;
|
use http_loader;
|
||||||
use data_loader;
|
use data_loader;
|
||||||
|
|
||||||
use std::comm::{Chan, Port};
|
use std::comm::{channel, Receiver, Sender};
|
||||||
use std::task;
|
use std::task;
|
||||||
use extra::url::Url;
|
|
||||||
use http::headers::content_type::MediaType;
|
use http::headers::content_type::MediaType;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use std::from_str::FromStr;
|
use std::from_str::FromStr;
|
||||||
|
|
||||||
pub enum ControlMsg {
|
pub enum ControlMsg {
|
||||||
/// Request the data associated with a particular URL
|
/// Request the data associated with a particular URL
|
||||||
Load(Url, Chan<LoadResponse>),
|
Load(Url, Sender<LoadResponse>),
|
||||||
Exit
|
Exit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ pub struct LoadResponse {
|
||||||
/// Metadata, such as from HTTP headers.
|
/// Metadata, such as from HTTP headers.
|
||||||
metadata: Metadata,
|
metadata: Metadata,
|
||||||
/// Port for reading data.
|
/// Port for reading data.
|
||||||
progress_port: Port<ProgressMsg>,
|
progress_port: Receiver<ProgressMsg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Messages sent in response to a `Load` message
|
/// Messages sent in response to a `Load` message
|
||||||
|
@ -84,9 +84,9 @@ pub enum ProgressMsg {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message.
|
/// For use by loaders in responding to a Load message.
|
||||||
pub fn start_sending(start_chan: Chan<LoadResponse>,
|
pub fn start_sending(start_chan: Sender<LoadResponse>,
|
||||||
metadata: Metadata) -> Chan<ProgressMsg> {
|
metadata: Metadata) -> Sender<ProgressMsg> {
|
||||||
let (progress_port, progress_chan) = Chan::new();
|
let (progress_chan, progress_port) = channel();
|
||||||
start_chan.send(LoadResponse {
|
start_chan.send(LoadResponse {
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
progress_port: progress_port,
|
progress_port: progress_port,
|
||||||
|
@ -97,7 +97,7 @@ pub fn start_sending(start_chan: Chan<LoadResponse>,
|
||||||
/// Convenience function for synchronously loading a whole resource.
|
/// Convenience function for synchronously loading a whole resource.
|
||||||
pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
||||||
-> Result<(Metadata, ~[u8]), ()> {
|
-> Result<(Metadata, ~[u8]), ()> {
|
||||||
let (start_port, start_chan) = Chan::new();
|
let (start_chan, start_port) = channel();
|
||||||
resource_task.send(Load(url, start_chan));
|
resource_task.send(Load(url, start_chan));
|
||||||
let response = start_port.recv();
|
let response = start_port.recv();
|
||||||
|
|
||||||
|
@ -112,9 +112,9 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle to a resource task
|
/// Handle to a resource task
|
||||||
pub type ResourceTask = Chan<ControlMsg>;
|
pub type ResourceTask = Sender<ControlMsg>;
|
||||||
|
|
||||||
pub type LoaderTask = proc(url: Url, Chan<LoadResponse>);
|
pub type LoaderTask = proc(url: Url, Sender<LoadResponse>);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Creates a task to load a specific resource
|
Creates a task to load a specific resource
|
||||||
|
@ -135,10 +135,10 @@ pub fn ResourceTask() -> ResourceTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
|
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
|
||||||
let (setup_port, setup_chan) = Chan::new();
|
let (setup_chan, setup_port) = channel();
|
||||||
let builder = task::task().named("ResourceManager");
|
let builder = task::task().named("ResourceManager");
|
||||||
builder.spawn(proc() {
|
builder.spawn(proc() {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
setup_chan.send(chan);
|
setup_chan.send(chan);
|
||||||
ResourceManager(port, loaders).start();
|
ResourceManager(port, loaders).start();
|
||||||
});
|
});
|
||||||
|
@ -146,13 +146,13 @@ fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> R
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ResourceManager {
|
pub struct ResourceManager {
|
||||||
from_client: Port<ControlMsg>,
|
from_client: Receiver<ControlMsg>,
|
||||||
/// Per-scheme resource loaders
|
/// Per-scheme resource loaders
|
||||||
loaders: ~[(~str, LoaderTaskFactory)],
|
loaders: ~[(~str, LoaderTaskFactory)],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn ResourceManager(from_client: Port<ControlMsg>,
|
pub fn ResourceManager(from_client: Receiver<ControlMsg>,
|
||||||
loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceManager {
|
loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceManager {
|
||||||
ResourceManager {
|
ResourceManager {
|
||||||
from_client : from_client,
|
from_client : from_client,
|
||||||
|
@ -175,7 +175,7 @@ impl ResourceManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(&self, url: Url, start_chan: Chan<LoadResponse>) {
|
fn load(&self, url: Url, start_chan: Sender<LoadResponse>) {
|
||||||
match self.get_loader_factory(&url) {
|
match self.get_loader_factory(&url) {
|
||||||
Some(loader_factory) => {
|
Some(loader_factory) => {
|
||||||
debug!("resource_task: loading url: {:s}", url.to_str());
|
debug!("resource_task: loading url: {:s}", url.to_str());
|
||||||
|
@ -211,7 +211,7 @@ fn test_exit() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bad_scheme() {
|
fn test_bad_scheme() {
|
||||||
let resource_task = ResourceTask();
|
let resource_task = ResourceTask();
|
||||||
let (start, start_chan) = Chan::new();
|
let (start_chan, start) = channel();
|
||||||
resource_task.send(Load(FromStr::from_str("bogus://whatever").unwrap(), start_chan));
|
resource_task.send(Load(FromStr::from_str("bogus://whatever").unwrap(), start_chan));
|
||||||
let response = start.recv();
|
let response = start.recv();
|
||||||
match response.progress_port.recv() {
|
match response.progress_port.recv() {
|
||||||
|
@ -226,7 +226,7 @@ static snicklefritz_payload: [u8, ..3] = [1, 2, 3];
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn snicklefritz_loader_factory() -> LoaderTask {
|
fn snicklefritz_loader_factory() -> LoaderTask {
|
||||||
let f: LoaderTask = proc(url: Url, start_chan: Chan<LoadResponse>) {
|
let f: LoaderTask = proc(url: Url, start_chan: Sender<LoadResponse>) {
|
||||||
let progress_chan = start_sending(start_chan, Metadata::default(url));
|
let progress_chan = start_sending(start_chan, Metadata::default(url));
|
||||||
progress_chan.send(Payload(snicklefritz_payload.into_owned()));
|
progress_chan.send(Payload(snicklefritz_payload.into_owned()));
|
||||||
progress_chan.send(Done(Ok(())));
|
progress_chan.send(Done(Ok(())));
|
||||||
|
@ -238,7 +238,7 @@ fn snicklefritz_loader_factory() -> LoaderTask {
|
||||||
fn should_delegate_to_scheme_loader() {
|
fn should_delegate_to_scheme_loader() {
|
||||||
let loader_factories = ~[(~"snicklefritz", snicklefritz_loader_factory)];
|
let loader_factories = ~[(~"snicklefritz", snicklefritz_loader_factory)];
|
||||||
let resource_task = create_resource_task_with_loaders(loader_factories);
|
let resource_task = create_resource_task_with_loaders(loader_factories);
|
||||||
let (start, start_chan) = Chan::new();
|
let (start_chan, start) = channel();
|
||||||
resource_task.send(Load(FromStr::from_str("snicklefritz://heya").unwrap(), start_chan));
|
resource_task.send(Load(FromStr::from_str("snicklefritz://heya").unwrap(), start_chan));
|
||||||
|
|
||||||
let response = start.recv();
|
let response = start.recv();
|
||||||
|
|
|
@ -2023,7 +2023,7 @@ def CreateBindingJSObject(descriptor, parent=None):
|
||||||
assert not descriptor.createGlobal
|
assert not descriptor.createGlobal
|
||||||
handler = """
|
handler = """
|
||||||
let js_info = aScope.get().page().js_info();
|
let js_info = aScope.get().page().js_info();
|
||||||
let handler = js_info.get().get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint));
|
let handler = js_info.get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint));
|
||||||
""" % descriptor.name
|
""" % descriptor.name
|
||||||
create += handler + """ let obj = NewProxyObject(aCx, *handler,
|
create += handler + """ let obj = NewProxyObject(aCx, *handler,
|
||||||
&PrivateValue(squirrel_away_unique(aObject) as *libc::c_void),
|
&PrivateValue(squirrel_away_unique(aObject) as *libc::c_void),
|
||||||
|
@ -2338,12 +2338,12 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
||||||
self.descriptor.name)
|
self.descriptor.name)
|
||||||
else:
|
else:
|
||||||
body += """ js_info.dom_static.attribute_ids.insert(PrototypeList::id::%s as uint,
|
body += """ js_info.dom_static.attribute_ids.insert(PrototypeList::id::%s as uint,
|
||||||
vec::cast_to_mut(vec::from_slice(sAttributes_ids)));
|
slice::cast_to_mut(slice::from_slice(sAttributes_ids)));
|
||||||
""" % self.descriptor.name
|
""" % self.descriptor.name
|
||||||
body = "" #XXXjdm xray stuff isn't necessary yet
|
body = "" #XXXjdm xray stuff isn't necessary yet
|
||||||
|
|
||||||
return (body + """ let cx = js_info.js_context.borrow().ptr;
|
return (body + """ let cx = js_info.js_context.deref().ptr;
|
||||||
let receiver = js_info.js_compartment.borrow().global_obj;
|
let receiver = js_info.js_compartment.global_obj;
|
||||||
let global: *JSObject = JS_GetGlobalForObject(cx, receiver);
|
let global: *JSObject = JS_GetGlobalForObject(cx, receiver);
|
||||||
return %s(cx, global, receiver).is_not_null();""" % (getter))
|
return %s(cx, global, receiver).is_not_null();""" % (getter))
|
||||||
|
|
||||||
|
@ -3700,7 +3700,7 @@ class CGXrayHelper(CGAbstractExternMethod):
|
||||||
methods = self.properties.methods
|
methods = self.properties.methods
|
||||||
if methods.hasNonChromeOnly() or methods.hasChromeOnly():
|
if methods.hasNonChromeOnly() or methods.hasChromeOnly():
|
||||||
methodArgs = "Some(zip_copies(%(methods)s, *method_ids))" % varNames
|
methodArgs = "Some(zip_copies(%(methods)s, *method_ids))" % varNames
|
||||||
setup += "let method_ids = js_info.get().get_ref().dom_static.method_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
|
setup += "let method_ids = js_info.get_ref().dom_static.method_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
|
||||||
else:
|
else:
|
||||||
methodArgs = "None"
|
methodArgs = "None"
|
||||||
methodArgs = CGGeneric(methodArgs)
|
methodArgs = CGGeneric(methodArgs)
|
||||||
|
@ -3708,7 +3708,7 @@ class CGXrayHelper(CGAbstractExternMethod):
|
||||||
attrs = self.properties.attrs
|
attrs = self.properties.attrs
|
||||||
if attrs.hasNonChromeOnly() or attrs.hasChromeOnly():
|
if attrs.hasNonChromeOnly() or attrs.hasChromeOnly():
|
||||||
attrArgs = "Some(zip_copies(%(attrs)s, *attr_ids))" % varNames
|
attrArgs = "Some(zip_copies(%(attrs)s, *attr_ids))" % varNames
|
||||||
setup += "let attr_ids = js_info.get().get_ref().dom_static.attribute_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
|
setup += "let attr_ids = js_info.get_ref().dom_static.attribute_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
|
||||||
else:
|
else:
|
||||||
attrArgs = "None"
|
attrArgs = "None"
|
||||||
attrArgs = CGGeneric(attrArgs)
|
attrArgs = CGGeneric(attrArgs)
|
||||||
|
@ -3716,7 +3716,7 @@ class CGXrayHelper(CGAbstractExternMethod):
|
||||||
consts = self.properties.consts
|
consts = self.properties.consts
|
||||||
if consts.hasNonChromeOnly() or consts.hasChromeOnly():
|
if consts.hasNonChromeOnly() or consts.hasChromeOnly():
|
||||||
constArgs = "Some(zip_copies(%(consts)s, *const_ids))" % varNames
|
constArgs = "Some(zip_copies(%(consts)s, *const_ids))" % varNames
|
||||||
setup += "let const_ids = js_info.get().get_ref().dom_static.constant_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
|
setup += "let const_ids = js_info.get_ref().dom_static.constant_ids.get(&(PrototypeList::id::ClientRect as uint));\n"
|
||||||
else:
|
else:
|
||||||
constArgs = "None"
|
constArgs = "None"
|
||||||
constArgs = CGGeneric(constArgs)
|
constArgs = CGGeneric(constArgs)
|
||||||
|
@ -4774,7 +4774,7 @@ class CGBindingRoot(CGThing):
|
||||||
'std::cmp',
|
'std::cmp',
|
||||||
'std::libc',
|
'std::libc',
|
||||||
'std::ptr',
|
'std::ptr',
|
||||||
'std::vec',
|
'std::slice',
|
||||||
'std::str',
|
'std::str',
|
||||||
'std::num',
|
'std::num',
|
||||||
])
|
])
|
||||||
|
@ -5336,7 +5336,7 @@ class CallbackMember(CGNativeMember):
|
||||||
if self.argCount > 0:
|
if self.argCount > 0:
|
||||||
replacements["argCount"] = self.argCountStr
|
replacements["argCount"] = self.argCountStr
|
||||||
replacements["argvDecl"] = string.Template(
|
replacements["argvDecl"] = string.Template(
|
||||||
"let mut argv = vec::from_elem(${argCount}, UndefinedValue());\n"
|
"let mut argv = slice::from_elem(${argCount}, UndefinedValue());\n"
|
||||||
).substitute(replacements)
|
).substitute(replacements)
|
||||||
else:
|
else:
|
||||||
# Avoid weird 0-sized arrays
|
# Avoid weird 0-sized arrays
|
||||||
|
|
|
@ -17,6 +17,7 @@ use js::jsval::JSVal;
|
||||||
use js::jsval::{NullValue, BooleanValue, Int32Value, UInt32Value, StringValue};
|
use js::jsval::{NullValue, BooleanValue, Int32Value, UInt32Value, StringValue};
|
||||||
use js::jsval::ObjectValue;
|
use js::jsval::ObjectValue;
|
||||||
use js::glue::RUST_JS_NumberValue;
|
use js::glue::RUST_JS_NumberValue;
|
||||||
|
use std::default::Default;
|
||||||
use std::libc;
|
use std::libc;
|
||||||
|
|
||||||
pub trait ToJSValConvertible {
|
pub trait ToJSValConvertible {
|
||||||
|
|
|
@ -64,14 +64,14 @@ impl<T> JS<T> {
|
||||||
pub fn get<'a>(&'a self) -> &'a T {
|
pub fn get<'a>(&'a self) -> &'a T {
|
||||||
let borrowed = self.ptr.borrow();
|
let borrowed = self.ptr.borrow();
|
||||||
unsafe {
|
unsafe {
|
||||||
&(**borrowed.get())
|
&**borrowed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
|
pub fn get_mut<'a>(&'a mut self) -> &'a mut T {
|
||||||
let mut borrowed = self.ptr.borrow_mut();
|
let mut borrowed = self.ptr.borrow_mut();
|
||||||
unsafe {
|
unsafe {
|
||||||
&mut (**borrowed.get())
|
&mut **borrowed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ use std::cmp::Eq;
|
||||||
use std::libc;
|
use std::libc;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::ptr::null;
|
use std::ptr::null;
|
||||||
|
use std::slice;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::vec;
|
|
||||||
use js::glue::*;
|
use js::glue::*;
|
||||||
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
|
use js::glue::{js_IsObjectProxyClass, js_IsFunctionProxyClass, IsProxyHandlerFamily};
|
||||||
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction};
|
use js::jsapi::{JS_AlreadyHasOwnProperty, JS_NewFunction};
|
||||||
|
@ -136,7 +136,7 @@ pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> DOMString {
|
||||||
unsafe {
|
unsafe {
|
||||||
let length = 0;
|
let length = 0;
|
||||||
let chars = JS_GetStringCharsAndLength(cx, s, &length);
|
let chars = JS_GetStringCharsAndLength(cx, s, &length);
|
||||||
vec::raw::buf_as_slice(chars, length as uint, |char_vec| {
|
slice::raw::buf_as_slice(chars, length as uint, |char_vec| {
|
||||||
str::from_utf16(char_vec).unwrap()
|
str::from_utf16(char_vec).unwrap()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -646,8 +646,8 @@ pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> {
|
||||||
fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext {
|
fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext {
|
||||||
let win = global_object_for_js_object(obj);
|
let win = global_object_for_js_object(obj);
|
||||||
let js_info = win.get().page().js_info();
|
let js_info = win.get().page().js_info();
|
||||||
match *js_info.get() {
|
match *js_info {
|
||||||
Some(ref info) => info.js_context.borrow().ptr,
|
Some(ref info) => info.js_context.deref().ptr,
|
||||||
None => fail!("no JS context for DOM global")
|
None => fail!("no JS context for DOM global")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,9 @@ use servo_util::namespace::{Namespace, Null};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
use collections::hashmap::HashMap;
|
use collections::hashmap::HashMap;
|
||||||
use extra::url::{Url, from_str};
|
|
||||||
use js::jsapi::JSContext;
|
use js::jsapi::JSContext;
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
|
use url::{Url, from_str};
|
||||||
|
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
|
|
||||||
|
@ -610,12 +610,14 @@ impl Document {
|
||||||
|
|
||||||
// TODO: support the case if multiple elements
|
// TODO: support the case if multiple elements
|
||||||
// which haves same id are in the same document.
|
// which haves same id are in the same document.
|
||||||
self.idmap.mangle(id, element,
|
// This would use mangle(), but some dumbass removed it.
|
||||||
|_, new_element: &JS<Element>| -> JS<Element> {
|
match self.idmap.find_mut(&id) {
|
||||||
new_element.clone()
|
Some(v) => {
|
||||||
},
|
*v = element.clone();
|
||||||
|_, old_element: &mut JS<Element>, new_element: &JS<Element>| {
|
return;
|
||||||
*old_element = new_element.clone();
|
},
|
||||||
});
|
None => (),
|
||||||
|
}
|
||||||
|
self.idmap.insert(id, element.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -569,7 +569,7 @@ impl Element {
|
||||||
let doc = self.node.owner_doc();
|
let doc = self.node.owner_doc();
|
||||||
let win = &doc.get().window;
|
let win = &doc.get().window;
|
||||||
let node: JS<Node> = NodeCast::from(abstract_self);
|
let node: JS<Node> = NodeCast::from(abstract_self);
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let addr = node.to_trusted_node_address();
|
let addr = node.to_trusted_node_address();
|
||||||
let ContentBoxesResponse(rects) = win.get().page().query_layout(ContentBoxesQuery(addr, chan), port);
|
let ContentBoxesResponse(rects) = win.get().page().query_layout(ContentBoxesQuery(addr, chan), port);
|
||||||
let rects = rects.map(|r| {
|
let rects = rects.map(|r| {
|
||||||
|
@ -589,7 +589,7 @@ impl Element {
|
||||||
let doc = self.node.owner_doc();
|
let doc = self.node.owner_doc();
|
||||||
let win = &doc.get().window;
|
let win = &doc.get().window;
|
||||||
let node: JS<Node> = NodeCast::from(abstract_self);
|
let node: JS<Node> = NodeCast::from(abstract_self);
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let addr = node.to_trusted_node_address();
|
let addr = node.to_trusted_node_address();
|
||||||
let ContentBoxResponse(rect) = win.get().page().query_layout(ContentBoxQuery(addr, chan), port);
|
let ContentBoxResponse(rect) = win.get().page().query_layout(ContentBoxQuery(addr, chan), port);
|
||||||
ClientRect::new(
|
ClientRect::new(
|
||||||
|
|
|
@ -15,10 +15,10 @@ use dom::node::{Node, ElementNodeTypeId};
|
||||||
use dom::windowproxy::WindowProxy;
|
use dom::windowproxy::WindowProxy;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
enum SandboxAllowance {
|
enum SandboxAllowance {
|
||||||
AllowNothing = 0x00,
|
AllowNothing = 0x00,
|
||||||
|
|
|
@ -13,12 +13,12 @@ use dom::element::{AttributeHandlers, AfterSetAttrListener, BeforeRemoveAttrList
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node};
|
use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node};
|
||||||
use extra::url::Url;
|
|
||||||
use servo_util::geometry::to_px;
|
use servo_util::geometry::to_px;
|
||||||
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
|
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
|
||||||
use servo_net::image_cache_task;
|
use servo_net::image_cache_task;
|
||||||
use servo_util::url::parse_url;
|
use servo_util::url::parse_url;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ impl HTMLImageElement {
|
||||||
let node: JS<Node> = NodeCast::from(abstract_self);
|
let node: JS<Node> = NodeCast::from(abstract_self);
|
||||||
let window = window_from_node(&node);
|
let window = window_from_node(&node);
|
||||||
let page = window.get().page();
|
let page = window.get().page();
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let addr = node.to_trusted_node_address();
|
let addr = node.to_trusted_node_address();
|
||||||
let ContentBoxResponse(rect) = page.query_layout(ContentBoxQuery(addr, chan), port);
|
let ContentBoxResponse(rect) = page.query_layout(ContentBoxQuery(addr, chan), port);
|
||||||
to_px(rect.size.width) as u32
|
to_px(rect.size.width) as u32
|
||||||
|
@ -153,7 +153,7 @@ impl HTMLImageElement {
|
||||||
let node = &self.htmlelement.element.node;
|
let node = &self.htmlelement.element.node;
|
||||||
let doc = node.owner_doc();
|
let doc = node.owner_doc();
|
||||||
let page = doc.get().window.get().page();
|
let page = doc.get().window.get().page();
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let this_node: JS<Node> = NodeCast::from(abstract_self);
|
let this_node: JS<Node> = NodeCast::from(abstract_self);
|
||||||
let addr = this_node.to_trusted_node_address();
|
let addr = this_node.to_trusted_node_address();
|
||||||
let ContentBoxResponse(rect) = page.query_layout(ContentBoxQuery(addr, chan), port);
|
let ContentBoxResponse(rect) = page.query_layout(ContentBoxQuery(addr, chan), port);
|
||||||
|
|
|
@ -18,12 +18,12 @@ use dom::validitystate::ValidityState;
|
||||||
use dom::windowproxy::WindowProxy;
|
use dom::windowproxy::WindowProxy;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use servo_net::image_cache_task;
|
use servo_net::image_cache_task;
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_util::url::parse_url;
|
use servo_util::url::parse_url;
|
||||||
use servo_util::namespace::Null;
|
use servo_util::namespace::Null;
|
||||||
use servo_util::url::is_image_data;
|
use servo_util::url::is_image_data;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct HTMLObjectElement {
|
pub struct HTMLObjectElement {
|
||||||
|
|
|
@ -27,7 +27,7 @@ struct Untraceable {
|
||||||
|
|
||||||
impl<S: Encoder> Encodable<S> for Untraceable {
|
impl<S: Encoder> Encodable<S> for Untraceable {
|
||||||
fn encode(&self, s: &mut S) {
|
fn encode(&self, s: &mut S) {
|
||||||
self.page.borrow().encode(s);
|
self.page.encode(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ impl Location {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Href(&self) -> DOMString {
|
pub fn Href(&self) -> DOMString {
|
||||||
self.extra.page.borrow().get_url().to_str()
|
self.extra.page.get_url().to_str()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn SetHref(&self, _href: DOMString) -> Fallible<()> {
|
pub fn SetHref(&self, _href: DOMString) -> Fallible<()> {
|
||||||
|
|
|
@ -162,14 +162,12 @@ impl LayoutDataRef {
|
||||||
/// Returns true if there is layout data present.
|
/// Returns true if there is layout data present.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_present(&self) -> bool {
|
pub fn is_present(&self) -> bool {
|
||||||
let data_ref = self.data_cell.borrow();
|
self.data_cell.borrow().is_some()
|
||||||
data_ref.get().is_some()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Take the chan out of the layout data if it is present.
|
/// Take the chan out of the layout data if it is present.
|
||||||
pub fn take_chan(&self) -> Option<LayoutChan> {
|
pub fn take_chan(&self) -> Option<LayoutChan> {
|
||||||
let mut data_ref = self.data_cell.borrow_mut();
|
let mut layout_data = self.data_cell.borrow_mut();
|
||||||
let layout_data = data_ref.get();
|
|
||||||
match *layout_data {
|
match *layout_data {
|
||||||
None => None,
|
None => None,
|
||||||
Some(..) => Some(layout_data.get_mut_ref().chan.take_unwrap()),
|
Some(..) => Some(layout_data.get_mut_ref().chan.take_unwrap()),
|
||||||
|
@ -1353,7 +1351,7 @@ impl Node {
|
||||||
if copy.is_document() {
|
if copy.is_document() {
|
||||||
document = DocumentCast::to(©).unwrap();
|
document = DocumentCast::to(©).unwrap();
|
||||||
}
|
}
|
||||||
assert_eq!(copy.get().owner_doc(), &document);
|
assert!(copy.get().owner_doc() == &document);
|
||||||
|
|
||||||
// Step 4 (some data already copied in step 2).
|
// Step 4 (some data already copied in step 2).
|
||||||
match node.type_id() {
|
match node.type_id() {
|
||||||
|
|
|
@ -28,14 +28,14 @@ use js::JSPROP_ENUMERATE;
|
||||||
use collections::hashmap::HashMap;
|
use collections::hashmap::HashMap;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::comm::Chan;
|
use std::comm::{channel, Sender, Receiver};
|
||||||
use std::comm::Select;
|
use std::comm::Select;
|
||||||
use std::hash::{Hash, sip};
|
use std::hash::{Hash, sip};
|
||||||
use std::io::timer::Timer;
|
use std::io::timer::Timer;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
use extra::url::{Url};
|
use url::Url;
|
||||||
|
|
||||||
pub enum TimerControlMsg {
|
pub enum TimerControlMsg {
|
||||||
TimerMessageFire(~TimerData),
|
TimerMessageFire(~TimerData),
|
||||||
|
@ -45,7 +45,7 @@ pub enum TimerControlMsg {
|
||||||
|
|
||||||
pub struct TimerHandle {
|
pub struct TimerHandle {
|
||||||
handle: i32,
|
handle: i32,
|
||||||
cancel_chan: Option<Chan<()>>,
|
cancel_chan: Option<Sender<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Encoder> Encodable<S> for TimerHandle {
|
impl<S: Encoder> Encodable<S> for TimerHandle {
|
||||||
|
@ -65,6 +65,12 @@ impl Eq for TimerHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TotalEq for TimerHandle {
|
||||||
|
fn equals(&self, other: &TimerHandle) -> bool {
|
||||||
|
self.eq(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TimerHandle {
|
impl TimerHandle {
|
||||||
fn cancel(&self) {
|
fn cancel(&self) {
|
||||||
self.cancel_chan.as_ref().map(|chan| chan.send(()));
|
self.cancel_chan.as_ref().map(|chan| chan.send(()));
|
||||||
|
@ -87,25 +93,23 @@ pub struct Window {
|
||||||
struct Untraceable {
|
struct Untraceable {
|
||||||
page: Rc<Page>,
|
page: Rc<Page>,
|
||||||
compositor: ~ScriptListener,
|
compositor: ~ScriptListener,
|
||||||
timer_chan: Chan<TimerControlMsg>,
|
timer_chan: Sender<TimerControlMsg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Encoder> Encodable<S> for Untraceable {
|
impl<S: Encoder> Encodable<S> for Untraceable {
|
||||||
fn encode(&self, s: &mut S) {
|
fn encode(&self, s: &mut S) {
|
||||||
let page = self.page.borrow();
|
self.page.encode(s);
|
||||||
page.encode(s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
pub fn get_cx(&self) -> *JSObject {
|
pub fn get_cx(&self) -> *JSObject {
|
||||||
let js_info = self.page().js_info();
|
let js_info = self.page().js_info();
|
||||||
(*js_info.get()).get_ref().js_compartment.borrow().cx.borrow().ptr
|
js_info.get_ref().js_compartment.cx.deref().ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page<'a>(&'a self) -> &'a Page {
|
pub fn page<'a>(&'a self) -> &'a Page {
|
||||||
let page = &self.extra.page;
|
&*self.extra.page
|
||||||
page.borrow()
|
|
||||||
}
|
}
|
||||||
pub fn get_url(&self) -> Url {
|
pub fn get_url(&self) -> Url {
|
||||||
self.page().get_url()
|
self.page().get_url()
|
||||||
|
@ -143,7 +147,7 @@ impl Window {
|
||||||
|
|
||||||
pub fn Document(&self) -> JS<Document> {
|
pub fn Document(&self) -> JS<Document> {
|
||||||
let frame = self.page().frame();
|
let frame = self.page().frame();
|
||||||
(*frame.get()).get_ref().document.clone()
|
frame.get_ref().document.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Name(&self) -> DOMString {
|
pub fn Name(&self) -> DOMString {
|
||||||
|
@ -233,7 +237,7 @@ impl Window {
|
||||||
// Post a delayed message to the per-window timer task; it will dispatch it
|
// Post a delayed message to the per-window timer task; it will dispatch it
|
||||||
// to the relevant script handler that will deal with it.
|
// to the relevant script handler that will deal with it.
|
||||||
let tm = Timer::new().unwrap();
|
let tm = Timer::new().unwrap();
|
||||||
let (cancel_port, cancel_chan) = Chan::new();
|
let (cancel_chan, cancel_port) = channel();
|
||||||
let chan = self.extra.timer_chan.clone();
|
let chan = self.extra.timer_chan.clone();
|
||||||
spawn_named("Window:SetTimeout", proc() {
|
spawn_named("Window:SetTimeout", proc() {
|
||||||
let mut tm = tm;
|
let mut tm = tm;
|
||||||
|
@ -294,8 +298,8 @@ impl Window {
|
||||||
compositor: compositor,
|
compositor: compositor,
|
||||||
page: page.clone(),
|
page: page.clone(),
|
||||||
timer_chan: {
|
timer_chan: {
|
||||||
let (timer_port, timer_chan): (Port<TimerControlMsg>, Chan<TimerControlMsg>) = Chan::new();
|
let (timer_chan, timer_port): (Sender<TimerControlMsg>, Receiver<TimerControlMsg>) = channel();
|
||||||
let id = page.borrow().id.clone();
|
let id = page.id.clone();
|
||||||
spawn_named("timer controller", proc() {
|
spawn_named("timer controller", proc() {
|
||||||
let ScriptChan(script_chan) = script_chan;
|
let ScriptChan(script_chan) = script_chan;
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
|
|
||||||
/// Some little helpers for hooking up the HTML parser with the CSS parser.
|
/// Some little helpers for hooking up the HTML parser with the CSS parser.
|
||||||
|
|
||||||
use std::comm::Port;
|
use std::comm::{channel, Receiver};
|
||||||
use encoding::EncodingRef;
|
use encoding::EncodingRef;
|
||||||
use encoding::all::UTF_8;
|
use encoding::all::UTF_8;
|
||||||
use style::Stylesheet;
|
use style::Stylesheet;
|
||||||
use servo_net::resource_task::{Load, LoadResponse, ProgressMsg, Payload, Done, ResourceTask};
|
use servo_net::resource_task::{Load, LoadResponse, ProgressMsg, Payload, Done, ResourceTask};
|
||||||
use servo_util::task::spawn_named;
|
use servo_util::task::spawn_named;
|
||||||
use extra::url::Url;
|
use url::Url;
|
||||||
|
|
||||||
/// Where a style sheet comes from.
|
/// Where a style sheet comes from.
|
||||||
pub enum StylesheetProvenance {
|
pub enum StylesheetProvenance {
|
||||||
|
@ -20,8 +20,8 @@ pub enum StylesheetProvenance {
|
||||||
|
|
||||||
pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
||||||
resource_task: ResourceTask)
|
resource_task: ResourceTask)
|
||||||
-> Port<Stylesheet> {
|
-> Receiver<Stylesheet> {
|
||||||
let (result_port, result_chan) = Chan::new();
|
let (result_chan, result_port) = channel();
|
||||||
|
|
||||||
// TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
|
// TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
|
||||||
let environment_encoding = UTF_8 as EncodingRef;
|
let environment_encoding = UTF_8 as EncodingRef;
|
||||||
|
@ -30,7 +30,7 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
||||||
let sheet = match provenance {
|
let sheet = match provenance {
|
||||||
UrlProvenance(url) => {
|
UrlProvenance(url) => {
|
||||||
debug!("cssparse: loading style sheet at {:s}", url.to_str());
|
debug!("cssparse: loading style sheet at {:s}", url.to_str());
|
||||||
let (input_port, input_chan) = Chan::new();
|
let (input_chan, input_port) = channel();
|
||||||
resource_task.send(Load(url, input_chan));
|
resource_task.send(Load(url, input_chan));
|
||||||
let LoadResponse { metadata: metadata, progress_port: progress_port }
|
let LoadResponse { metadata: metadata, progress_port: progress_port }
|
||||||
= input_port.recv();
|
= input_port.recv();
|
||||||
|
@ -52,7 +52,7 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProgressMsgPortIterator {
|
struct ProgressMsgPortIterator {
|
||||||
progress_port: Port<ProgressMsg>
|
progress_port: Receiver<ProgressMsg>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator<~[u8]> for ProgressMsgPortIterator {
|
impl Iterator<~[u8]> for ProgressMsgPortIterator {
|
||||||
|
|
|
@ -17,7 +17,6 @@ use dom::types::*;
|
||||||
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
|
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
|
||||||
use script_task::Page;
|
use script_task::Page;
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use hubbub::hubbub;
|
use hubbub::hubbub;
|
||||||
use servo_msg::constellation_msg::SubpageId;
|
use servo_msg::constellation_msg::SubpageId;
|
||||||
use servo_net::resource_task::{Load, Payload, Done, ResourceTask, load_whole_resource};
|
use servo_net::resource_task::{Load, Payload, Done, ResourceTask, load_whole_resource};
|
||||||
|
@ -28,9 +27,10 @@ use servo_util::url::parse_url;
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::comm::{Port, Chan};
|
use std::comm::{channel, Sender, Receiver};
|
||||||
use std::str;
|
use std::str;
|
||||||
use style::Stylesheet;
|
use style::Stylesheet;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
macro_rules! handle_element(
|
macro_rules! handle_element(
|
||||||
($document: expr,
|
($document: expr,
|
||||||
|
@ -71,7 +71,7 @@ pub enum HtmlDiscoveryMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct HtmlParserResult {
|
pub struct HtmlParserResult {
|
||||||
discovery_port: Port<HtmlDiscoveryMessage>,
|
discovery_port: Receiver<HtmlDiscoveryMessage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait NodeWrapping {
|
trait NodeWrapping {
|
||||||
|
@ -103,8 +103,8 @@ spawned, collates them, and sends them to the given result channel.
|
||||||
* `from_parent` - A port on which to receive new links.
|
* `from_parent` - A port on which to receive new links.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
fn css_link_listener(to_parent: Chan<HtmlDiscoveryMessage>,
|
fn css_link_listener(to_parent: Sender<HtmlDiscoveryMessage>,
|
||||||
from_parent: Port<CSSMessage>,
|
from_parent: Receiver<CSSMessage>,
|
||||||
resource_task: ResourceTask) {
|
resource_task: ResourceTask) {
|
||||||
let mut result_vec = ~[];
|
let mut result_vec = ~[];
|
||||||
|
|
||||||
|
@ -126,8 +126,8 @@ fn css_link_listener(to_parent: Chan<HtmlDiscoveryMessage>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn js_script_listener(to_parent: Chan<HtmlDiscoveryMessage>,
|
fn js_script_listener(to_parent: Sender<HtmlDiscoveryMessage>,
|
||||||
from_parent: Port<JSMessage>,
|
from_parent: Receiver<JSMessage>,
|
||||||
resource_task: ResourceTask) {
|
resource_task: ResourceTask) {
|
||||||
let mut result_vec = ~[];
|
let mut result_vec = ~[];
|
||||||
|
|
||||||
|
@ -256,9 +256,9 @@ pub fn parse_html(page: &Page,
|
||||||
// Spawn a CSS parser to receive links to CSS style sheets.
|
// Spawn a CSS parser to receive links to CSS style sheets.
|
||||||
let resource_task2 = resource_task.clone();
|
let resource_task2 = resource_task.clone();
|
||||||
|
|
||||||
let (discovery_port, discovery_chan) = Chan::new();
|
let (discovery_chan, discovery_port) = channel();
|
||||||
let stylesheet_chan = discovery_chan.clone();
|
let stylesheet_chan = discovery_chan.clone();
|
||||||
let (css_msg_port, css_chan) = Chan::new();
|
let (css_chan, css_msg_port) = channel();
|
||||||
spawn_named("parse_html:css", proc() {
|
spawn_named("parse_html:css", proc() {
|
||||||
css_link_listener(stylesheet_chan, css_msg_port, resource_task2.clone());
|
css_link_listener(stylesheet_chan, css_msg_port, resource_task2.clone());
|
||||||
});
|
});
|
||||||
|
@ -266,13 +266,13 @@ pub fn parse_html(page: &Page,
|
||||||
// Spawn a JS parser to receive JavaScript.
|
// Spawn a JS parser to receive JavaScript.
|
||||||
let resource_task2 = resource_task.clone();
|
let resource_task2 = resource_task.clone();
|
||||||
let js_result_chan = discovery_chan.clone();
|
let js_result_chan = discovery_chan.clone();
|
||||||
let (js_msg_port, js_chan) = Chan::new();
|
let (js_chan, js_msg_port) = channel();
|
||||||
spawn_named("parse_html:js", proc() {
|
spawn_named("parse_html:js", proc() {
|
||||||
js_script_listener(js_result_chan, js_msg_port, resource_task2.clone());
|
js_script_listener(js_result_chan, js_msg_port, resource_task2.clone());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for the LoadResponse so that the parser knows the final URL.
|
// Wait for the LoadResponse so that the parser knows the final URL.
|
||||||
let (input_port, input_chan) = Chan::new();
|
let (input_chan, input_port) = channel();
|
||||||
resource_task.send(Load(url.clone(), input_chan));
|
resource_task.send(Load(url.clone(), input_chan));
|
||||||
let load_response = input_port.recv();
|
let load_response = input_port.recv();
|
||||||
|
|
||||||
|
@ -286,8 +286,7 @@ pub fn parse_html(page: &Page,
|
||||||
// Store the final URL before we start parsing, so that DOM routines
|
// Store the final URL before we start parsing, so that DOM routines
|
||||||
// (e.g. HTMLImageElement::update_image) can resolve relative URLs
|
// (e.g. HTMLImageElement::update_image) can resolve relative URLs
|
||||||
// correctly.
|
// correctly.
|
||||||
let mut page_url = page.mut_url();
|
*page.mut_url() = Some((url2.clone(), true));
|
||||||
*page_url.get() = Some((url2.clone(), true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let pipeline_id = page.id;
|
let pipeline_id = page.id;
|
||||||
|
@ -310,7 +309,7 @@ pub fn parse_html(page: &Page,
|
||||||
debug!("create comment");
|
debug!("create comment");
|
||||||
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
||||||
let tmp_borrow = doc_cell.borrow();
|
let tmp_borrow = doc_cell.borrow();
|
||||||
let tmp = tmp_borrow.get();
|
let tmp = &*tmp_borrow;
|
||||||
let comment: JS<Node> = NodeCast::from(&Comment::new(data, *tmp));
|
let comment: JS<Node> = NodeCast::from(&Comment::new(data, *tmp));
|
||||||
unsafe { comment.to_hubbub_node() }
|
unsafe { comment.to_hubbub_node() }
|
||||||
},
|
},
|
||||||
|
@ -322,7 +321,7 @@ pub fn parse_html(page: &Page,
|
||||||
force_quirks: _ } = doctype;
|
force_quirks: _ } = doctype;
|
||||||
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
||||||
let tmp_borrow = doc_cell.borrow();
|
let tmp_borrow = doc_cell.borrow();
|
||||||
let tmp = tmp_borrow.get();
|
let tmp = &*tmp_borrow;
|
||||||
let doctype_node = DocumentType::new(name, public_id, system_id, *tmp);
|
let doctype_node = DocumentType::new(name, public_id, system_id, *tmp);
|
||||||
unsafe {
|
unsafe {
|
||||||
doctype_node.to_hubbub_node()
|
doctype_node.to_hubbub_node()
|
||||||
|
@ -332,7 +331,7 @@ pub fn parse_html(page: &Page,
|
||||||
debug!("create element");
|
debug!("create element");
|
||||||
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
||||||
let tmp_borrow = doc_cell.borrow();
|
let tmp_borrow = doc_cell.borrow();
|
||||||
let tmp = tmp_borrow.get();
|
let tmp = &*tmp_borrow;
|
||||||
let mut element = build_element_from_tag(tag.name.clone(), *tmp);
|
let mut element = build_element_from_tag(tag.name.clone(), *tmp);
|
||||||
|
|
||||||
debug!("-- attach attrs");
|
debug!("-- attach attrs");
|
||||||
|
@ -398,7 +397,7 @@ pub fn parse_html(page: &Page,
|
||||||
debug!("create text");
|
debug!("create text");
|
||||||
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
||||||
let tmp_borrow = doc_cell.borrow();
|
let tmp_borrow = doc_cell.borrow();
|
||||||
let tmp = tmp_borrow.get();
|
let tmp = &*tmp_borrow;
|
||||||
let text = Text::new(data, *tmp);
|
let text = Text::new(data, *tmp);
|
||||||
unsafe { text.to_hubbub_node() }
|
unsafe { text.to_hubbub_node() }
|
||||||
},
|
},
|
||||||
|
@ -448,14 +447,14 @@ pub fn parse_html(page: &Page,
|
||||||
debug!("set quirks mode");
|
debug!("set quirks mode");
|
||||||
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
||||||
let mut tmp_borrow = doc_cell.borrow_mut();
|
let mut tmp_borrow = doc_cell.borrow_mut();
|
||||||
let tmp = tmp_borrow.get();
|
let tmp = &mut *tmp_borrow;
|
||||||
tmp.get_mut().set_quirks_mode(mode);
|
tmp.get_mut().set_quirks_mode(mode);
|
||||||
},
|
},
|
||||||
encoding_change: |encname| {
|
encoding_change: |encname| {
|
||||||
debug!("encoding change");
|
debug!("encoding change");
|
||||||
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
// NOTE: tmp vars are workaround for lifetime issues. Both required.
|
||||||
let mut tmp_borrow = doc_cell.borrow_mut();
|
let mut tmp_borrow = doc_cell.borrow_mut();
|
||||||
let tmp = tmp_borrow.get();
|
let tmp = &mut *tmp_borrow;
|
||||||
tmp.get_mut().set_encoding_name(encname);
|
tmp.get_mut().set_encoding_name(encname);
|
||||||
},
|
},
|
||||||
complete_script: |script| {
|
complete_script: |script| {
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
|
|
||||||
use dom::node::LayoutDataRef;
|
use dom::node::LayoutDataRef;
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::rect::Rect;
|
use geom::rect::Rect;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use script_task::{ScriptChan};
|
use script_task::{ScriptChan};
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::comm::Chan;
|
use std::comm::{channel, Receiver, Sender};
|
||||||
use std::libc::c_void;
|
use std::libc::c_void;
|
||||||
use style::Stylesheet;
|
use style::Stylesheet;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
/// Asynchronous messages that script can send to layout.
|
/// Asynchronous messages that script can send to layout.
|
||||||
///
|
///
|
||||||
|
@ -42,7 +42,7 @@ pub enum Msg {
|
||||||
/// Requests that the layout task enter a quiescent state in which no more messages are
|
/// Requests that the layout task enter a quiescent state in which no more messages are
|
||||||
/// accepted except `ExitMsg`. A response message will be sent on the supplied channel when
|
/// accepted except `ExitMsg`. A response message will be sent on the supplied channel when
|
||||||
/// this happens.
|
/// this happens.
|
||||||
PrepareToExitMsg(Chan<()>),
|
PrepareToExitMsg(Sender<()>),
|
||||||
|
|
||||||
/// Requests that the layout task immediately shut down. There must be no more nodes left after
|
/// Requests that the layout task immediately shut down. There must be no more nodes left after
|
||||||
/// this, or layout will crash.
|
/// this, or layout will crash.
|
||||||
|
@ -52,12 +52,12 @@ pub enum Msg {
|
||||||
/// Synchronous messages that script can send to layout.
|
/// Synchronous messages that script can send to layout.
|
||||||
pub enum LayoutQuery {
|
pub enum LayoutQuery {
|
||||||
/// Requests the dimensions of the content box, as in the `getBoundingClientRect()` call.
|
/// Requests the dimensions of the content box, as in the `getBoundingClientRect()` call.
|
||||||
ContentBoxQuery(TrustedNodeAddress, Chan<ContentBoxResponse>),
|
ContentBoxQuery(TrustedNodeAddress, Sender<ContentBoxResponse>),
|
||||||
/// Requests the dimensions of all the content boxes, as in the `getClientRects()` call.
|
/// Requests the dimensions of all the content boxes, as in the `getClientRects()` call.
|
||||||
ContentBoxesQuery(TrustedNodeAddress, Chan<ContentBoxesResponse>),
|
ContentBoxesQuery(TrustedNodeAddress, Sender<ContentBoxesResponse>),
|
||||||
/// Requests the node containing the point of interest
|
/// Requests the node containing the point of interest
|
||||||
HitTestQuery(TrustedNodeAddress, Point2D<f32>, Chan<Result<HitTestResponse, ()>>),
|
HitTestQuery(TrustedNodeAddress, Point2D<f32>, Sender<Result<HitTestResponse, ()>>),
|
||||||
MouseOverQuery(TrustedNodeAddress, Point2D<f32>, Chan<Result<MouseOverResponse, ()>>),
|
MouseOverQuery(TrustedNodeAddress, Point2D<f32>, Sender<Result<MouseOverResponse, ()>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The address of a node known to be valid. These must only be sent from content -> layout,
|
/// The address of a node known to be valid. These must only be sent from content -> layout,
|
||||||
|
@ -74,7 +74,7 @@ pub struct HitTestResponse(UntrustedNodeAddress);
|
||||||
pub struct MouseOverResponse(~[UntrustedNodeAddress]);
|
pub struct MouseOverResponse(~[UntrustedNodeAddress]);
|
||||||
|
|
||||||
/// Determines which part of the
|
/// Determines which part of the
|
||||||
#[deriving(Eq, Ord)]
|
#[deriving(Eq, Ord, TotalEq, TotalOrd)]
|
||||||
pub enum DocumentDamageLevel {
|
pub enum DocumentDamageLevel {
|
||||||
/// Reflow, but do not perform CSS selector matching.
|
/// Reflow, but do not perform CSS selector matching.
|
||||||
ReflowDocumentDamage,
|
ReflowDocumentDamage,
|
||||||
|
@ -125,18 +125,18 @@ pub struct Reflow {
|
||||||
/// The current window size.
|
/// The current window size.
|
||||||
window_size: Size2D<uint>,
|
window_size: Size2D<uint>,
|
||||||
/// The channel that we send a notification to.
|
/// The channel that we send a notification to.
|
||||||
script_join_chan: Chan<()>,
|
script_join_chan: Sender<()>,
|
||||||
/// Unique identifier
|
/// Unique identifier
|
||||||
id: uint
|
id: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Encapsulates a channel to the layout task.
|
/// Encapsulates a channel to the layout task.
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct LayoutChan(Chan<Msg>);
|
pub struct LayoutChan(Sender<Msg>);
|
||||||
|
|
||||||
impl LayoutChan {
|
impl LayoutChan {
|
||||||
pub fn new() -> (Port<Msg>, LayoutChan) {
|
pub fn new() -> (Receiver<Msg>, LayoutChan) {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
(port, LayoutChan(chan))
|
(port, LayoutChan(chan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,15 @@
|
||||||
|
|
||||||
#[feature(globs, macro_rules, struct_variant, managed_boxes, phase)];
|
#[feature(globs, macro_rules, struct_variant, managed_boxes, phase)];
|
||||||
|
|
||||||
|
#[feature(phase)];
|
||||||
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
extern crate collections;
|
extern crate collections;
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
extern crate hubbub;
|
extern crate hubbub;
|
||||||
extern crate encoding;
|
extern crate encoding;
|
||||||
extern crate js;
|
extern crate js;
|
||||||
|
extern crate native;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
#[phase(syntax)]
|
#[phase(syntax)]
|
||||||
extern crate servo_macros = "macros";
|
extern crate servo_macros = "macros";
|
||||||
|
@ -22,8 +26,7 @@ extern crate servo_net = "net";
|
||||||
extern crate servo_util = "util";
|
extern crate servo_util = "util";
|
||||||
extern crate style;
|
extern crate style;
|
||||||
extern crate servo_msg = "msg";
|
extern crate servo_msg = "msg";
|
||||||
extern crate extra;
|
extern crate url;
|
||||||
extern crate native;
|
|
||||||
|
|
||||||
pub mod dom {
|
pub mod dom {
|
||||||
pub mod bindings {
|
pub mod bindings {
|
||||||
|
|
|
@ -29,7 +29,6 @@ use layout_interface::{Reflow, ReflowDocumentDamage, ReflowForDisplay, ReflowGoa
|
||||||
use layout_interface::ContentChangedDocumentDamage;
|
use layout_interface::ContentChangedDocumentDamage;
|
||||||
use layout_interface;
|
use layout_interface;
|
||||||
|
|
||||||
use extra::url::Url;
|
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
use geom::size::Size2D;
|
use geom::size::Size2D;
|
||||||
use js::global::DEBUG_FNS;
|
use js::global::DEBUG_FNS;
|
||||||
|
@ -51,11 +50,12 @@ use servo_util::task::send_on_failure;
|
||||||
use servo_util::namespace::Null;
|
use servo_util::namespace::Null;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::cell::{RefCell, Ref, RefMut};
|
use std::cell::{RefCell, Ref, RefMut};
|
||||||
use std::comm::{Port, Chan, Empty, Disconnected, Data};
|
use std::comm::{channel, Sender, Receiver, Empty, Disconnected, Data};
|
||||||
use std::mem::replace;
|
use std::mem::replace;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::task;
|
use std::task;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ pub struct NewLayoutInfo {
|
||||||
|
|
||||||
/// Encapsulates external communication with the script task.
|
/// Encapsulates external communication with the script task.
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct ScriptChan(Chan<ScriptMsg>);
|
pub struct ScriptChan(Sender<ScriptMsg>);
|
||||||
|
|
||||||
impl<S: Encoder> Encodable<S> for ScriptChan {
|
impl<S: Encoder> Encodable<S> for ScriptChan {
|
||||||
fn encode(&self, _s: &mut S) {
|
fn encode(&self, _s: &mut S) {
|
||||||
|
@ -100,8 +100,8 @@ impl<S: Encoder> Encodable<S> for ScriptChan {
|
||||||
|
|
||||||
impl ScriptChan {
|
impl ScriptChan {
|
||||||
/// Creates a new script chan.
|
/// Creates a new script chan.
|
||||||
pub fn new() -> (Port<ScriptMsg>, ScriptChan) {
|
pub fn new() -> (Receiver<ScriptMsg>, ScriptChan) {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
(port, ScriptChan(chan))
|
(port, ScriptChan(chan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ pub struct Page {
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
|
|
||||||
/// The port that we will use to join layout. If this is `None`, then layout is not running.
|
/// The port that we will use to join layout. If this is `None`, then layout is not running.
|
||||||
layout_join_port: RefCell<Option<Port<()>>>,
|
layout_join_port: RefCell<Option<Receiver<()>>>,
|
||||||
|
|
||||||
/// What parts of the document are dirty, if any.
|
/// What parts of the document are dirty, if any.
|
||||||
damage: RefCell<Option<DocumentDamage>>,
|
damage: RefCell<Option<DocumentDamage>>,
|
||||||
|
@ -149,7 +149,7 @@ pub struct Page {
|
||||||
impl<S: Encoder> Encodable<S> for Page {
|
impl<S: Encoder> Encodable<S> for Page {
|
||||||
fn encode(&self, s: &mut S) {
|
fn encode(&self, s: &mut S) {
|
||||||
let fragment_node = self.fragment_node.borrow();
|
let fragment_node = self.fragment_node.borrow();
|
||||||
fragment_node.get().encode(s);
|
fragment_node.encode(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ impl PageTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn page<'a>(&'a self) -> &'a Page {
|
fn page<'a>(&'a self) -> &'a Page {
|
||||||
self.page.borrow()
|
&*self.page
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find<'a> (&'a mut self, id: PipelineId) -> Option<&'a mut PageTree> {
|
pub fn find<'a> (&'a mut self, id: PipelineId) -> Option<&'a mut PageTree> {
|
||||||
|
@ -276,8 +276,7 @@ impl Page {
|
||||||
|
|
||||||
/// Adds the given damage.
|
/// Adds the given damage.
|
||||||
pub fn damage(&self, level: DocumentDamageLevel) {
|
pub fn damage(&self, level: DocumentDamageLevel) {
|
||||||
let frame = self.frame();
|
let root = match *self.frame() {
|
||||||
let root = match *frame.get() {
|
|
||||||
None => return,
|
None => return,
|
||||||
Some(ref frame) => frame.document.get().GetDocumentElement()
|
Some(ref frame) => frame.document.get().GetDocumentElement()
|
||||||
};
|
};
|
||||||
|
@ -285,8 +284,8 @@ impl Page {
|
||||||
None => {},
|
None => {},
|
||||||
Some(root) => {
|
Some(root) => {
|
||||||
let root: JS<Node> = NodeCast::from(&root);
|
let root: JS<Node> = NodeCast::from(&root);
|
||||||
let mut damage = self.damage.borrow_mut();
|
let mut damage = *self.damage.borrow_mut();
|
||||||
match *damage.get() {
|
match damage {
|
||||||
None => {}
|
None => {}
|
||||||
Some(ref mut damage) => {
|
Some(ref mut damage) => {
|
||||||
// FIXME(pcwalton): This is wrong. We should trace up to the nearest ancestor.
|
// FIXME(pcwalton): This is wrong. We should trace up to the nearest ancestor.
|
||||||
|
@ -296,7 +295,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*damage.get() = Some(DocumentDamage {
|
*self.damage.borrow_mut() = Some(DocumentDamage {
|
||||||
root: root.to_trusted_node_address(),
|
root: root.to_trusted_node_address(),
|
||||||
level: level,
|
level: level,
|
||||||
})
|
})
|
||||||
|
@ -305,16 +304,15 @@ impl Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_url(&self) -> Url {
|
pub fn get_url(&self) -> Url {
|
||||||
let url = self.url();
|
self.url().get_ref().ref0().clone()
|
||||||
url.get().get_ref().ref0().clone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a ping to layout and waits for the response. The response will arrive when the
|
/// Sends a ping to layout and waits for the response. The response will arrive when the
|
||||||
/// layout task has finished any pending request messages.
|
/// layout task has finished any pending request messages.
|
||||||
pub fn join_layout(&self) {
|
pub fn join_layout(&self) {
|
||||||
let mut layout_join_port = self.layout_join_port.borrow_mut();
|
let mut layout_join_port = self.layout_join_port.borrow_mut();
|
||||||
if layout_join_port.get().is_some() {
|
if layout_join_port.is_some() {
|
||||||
let join_port = replace(layout_join_port.get(), None);
|
let join_port = replace(&mut *layout_join_port, None);
|
||||||
match join_port {
|
match join_port {
|
||||||
Some(ref join_port) => {
|
Some(ref join_port) => {
|
||||||
match join_port.try_recv() {
|
match join_port.try_recv() {
|
||||||
|
@ -338,7 +336,7 @@ impl Page {
|
||||||
/// Sends the given query to layout.
|
/// Sends the given query to layout.
|
||||||
pub fn query_layout<T: Send>(&self,
|
pub fn query_layout<T: Send>(&self,
|
||||||
query: LayoutQuery,
|
query: LayoutQuery,
|
||||||
response_port: Port<T>)
|
response_port: Receiver<T>)
|
||||||
-> T {
|
-> T {
|
||||||
self.join_layout();
|
self.join_layout();
|
||||||
let LayoutChan(ref chan) = self.layout_chan;
|
let LayoutChan(ref chan) = self.layout_chan;
|
||||||
|
@ -357,8 +355,7 @@ impl Page {
|
||||||
goal: ReflowGoal,
|
goal: ReflowGoal,
|
||||||
script_chan: ScriptChan,
|
script_chan: ScriptChan,
|
||||||
compositor: &ScriptListener) {
|
compositor: &ScriptListener) {
|
||||||
let frame = self.frame();
|
let root = match *self.frame() {
|
||||||
let root = match *frame.get() {
|
|
||||||
None => return,
|
None => return,
|
||||||
Some(ref frame) => {
|
Some(ref frame) => {
|
||||||
frame.document.get().GetDocumentElement()
|
frame.document.get().GetDocumentElement()
|
||||||
|
@ -377,12 +374,12 @@ impl Page {
|
||||||
compositor.set_ready_state(PerformingLayout);
|
compositor.set_ready_state(PerformingLayout);
|
||||||
|
|
||||||
// Layout will let us know when it's done.
|
// Layout will let us know when it's done.
|
||||||
let (join_port, join_chan) = Chan::new();
|
let (join_chan, join_port) = channel();
|
||||||
let mut layout_join_port = self.layout_join_port.borrow_mut();
|
let mut layout_join_port = self.layout_join_port.borrow_mut();
|
||||||
*layout_join_port.get() = Some(join_port);
|
*layout_join_port = Some(join_port);
|
||||||
|
|
||||||
let mut last_reflow_id = self.last_reflow_id.borrow_mut();
|
let mut last_reflow_id = self.last_reflow_id.borrow_mut();
|
||||||
*last_reflow_id.get() += 1;
|
*last_reflow_id += 1;
|
||||||
|
|
||||||
let root: JS<Node> = NodeCast::from(&root);
|
let root: JS<Node> = NodeCast::from(&root);
|
||||||
let mut damage = self.damage.borrow_mut();
|
let mut damage = self.damage.borrow_mut();
|
||||||
|
@ -393,11 +390,11 @@ impl Page {
|
||||||
document_root: root.to_trusted_node_address(),
|
document_root: root.to_trusted_node_address(),
|
||||||
url: self.get_url(),
|
url: self.get_url(),
|
||||||
goal: goal,
|
goal: goal,
|
||||||
window_size: *window_size.get(),
|
window_size: *window_size,
|
||||||
script_chan: script_chan,
|
script_chan: script_chan,
|
||||||
script_join_chan: join_chan,
|
script_join_chan: join_chan,
|
||||||
damage: replace(damage.get(), None).unwrap(),
|
damage: replace(&mut *damage, None).unwrap(),
|
||||||
id: *last_reflow_id.get(),
|
id: *last_reflow_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
let LayoutChan(ref chan) = self.layout_chan;
|
let LayoutChan(ref chan) = self.layout_chan;
|
||||||
|
@ -414,8 +411,8 @@ impl Page {
|
||||||
// Note that the order that these variables are initialized is _not_ arbitrary. Switching
|
// Note that the order that these variables are initialized is _not_ arbitrary. Switching
|
||||||
// them around can -- and likely will -- lead to things breaking.
|
// them around can -- and likely will -- lead to things breaking.
|
||||||
|
|
||||||
js_context.borrow().set_default_options_and_version();
|
js_context.set_default_options_and_version();
|
||||||
js_context.borrow().set_logging_error_reporter();
|
js_context.set_logging_error_reporter();
|
||||||
|
|
||||||
let compartment = match js_context.new_compartment_with_global(global) {
|
let compartment = match js_context.new_compartment_with_global(global) {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
|
@ -423,11 +420,11 @@ impl Page {
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_InhibitGC(js_context.borrow().ptr);
|
JS_InhibitGC(js_context.deref().ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut js_info = self.mut_js_info();
|
let mut js_info = self.mut_js_info();
|
||||||
*js_info.get() = Some(JSPageInfo {
|
*js_info = Some(JSPageInfo {
|
||||||
dom_static: GlobalStaticData(),
|
dom_static: GlobalStaticData(),
|
||||||
js_compartment: compartment,
|
js_compartment: compartment,
|
||||||
js_context: js_context,
|
js_context: js_context,
|
||||||
|
@ -467,7 +464,7 @@ pub struct ScriptTask {
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
|
|
||||||
/// The port on which the script task receives messages (load URL, exit, etc.)
|
/// The port on which the script task receives messages (load URL, exit, etc.)
|
||||||
port: Port<ScriptMsg>,
|
port: Receiver<ScriptMsg>,
|
||||||
/// A channel to hand out when some other task needs to be able to respond to a message from
|
/// A channel to hand out when some other task needs to be able to respond to a message from
|
||||||
/// the script task.
|
/// the script task.
|
||||||
chan: ScriptChan,
|
chan: ScriptChan,
|
||||||
|
@ -488,7 +485,7 @@ impl ScriptTask {
|
||||||
pub fn new(id: PipelineId,
|
pub fn new(id: PipelineId,
|
||||||
compositor: ~ScriptListener,
|
compositor: ~ScriptListener,
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
port: Port<ScriptMsg>,
|
port: Receiver<ScriptMsg>,
|
||||||
chan: ScriptChan,
|
chan: ScriptChan,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
resource_task: ResourceTask,
|
resource_task: ResourceTask,
|
||||||
|
@ -525,7 +522,7 @@ impl ScriptTask {
|
||||||
id: PipelineId,
|
id: PipelineId,
|
||||||
compositor: ~C,
|
compositor: ~C,
|
||||||
layout_chan: LayoutChan,
|
layout_chan: LayoutChan,
|
||||||
port: Port<ScriptMsg>,
|
port: Receiver<ScriptMsg>,
|
||||||
chan: ScriptChan,
|
chan: ScriptChan,
|
||||||
constellation_chan: ConstellationChan,
|
constellation_chan: ConstellationChan,
|
||||||
failure_msg: Failure,
|
failure_msg: Failure,
|
||||||
|
@ -545,7 +542,7 @@ impl ScriptTask {
|
||||||
resource_task,
|
resource_task,
|
||||||
image_cache_task,
|
image_cache_task,
|
||||||
window_size);
|
window_size);
|
||||||
script_task.borrow().start();
|
script_task.start();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,13 +554,12 @@ impl ScriptTask {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
for page in page_tree.get().iter() {
|
for page in page_tree.iter() {
|
||||||
// Only process a resize if layout is idle.
|
// Only process a resize if layout is idle.
|
||||||
let page = page.borrow();
|
|
||||||
let layout_join_port = page.layout_join_port.borrow();
|
let layout_join_port = page.layout_join_port.borrow();
|
||||||
if layout_join_port.get().is_none() {
|
if layout_join_port.is_none() {
|
||||||
let mut resize_event = page.resize_event.borrow_mut();
|
let mut resize_event = page.resize_event.borrow_mut();
|
||||||
match resize_event.get().take() {
|
match resize_event.take() {
|
||||||
Some(size) => resizes.push((page.id, size)),
|
Some(size) => resizes.push((page.id, size)),
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
@ -585,9 +581,9 @@ impl ScriptTask {
|
||||||
match event {
|
match event {
|
||||||
ResizeMsg(id, size) => {
|
ResizeMsg(id, size) => {
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
let page = page_tree.get().find(id).expect("resize sent to nonexistent pipeline").page();
|
let page = page_tree.find(id).expect("resize sent to nonexistent pipeline").page();
|
||||||
let mut resize_event = page.resize_event.borrow_mut();
|
let mut resize_event = page.resize_event.borrow_mut();
|
||||||
*resize_event.get() = Some(size);
|
*resize_event = Some(size);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
sequential.push(event);
|
sequential.push(event);
|
||||||
|
@ -629,12 +625,12 @@ impl ScriptTask {
|
||||||
} = new_layout_info;
|
} = new_layout_info;
|
||||||
|
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
let parent_page_tree = page_tree.get().find(old_id).expect("ScriptTask: received a layout
|
let parent_page_tree = page_tree.find(old_id).expect("ScriptTask: received a layout
|
||||||
whose parent has a PipelineId which does not correspond to a pipeline in the script
|
whose parent has a PipelineId which does not correspond to a pipeline in the script
|
||||||
task's page tree. This is a bug.");
|
task's page tree. This is a bug.");
|
||||||
let new_page_tree = {
|
let new_page_tree = {
|
||||||
let window_size = parent_page_tree.page().window_size.borrow();
|
let window_size = parent_page_tree.page().window_size.borrow();
|
||||||
PageTree::new(new_id, layout_chan, *window_size.get())
|
PageTree::new(new_id, layout_chan, *window_size)
|
||||||
};
|
};
|
||||||
parent_page_tree.inner.push(new_page_tree);
|
parent_page_tree.inner.push(new_page_tree);
|
||||||
}
|
}
|
||||||
|
@ -642,10 +638,10 @@ impl ScriptTask {
|
||||||
/// Handles a timer that fired.
|
/// Handles a timer that fired.
|
||||||
fn handle_fire_timer_msg(&self, id: PipelineId, timer_data: ~TimerData) {
|
fn handle_fire_timer_msg(&self, id: PipelineId, timer_data: ~TimerData) {
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
let page = page_tree.get().find(id).expect("ScriptTask: received fire timer msg for a
|
let page = page_tree.find(id).expect("ScriptTask: received fire timer msg for a
|
||||||
pipeline ID not associated with this script task. This is a bug.").page();
|
pipeline ID not associated with this script task. This is a bug.").page();
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
let mut window = frame.get().get_ref().window.clone();
|
let mut window = frame.get_ref().window.clone();
|
||||||
|
|
||||||
let timer_handle = window.get_mut().active_timers.pop(&timer_data.handle);
|
let timer_handle = window.get_mut().active_timers.pop(&timer_data.handle);
|
||||||
if timer_handle.is_none() {
|
if timer_handle.is_none() {
|
||||||
|
@ -656,12 +652,12 @@ impl ScriptTask {
|
||||||
let this_value = if timer_data.args.len() > 0 {
|
let this_value = if timer_data.args.len() > 0 {
|
||||||
fail!("NYI")
|
fail!("NYI")
|
||||||
} else {
|
} else {
|
||||||
js_info.get().get_ref().js_compartment.borrow().global_obj
|
js_info.get_ref().js_compartment.global_obj
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`.
|
// TODO: Support extra arguments. This requires passing a `*JSVal` array as `argv`.
|
||||||
let rval = NullValue();
|
let rval = NullValue();
|
||||||
let cx = js_info.get().get_ref().js_context.borrow().ptr;
|
let cx = js_info.get_ref().js_context.deref().ptr;
|
||||||
with_gc_enabled(cx, || {
|
with_gc_enabled(cx, || {
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_CallFunctionValue(cx, this_value, timer_data.funval, 0, ptr::null(), &rval);
|
JS_CallFunctionValue(cx, this_value, timer_data.funval, 0, ptr::null(), &rval);
|
||||||
|
@ -673,13 +669,13 @@ impl ScriptTask {
|
||||||
fn handle_reflow_complete_msg(&self, pipeline_id: PipelineId, reflow_id: uint) {
|
fn handle_reflow_complete_msg(&self, pipeline_id: PipelineId, reflow_id: uint) {
|
||||||
debug!("Script: Reflow {:?} complete for {:?}", reflow_id, pipeline_id);
|
debug!("Script: Reflow {:?} complete for {:?}", reflow_id, pipeline_id);
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
let page = page_tree.get().find(pipeline_id).expect(
|
let page = page_tree.find(pipeline_id).expect(
|
||||||
"ScriptTask: received a load message for a layout channel that is not associated \
|
"ScriptTask: received a load message for a layout channel that is not associated \
|
||||||
with this script task. This is a bug.").page();
|
with this script task. This is a bug.").page();
|
||||||
let last_reflow_id = page.last_reflow_id.borrow();
|
let last_reflow_id = page.last_reflow_id.borrow();
|
||||||
if *last_reflow_id.get() == reflow_id {
|
if *last_reflow_id == reflow_id {
|
||||||
let mut layout_join_port = page.layout_join_port.borrow_mut();
|
let mut layout_join_port = page.layout_join_port.borrow_mut();
|
||||||
*layout_join_port.get() = None;
|
*layout_join_port = None;
|
||||||
}
|
}
|
||||||
self.compositor.set_ready_state(FinishedLoading);
|
self.compositor.set_ready_state(FinishedLoading);
|
||||||
}
|
}
|
||||||
|
@ -694,14 +690,14 @@ impl ScriptTask {
|
||||||
/// Window was resized, but this script was not active, so don't reflow yet
|
/// Window was resized, but this script was not active, so don't reflow yet
|
||||||
fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: Size2D<uint>) {
|
fn handle_resize_inactive_msg(&self, id: PipelineId, new_size: Size2D<uint>) {
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
let page = page_tree.get().find(id).expect("Received resize message for PipelineId not associated
|
let page = page_tree.find(id).expect("Received resize message for PipelineId not associated
|
||||||
with a page in the page tree. This is a bug.").page();
|
with a page in the page tree. This is a bug.").page();
|
||||||
let mut window_size = page.window_size.borrow_mut();
|
let mut window_size = page.window_size.borrow_mut();
|
||||||
*window_size.get() = new_size;
|
*window_size = new_size;
|
||||||
let mut page_url = page.mut_url();
|
let mut page_url = page.mut_url();
|
||||||
let last_loaded_url = replace(page_url.get(), None);
|
let last_loaded_url = replace(&mut *page_url, None);
|
||||||
for url in last_loaded_url.iter() {
|
for url in last_loaded_url.iter() {
|
||||||
*page_url.get() = Some((url.ref0().clone(), true));
|
*page_url = Some((url.ref0().clone(), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,22 +720,20 @@ impl ScriptTask {
|
||||||
fn handle_exit_pipeline_msg(&self, id: PipelineId) -> bool {
|
fn handle_exit_pipeline_msg(&self, id: PipelineId) -> bool {
|
||||||
// If root is being exited, shut down all pages
|
// If root is being exited, shut down all pages
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
if page_tree.get().page().id == id {
|
if page_tree.page().id == id {
|
||||||
for page in page_tree.get().iter() {
|
for page in page_tree.iter() {
|
||||||
let page = page.borrow();
|
|
||||||
debug!("shutting down layout for root page {:?}", page.id);
|
debug!("shutting down layout for root page {:?}", page.id);
|
||||||
shut_down_layout(page)
|
shut_down_layout(&*page)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise find just the matching page and exit all sub-pages
|
// otherwise find just the matching page and exit all sub-pages
|
||||||
match page_tree.get().remove(id) {
|
match page_tree.remove(id) {
|
||||||
Some(ref mut page_tree) => {
|
Some(ref mut page_tree) => {
|
||||||
for page in page_tree.iter() {
|
for page in page_tree.iter() {
|
||||||
let page = page.borrow();
|
|
||||||
debug!("shutting down layout for page {:?}", page.id);
|
debug!("shutting down layout for page {:?}", page.id);
|
||||||
shut_down_layout(page)
|
shut_down_layout(&*page)
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -757,18 +751,18 @@ impl ScriptTask {
|
||||||
debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id);
|
debug!("ScriptTask: loading {:?} on page {:?}", url, pipeline_id);
|
||||||
|
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
let page_tree = page_tree.get().find(pipeline_id).expect("ScriptTask: received a load
|
let page_tree = page_tree.find(pipeline_id).expect("ScriptTask: received a load
|
||||||
message for a layout channel that is not associated with this script task. This
|
message for a layout channel that is not associated with this script task. This
|
||||||
is a bug.");
|
is a bug.");
|
||||||
let page = page_tree.page();
|
let page = page_tree.page();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut page_url = page.mut_url();
|
let mut page_url = page.mut_url();
|
||||||
let last_loaded_url = replace(page_url.get(), None);
|
let last_loaded_url = replace(&mut *page_url, None);
|
||||||
for loaded in last_loaded_url.iter() {
|
for loaded in last_loaded_url.iter() {
|
||||||
let (ref loaded, needs_reflow) = *loaded;
|
let (ref loaded, needs_reflow) = *loaded;
|
||||||
if *loaded == url {
|
if *loaded == url {
|
||||||
*page_url.get() = Some((loaded.clone(), false));
|
*page_url = Some((loaded.clone(), false));
|
||||||
if needs_reflow {
|
if needs_reflow {
|
||||||
page.damage(ContentChangedDocumentDamage);
|
page.damage(ContentChangedDocumentDamage);
|
||||||
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor);
|
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor);
|
||||||
|
@ -780,7 +774,7 @@ impl ScriptTask {
|
||||||
|
|
||||||
let cx = self.js_runtime.cx();
|
let cx = self.js_runtime.cx();
|
||||||
// Create the window and document objects.
|
// Create the window and document objects.
|
||||||
let window = Window::new(cx.borrow().ptr,
|
let window = Window::new(cx.deref().ptr,
|
||||||
page_tree.page.clone(),
|
page_tree.page.clone(),
|
||||||
self.chan.clone(),
|
self.chan.clone(),
|
||||||
self.compositor.dup(),
|
self.compositor.dup(),
|
||||||
|
@ -789,7 +783,7 @@ impl ScriptTask {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut js_info = page.mut_js_info();
|
let mut js_info = page.mut_js_info();
|
||||||
RegisterBindings::Register(js_info.get().get_mut_ref());
|
RegisterBindings::Register(js_info.get_mut_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.compositor.set_ready_state(Loading);
|
self.compositor.set_ready_state(Loading);
|
||||||
|
@ -809,7 +803,7 @@ impl ScriptTask {
|
||||||
{
|
{
|
||||||
// Create the root frame.
|
// Create the root frame.
|
||||||
let mut frame = page.mut_frame();
|
let mut frame = page.mut_frame();
|
||||||
*frame.get() = Some(Frame {
|
*frame = Some(Frame {
|
||||||
document: document.clone(),
|
document: document.clone(),
|
||||||
window: window.clone(),
|
window: window.clone(),
|
||||||
});
|
});
|
||||||
|
@ -857,7 +851,7 @@ impl ScriptTask {
|
||||||
{
|
{
|
||||||
// No more reflow required
|
// No more reflow required
|
||||||
let mut page_url = page.mut_url();
|
let mut page_url = page.mut_url();
|
||||||
*page_url.get() = Some((url.clone(), false));
|
*page_url = Some((url.clone(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive the JavaScript scripts.
|
// Receive the JavaScript scripts.
|
||||||
|
@ -868,11 +862,10 @@ impl ScriptTask {
|
||||||
// Define debug functions.
|
// Define debug functions.
|
||||||
let cx = {
|
let cx = {
|
||||||
let js_info = page.js_info();
|
let js_info = page.js_info();
|
||||||
let js_info = js_info.get().get_ref();
|
let js_info = js_info.get_ref();
|
||||||
let compartment = js_info.js_compartment.borrow();
|
assert!(js_info.js_compartment.define_functions(DEBUG_FNS).is_ok());
|
||||||
assert!(compartment.define_functions(DEBUG_FNS).is_ok());
|
|
||||||
|
|
||||||
js_info.js_context.borrow().ptr
|
js_info.js_context.deref().ptr
|
||||||
};
|
};
|
||||||
|
|
||||||
// Evaluate every script in the document.
|
// Evaluate every script in the document.
|
||||||
|
@ -880,15 +873,15 @@ impl ScriptTask {
|
||||||
with_gc_enabled(cx, || {
|
with_gc_enabled(cx, || {
|
||||||
let (cx, global_obj) = {
|
let (cx, global_obj) = {
|
||||||
let js_info = page.js_info();
|
let js_info = page.js_info();
|
||||||
(js_info.get().get_ref().js_context.clone(),
|
(js_info.get_ref().js_context.clone(),
|
||||||
js_info.get().get_ref().js_compartment.borrow().global_obj)
|
js_info.get_ref().js_compartment.global_obj)
|
||||||
};
|
};
|
||||||
//FIXME: this should have some kind of error handling, or explicitly
|
//FIXME: this should have some kind of error handling, or explicitly
|
||||||
// drop an exception on the floor.
|
// drop an exception on the floor.
|
||||||
assert!(cx.borrow().evaluate_script(global_obj,
|
assert!(cx.evaluate_script(global_obj,
|
||||||
file.data.clone(),
|
file.data.clone(),
|
||||||
file.url.to_str(),
|
file.url.to_str(),
|
||||||
1).is_ok());
|
1).is_ok());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,7 +896,7 @@ impl ScriptTask {
|
||||||
let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event);
|
let _ = wintarget.get_mut().dispatch_event_with_target(&winclone, Some(doctarget), &mut event);
|
||||||
|
|
||||||
let mut fragment_node = page.fragment_node.borrow_mut();
|
let mut fragment_node = page.fragment_node.borrow_mut();
|
||||||
*fragment_node.get() = fragment.map_or(None, |fragid| self.find_fragment_node(page, fragid));
|
*fragment_node = fragment.map_or(None, |fragid| self.find_fragment_node(page, fragid));
|
||||||
|
|
||||||
let ConstellationChan(ref chan) = self.constellation_chan;
|
let ConstellationChan(ref chan) = self.constellation_chan;
|
||||||
chan.send(LoadCompleteMsg(page.id, url));
|
chan.send(LoadCompleteMsg(page.id, url));
|
||||||
|
@ -911,7 +904,7 @@ impl ScriptTask {
|
||||||
|
|
||||||
fn find_fragment_node(&self, page: &Page, fragid: ~str) -> Option<JS<Element>> {
|
fn find_fragment_node(&self, page: &Page, fragid: ~str) -> Option<JS<Element>> {
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
let document = frame.get().get_ref().document.clone();
|
let document = frame.get_ref().document.clone();
|
||||||
match document.get().GetElementById(fragid.to_owned()) {
|
match document.get().GetElementById(fragid.to_owned()) {
|
||||||
Some(node) => Some(node),
|
Some(node) => Some(node),
|
||||||
None => {
|
None => {
|
||||||
|
@ -928,7 +921,7 @@ impl ScriptTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scroll_fragment_point(&self, pipeline_id: PipelineId, page: &Page, node: JS<Element>) {
|
fn scroll_fragment_point(&self, pipeline_id: PipelineId, page: &Page, node: JS<Element>) {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let node: JS<Node> = NodeCast::from(&node);
|
let node: JS<Node> = NodeCast::from(&node);
|
||||||
let ContentBoxResponse(rect) =
|
let ContentBoxResponse(rect) =
|
||||||
page.query_layout(ContentBoxQuery(node.to_trusted_node_address(), chan), port);
|
page.query_layout(ContentBoxQuery(node.to_trusted_node_address(), chan), port);
|
||||||
|
@ -946,7 +939,7 @@ impl ScriptTask {
|
||||||
/// TODO: Actually perform DOM event dispatch.
|
/// TODO: Actually perform DOM event dispatch.
|
||||||
fn handle_event(&self, pipeline_id: PipelineId, event: Event_) {
|
fn handle_event(&self, pipeline_id: PipelineId, event: Event_) {
|
||||||
let mut page_tree = self.page_tree.borrow_mut();
|
let mut page_tree = self.page_tree.borrow_mut();
|
||||||
let page = page_tree.get().find(pipeline_id).expect("ScriptTask: received an event
|
let page = page_tree.find(pipeline_id).expect("ScriptTask: received an event
|
||||||
message for a layout channel that is not associated with this script task. This
|
message for a layout channel that is not associated with this script task. This
|
||||||
is a bug.").page();
|
is a bug.").page();
|
||||||
|
|
||||||
|
@ -956,25 +949,25 @@ impl ScriptTask {
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut window_size = page.window_size.borrow_mut();
|
let mut window_size = page.window_size.borrow_mut();
|
||||||
*window_size.get() = Size2D(new_width, new_height);
|
*window_size = Size2D(new_width, new_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
if frame.get().is_some() {
|
if frame.is_some() {
|
||||||
page.damage(ReflowDocumentDamage);
|
page.damage(ReflowDocumentDamage);
|
||||||
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor)
|
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut fragment_node = page.fragment_node.borrow_mut();
|
let mut fragment_node = page.fragment_node.borrow_mut();
|
||||||
match fragment_node.get().take() {
|
match fragment_node.take() {
|
||||||
Some(node) => self.scroll_fragment_point(pipeline_id, page, node),
|
Some(node) => self.scroll_fragment_point(pipeline_id, page, node),
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
match *frame.get() {
|
match *frame {
|
||||||
Some(ref frame) => {
|
Some(ref frame) => {
|
||||||
// http://dev.w3.org/csswg/cssom-view/#resizing-viewports
|
// http://dev.w3.org/csswg/cssom-view/#resizing-viewports
|
||||||
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize
|
// https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-resize
|
||||||
|
@ -997,7 +990,7 @@ impl ScriptTask {
|
||||||
debug!("script got reflow event");
|
debug!("script got reflow event");
|
||||||
|
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
if frame.get().is_some() {
|
if frame.is_some() {
|
||||||
page.damage(MatchSelectorsDocumentDamage);
|
page.damage(MatchSelectorsDocumentDamage);
|
||||||
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor)
|
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor)
|
||||||
}
|
}
|
||||||
|
@ -1007,18 +1000,18 @@ impl ScriptTask {
|
||||||
debug!("ClickEvent: clicked at {:?}", point);
|
debug!("ClickEvent: clicked at {:?}", point);
|
||||||
|
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
let document = frame.get().get_ref().document.clone();
|
let document = frame.get_ref().document.clone();
|
||||||
let root = document.get().GetDocumentElement();
|
let root = document.get().GetDocumentElement();
|
||||||
if root.is_none() {
|
if root.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
let root: JS<Node> = NodeCast::from(&root.unwrap());
|
let root: JS<Node> = NodeCast::from(&root.unwrap());
|
||||||
match page.query_layout(HitTestQuery(root.to_trusted_node_address(), point, chan), port) {
|
match page.query_layout(HitTestQuery(root.to_trusted_node_address(), point, chan), port) {
|
||||||
Ok(HitTestResponse(node_address)) => {
|
Ok(HitTestResponse(node_address)) => {
|
||||||
debug!("node address is {:?}", node_address);
|
debug!("node address is {:?}", node_address);
|
||||||
let mut node: JS<Node> =
|
let mut node: JS<Node> =
|
||||||
NodeHelpers::from_untrusted_node_address(self.js_runtime.borrow().ptr,
|
NodeHelpers::from_untrusted_node_address(self.js_runtime.deref().ptr,
|
||||||
node_address);
|
node_address);
|
||||||
debug!("clicked on {:s}", node.debug_str());
|
debug!("clicked on {:s}", node.debug_str());
|
||||||
|
|
||||||
|
@ -1045,21 +1038,21 @@ impl ScriptTask {
|
||||||
MouseUpEvent(..) => {}
|
MouseUpEvent(..) => {}
|
||||||
MouseMoveEvent(point) => {
|
MouseMoveEvent(point) => {
|
||||||
let frame = page.frame();
|
let frame = page.frame();
|
||||||
let document = frame.get().get_ref().document.clone();
|
let document = frame.get_ref().document.clone();
|
||||||
let root = document.get().GetDocumentElement();
|
let root = document.get().GetDocumentElement();
|
||||||
if root.is_none() {
|
if root.is_none() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let root: JS<Node> = NodeCast::from(&root.unwrap());
|
let root: JS<Node> = NodeCast::from(&root.unwrap());
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
match page.query_layout(MouseOverQuery(root.to_trusted_node_address(), point, chan), port) {
|
match page.query_layout(MouseOverQuery(root.to_trusted_node_address(), point, chan), port) {
|
||||||
Ok(MouseOverResponse(node_address)) => {
|
Ok(MouseOverResponse(node_address)) => {
|
||||||
|
|
||||||
let mut target_list: ~[JS<Node>] = ~[];
|
let mut target_list: ~[JS<Node>] = ~[];
|
||||||
let mut target_compare = false;
|
let mut target_compare = false;
|
||||||
|
|
||||||
let mut mouse_over_targets = self.mouse_over_targets.borrow_mut();
|
let mouse_over_targets = &mut *self.mouse_over_targets.borrow_mut();
|
||||||
match *mouse_over_targets.get() {
|
match *mouse_over_targets {
|
||||||
Some(ref mut mouse_over_targets) => {
|
Some(ref mut mouse_over_targets) => {
|
||||||
for node in mouse_over_targets.mut_iter() {
|
for node in mouse_over_targets.mut_iter() {
|
||||||
node.set_hover_state(false);
|
node.set_hover_state(false);
|
||||||
|
@ -1071,7 +1064,7 @@ impl ScriptTask {
|
||||||
for node_address in node_address.iter() {
|
for node_address in node_address.iter() {
|
||||||
let mut node: JS<Node> =
|
let mut node: JS<Node> =
|
||||||
NodeHelpers::from_untrusted_node_address(
|
NodeHelpers::from_untrusted_node_address(
|
||||||
self.js_runtime.borrow().ptr, *node_address);
|
self.js_runtime.deref().ptr, *node_address);
|
||||||
// Traverse node generations until a node that is an element is
|
// Traverse node generations until a node that is an element is
|
||||||
// found.
|
// found.
|
||||||
while !node.is_element() {
|
while !node.is_element() {
|
||||||
|
@ -1084,7 +1077,7 @@ impl ScriptTask {
|
||||||
if node.is_element() {
|
if node.is_element() {
|
||||||
node.set_hover_state(true);
|
node.set_hover_state(true);
|
||||||
|
|
||||||
match *mouse_over_targets.get() {
|
match *mouse_over_targets {
|
||||||
Some(ref mouse_over_targets) => {
|
Some(ref mouse_over_targets) => {
|
||||||
if !target_compare {
|
if !target_compare {
|
||||||
target_compare = !mouse_over_targets.contains(&node);
|
target_compare = !mouse_over_targets.contains(&node);
|
||||||
|
@ -1095,7 +1088,7 @@ impl ScriptTask {
|
||||||
target_list.push(node);
|
target_list.push(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match *mouse_over_targets.get() {
|
match *mouse_over_targets {
|
||||||
Some(ref mouse_over_targets) => {
|
Some(ref mouse_over_targets) => {
|
||||||
if mouse_over_targets.len() != target_list.len() {
|
if mouse_over_targets.len() != target_list.len() {
|
||||||
target_compare = true;
|
target_compare = true;
|
||||||
|
@ -1105,11 +1098,11 @@ impl ScriptTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
if target_compare {
|
if target_compare {
|
||||||
if mouse_over_targets.get().is_some() {
|
if mouse_over_targets.is_some() {
|
||||||
page.damage(MatchSelectorsDocumentDamage);
|
page.damage(MatchSelectorsDocumentDamage);
|
||||||
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor);
|
page.reflow(ReflowForDisplay, self.chan.clone(), self.compositor);
|
||||||
}
|
}
|
||||||
*mouse_over_targets.get() = Some(target_list);
|
*mouse_over_targets = Some(target_list);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(()) => {},
|
Err(()) => {},
|
||||||
|
@ -1146,7 +1139,7 @@ fn shut_down_layout(page: &Page) {
|
||||||
page.join_layout();
|
page.join_layout();
|
||||||
|
|
||||||
// Tell the layout task to begin shutting down.
|
// Tell the layout task to begin shutting down.
|
||||||
let (response_port, response_chan) = Chan::new();
|
let (response_chan, response_port) = channel();
|
||||||
let LayoutChan(ref chan) = page.layout_chan;
|
let LayoutChan(ref chan) = page.layout_chan;
|
||||||
chan.send(layout_interface::PrepareToExitMsg(response_chan));
|
chan.send(layout_interface::PrepareToExitMsg(response_chan));
|
||||||
response_port.recv();
|
response_port.recv();
|
||||||
|
@ -1156,12 +1149,12 @@ fn shut_down_layout(page: &Page) {
|
||||||
|
|
||||||
let mut js_info = page.mut_js_info();
|
let mut js_info = page.mut_js_info();
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_AllowGC(js_info.get().get_ref().js_context.borrow().ptr);
|
JS_AllowGC(js_info.get_ref().js_context.deref().ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut frame = page.mut_frame();
|
let mut frame = page.mut_frame();
|
||||||
*frame.get() = None;
|
*frame = None;
|
||||||
*js_info.get() = None;
|
*js_info = None;
|
||||||
|
|
||||||
// Destroy the layout task. If there were node leaks, layout will now crash safely.
|
// Destroy the layout task. If there were node leaks, layout will now crash safely.
|
||||||
chan.send(layout_interface::ExitNowMsg);
|
chan.send(layout_interface::ExitNowMsg);
|
||||||
|
|
|
@ -9,7 +9,7 @@ use cssparser::ast::*;
|
||||||
use errors::{ErrorLoggerIterator, log_css_error};
|
use errors::{ErrorLoggerIterator, log_css_error};
|
||||||
use stylesheets::{CSSRule, CSSMediaRule, parse_style_rule, parse_nested_at_rule};
|
use stylesheets::{CSSRule, CSSMediaRule, parse_style_rule, parse_nested_at_rule};
|
||||||
use namespaces::NamespaceMap;
|
use namespaces::NamespaceMap;
|
||||||
use extra::url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
|
||||||
pub struct MediaRule {
|
pub struct MediaRule {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
pub use servo_util::url::parse_url;
|
pub use servo_util::url::parse_url;
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
pub use extra::url::Url;
|
pub use url::Url;
|
||||||
use servo_util::cowarc::CowArc;
|
use servo_util::cowarc::CowArc;
|
||||||
|
|
||||||
pub use cssparser::*;
|
pub use cssparser::*;
|
||||||
|
@ -568,7 +568,7 @@ pub mod longhands {
|
||||||
// The computed value is the same as the specified value.
|
// The computed value is the same as the specified value.
|
||||||
pub use to_computed_value = super::computed_as_specified;
|
pub use to_computed_value = super::computed_as_specified;
|
||||||
pub mod computed_value {
|
pub mod computed_value {
|
||||||
pub use extra::url::Url;
|
pub use url::Url;
|
||||||
pub type T = Option<Url>;
|
pub type T = Option<Url>;
|
||||||
}
|
}
|
||||||
pub type SpecifiedValue = computed_value::T;
|
pub type SpecifiedValue = computed_value::T;
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::{cmp, vec, iter};
|
use std::{cmp, iter};
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
|
use std::slice;
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
use cssparser::ast::*;
|
use cssparser::ast::*;
|
||||||
|
@ -103,7 +104,7 @@ pub enum NamespaceConstraint {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Iter = iter::Peekable<ComponentValue, vec::MoveItems<ComponentValue>>;
|
type Iter = iter::Peekable<ComponentValue, slice::MoveItems<ComponentValue>>;
|
||||||
|
|
||||||
|
|
||||||
/// Parse a comma-separated list of Selectors.
|
/// Parse a comma-separated list of Selectors.
|
||||||
|
|
|
@ -10,14 +10,17 @@
|
||||||
|
|
||||||
#[feature(globs, macro_rules, managed_boxes)];
|
#[feature(globs, macro_rules, managed_boxes)];
|
||||||
|
|
||||||
|
#[feature(phase)];
|
||||||
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
extern crate cssparser;
|
extern crate cssparser;
|
||||||
extern crate collections;
|
extern crate collections;
|
||||||
extern crate encoding;
|
extern crate encoding;
|
||||||
extern crate extra;
|
|
||||||
extern crate num;
|
extern crate num;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate servo_util = "util";
|
extern crate servo_util = "util";
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
|
extern crate url;
|
||||||
|
|
||||||
|
|
||||||
// Public API
|
// Public API
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
use extra::url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use encoding::EncodingRef;
|
use encoding::EncodingRef;
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
use rand;
|
||||||
|
use rand::Rng;
|
||||||
use std::hash::{Hash, sip};
|
use std::hash::{Hash, sip};
|
||||||
use std::rand::Rng;
|
use std::slice;
|
||||||
use std::rand;
|
use std::slice::Items;
|
||||||
use std::vec::Items;
|
|
||||||
use std::vec;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
@ -75,7 +75,7 @@ pub struct HashCache<K, V> {
|
||||||
entries: HashMap<K, V>,
|
entries: HashMap<K, V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Clone + Eq + Hash, V: Clone> HashCache<K,V> {
|
impl<K: Clone + Eq + TotalEq + Hash, V: Clone> HashCache<K,V> {
|
||||||
pub fn new() -> HashCache<K, V> {
|
pub fn new() -> HashCache<K, V> {
|
||||||
HashCache {
|
HashCache {
|
||||||
entries: HashMap::new(),
|
entries: HashMap::new(),
|
||||||
|
@ -83,7 +83,7 @@ impl<K: Clone + Eq + Hash, V: Clone> HashCache<K,V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K: Clone + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> {
|
impl<K: Clone + Eq + TotalEq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> {
|
||||||
fn insert(&mut self, key: K, value: V) {
|
fn insert(&mut self, key: K, value: V) {
|
||||||
self.entries.insert(key, value);
|
self.entries.insert(key, value);
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ impl<K:Clone+Eq+Hash,V:Clone> SimpleHashCache<K,V> {
|
||||||
pub fn new(cache_size: uint) -> SimpleHashCache<K,V> {
|
pub fn new(cache_size: uint) -> SimpleHashCache<K,V> {
|
||||||
let mut r = rand::task_rng();
|
let mut r = rand::task_rng();
|
||||||
SimpleHashCache {
|
SimpleHashCache {
|
||||||
entries: vec::from_elem(cache_size, None),
|
entries: slice::from_elem(cache_size, None),
|
||||||
k0: r.gen(),
|
k0: r.gen(),
|
||||||
k1: r.gen(),
|
k1: r.gen(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
//! A Doug Lea-style concurrent hash map using striped locks.
|
//! A Doug Lea-style concurrent hash map using striped locks.
|
||||||
|
|
||||||
|
use rand;
|
||||||
|
use rand::Rng;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::hash::{Hash, sip};
|
use std::hash::{Hash, sip};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::rand::Rng;
|
|
||||||
use std::rand;
|
|
||||||
use std::sync::atomics::{AtomicUint, Relaxed, SeqCst};
|
use std::sync::atomics::{AtomicUint, Relaxed, SeqCst};
|
||||||
use std::unstable::mutex::StaticNativeMutex;
|
use std::unstable::mutex::StaticNativeMutex;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::vec;
|
use std::slice;
|
||||||
|
|
||||||
/// When the size exceeds (number of buckets * LOAD_NUMERATOR/LOAD_DENOMINATOR), the hash table
|
/// When the size exceeds (number of buckets * LOAD_NUMERATOR/LOAD_DENOMINATOR), the hash table
|
||||||
/// grows.
|
/// grows.
|
||||||
|
@ -57,12 +57,12 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
|
||||||
k0: rand.gen(),
|
k0: rand.gen(),
|
||||||
k1: rand.gen(),
|
k1: rand.gen(),
|
||||||
size: AtomicUint::new(0),
|
size: AtomicUint::new(0),
|
||||||
locks: vec::from_fn(lock_count, |_| {
|
locks: slice::from_fn(lock_count, |_| {
|
||||||
unsafe {
|
unsafe {
|
||||||
StaticNativeMutex::new()
|
StaticNativeMutex::new()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
buckets: vec::from_fn(lock_count * buckets_per_lock, |_| None),
|
buckets: slice::from_fn(lock_count * buckets_per_lock, |_| None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +295,7 @@ impl<K:Hash + Eq,V> ConcurrentHashMap<K,V> {
|
||||||
let new_bucket_count = lock_count * new_buckets_per_lock;
|
let new_bucket_count = lock_count * new_buckets_per_lock;
|
||||||
if new_bucket_count > this.buckets.len() {
|
if new_bucket_count > this.buckets.len() {
|
||||||
// Create a new set of buckets.
|
// Create a new set of buckets.
|
||||||
let mut buckets = vec::from_fn(new_bucket_count, |_| None);
|
let mut buckets = slice::from_fn(new_bucket_count, |_| None);
|
||||||
mem::swap(&mut this.buckets, &mut buckets);
|
mem::swap(&mut this.buckets, &mut buckets);
|
||||||
this.size.store(0, Relaxed);
|
this.size.store(0, Relaxed);
|
||||||
|
|
||||||
|
|
|
@ -31,13 +31,13 @@ impl<T> Drop for CowArc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Eq + Freeze + Clone> Eq for CowArc<T> {
|
impl<T:Eq + Clone> Eq for CowArc<T> {
|
||||||
fn eq(&self, other: &CowArc<T>) -> bool {
|
fn eq(&self, other: &CowArc<T>) -> bool {
|
||||||
self.get() == other.get()
|
self.get() == other.get()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Freeze + Clone> Clone for CowArc<T> {
|
impl<T:Clone> Clone for CowArc<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> CowArc<T> {
|
fn clone(&self) -> CowArc<T> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -49,7 +49,7 @@ impl<T:Freeze + Clone> Clone for CowArc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Freeze + Clone> CowArc<T> {
|
impl<T:Clone> CowArc<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(value: T) -> CowArc<T> {
|
pub fn new(value: T) -> CowArc<T> {
|
||||||
let alloc = ~CowArcAlloc {
|
let alloc = ~CowArcAlloc {
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#[feature(phase)];
|
||||||
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Writer;
|
use std::io::Writer;
|
||||||
use std::vec::raw::buf_as_slice;
|
|
||||||
use std::cast::transmute;
|
use std::cast::transmute;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
|
use std::slice::raw::buf_as_slice;
|
||||||
|
|
||||||
fn hexdump_slice(buf: &[u8]) {
|
fn hexdump_slice(buf: &[u8]) {
|
||||||
let mut stderr = io::stderr();
|
let mut stderr = io::stderr();
|
||||||
|
|
|
@ -15,7 +15,7 @@ use std::os;
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct Opts {
|
pub struct Opts {
|
||||||
/// The initial URLs to load.
|
/// The initial URLs to load.
|
||||||
urls: ~[~str],
|
urls: Vec<~str>,
|
||||||
|
|
||||||
/// The rendering backend to use (`-r`).
|
/// The rendering backend to use (`-r`).
|
||||||
render_backend: BackendType,
|
render_backend: BackendType,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
use std::str::IntoMaybeOwned;
|
use std::str::IntoMaybeOwned;
|
||||||
use std::task;
|
use std::task;
|
||||||
use std::comm::Chan;
|
use std::comm::Sender;
|
||||||
use std::task::TaskBuilder;
|
use std::task::TaskBuilder;
|
||||||
|
|
||||||
pub fn spawn_named<S: IntoMaybeOwned<'static>>(name: S, f: proc()) {
|
pub fn spawn_named<S: IntoMaybeOwned<'static>>(name: S, f: proc()) {
|
||||||
|
@ -14,7 +14,7 @@ pub fn spawn_named<S: IntoMaybeOwned<'static>>(name: S, f: proc()) {
|
||||||
|
|
||||||
/// Arrange to send a particular message to a channel if the task built by
|
/// Arrange to send a particular message to a channel if the task built by
|
||||||
/// this `TaskBuilder` fails.
|
/// this `TaskBuilder` fails.
|
||||||
pub fn send_on_failure<T: Send>(builder: &mut TaskBuilder, msg: T, dest: Chan<T>) {
|
pub fn send_on_failure<T: Send>(builder: &mut TaskBuilder, msg: T, dest: Sender<T>) {
|
||||||
let port = builder.future_result();
|
let port = builder.future_result();
|
||||||
spawn(proc() {
|
spawn(proc() {
|
||||||
match port.recv() {
|
match port.recv() {
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
use std_time::precise_time_ns;
|
use std_time::precise_time_ns;
|
||||||
use collections::treemap::TreeMap;
|
use collections::treemap::TreeMap;
|
||||||
use std::comm::{Port, Chan};
|
use std::comm::{Sender, channel, Receiver};
|
||||||
|
use std::f64;
|
||||||
use std::iter::AdditiveIterator;
|
use std::iter::AdditiveIterator;
|
||||||
use task::{spawn_named};
|
use task::{spawn_named};
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ impl Timer {
|
||||||
|
|
||||||
// front-end representation of the profiler used to communicate with the profiler
|
// front-end representation of the profiler used to communicate with the profiler
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
pub struct ProfilerChan(Chan<ProfilerMsg>);
|
pub struct ProfilerChan(Sender<ProfilerMsg>);
|
||||||
|
|
||||||
impl ProfilerChan {
|
impl ProfilerChan {
|
||||||
pub fn send(&self, msg: ProfilerMsg) {
|
pub fn send(&self, msg: ProfilerMsg) {
|
||||||
|
@ -46,7 +47,8 @@ pub enum ProfilerMsg {
|
||||||
ExitMsg,
|
ExitMsg,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Eq, Clone, TotalEq, TotalOrd)]
|
#[repr(u32)]
|
||||||
|
#[deriving(Eq, Clone, Ord, TotalEq, TotalOrd)]
|
||||||
pub enum ProfilerCategory {
|
pub enum ProfilerCategory {
|
||||||
CompositingCategory,
|
CompositingCategory,
|
||||||
LayoutQueryCategory,
|
LayoutQueryCategory,
|
||||||
|
@ -117,14 +119,14 @@ type ProfilerBuckets = TreeMap<ProfilerCategory, ~[f64]>;
|
||||||
|
|
||||||
// back end of the profiler that handles data aggregation and performance metrics
|
// back end of the profiler that handles data aggregation and performance metrics
|
||||||
pub struct Profiler {
|
pub struct Profiler {
|
||||||
port: Port<ProfilerMsg>,
|
port: Receiver<ProfilerMsg>,
|
||||||
buckets: ProfilerBuckets,
|
buckets: ProfilerBuckets,
|
||||||
last_msg: Option<ProfilerMsg>,
|
last_msg: Option<ProfilerMsg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Profiler {
|
impl Profiler {
|
||||||
pub fn create(period: Option<f64>) -> ProfilerChan {
|
pub fn create(period: Option<f64>) -> ProfilerChan {
|
||||||
let (port, chan) = Chan::new();
|
let (chan, port) = channel();
|
||||||
match period {
|
match period {
|
||||||
Some(period) => {
|
Some(period) => {
|
||||||
let period = (period * 1000f64) as u64;
|
let period = (period * 1000f64) as u64;
|
||||||
|
@ -159,7 +161,7 @@ impl Profiler {
|
||||||
ProfilerChan(chan)
|
ProfilerChan(chan)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(port: Port<ProfilerMsg>) -> Profiler {
|
pub fn new(port: Receiver<ProfilerMsg>) -> Profiler {
|
||||||
Profiler {
|
Profiler {
|
||||||
port: port,
|
port: port,
|
||||||
buckets: ProfilerCategory::empty_buckets(),
|
buckets: ProfilerCategory::empty_buckets(),
|
||||||
|
@ -211,11 +213,11 @@ impl Profiler {
|
||||||
});
|
});
|
||||||
let data_len = data.len();
|
let data_len = data.len();
|
||||||
if data_len > 0 {
|
if data_len > 0 {
|
||||||
let (mean, median, &min, &max) =
|
let (mean, median, min, max) =
|
||||||
(data.iter().map(|&x|x).sum() / (data_len as f64),
|
(data.iter().map(|&x|x).sum() / (data_len as f64),
|
||||||
data[data_len / 2],
|
data[data_len / 2],
|
||||||
data.iter().min().unwrap(),
|
data.iter().fold(f64::INFINITY, |a, &b| a.min(b)),
|
||||||
data.iter().max().unwrap());
|
data.iter().fold(-f64::INFINITY, |a, &b| a.max(b)));
|
||||||
println!("{:-35s}: {:15.4f} {:15.4f} {:15.4f} {:15.4f} {:15u}",
|
println!("{:-35s}: {:15.4f} {:15.4f} {:15.4f} {:15.4f} {:15u}",
|
||||||
category.format(), mean, median, min, max, data_len);
|
category.format(), mean, median, min, max, data_len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,11 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use extra::url;
|
|
||||||
use extra::url::Url;
|
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use std::os;
|
use std::os;
|
||||||
|
use std::vec::Vec;
|
||||||
|
use std_url;
|
||||||
|
use std_url::Url;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a URL object from a string. Does various helpful browsery things like
|
Create a URL object from a string. Does various helpful browsery things like
|
||||||
|
@ -17,9 +18,9 @@ Create a URL object from a string. Does various helpful browsery things like
|
||||||
|
|
||||||
*/
|
*/
|
||||||
// TODO: about:failure->
|
// TODO: about:failure->
|
||||||
pub fn parse_url(str_url: &str, base_url: Option<Url>) -> Url {
|
pub fn parse_url(str_url: &str, base_url: Option<std_url::Url>) -> std_url::Url {
|
||||||
let str_url = str_url.trim_chars(& &[' ', '\t', '\n', '\r', '\x0C']).to_owned();
|
let str_url = str_url.trim_chars(& &[' ', '\t', '\n', '\r', '\x0C']).to_owned();
|
||||||
let schm = url::get_scheme(str_url);
|
let schm = std_url::get_scheme(str_url);
|
||||||
let str_url = match schm {
|
let str_url = match schm {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
if base_url.is_none() {
|
if base_url.is_none() {
|
||||||
|
@ -38,7 +39,7 @@ pub fn parse_url(str_url: &str, base_url: Option<Url>) -> Url {
|
||||||
debug!("parse_url: base_url: {:?}", base_url);
|
debug!("parse_url: base_url: {:?}", base_url);
|
||||||
|
|
||||||
let mut new_url = base_url.clone();
|
let mut new_url = base_url.clone();
|
||||||
new_url.query = ~[];
|
new_url.query = Vec::new();
|
||||||
new_url.fragment = None;
|
new_url.fragment = None;
|
||||||
|
|
||||||
if str_url.starts_with("//") {
|
if str_url.starts_with("//") {
|
||||||
|
@ -84,7 +85,7 @@ pub fn parse_url(str_url: &str, base_url: Option<Url>) -> Url {
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: Need to handle errors
|
// FIXME: Need to handle errors
|
||||||
url::from_str(str_url).ok().expect("URL parsing failed")
|
std_url::from_str(str_url).ok().expect("URL parsing failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -162,7 +163,7 @@ mod parse_url_tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_create_url_based_on_old_url_6() {
|
fn should_create_url_based_on_old_url_6() {
|
||||||
use extra::url::UserInfo;
|
use std_url::UserInfo;
|
||||||
|
|
||||||
let old_str = "http://foo:bar@example.com:8080/index.html";
|
let old_str = "http://foo:bar@example.com:8080/index.html";
|
||||||
let old_url = parse_url(old_str, None);
|
let old_url = parse_url(old_str, None);
|
||||||
|
@ -190,7 +191,7 @@ mod parse_url_tests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type UrlMap<T> = HashMap<Url, T>;
|
pub type UrlMap<T> = HashMap<std_url::Url, T>;
|
||||||
|
|
||||||
pub fn url_map<T: Clone + 'static>() -> UrlMap<T> {
|
pub fn url_map<T: Clone + 'static>() -> UrlMap<T> {
|
||||||
HashMap::new()
|
HashMap::new()
|
||||||
|
|
|
@ -7,15 +7,19 @@
|
||||||
|
|
||||||
#[feature(macro_rules, managed_boxes)];
|
#[feature(macro_rules, managed_boxes)];
|
||||||
|
|
||||||
|
#[feature(phase)];
|
||||||
|
#[phase(syntax, link)] extern crate log;
|
||||||
|
|
||||||
extern crate azure;
|
extern crate azure;
|
||||||
extern crate collections;
|
extern crate collections;
|
||||||
extern crate extra;
|
|
||||||
extern crate geom;
|
extern crate geom;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
extern crate native;
|
extern crate native;
|
||||||
|
extern crate rand;
|
||||||
extern crate serialize;
|
extern crate serialize;
|
||||||
extern crate sync;
|
extern crate sync;
|
||||||
extern crate std_time = "time";
|
extern crate std_time = "time";
|
||||||
|
extern crate std_url = "url";
|
||||||
|
|
||||||
pub mod cache;
|
pub mod cache;
|
||||||
pub mod concurrentmap;
|
pub mod concurrentmap;
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
//! higher-level API on top of this could allow safe fork-join parallelism.
|
//! higher-level API on top of this could allow safe fork-join parallelism.
|
||||||
|
|
||||||
use native;
|
use native;
|
||||||
|
use rand;
|
||||||
|
use rand::{Rng, XorShiftRng};
|
||||||
use std::cast;
|
use std::cast;
|
||||||
use std::comm;
|
use std::comm;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rand::{Rng, XorShiftRng};
|
|
||||||
use std::rand;
|
|
||||||
use std::sync::atomics::{AtomicUint, SeqCst};
|
use std::sync::atomics::{AtomicUint, SeqCst};
|
||||||
use std::sync::deque::{Abort, BufferPool, Data, Empty, Stealer, Worker};
|
use std::sync::deque::{Abort, BufferPool, Data, Empty, Stealer, Worker};
|
||||||
use std::task::TaskOpts;
|
use std::task::TaskOpts;
|
||||||
|
@ -50,7 +50,7 @@ enum SupervisorMsg<QUD,WUD> {
|
||||||
/// Information that the supervisor thread keeps about the worker threads.
|
/// Information that the supervisor thread keeps about the worker threads.
|
||||||
struct WorkerInfo<QUD,WUD> {
|
struct WorkerInfo<QUD,WUD> {
|
||||||
/// The communication channel to the workers.
|
/// The communication channel to the workers.
|
||||||
chan: Chan<WorkerMsg<QUD,WUD>>,
|
chan: Sender<WorkerMsg<QUD,WUD>>,
|
||||||
/// The buffer pool for this deque.
|
/// The buffer pool for this deque.
|
||||||
pool: BufferPool<WorkUnit<QUD,WUD>>,
|
pool: BufferPool<WorkUnit<QUD,WUD>>,
|
||||||
/// The worker end of the deque, if we have it.
|
/// The worker end of the deque, if we have it.
|
||||||
|
@ -64,9 +64,9 @@ struct WorkerThread<QUD,WUD> {
|
||||||
/// The index of this worker.
|
/// The index of this worker.
|
||||||
index: uint,
|
index: uint,
|
||||||
/// The communication port from the supervisor.
|
/// The communication port from the supervisor.
|
||||||
port: Port<WorkerMsg<QUD,WUD>>,
|
port: Receiver<WorkerMsg<QUD,WUD>>,
|
||||||
/// The communication channel on which messages are sent to the supervisor.
|
/// The communication channel on which messages are sent to the supervisor.
|
||||||
chan: Chan<SupervisorMsg<QUD,WUD>>,
|
chan: Sender<SupervisorMsg<QUD,WUD>>,
|
||||||
/// The thief end of the work-stealing deque for all other workers.
|
/// The thief end of the work-stealing deque for all other workers.
|
||||||
other_deques: ~[Stealer<WorkUnit<QUD,WUD>>],
|
other_deques: ~[Stealer<WorkUnit<QUD,WUD>>],
|
||||||
/// The random number generator for this worker.
|
/// The random number generator for this worker.
|
||||||
|
@ -191,7 +191,7 @@ pub struct WorkQueue<QUD,WUD> {
|
||||||
/// Information about each of the workers.
|
/// Information about each of the workers.
|
||||||
priv workers: ~[WorkerInfo<QUD,WUD>],
|
priv workers: ~[WorkerInfo<QUD,WUD>],
|
||||||
/// A port on which deques can be received from the workers.
|
/// A port on which deques can be received from the workers.
|
||||||
priv port: Port<SupervisorMsg<QUD,WUD>>,
|
priv port: Receiver<SupervisorMsg<QUD,WUD>>,
|
||||||
/// The amount of work that has been enqueued.
|
/// The amount of work that has been enqueued.
|
||||||
priv work_count: uint,
|
priv work_count: uint,
|
||||||
/// Arbitrary user data.
|
/// Arbitrary user data.
|
||||||
|
@ -203,10 +203,10 @@ impl<QUD:Send,WUD:Send> WorkQueue<QUD,WUD> {
|
||||||
/// it.
|
/// it.
|
||||||
pub fn new(task_name: &'static str, thread_count: uint, user_data: QUD) -> WorkQueue<QUD,WUD> {
|
pub fn new(task_name: &'static str, thread_count: uint, user_data: QUD) -> WorkQueue<QUD,WUD> {
|
||||||
// Set up data structures.
|
// Set up data structures.
|
||||||
let (supervisor_port, supervisor_chan) = Chan::new();
|
let (supervisor_chan, supervisor_port) = channel();
|
||||||
let (mut infos, mut threads) = (~[], ~[]);
|
let (mut infos, mut threads) = (~[], ~[]);
|
||||||
for i in range(0, thread_count) {
|
for i in range(0, thread_count) {
|
||||||
let (worker_port, worker_chan) = Chan::new();
|
let (worker_chan, worker_port) = channel();
|
||||||
let mut pool = BufferPool::new();
|
let mut pool = BufferPool::new();
|
||||||
let (worker, thief) = pool.deque();
|
let (worker, thief) = pool.deque();
|
||||||
infos.push(WorkerInfo {
|
infos.push(WorkerInfo {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c4851d5282da56c0bf3e5589b924a109d255de9b
|
Subproject commit bc65fde3837c321d0b311891b66d708495cd2116
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1c583b83da60bf4bb1a002075282d6918441929c
|
Subproject commit 2041e8869c475555a859898db37a8126c20c02f6
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8123844a04767a8a5573e0d44e75b7475a537e12
|
Subproject commit 2ceffefc17d0a855d4e3d4d4d298f943c7202a6c
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9762797c18243a82bddb58ff2fdb8e1af1076e2d
|
Subproject commit 488bde06d8c9c06743805007be096cdf2c6a4a6b
|
|
@ -1 +1 @@
|
||||||
Subproject commit bfd82f969b40cda6b0b89173edeb1b138bd9f3fa
|
Subproject commit 67628775b3771854a1fa77aa77462eda7c513fed
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5940560e5b62fe63e1e8b1007bb4012d89586635
|
Subproject commit d1c53f142c7885c1cf1a26d4de94fd823d69203c
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0f2839641b3e198bb82573a3f766e0bd3ea9ed9b
|
Subproject commit eb2bef3f2ed56c61997c08f966706d5a3bf1e2fe
|
|
@ -1 +1 @@
|
||||||
Subproject commit 50f12501235b8bc6f5ada9f729a718899ca01987
|
Subproject commit 1eb914fee8e35a4d137f84b2a93379e097db6c57
|
|
@ -1 +1 @@
|
||||||
Subproject commit f0bf028894d38e46efc8651f69d62e4f3a151179
|
Subproject commit d858b43e1da31bc61f75bcaeb642c37a0758ed5b
|
|
@ -1 +1 @@
|
||||||
Subproject commit 10b1cf8e35fa1757bcab11dcc284f77e4ceeaffc
|
Subproject commit 606de29afbf2daf2b66db15853f5f617e6e74087
|
|
@ -1 +1 @@
|
||||||
Subproject commit 093b9c0a4741fad66f9c4596f53c6505f54a080f
|
Subproject commit 6a1086270b00531c6551c9d0aa660a6aff435f87
|
|
@ -1 +1 @@
|
||||||
Subproject commit 5b67991531bd98376948d9a3b395e39113107b49
|
Subproject commit 189a70d6c748a376540ce679530e6d8f317b198c
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8ce92e802dcb268eaa80138e284b1e12f5c10f47
|
Subproject commit c639371647bb82d652aa47c47cea5b39a1a6fdaa
|
|
@ -1 +1 @@
|
||||||
Subproject commit d3f2daf64610ec34a04f03f49aa4a03590fc0c72
|
Subproject commit 0e465e5cbde56eaa4c29c25bd039c342e34f5fed
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0266c1d03c4d2d653a81483e54e85a12e8769e43
|
Subproject commit 79831beec751932d691bdfe93ed464debec00e51
|
|
@ -1 +1 @@
|
||||||
Subproject commit 32d5814e98dfb4c39480b2fbec7e6768ecfade55
|
Subproject commit 80300341c4328f3478cc074b8229d5d44031a787
|
|
@ -1 +1 @@
|
||||||
Subproject commit 79e405fa59c052ff78d7a2527a92474a32ac9b4d
|
Subproject commit d81ccfcdc51a84b7662e30acd95691a6b1a52cfa
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2e67961270c7674233daa496828177f5f8d1f4cc
|
Subproject commit ae9b6f11e95f666d3ea8024a8d404dfb760e4a26
|
|
@ -1 +1 @@
|
||||||
Subproject commit 52202fbe5838c5e7736424975885fd5fc54d446e
|
Subproject commit 4891b380a54f163d73323be53f9e614b4cf3527c
|
|
@ -1 +1 @@
|
||||||
Subproject commit b8454b439aacfe12f69f7c841dbfb33522dcefd1
|
Subproject commit 319be39647b1f7c04c910c8456844584841b5f37
|
|
@ -1 +1 @@
|
||||||
Subproject commit 63cd9347653b280f6b0c158f505e71743e8110b7
|
Subproject commit 1c2fd1351d7d8effeb40874953030760a5d978e2
|
|
@ -1 +1 @@
|
||||||
Subproject commit 03063eb30d612dc529f4c43c06ca30a977e14a7a
|
Subproject commit 064e33d8217424a33636c8019b1f1f74a44ee2bb
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue