mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
servo: Upgrade for language changes
Source-Repo: https://github.com/servo/servo Source-Revision: 0458783bc798737d6772784b5805b6deb1b6ba9f
This commit is contained in:
parent
4af01fc238
commit
733059dd4c
4
servo/configure
vendored
4
servo/configure
vendored
@ -391,7 +391,7 @@ if [ $CFG_OSTYPE = "apple-darwin" ]
|
||||
then
|
||||
# pkg-config is installed in a different place on mac (via homebrew? not sure)
|
||||
# and the way to set this seems to be calling aclocal by hand (instead of via autoreconf)
|
||||
OSX_PKG_CONFIG_M4_MACROS="-I/usr/local/share/aclocal"
|
||||
OSX_PKG_CONFIG_M4_MACROS="-I/usr/share/aclocal -I/usr/local/share/aclocal"
|
||||
LIBTOOLIZE=glibtoolize
|
||||
else
|
||||
OSX_PKG_CONFIG_M4_MACROS=""
|
||||
@ -400,7 +400,7 @@ fi
|
||||
|
||||
PIXMAN_ACLOCALCMD="aclocal ${OSX_PKG_CONFIG_M4_MACROS}"
|
||||
CAIRO_ACLOCALCMD="aclocal ${OSX_PKG_CONFIG_M4_MACROS} -Ibuild"
|
||||
AUTOCMD="${LIBTOOLIZE} && autoconf && autoheader && automake --add-missing --copy --no-force"
|
||||
AUTOCMD="${LIBTOOLIZE} && autoconf && autoheader && automake --add-missing --copy --force"
|
||||
# Copied from cairo's autogen.sh. Build fails without
|
||||
CAIRO_BOILERPLATE="touch boilerplate/Makefile.am.features && touch src/Makefile.am.features"
|
||||
PIXMAN_AUTOCMD="${PIXMAN_ACLOCALCMD} && ${AUTOCMD}"
|
||||
|
@ -90,18 +90,11 @@ pub struct DisplayList {
|
||||
list: ~[~DisplayItem]
|
||||
}
|
||||
|
||||
trait DisplayListMethods {
|
||||
fn append_item(&mut self, item: ~DisplayItem);
|
||||
fn draw_into_context(ctx: &RenderContext);
|
||||
}
|
||||
|
||||
pub impl DisplayList {
|
||||
static fn new() -> DisplayList {
|
||||
DisplayList { list: ~[] }
|
||||
}
|
||||
}
|
||||
|
||||
impl DisplayList : DisplayListMethods {
|
||||
fn append_item(&mut self, item: ~DisplayItem) {
|
||||
// FIXME(Issue #150): crashes
|
||||
//debug!("Adding display item %u: %?", self.len(), item);
|
||||
|
@ -4,9 +4,11 @@ use geometry::Au;
|
||||
use render_context::RenderContext;
|
||||
use util::range::Range;
|
||||
use text::glyph::{GlyphStore, GlyphIndex};
|
||||
use text::shaper::ShaperMethods;
|
||||
use text::{Shaper, TextRun};
|
||||
|
||||
use azure::{AzFloat, AzScaledFontRef};
|
||||
use azure::{AzFloat, AzScaledFontRef, struct__AzDrawOptions, struct__AzGlyph};
|
||||
use azure::{struct__AzGlyphBuffer, struct__AzPoint};
|
||||
use azure::scaled_font::ScaledFont;
|
||||
use azure::azure_hl::{BackendType, ColorPattern};
|
||||
use core::dvec::DVec;
|
||||
@ -374,26 +376,8 @@ pub impl Font {
|
||||
}
|
||||
}
|
||||
|
||||
// Public API
|
||||
pub trait FontMethods {
|
||||
fn draw_text_into_context(rctx: &RenderContext,
|
||||
run: &TextRun,
|
||||
range: &Range,
|
||||
baseline_origin: Point2D<Au>,
|
||||
color: Color);
|
||||
// This calculates run metrics for the specified character range
|
||||
// within the provided textrun.
|
||||
fn measure_text(&TextRun, &const Range) -> RunMetrics;
|
||||
fn shape_text(@self, &str, &mut GlyphStore);
|
||||
fn get_descriptor() -> FontDescriptor;
|
||||
|
||||
// these are used to get glyphs and advances in the case that the
|
||||
// shaper can't figure it out.
|
||||
fn glyph_index(char) -> Option<GlyphIndex>;
|
||||
fn glyph_h_advance(GlyphIndex) -> FractionalPixel;
|
||||
}
|
||||
|
||||
pub impl Font : FontMethods {
|
||||
pub impl Font {
|
||||
fn draw_text_into_context(rctx: &RenderContext,
|
||||
run: &TextRun,
|
||||
range: &const Range,
|
||||
@ -413,7 +397,7 @@ pub impl Font : FontMethods {
|
||||
let azure_pattern = pattern.azure_color_pattern;
|
||||
assert azure_pattern.is_not_null();
|
||||
|
||||
let options: AzDrawOptions = {
|
||||
let options = struct__AzDrawOptions {
|
||||
mAlpha: 1f as AzFloat,
|
||||
fields: 0x0200 as uint16_t
|
||||
};
|
||||
@ -426,9 +410,9 @@ pub impl Font : FontMethods {
|
||||
let glyph_advance = glyph.advance();
|
||||
let glyph_offset = glyph.offset().get_or_default(Au::zero_point());
|
||||
|
||||
let azglyph: AzGlyph = {
|
||||
let azglyph = struct__AzGlyph {
|
||||
mIndex: glyph.index() as uint32_t,
|
||||
mPosition: {
|
||||
mPosition: struct__AzPoint {
|
||||
x: (origin.x + glyph_offset.x).to_px() as AzFloat,
|
||||
y: (origin.y + glyph_offset.y).to_px() as AzFloat
|
||||
}
|
||||
@ -441,10 +425,12 @@ pub impl Font : FontMethods {
|
||||
if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert.
|
||||
|
||||
let azglyph_buf = dvec::unwrap(move azglyphs);
|
||||
let glyphbuf: AzGlyphBuffer = unsafe {{
|
||||
mGlyphs: vec::raw::to_ptr(azglyph_buf),
|
||||
mNumGlyphs: azglyph_buf_len as uint32_t
|
||||
}};
|
||||
let glyphbuf = unsafe {
|
||||
struct__AzGlyphBuffer {
|
||||
mGlyphs: vec::raw::to_ptr(azglyph_buf),
|
||||
mNumGlyphs: azglyph_buf_len as uint32_t
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(Issue #64): this call needs to move into azure_hl.rs
|
||||
AzDrawTargetFillGlyphs(target.azure_draw_target,
|
||||
|
@ -1,4 +1,5 @@
|
||||
use font::{CSSFontWeight, SpecifiedFontStyle, UsedFontStyle};
|
||||
use gfx_font::FontHandleMethods;
|
||||
use native::FontHandle;
|
||||
|
||||
use dvec::DVec;
|
||||
@ -82,13 +83,13 @@ pub impl FontList {
|
||||
|
||||
priv fn find_family(family_name: &str) -> Option<@FontFamily> {
|
||||
// look up canonical name
|
||||
let family = self.family_map.find_copy(&str::from_slice(family_name));
|
||||
let family = self.family_map.find(&str::from_slice(family_name));
|
||||
|
||||
let decision = if family.is_some() { "Found" } else { "Couldn't find" };
|
||||
debug!("FontList: %s font family with name=%s", decision, family_name);
|
||||
|
||||
// TODO(Issue #188): look up localized font family names if canonical name not found
|
||||
return family;
|
||||
return family.map(|f| **f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ pub struct FreeTypeFontHandle {
|
||||
drop {
|
||||
assert self.face.is_not_null();
|
||||
if !FT_Done_Face(self.face).succeeded() {
|
||||
fail ~"FT_Done_Face failed";
|
||||
fail!(~"FT_Done_Face failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -186,7 +186,6 @@ pub impl FreeTypeFontHandle {
|
||||
}
|
||||
|
||||
pub impl FreeTypeFontHandle : FontHandleMethods {
|
||||
|
||||
// an identifier usable by FontContextHandle to recreate this FontHandle.
|
||||
pure fn face_identifier() -> ~str {
|
||||
/* FT_Get_Postscript_Name seems like a better choice here, but it
|
||||
|
@ -1,33 +1,43 @@
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
use geom::size::Size2D;
|
||||
use num::Num;
|
||||
|
||||
pub enum Au = i32;
|
||||
use core::num::NumCast;
|
||||
|
||||
impl Au : Num {
|
||||
pure fn add(&self, other: &Au) -> Au { Au(**self + **other) }
|
||||
pure fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
|
||||
pure fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
|
||||
pure fn div(&self, other: &Au) -> Au { Au(**self / **other) }
|
||||
pure fn modulo(&self, other: &Au) -> Au { Au(**self % **other) }
|
||||
pure fn neg(&self) -> Au { Au(-**self) }
|
||||
pub struct Au(i32);
|
||||
|
||||
pure fn to_int(&self) -> int { **self as int }
|
||||
|
||||
static pure fn from_int(n: int) -> Au {
|
||||
Au((n & (i32::max_value as int)) as i32)
|
||||
}
|
||||
pub impl Add<Au,Au> for Au {
|
||||
pure fn add(&self, other: &Au) -> Au { Au(**self + **other) }
|
||||
}
|
||||
|
||||
impl Au : cmp::Ord {
|
||||
pub impl Sub<Au,Au> for Au {
|
||||
pure fn sub(&self, other: &Au) -> Au { Au(**self - **other) }
|
||||
}
|
||||
|
||||
pub impl Mul<Au,Au> for Au {
|
||||
pure fn mul(&self, other: &Au) -> Au { Au(**self * **other) }
|
||||
}
|
||||
|
||||
pub impl Div<Au,Au> for Au {
|
||||
pure fn div(&self, other: &Au) -> Au { Au(**self / **other) }
|
||||
}
|
||||
|
||||
pub impl Modulo<Au,Au> for Au {
|
||||
pure fn modulo(&self, other: &Au) -> Au { Au(**self % **other) }
|
||||
}
|
||||
|
||||
pub impl Neg<Au> for Au {
|
||||
pure fn neg(&self) -> Au { Au(-**self) }
|
||||
}
|
||||
|
||||
pub impl cmp::Ord for Au {
|
||||
pure fn lt(&self, other: &Au) -> bool { **self < **other }
|
||||
pure fn le(&self, other: &Au) -> bool { **self <= **other }
|
||||
pure fn ge(&self, other: &Au) -> bool { **self >= **other }
|
||||
pure fn gt(&self, other: &Au) -> bool { **self > **other }
|
||||
}
|
||||
|
||||
impl Au : cmp::Eq {
|
||||
pub impl cmp::Eq for Au {
|
||||
pure fn eq(&self, other: &Au) -> bool { **self == **other }
|
||||
pure fn ne(&self, other: &Au) -> bool { **self != **other }
|
||||
}
|
||||
@ -35,17 +45,37 @@ impl Au : cmp::Eq {
|
||||
pub pure fn min(x: Au, y: Au) -> Au { if x < y { x } else { y } }
|
||||
pub pure fn max(x: Au, y: Au) -> Au { if x > y { x } else { y } }
|
||||
|
||||
pub fn box<A:Copy Num>(x: A, y: A, w: A, h: A) -> Rect<A> {
|
||||
impl NumCast for Au {
|
||||
static pure fn from<T:NumCast>(n: T) -> Au { Au(n.to_i32()) }
|
||||
|
||||
pure fn to_u8(&self) -> u8 { (**self).to_u8() }
|
||||
pure fn to_u16(&self) -> u16 { (**self).to_u16() }
|
||||
pure fn to_u32(&self) -> u32 { (**self).to_u32() }
|
||||
pure fn to_u64(&self) -> u64 { (**self).to_u64() }
|
||||
pure fn to_uint(&self) -> uint { (**self).to_uint() }
|
||||
|
||||
pure fn to_i8(&self) -> i8 { (**self).to_i8() }
|
||||
pure fn to_i16(&self) -> i16 { (**self).to_i16() }
|
||||
pure fn to_i32(&self) -> i32 { (**self).to_i32() }
|
||||
pure fn to_i64(&self) -> i64 { (**self).to_i64() }
|
||||
pure fn to_int(&self) -> int { (**self).to_int() }
|
||||
|
||||
pure fn to_f32(&self) -> f32 { (**self).to_f32() }
|
||||
pure fn to_f64(&self) -> f64 { (**self).to_f64() }
|
||||
pure fn to_float(&self) -> float { (**self).to_float() }
|
||||
}
|
||||
|
||||
pub fn box<T:Copy + Ord + Add<T,T> + Sub<T,T>>(x: T, y: T, w: T, h: T) -> Rect<T> {
|
||||
Rect(Point2D(x, y), Size2D(w, h))
|
||||
}
|
||||
|
||||
impl Au {
|
||||
pub impl Au {
|
||||
pub pure fn scale_by(factor: float) -> Au {
|
||||
Au(((*self as float) * factor) as i32)
|
||||
}
|
||||
|
||||
static pub pure fn from_px(i: int) -> Au {
|
||||
Num::from_int(i * 60)
|
||||
NumCast::from(i * 60)
|
||||
}
|
||||
|
||||
pub pure fn to_px(&const self) -> int {
|
||||
@ -98,7 +128,7 @@ pub pure fn from_frac_px(f: float) -> Au {
|
||||
}
|
||||
|
||||
pub pure fn from_px(i: int) -> Au {
|
||||
Num::from_int(i * 60)
|
||||
NumCast::from(i * 60)
|
||||
}
|
||||
|
||||
pub pure fn to_px(au: Au) -> int {
|
||||
|
@ -32,7 +32,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
|
||||
1 => image.data[pixel * 4 + 1],
|
||||
2 => image.data[pixel * 4 + 0],
|
||||
3 => 0xffu8,
|
||||
_ => fail
|
||||
_ => fail!()
|
||||
}
|
||||
};
|
||||
|
||||
@ -40,7 +40,7 @@ pub fn load_from_memory(buffer: &[u8]) -> Option<Image> {
|
||||
|
||||
Some(Image(image.width, image.height, image.depth, move data))
|
||||
}
|
||||
stb_image::ImageF32(_image) => fail ~"HDR images not implemented",
|
||||
stb_image::ImageF32(_image) => fail!(~"HDR images not implemented"),
|
||||
stb_image::Error => None
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use io::WriterUtil;
|
||||
use surface;
|
||||
|
||||
fn encode(writer: io::Writer, surface: &surface::image_surface) {
|
||||
fn encode(writer: io::Writer, surface: &surface::ImageSurface) {
|
||||
assert surface.format == surface::fo_rgba_8888;
|
||||
|
||||
writer.write_u8(0u8); // identsize
|
||||
|
@ -32,11 +32,11 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
||||
|
||||
let opt_match = match getopts::getopts(args, opts) {
|
||||
result::Ok(m) => { copy m }
|
||||
result::Err(f) => { fail getopts::fail_str(copy f) }
|
||||
result::Err(f) => { fail!(getopts::fail_str(copy f)) }
|
||||
};
|
||||
|
||||
let urls = if opt_match.free.is_empty() {
|
||||
fail ~"servo asks that you provide 1 or more URLs"
|
||||
fail!(~"servo asks that you provide 1 or more URLs")
|
||||
} else {
|
||||
copy opt_match.free
|
||||
};
|
||||
@ -59,7 +59,7 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
|
||||
} else if backend_str == ~"skia" {
|
||||
SkiaBackend
|
||||
} else {
|
||||
fail ~"unknown backend type"
|
||||
fail!(~"unknown backend type")
|
||||
}
|
||||
}
|
||||
None => CairoBackend
|
||||
|
@ -14,7 +14,8 @@ use quartz::font_list::core_text::font_descriptor::{debug_descriptor};
|
||||
|
||||
use quartz::font::QuartzFontHandle;
|
||||
use quartz::font_context::QuartzFontContextHandle;
|
||||
use gfx_font::FontHandle;
|
||||
use gfx_font::{FontHandle, FontHandleMethods};
|
||||
use gfx_font_context::FontContextHandleMethods;
|
||||
use gfx_font_list::{FontEntry, FontFamily, FontFamilyMap};
|
||||
|
||||
use core::dvec::DVec;
|
||||
|
@ -1,17 +1,19 @@
|
||||
// The task that handles all rendering/painting.
|
||||
|
||||
use azure::AzFloat;
|
||||
use compositor::{Compositor, LayerBufferSet};
|
||||
use font_context::FontContext;
|
||||
use geom::matrix2d::Matrix2D;
|
||||
use opts::Opts;
|
||||
use render_context::RenderContext;
|
||||
use render_layers::{RenderLayer, render_layers};
|
||||
use resource::util::spawn_listener;
|
||||
use util::time::time;
|
||||
use azure::AzFloat;
|
||||
use core::oldcomm::*;
|
||||
|
||||
use core::libc::size_t;
|
||||
use core::libc::types::common::c99::uint16_t;
|
||||
use core::pipes::{Port, Chan};
|
||||
use core::pipes::{Chan, Port, SharedChan};
|
||||
use core::task::SingleThreaded;
|
||||
use geom::matrix2d::Matrix2D;
|
||||
use std::arc::ARC;
|
||||
use std::arc;
|
||||
use std::cell::Cell;
|
||||
@ -22,12 +24,12 @@ pub enum Msg {
|
||||
ExitMsg(pipes::Chan<()>)
|
||||
}
|
||||
|
||||
pub type RenderTask = oldcomm::Chan<Msg>;
|
||||
pub type RenderTask = SharedChan<Msg>;
|
||||
|
||||
pub fn RenderTask<C: Compositor Owned>(compositor: C, opts: Opts) -> RenderTask {
|
||||
pub fn RenderTask<C:Compositor + Owned>(compositor: C, opts: Opts) -> RenderTask {
|
||||
let compositor_cell = Cell(move compositor);
|
||||
let opts_cell = Cell(move opts);
|
||||
do spawn_listener |po: oldcomm::Port<Msg>, move compositor_cell, move opts_cell| {
|
||||
let render_task = do spawn_listener |po: Port<Msg>| {
|
||||
let (layer_buffer_set_port, layer_buffer_channel) = pipes::stream();
|
||||
|
||||
let compositor = compositor_cell.take();
|
||||
@ -58,7 +60,8 @@ pub fn RenderTask<C: Compositor Owned>(compositor: C, opts: Opts) -> RenderTask
|
||||
thread_pool: move thread_pool,
|
||||
opts: opts_cell.take()
|
||||
}.start();
|
||||
}
|
||||
};
|
||||
SharedChan(render_task)
|
||||
}
|
||||
|
||||
/// Data that needs to be kept around for each render thread.
|
||||
@ -68,8 +71,8 @@ priv struct ThreadRenderContext {
|
||||
opts: Opts,
|
||||
}
|
||||
|
||||
priv struct Renderer<C: Compositor Owned> {
|
||||
port: oldcomm::Port<Msg>,
|
||||
priv struct Renderer<C> {
|
||||
port: Port<Msg>,
|
||||
compositor: C,
|
||||
layer_buffer_set_port: Cell<pipes::Port<LayerBufferSet>>,
|
||||
thread_pool: TaskPool<ThreadRenderContext>,
|
||||
|
@ -1,29 +1,29 @@
|
||||
export factory;
|
||||
|
||||
use oldcomm::Chan;
|
||||
use pipes::Chan;
|
||||
use task::spawn;
|
||||
use resource::resource_task::{ProgressMsg, Payload, Done};
|
||||
use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask};
|
||||
use std::net::url::Url;
|
||||
use io::{file_reader, ReaderUtil};
|
||||
|
||||
const READ_SIZE: uint = 1024;
|
||||
|
||||
pub fn factory(url: Url, progress_chan: Chan<ProgressMsg>) {
|
||||
assert url.scheme == ~"file";
|
||||
|
||||
do spawn |move url| {
|
||||
// FIXME: Resolve bug prevents us from moving the path out of the URL.
|
||||
match file_reader(&Path(url.path)) {
|
||||
Ok(reader) => {
|
||||
while !reader.eof() {
|
||||
let data = reader.read_bytes(READ_SIZE);
|
||||
progress_chan.send(Payload(move data));
|
||||
}
|
||||
progress_chan.send(Done(Ok(())));
|
||||
}
|
||||
Err(*) => {
|
||||
progress_chan.send(Done(Err(())));
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn factory() -> LoaderTask {
|
||||
let f: LoaderTask = |url, progress_chan| {
|
||||
assert url.scheme == ~"file";
|
||||
do spawn {
|
||||
// FIXME: Resolve bug prevents us from moving the path out of the URL.
|
||||
match file_reader(&Path(url.path)) {
|
||||
Ok(reader) => {
|
||||
while !reader.eof() {
|
||||
let data = reader.read_bytes(READ_SIZE);
|
||||
progress_chan.send(Payload(move data));
|
||||
}
|
||||
progress_chan.send(Done(Ok(())));
|
||||
}
|
||||
Err(*) => {
|
||||
progress_chan.send(Done(Err(())));
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
f
|
||||
}
|
||||
|
@ -1,39 +1,46 @@
|
||||
export factory;
|
||||
|
||||
use oldcomm::Chan;
|
||||
use pipes::{Chan, SharedChan};
|
||||
use task::spawn;
|
||||
use resource::resource_task::{ProgressMsg, Payload, Done};
|
||||
use resource::resource_task::{ProgressMsg, Payload, Done, LoaderTask};
|
||||
use std::cell::Cell;
|
||||
use std::net::url::Url;
|
||||
use http_client;
|
||||
use http_client::{uv_http_request};
|
||||
|
||||
pub fn factory(url: Url, progress_chan: Chan<ProgressMsg>) {
|
||||
assert url.scheme == ~"http";
|
||||
pub fn factory() -> LoaderTask {
|
||||
let f: LoaderTask = |url, progress_chan| {
|
||||
assert url.scheme == ~"http";
|
||||
|
||||
do spawn |move url| {
|
||||
debug!("http_loader: requesting via http: %?", copy url);
|
||||
let request = uv_http_request(copy url);
|
||||
let errored = @mut false;
|
||||
do request.begin |event, copy url| {
|
||||
let url = copy url;
|
||||
match event {
|
||||
http_client::Status(*) => { }
|
||||
http_client::Payload(data) => {
|
||||
debug!("http_loader: got data from %?", url);
|
||||
let mut junk = None;
|
||||
*data <-> junk;
|
||||
progress_chan.send(Payload(option::unwrap(move junk)));
|
||||
}
|
||||
http_client::Error(*) => {
|
||||
debug!("http_loader: error loading %?", url);
|
||||
*errored = true;
|
||||
progress_chan.send(Done(Err(())));
|
||||
}
|
||||
}
|
||||
}
|
||||
let progress_chan = SharedChan(progress_chan);
|
||||
do spawn {
|
||||
debug!("http_loader: requesting via http: %?", copy url);
|
||||
let request = uv_http_request(copy url);
|
||||
let errored = @mut false;
|
||||
let url = copy url;
|
||||
{
|
||||
let progress_chan = progress_chan.clone();
|
||||
do request.begin |event| {
|
||||
let url = copy url;
|
||||
match event {
|
||||
http_client::Status(*) => { }
|
||||
http_client::Payload(data) => {
|
||||
debug!("http_loader: got data from %?", url);
|
||||
let mut junk = None;
|
||||
*data <-> junk;
|
||||
progress_chan.send(Payload(option::unwrap(move junk)));
|
||||
}
|
||||
http_client::Error(*) => {
|
||||
debug!("http_loader: error loading %?", url);
|
||||
*errored = true;
|
||||
progress_chan.send(Done(Err(())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !*errored {
|
||||
progress_chan.send(Done(Ok(())));
|
||||
}
|
||||
}
|
||||
if !*errored {
|
||||
progress_chan.send(Done(Ok(())));
|
||||
}
|
||||
}
|
||||
};
|
||||
f
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ impl ImageResponseMsg: cmp::Eq {
|
||||
pure fn eq(&self, other: &ImageResponseMsg) -> bool {
|
||||
// FIXME: Bad copies
|
||||
match (self.clone(), other.clone()) {
|
||||
(ImageReady(*), ImageReady(*)) => fail ~"unimplemented comparison",
|
||||
(ImageReady(*), ImageReady(*)) => fail!(~"unimplemented comparison"),
|
||||
(ImageNotReady, ImageNotReady) => true,
|
||||
(ImageFailed, ImageFailed) => true,
|
||||
|
||||
@ -84,7 +84,9 @@ pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||
ImageCacheTask_(resource_task, default_decoder_factory)
|
||||
}
|
||||
|
||||
pub fn ImageCacheTask_(resource_task: ResourceTask, decoder_factory: DecoderFactory) -> ImageCacheTask {
|
||||
pub fn ImageCacheTask_(resource_task: ResourceTask,
|
||||
decoder_factory: DecoderFactory)
|
||||
-> ImageCacheTask {
|
||||
// FIXME: Doing some dancing to avoid copying decoder_factory, our test
|
||||
// version of which contains an uncopyable type which rust will currently
|
||||
// copy unsoundly
|
||||
@ -95,9 +97,9 @@ pub fn ImageCacheTask_(resource_task: ResourceTask, decoder_factory: DecoderFact
|
||||
let port_cell = Cell(move port);
|
||||
let chan_cell = Cell(chan.clone());
|
||||
|
||||
do spawn |move port_cell, move chan_cell, move decoder_factory_cell| {
|
||||
do spawn {
|
||||
ImageCache {
|
||||
resource_task: resource_task,
|
||||
resource_task: resource_task.clone(),
|
||||
decoder_factory: decoder_factory_cell.take(),
|
||||
port: port_cell.take(),
|
||||
chan: chan_cell.take(),
|
||||
@ -114,9 +116,9 @@ fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
|
||||
let (port, chan) = stream();
|
||||
let port_cell = Cell(move port);
|
||||
|
||||
do spawn |move port_cell, move resource_task| {
|
||||
do spawn {
|
||||
let port = port_cell.take();
|
||||
let inner_cache = ImageCacheTask(resource_task);
|
||||
let inner_cache = ImageCacheTask(resource_task.clone());
|
||||
|
||||
loop {
|
||||
let msg: Msg = port.recv();
|
||||
@ -177,7 +179,9 @@ impl ImageCache {
|
||||
loop {
|
||||
let msg = self.port.recv();
|
||||
|
||||
for msg_handlers.each |handler| { (*handler)(&msg) }
|
||||
for msg_handlers.each |handler| {
|
||||
(*handler)(&msg)
|
||||
}
|
||||
|
||||
debug!("image_cache_task: received: %?", msg);
|
||||
|
||||
@ -192,7 +196,7 @@ impl ImageCache {
|
||||
WaitForImage(move url, move response) => {
|
||||
self.wait_for_image(move url, move response)
|
||||
}
|
||||
OnMsg(move handler) => msg_handlers += [move handler],
|
||||
OnMsg(move handler) => msg_handlers.push(handler),
|
||||
Exit(move response) => {
|
||||
assert self.need_exit.is_none();
|
||||
self.need_exit = Some(move response);
|
||||
@ -207,14 +211,11 @@ impl ImageCache {
|
||||
// before exiting
|
||||
let mut can_exit = true;
|
||||
for self.state_map.each_value |state| {
|
||||
match state {
|
||||
Prefetching(*) => can_exit = false,
|
||||
Decoding => can_exit = false,
|
||||
match *state {
|
||||
Prefetching(*) => can_exit = false,
|
||||
Decoding => can_exit = false,
|
||||
|
||||
Init
|
||||
| Prefetched(*)
|
||||
| Decoded(*)
|
||||
| Failed => ()
|
||||
Init | Prefetched(*) | Decoded(*) | Failed => ()
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,7 +232,7 @@ impl ImageCache {
|
||||
}
|
||||
|
||||
priv fn get_state(url: Url) -> ImageState {
|
||||
match move self.state_map.find(move url) {
|
||||
match move self.state_map.find(&url) {
|
||||
Some(move state) => move state,
|
||||
None => Init
|
||||
}
|
||||
@ -243,36 +244,32 @@ impl ImageCache {
|
||||
|
||||
priv fn prefetch(url: Url) {
|
||||
match self.get_state(copy url) {
|
||||
Init => {
|
||||
let to_cache = self.chan.clone();
|
||||
let resource_task = self.resource_task;
|
||||
let url_cell = Cell(copy url);
|
||||
Init => {
|
||||
let to_cache = self.chan.clone();
|
||||
let resource_task = self.resource_task.clone();
|
||||
let url_cell = Cell(copy url);
|
||||
|
||||
do spawn |move to_cache, move url_cell| {
|
||||
let url = url_cell.take();
|
||||
debug!("image_cache_task: started fetch for %s", url.to_str());
|
||||
do spawn {
|
||||
let url = url_cell.take();
|
||||
debug!("image_cache_task: started fetch for %s", url.to_str());
|
||||
|
||||
let image = load_image_data(copy url, resource_task);
|
||||
let image = load_image_data(copy url, resource_task.clone());
|
||||
|
||||
let result = if image.is_ok() {
|
||||
Ok(Cell(result::unwrap(move image)))
|
||||
} else {
|
||||
Err(())
|
||||
};
|
||||
to_cache.send(StorePrefetchedImageData(copy url, move result));
|
||||
debug!("image_cache_task: ended fetch for %s", (copy url).to_str());
|
||||
let result = if image.is_ok() {
|
||||
Ok(Cell(result::unwrap(move image)))
|
||||
} else {
|
||||
Err(())
|
||||
};
|
||||
to_cache.send(StorePrefetchedImageData(copy url, move result));
|
||||
debug!("image_cache_task: ended fetch for %s", (copy url).to_str());
|
||||
}
|
||||
|
||||
self.set_state(move url, Prefetching(DoNotDecode));
|
||||
}
|
||||
|
||||
self.set_state(move url, Prefetching(DoNotDecode));
|
||||
}
|
||||
|
||||
Prefetching(*)
|
||||
| Prefetched(*)
|
||||
| Decoding
|
||||
| Decoded(*)
|
||||
| Failed => {
|
||||
// We've already begun working on this image
|
||||
}
|
||||
Prefetching(*) | Prefetched(*) | Decoding | Decoded(*) | Failed => {
|
||||
// We've already begun working on this image
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,14 +297,14 @@ impl ImageCache {
|
||||
| Decoding
|
||||
| Decoded(*)
|
||||
| Failed => {
|
||||
fail ~"wrong state for storing prefetched image"
|
||||
fail!(~"wrong state for storing prefetched image")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
priv fn decode(url: Url) {
|
||||
match self.get_state(copy url) {
|
||||
Init => fail ~"decoding image before prefetch",
|
||||
Init => fail!(~"decoding image before prefetch"),
|
||||
|
||||
Prefetching(DoNotDecode) => {
|
||||
// We don't have the data yet, queue up the decode
|
||||
@ -369,14 +366,13 @@ impl ImageCache {
|
||||
| Prefetched(*)
|
||||
| Decoded(*)
|
||||
| Failed => {
|
||||
fail ~"incorrect state in store_image"
|
||||
fail!(~"incorrect state in store_image")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
priv fn purge_waiters(url: Url, f: fn() -> ImageResponseMsg) {
|
||||
match self.wait_map.find(copy url) {
|
||||
Some(waiters) => {
|
||||
let waiters = &mut *waiters;
|
||||
let mut new_waiters = ~[];
|
||||
@ -387,7 +383,7 @@ impl ImageCache {
|
||||
}
|
||||
|
||||
*waiters <-> new_waiters;
|
||||
self.wait_map.remove(move url);
|
||||
self.wait_map.remove(&url);
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
@ -395,16 +391,15 @@ impl ImageCache {
|
||||
|
||||
|
||||
priv fn get_image(url: Url, response: Chan<ImageResponseMsg>) {
|
||||
|
||||
match self.get_state(copy url) {
|
||||
Init => fail ~"request for image before prefetch",
|
||||
Init => fail!(~"request for image before prefetch"),
|
||||
|
||||
Prefetching(DoDecode) => {
|
||||
response.send(ImageNotReady);
|
||||
}
|
||||
|
||||
Prefetching(DoNotDecode)
|
||||
| Prefetched(*) => fail ~"request for image before decode",
|
||||
| Prefetched(*) => fail!(~"request for image before decode"),
|
||||
|
||||
Decoding => {
|
||||
response.send(ImageNotReady)
|
||||
@ -422,13 +417,13 @@ impl ImageCache {
|
||||
|
||||
priv fn wait_for_image(url: Url, response: Chan<ImageResponseMsg>) {
|
||||
match self.get_state(copy url) {
|
||||
Init => fail ~"request for image before prefetch",
|
||||
Init => fail!(~"request for image before prefetch"),
|
||||
|
||||
Prefetching(DoNotDecode) | Prefetched(*) => fail ~"request for image before decode",
|
||||
Prefetching(DoNotDecode) | Prefetched(*) => fail!(~"request for image before decode"),
|
||||
|
||||
Prefetching(DoDecode) | Decoding => {
|
||||
// We don't have this image yet
|
||||
match self.wait_map.find(copy url) {
|
||||
match self.wait_map.find(&url) {
|
||||
Some(waiters) => {
|
||||
vec::push(&mut *waiters, move response);
|
||||
}
|
||||
@ -466,8 +461,8 @@ impl ImageCacheTask: ImageCacheTaskClient {
|
||||
}
|
||||
|
||||
fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
|
||||
let response_port = oldcomm::Port();
|
||||
resource_task.send(resource_task::Load(move url, response_port.chan()));
|
||||
let (response_port, response_chan) = stream();
|
||||
resource_task.send(resource_task::Load(move url, response_chan));
|
||||
|
||||
let mut image_data = ~[];
|
||||
|
||||
@ -491,8 +486,8 @@ fn default_decoder_factory() -> ~fn(&[u8]) -> Option<Image> {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn mock_resource_task(on_load: ~fn(resource: oldcomm::Chan<resource_task::ProgressMsg>)) -> ResourceTask {
|
||||
do spawn_listener |port: oldcomm::Port<resource_task::ControlMsg>, move on_load| {
|
||||
fn mock_resource_task(on_load: ~fn(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
|
||||
do spawn_listener |port: Port<resource_task::ControlMsg>, move on_load| {
|
||||
loop {
|
||||
match port.recv() {
|
||||
resource_task::Load(_, response) => {
|
||||
@ -532,7 +527,7 @@ fn should_fail_if_unprefetched_image_is_requested() {
|
||||
|
||||
#[test]
|
||||
fn should_request_url_from_resource_task_on_prefetch() {
|
||||
let url_requested = oldcomm::Port();
|
||||
let url_requested = Port();
|
||||
let url_requested_chan = url_requested.chan();
|
||||
|
||||
let mock_resource_task = do mock_resource_task |response| {
|
||||
|
@ -133,7 +133,7 @@ pub impl LocalImageCache {
|
||||
}
|
||||
|
||||
priv fn get_state(url: &Url) -> @ImageState {
|
||||
match self.state_map.find(copy *url) {
|
||||
match self.state_map.find(url) {
|
||||
Some(state) => state,
|
||||
None => {
|
||||
let new_state = @ImageState {
|
||||
|
@ -4,8 +4,9 @@ A task that takes a URL and streams back the binary data
|
||||
|
||||
*/
|
||||
|
||||
use oldcomm::{Chan, Port};
|
||||
use pipes::{Chan, Port, SharedChan};
|
||||
use resource::util::spawn_listener;
|
||||
use std::cell::Cell;
|
||||
use std::net::url;
|
||||
use std::net::url::{Url, to_str};
|
||||
use super::{file_loader, http_loader};
|
||||
@ -17,6 +18,7 @@ pub enum ControlMsg {
|
||||
}
|
||||
|
||||
/// Messages sent in response to a `Load` message
|
||||
#[deriving_eq]
|
||||
pub enum ProgressMsg {
|
||||
/// Binary data - there may be multiple of these
|
||||
Payload(~[u8]),
|
||||
@ -24,24 +26,8 @@ pub enum ProgressMsg {
|
||||
Done(Result<(), ()>)
|
||||
}
|
||||
|
||||
impl ProgressMsg: cmp::Eq {
|
||||
pure fn eq(&self, other: &ProgressMsg) -> bool {
|
||||
// FIXME: Bad copies
|
||||
match (copy *self, copy *other) {
|
||||
(Payload(a), Payload(b)) => a == b,
|
||||
(Done(a), Done(b)) => a == b,
|
||||
|
||||
(Payload(*), _)
|
||||
| (Done(*), _) => false
|
||||
}
|
||||
}
|
||||
pure fn ne(&self, other: &ProgressMsg) -> bool {
|
||||
return !(*self).eq(other);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle to a resource task
|
||||
pub type ResourceTask = Chan<ControlMsg>;
|
||||
pub type ResourceTask = SharedChan<ControlMsg>;
|
||||
|
||||
/**
|
||||
Creates a task to load a specific resource
|
||||
@ -49,7 +35,9 @@ Creates a task to load a specific resource
|
||||
The ResourceManager delegates loading to a different type of loader task for
|
||||
each URL scheme
|
||||
*/
|
||||
type LoaderTaskFactory = fn~(url: Url, Chan<ProgressMsg>);
|
||||
type LoaderTaskFactory = ~fn() -> ~fn(url: Url, Chan<ProgressMsg>);
|
||||
|
||||
pub type LoaderTask = ~fn(url: Url, Chan<ProgressMsg>);
|
||||
|
||||
/// Create a ResourceTask with the default loaders
|
||||
pub fn ResourceTask() -> ResourceTask {
|
||||
@ -63,10 +51,12 @@ pub fn ResourceTask() -> ResourceTask {
|
||||
}
|
||||
|
||||
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
|
||||
do spawn_listener |from_client, move loaders| {
|
||||
let loaders_cell = Cell(loaders);
|
||||
let chan = do spawn_listener |from_client| {
|
||||
// TODO: change copy to move once we can move out of closures
|
||||
ResourceManager(from_client, copy loaders).start()
|
||||
}
|
||||
ResourceManager(from_client, loaders_cell.take()).start()
|
||||
};
|
||||
SharedChan(chan)
|
||||
}
|
||||
|
||||
pub struct ResourceManager {
|
||||
@ -113,12 +103,15 @@ impl ResourceManager {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_loader_factory(url: &Url) -> Option<LoaderTaskFactory> {
|
||||
fn get_loader_factory(url: &Url) -> Option<LoaderTask> {
|
||||
for self.loaders.each |scheme_loader| {
|
||||
let (scheme, loader_factory) = copy *scheme_loader;
|
||||
if scheme == url.scheme {
|
||||
return Some(move loader_factory);
|
||||
}
|
||||
match *scheme_loader {
|
||||
(ref scheme, ref loader_factory) => {
|
||||
if (*scheme) == url.scheme {
|
||||
return Some((*loader_factory)());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
pub fn spawn_listener<A: Owned>(
|
||||
f: fn~(oldcomm::Port<A>)) -> oldcomm::Chan<A> {
|
||||
let setup_po = oldcomm::Port();
|
||||
let setup_ch = oldcomm::Chan(&setup_po);
|
||||
use core::pipes::{Chan, Port};
|
||||
use core::pipes;
|
||||
|
||||
pub fn spawn_listener<A: Owned>(f: ~fn(Port<A>)) -> Chan<A> {
|
||||
let (setup_po, setup_ch) = pipes::stream();
|
||||
do task::spawn |move f| {
|
||||
let po = oldcomm::Port();
|
||||
let ch = oldcomm::Chan(&po);
|
||||
oldcomm::send(setup_ch, ch);
|
||||
let (po, ch) = pipes::stream();
|
||||
setup_ch.send(ch);
|
||||
f(move po);
|
||||
}
|
||||
oldcomm::recv(setup_po)
|
||||
setup_po.recv()
|
||||
}
|
||||
|
@ -1,27 +1,11 @@
|
||||
use geom::size::Size2D;
|
||||
|
||||
#[deriving_eq]
|
||||
pub enum format {
|
||||
fo_rgba_8888
|
||||
// TODO: RGB 565, others?
|
||||
}
|
||||
|
||||
impl format: cmp::Eq {
|
||||
pure fn eq(&self, other: &format) -> bool {
|
||||
match (*self, *other) {
|
||||
(fo_rgba_8888, fo_rgba_8888) => true,
|
||||
}
|
||||
}
|
||||
pure fn ne(&self, other: &format) -> bool {
|
||||
return !self.eq(other);
|
||||
}
|
||||
}
|
||||
|
||||
pub type image_surface = {
|
||||
size: Size2D<int>,
|
||||
format: format,
|
||||
buffer: ~[u8]
|
||||
};
|
||||
|
||||
impl format {
|
||||
fn bpp() -> uint {
|
||||
match self {
|
||||
@ -30,11 +14,19 @@ impl format {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn image_surface(size: Size2D<int>, format: format) -> image_surface {
|
||||
{
|
||||
size: copy size,
|
||||
format: format,
|
||||
buffer: vec::from_elem((size.area() as uint) * format.bpp(), 0u8)
|
||||
}
|
||||
pub struct ImageSurface {
|
||||
size: Size2D<int>,
|
||||
format: format,
|
||||
buffer: ~[u8]
|
||||
}
|
||||
|
||||
impl ImageSurface {
|
||||
static pub fn new(size: Size2D<int>, format: format) -> ImageSurface {
|
||||
ImageSurface {
|
||||
size: copy size,
|
||||
format: format,
|
||||
buffer: vec::from_elem((size.area() as uint) * format.bpp(), 0u8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,10 +6,10 @@ use geometry;
|
||||
use core;
|
||||
use core::cmp::{Ord, Eq};
|
||||
use core::dvec::DVec;
|
||||
use core::num::NumCast;
|
||||
use core::u16;
|
||||
use geom::point::Point2D;
|
||||
use std::sort;
|
||||
use num::Num;
|
||||
|
||||
|
||||
// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing
|
||||
@ -174,7 +174,7 @@ impl GlyphEntry {
|
||||
#[inline(always)]
|
||||
pure fn advance() -> Au {
|
||||
//assert self.is_simple();
|
||||
Num::from_int(((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT) as int)
|
||||
NumCast::from((self.value & GLYPH_ADVANCE_MASK) >> GLYPH_ADVANCE_SHIFT)
|
||||
}
|
||||
|
||||
pure fn index() -> GlyphIndex {
|
||||
@ -375,7 +375,7 @@ impl DetailedGlyphStore {
|
||||
// FIXME: This is a workaround for borrow of self.detail_lookup not getting inferred.
|
||||
let records : &[DetailedGlyphRecord] = self.detail_lookup;
|
||||
match records.binary_search_index(&key) {
|
||||
None => fail ~"Invalid index not found in detailed glyph lookup table!",
|
||||
None => fail!(~"Invalid index not found in detailed glyph lookup table!"),
|
||||
Some(i) => {
|
||||
assert i + (count as uint) <= self.detail_buffer.len();
|
||||
// return a view into the buffer
|
||||
@ -384,7 +384,10 @@ impl DetailedGlyphStore {
|
||||
}
|
||||
}
|
||||
|
||||
pure fn get_detailed_glyph_with_index(&self, entry_offset: uint, detail_offset: u16) -> &self/DetailedGlyph {
|
||||
pure fn get_detailed_glyph_with_index(&self,
|
||||
entry_offset: uint,
|
||||
detail_offset: u16)
|
||||
-> &self/DetailedGlyph {
|
||||
assert (detail_offset as uint) <= self.detail_buffer.len();
|
||||
assert self.lookup_is_sorted;
|
||||
|
||||
@ -396,7 +399,7 @@ impl DetailedGlyphStore {
|
||||
// FIXME: This is a workaround for borrow of self.detail_lookup not getting inferred.
|
||||
let records : &[DetailedGlyphRecord] = self.detail_lookup;
|
||||
match records.binary_search_index(&key) {
|
||||
None => fail ~"Invalid index not found in detailed glyph lookup table!",
|
||||
None => fail!(~"Invalid index not found in detailed glyph lookup table!"),
|
||||
Some(i) => {
|
||||
assert i + (detail_offset as uint) < self.detail_buffer.len();
|
||||
&self.detail_buffer[i+(detail_offset as uint)]
|
||||
|
@ -4,7 +4,7 @@ use geom::Point2D;
|
||||
|
||||
use geometry::Au;
|
||||
|
||||
use font::{Font, FontTable, FontTableTag};
|
||||
use font::{Font, FontTable, FontTableMethods, FontTableTag};
|
||||
|
||||
use text::glyph::{GlyphStore, GlyphIndex, GlyphData};
|
||||
use text::shaper::ShaperMethods;
|
||||
@ -202,7 +202,7 @@ pub impl HarfbuzzShaper {
|
||||
}
|
||||
}
|
||||
|
||||
pub impl HarfbuzzShaper : ShaperMethods {
|
||||
impl ShaperMethods for HarfbuzzShaper {
|
||||
/**
|
||||
Calculate the layout metrics associated with a some given text
|
||||
when rendered in a specific font.
|
||||
|
@ -12,7 +12,6 @@ pub type Shaper/& = harfbuzz::shaper::HarfbuzzShaper;
|
||||
|
||||
pub trait ShaperMethods {
|
||||
fn shape_text(text: &str, glyphs: &mut GlyphStore);
|
||||
|
||||
}
|
||||
|
||||
// TODO(Issue #163): this is a workaround for static methods and
|
||||
|
@ -28,7 +28,7 @@ impl SendableTextRun {
|
||||
pub fn deserialize(&self, fctx: @FontContext) -> TextRun {
|
||||
let font = match fctx.get_font_by_descriptor(&self.font) {
|
||||
Ok(f) => f,
|
||||
Err(_) => fail fmt!("Font descriptor deserialization failed! desc=%?", self.font)
|
||||
Err(_) => fail!(fmt!("Font descriptor deserialization failed! desc=%?", self.font))
|
||||
};
|
||||
|
||||
TextRun {
|
||||
|
@ -1,14 +1,14 @@
|
||||
use core::cmp::*;
|
||||
|
||||
pub trait Cache<K: Copy Eq, V: Copy> {
|
||||
static fn new(size: uint) -> self;
|
||||
static fn new(size: uint) -> Self;
|
||||
fn insert(key: &K, value: V);
|
||||
fn find(key: &K) -> Option<V>;
|
||||
fn find_or_create(key: &K, blk: pure fn&(&K) -> V) -> V;
|
||||
fn evict_all();
|
||||
}
|
||||
|
||||
pub struct MonoCache<K: Copy Eq, V: Copy> {
|
||||
pub struct MonoCache<K, V> {
|
||||
mut entry: Option<(K,V)>,
|
||||
}
|
||||
|
||||
@ -56,4 +56,4 @@ fn test_monocache() {
|
||||
cache.find_or_create(&2, |_v| { two });
|
||||
assert cache.find(&2).is_some();
|
||||
assert cache.find(&1).is_none();
|
||||
}
|
||||
}
|
||||
|
@ -88,8 +88,8 @@ pub impl Range {
|
||||
let overlap = other.end() - self.begin();
|
||||
return OverlapsEnd(overlap);
|
||||
}
|
||||
fail fmt!("relation_to_range(): didn't classify self=%?, other=%?",
|
||||
self, other);
|
||||
fail!(fmt!("relation_to_range(): didn't classify self=%?, other=%?",
|
||||
self, other));
|
||||
}
|
||||
|
||||
fn repair_after_coalesced_range(&mut self, other: &const Range) {
|
||||
@ -103,8 +103,10 @@ pub impl Range {
|
||||
Coincides | ContainedBy => { self.reset(other.begin(), 1); },
|
||||
Contains => { self.extend_by(-(other.length() as int)); },
|
||||
OverlapsBegin(overlap) => { self.extend_by(1 - (overlap as int)); },
|
||||
OverlapsEnd(overlap) =>
|
||||
{ self.reset(other.begin(), self.length() - overlap + 1); }
|
||||
OverlapsEnd(overlap) => {
|
||||
let len = self.length() - overlap + 1;
|
||||
self.reset(other.begin(), len);
|
||||
}
|
||||
};
|
||||
debug!("repair_after_coalesced_range: new range: ---- %?", self);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use core::path::Path;
|
||||
use std::map::HashMap;
|
||||
use std::net::url;
|
||||
use std::net::url::Url;
|
||||
use std::oldmap::HashMap;
|
||||
|
||||
/**
|
||||
Create a URL object from a string. Does various helpful browsery things like
|
||||
@ -98,7 +98,7 @@ mod make_url_tests {
|
||||
|
||||
}
|
||||
|
||||
pub type UrlMap<T: Copy> = HashMap<Url, T>;
|
||||
pub type UrlMap<T> = HashMap<Url, T>;
|
||||
|
||||
pub fn url_map<T: Copy>() -> UrlMap<T> {
|
||||
use core::to_str::ToStr;
|
||||
|
@ -13,7 +13,7 @@ use layout::layout_task::{AddStylesheet, BuildData, BuildMsg, Damage, LayoutTask
|
||||
use layout::layout_task::{MatchSelectorsDamage, NoDamage, ReflowDamage};
|
||||
use util::task::spawn_listener;
|
||||
|
||||
use core::oldcomm::{Port, Chan, listen, select2};
|
||||
use core::pipes::{Port, Chan, SharedChan, select2};
|
||||
use core::either;
|
||||
use core::task::{SingleThreaded, spawn, task};
|
||||
use core::io::{println, read_whole_file};
|
||||
@ -28,7 +28,7 @@ use js::global::{global_class, debug_fns};
|
||||
use js::glue::bindgen::RUST_JSVAL_TO_OBJECT;
|
||||
use js::jsapi::{JSContext, JSVal};
|
||||
use js::jsapi::bindgen::{JS_CallFunctionValue, JS_GetContextPrivate};
|
||||
use js::rust::{compartment, cx, methods};
|
||||
use js::rust::{Compartment, Cx};
|
||||
use jsrt = js::rust::rt;
|
||||
use newcss::stylesheet::Stylesheet;
|
||||
use std::arc::{ARC, clone};
|
||||
@ -49,29 +49,30 @@ pub enum PingMsg {
|
||||
PongMsg
|
||||
}
|
||||
|
||||
pub type ContentTask = pipes::SharedChan<ControlMsg>;
|
||||
pub type ContentTask = SharedChan<ControlMsg>;
|
||||
|
||||
pub fn ContentTask(layout_task: LayoutTask,
|
||||
dom_event_port: pipes::Port<Event>,
|
||||
dom_event_chan: pipes::SharedChan<Event>,
|
||||
resource_task: ResourceTask,
|
||||
img_cache_task: ImageCacheTask) -> ContentTask {
|
||||
|
||||
dom_event_port: Port<Event>,
|
||||
dom_event_chan: SharedChan<Event>,
|
||||
resource_task: ResourceTask,
|
||||
img_cache_task: ImageCacheTask)
|
||||
-> ContentTask {
|
||||
let (control_port, control_chan) = pipes::stream();
|
||||
|
||||
let control_chan = pipes::SharedChan(move control_chan);
|
||||
let control_chan = SharedChan(control_chan);
|
||||
let control_chan_copy = control_chan.clone();
|
||||
let control_port = Cell(move control_port);
|
||||
let dom_event_port = Cell(move dom_event_port);
|
||||
let dom_event_chan = Cell(move dom_event_chan);
|
||||
let control_port = Cell(control_port);
|
||||
let dom_event_port = Cell(dom_event_port);
|
||||
let dom_event_chan = Cell(dom_event_chan);
|
||||
|
||||
do task().sched_mode(SingleThreaded).spawn |move layout_task, move control_port,
|
||||
move control_chan_copy, move resource_task,
|
||||
move img_cache_task, move dom_event_port,
|
||||
move dom_event_chan| {
|
||||
let content = Content(layout_task, control_port.take(), control_chan_copy.clone(),
|
||||
resource_task, img_cache_task.clone(),
|
||||
dom_event_port.take(), dom_event_chan.take());
|
||||
do task().sched_mode(SingleThreaded).spawn {
|
||||
let content = Content(layout_task.clone(),
|
||||
control_port.take(),
|
||||
control_chan_copy.clone(),
|
||||
resource_task.clone(),
|
||||
img_cache_task.clone(),
|
||||
dom_event_port.take(),
|
||||
dom_event_chan.take());
|
||||
content.start();
|
||||
}
|
||||
|
||||
@ -90,7 +91,7 @@ pub struct Content {
|
||||
|
||||
scope: NodeScope,
|
||||
jsrt: jsrt,
|
||||
cx: cx,
|
||||
cx: @Cx,
|
||||
|
||||
mut document: Option<@Document>,
|
||||
mut window: Option<@Window>,
|
||||
@ -99,20 +100,20 @@ pub struct Content {
|
||||
|
||||
resource_task: ResourceTask,
|
||||
|
||||
compartment: Option<compartment>,
|
||||
compartment: Option<@mut Compartment>,
|
||||
|
||||
// What parts of layout are dirty.
|
||||
mut damage: Damage,
|
||||
}
|
||||
|
||||
pub fn Content(layout_task: LayoutTask,
|
||||
control_port: pipes::Port<ControlMsg>,
|
||||
control_chan: pipes::SharedChan<ControlMsg>,
|
||||
resource_task: ResourceTask,
|
||||
img_cache_task: ImageCacheTask,
|
||||
event_port: pipes::Port<Event>,
|
||||
event_chan: pipes::SharedChan<Event>) -> @Content {
|
||||
|
||||
control_port: pipes::Port<ControlMsg>,
|
||||
control_chan: pipes::SharedChan<ControlMsg>,
|
||||
resource_task: ResourceTask,
|
||||
img_cache_task: ImageCacheTask,
|
||||
event_port: pipes::Port<Event>,
|
||||
event_chan: pipes::SharedChan<Event>)
|
||||
-> @Content {
|
||||
let jsrt = jsrt();
|
||||
let cx = jsrt.cx();
|
||||
|
||||
@ -161,7 +162,6 @@ pub fn task_from_context(cx: *JSContext) -> *Content {
|
||||
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
impl Content {
|
||||
|
||||
fn start() {
|
||||
while self.handle_msg() {
|
||||
// Go on ...
|
||||
@ -185,7 +185,7 @@ impl Content {
|
||||
|
||||
let result = html::hubbub_html_parser::parse_html(self.scope,
|
||||
copy url,
|
||||
self.resource_task,
|
||||
self.resource_task.clone(),
|
||||
self.image_cache_task.clone());
|
||||
|
||||
let root = result.root;
|
||||
@ -286,7 +286,7 @@ impl Content {
|
||||
join_port.recv();
|
||||
debug!("content: layout joined");
|
||||
}
|
||||
None => fail ~"reader forked but no join port?"
|
||||
None => fail!(~"reader forked but no join port?")
|
||||
}
|
||||
|
||||
self.scope.reader_joined();
|
||||
@ -332,9 +332,9 @@ impl Content {
|
||||
fn query_layout(query: layout_task::LayoutQuery) -> layout_task::LayoutQueryResponse {
|
||||
self.relayout(self.document.get(), &(copy self.doc_url).get());
|
||||
self.join_layout();
|
||||
|
||||
let response_port = Port();
|
||||
self.layout_task.send(layout_task::QueryMsg(query, response_port.chan()));
|
||||
|
||||
let (response_port, response_chan) = pipes::stream();
|
||||
self.layout_task.send(layout_task::QueryMsg(query, response_chan));
|
||||
return response_port.recv()
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
/**
|
||||
* High-level interface to CSS selector matching.
|
||||
*/
|
||||
use std::arc::{ARC, get, clone};
|
||||
use dom::node::{Node, NodeTree};
|
||||
use newcss::select::{SelectCtx, SelectResults};
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
use layout::context::LayoutContext;
|
||||
use css::select_handler::NodeSelectHandler;
|
||||
// High-level interface to CSS selector matching.
|
||||
|
||||
trait MatchMethods {
|
||||
use css::node_util::NodeUtil;
|
||||
use css::select_handler::NodeSelectHandler;
|
||||
use dom::node::{Node, NodeTree};
|
||||
use layout::context::LayoutContext;
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
use newcss::select::{SelectCtx, SelectResults};
|
||||
|
||||
use std::arc::{ARC, get, clone};
|
||||
|
||||
pub trait MatchMethods {
|
||||
fn restyle_subtree(select_ctx: &SelectCtx);
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
// Style retrieval from DOM elements.
|
||||
|
||||
use css::node_util::NodeUtil;
|
||||
use dom::node::Node;
|
||||
use newcss::complete::CompleteStyle;
|
||||
|
||||
/// Node mixin providing `style` method that returns a `NodeStyle`
|
||||
trait StyledNode {
|
||||
pub trait StyledNode {
|
||||
fn style(&self) -> CompleteStyle/&self;
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,12 @@ use dom::node::Node;
|
||||
use newcss::complete::CompleteSelectResults;
|
||||
use std::cell::Cell;
|
||||
|
||||
trait NodeUtil {
|
||||
pub trait NodeUtil {
|
||||
fn get_css_select_results() -> &self/CompleteSelectResults;
|
||||
fn set_css_select_results(decl : CompleteSelectResults);
|
||||
}
|
||||
|
||||
impl Node: NodeUtil {
|
||||
impl NodeUtil for Node {
|
||||
/**
|
||||
* Provides the computed style for the given node. If CSS selector
|
||||
* Returns the style results for the given node. If CSS selector
|
||||
@ -17,12 +17,12 @@ impl Node: NodeUtil {
|
||||
*/
|
||||
fn get_css_select_results() -> &self/CompleteSelectResults {
|
||||
if !self.has_aux() {
|
||||
fail ~"style() called on a node without aux data!";
|
||||
fail!(~"style() called on a node without aux data!");
|
||||
}
|
||||
unsafe { &*self.aux( |x| {
|
||||
match x.style {
|
||||
Some(ref style) => ptr::to_unsafe_ptr(style),
|
||||
None => fail ~"style() called on node without a style!"
|
||||
None => fail!(~"style() called on node without a style!")
|
||||
}
|
||||
})}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ pub struct NodeSelectHandler {
|
||||
fn with_node_name<R>(data: &NodeData, f: &fn(&str) -> R) -> R {
|
||||
match *data.kind {
|
||||
Element(ref data) => f(data.tag_name),
|
||||
_ => fail ~"attempting to style non-element node"
|
||||
_ => fail!(~"attempting to style non-element node")
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ impl NodeSelectHandler: SelectHandler<Node> {
|
||||
do node.read |data| {
|
||||
match *data.kind {
|
||||
Element(ref data) => data.with_attr("id", f),
|
||||
_ => fail ~"attempting to style non-element node"
|
||||
_ => fail!(~"attempting to style non-element node")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,7 +91,7 @@ impl NodeSelectHandler: SelectHandler<Node> {
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => fail ~"attempting to style non-element node"
|
||||
_ => fail!(~"attempting to style non-element node")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use js::rust::{compartment, bare_compartment, methods, jsobj};
|
||||
use js::rust::{Compartment, jsobj};
|
||||
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED,
|
||||
JSVAL_NULL, JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
|
||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp};
|
||||
@ -62,8 +62,7 @@ enum Element = int;
|
||||
return 1;
|
||||
}*/
|
||||
|
||||
extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal)
|
||||
-> JSBool {
|
||||
extern fn getDocumentElement(cx: *JSContext, _argc: c_uint, vp: *mut JSVal) -> JSBool {
|
||||
unsafe {
|
||||
let obj = JS_THIS_OBJECT(cx, cast::reinterpret_cast(&vp));
|
||||
if obj.is_null() {
|
||||
@ -92,7 +91,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(compartment: &bare_compartment, doc: @Document) {
|
||||
pub fn init(compartment: @mut Compartment, doc: @Document) {
|
||||
let obj = utils::define_empty_prototype(~"Document", None, compartment);
|
||||
|
||||
let attrs = @~[
|
||||
|
@ -1,4 +1,4 @@
|
||||
use js::rust::{bare_compartment, methods, jsobj};
|
||||
use js::rust::{Compartment, jsobj};
|
||||
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
|
||||
JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
|
||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSPropertySpec};
|
||||
@ -29,7 +29,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(compartment: &bare_compartment) {
|
||||
pub fn init(compartment: @mut Compartment) {
|
||||
let obj = utils::define_empty_prototype(~"Element", Some(~"Node"), compartment);
|
||||
let attrs = @~[
|
||||
{name: compartment.add_name(~"tagName"),
|
||||
@ -87,10 +87,10 @@ extern fn HTMLImageElement_getWidth(cx: *JSContext, _argc: c_uint, vp: *mut JSVa
|
||||
}
|
||||
// TODO: if nothing is being rendered(?), return zero dimensions
|
||||
}
|
||||
_ => fail ~"why is this not an image element?"
|
||||
_ => fail!(~"why is this not an image element?")
|
||||
}
|
||||
}
|
||||
_ => fail ~"why is this not an element?"
|
||||
_ => fail!(~"why is this not an element?")
|
||||
}
|
||||
});
|
||||
*vp = RUST_INT_TO_JSVAL(
|
||||
@ -117,10 +117,10 @@ extern fn HTMLImageElement_setWidth(cx: *JSContext, _argc: c_uint, vp: *mut JSVa
|
||||
let arg = ptr::offset(JS_ARGV(cx, cast::reinterpret_cast(&vp)), 0);
|
||||
ed.set_attr(~"width", int::str(RUST_JSVAL_TO_INT(*arg) as int))
|
||||
}
|
||||
_ => fail ~"why is this not an image element?"
|
||||
_ => fail!(~"why is this not an image element?")
|
||||
}
|
||||
}
|
||||
_ => fail ~"why is this not an element?"
|
||||
_ => fail!(~"why is this not an element?")
|
||||
}
|
||||
};
|
||||
return 1;
|
||||
@ -166,7 +166,7 @@ pub fn create(cx: *JSContext, node: Node, scope: NodeScope) -> jsobj {
|
||||
_ => ~"HTMLElement"
|
||||
}
|
||||
}
|
||||
_ => fail ~"element::create only handles elements"
|
||||
_ => fail!(~"element::create only handles elements")
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use js::rust::{bare_compartment, methods, jsobj};
|
||||
use js::rust::{Compartment, jsobj};
|
||||
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
|
||||
JS_THIS_OBJECT, JS_SET_RVAL, JSPROP_NATIVE_ACCESSORS};
|
||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSPropertySpec};
|
||||
@ -18,7 +18,7 @@ use super::utils;
|
||||
use super::element;
|
||||
use js;
|
||||
|
||||
pub fn init(compartment: &bare_compartment) {
|
||||
pub fn init(compartment: @mut Compartment) {
|
||||
let obj = utils::define_empty_prototype(~"Node", None, compartment);
|
||||
|
||||
let attrs = @~[
|
||||
@ -49,18 +49,10 @@ pub fn init(compartment: &bare_compartment) {
|
||||
pub fn create(cx: *JSContext, node: Node, scope: NodeScope) -> jsobj {
|
||||
do scope.write(&node) |nd| {
|
||||
match nd.kind {
|
||||
~Element(*) => {
|
||||
element::create(cx, node, scope)
|
||||
}
|
||||
~Text(*) => {
|
||||
fail ~"no text node bindings yet";
|
||||
}
|
||||
~Comment(*) => {
|
||||
fail ~"no comment node bindings yet";
|
||||
}
|
||||
~Doctype(*) => {
|
||||
fail ~"no doctype node bindings yet";
|
||||
}
|
||||
~Element(*) => element::create(cx, node, scope),
|
||||
~Text(*) => fail!(~"no text node bindings yet"),
|
||||
~Comment(*) => fail!(~"no comment node bindings yet"),
|
||||
~Doctype(*) => fail!(~"no doctype node bindings yet")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use js;
|
||||
use js::rust::{compartment, bare_compartment, methods};
|
||||
use js::rust::Compartment;
|
||||
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
|
||||
JS_THIS_OBJECT, JS_SET_RVAL};
|
||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp};
|
||||
@ -70,7 +70,7 @@ pub unsafe fn domstring_to_jsval(cx: *JSContext, string: &DOMString) -> JSVal {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_compartment(cx: *JSContext) -> compartment {
|
||||
pub fn get_compartment(cx: *JSContext) -> @mut Compartment {
|
||||
unsafe {
|
||||
let content = task_from_context(cx);
|
||||
let compartment = option::expect((*content).compartment,
|
||||
@ -96,68 +96,71 @@ extern fn has_instance(_cx: *JSContext, obj: **JSObject, v: *JSVal, bp: *mut JSB
|
||||
return 1;
|
||||
}
|
||||
|
||||
pub fn prototype_jsclass(name: ~str) -> @fn(compartment: &bare_compartment) -> JSClass {
|
||||
let f: @fn(&bare_compartment) -> JSClass = |compartment: &bare_compartment, move name| {
|
||||
{name: compartment.add_name(copy name),
|
||||
flags: 0,
|
||||
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
|
||||
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
|
||||
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
|
||||
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
|
||||
finalize: null(),
|
||||
checkAccess: null(),
|
||||
call: null(),
|
||||
hasInstance: has_instance,
|
||||
construct: null(),
|
||||
trace: null(),
|
||||
reserved: (null(), null(), null(), null(), null(), // 05
|
||||
null(), null(), null(), null(), null(), // 10
|
||||
null(), null(), null(), null(), null(), // 15
|
||||
null(), null(), null(), null(), null(), // 20
|
||||
null(), null(), null(), null(), null(), // 25
|
||||
null(), null(), null(), null(), null(), // 30
|
||||
null(), null(), null(), null(), null(), // 35
|
||||
null(), null(), null(), null(), null())} // 40
|
||||
pub fn prototype_jsclass(name: ~str) -> @fn(compartment: @mut Compartment) -> JSClass {
|
||||
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment, move name| {
|
||||
JSClass {
|
||||
name: compartment.add_name(copy name),
|
||||
flags: 0,
|
||||
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
|
||||
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
|
||||
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
|
||||
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
|
||||
finalize: null(),
|
||||
checkAccess: null(),
|
||||
call: null(),
|
||||
hasInstance: has_instance,
|
||||
construct: null(),
|
||||
trace: null(),
|
||||
reserved: (null(), null(), null(), null(), null(), // 05
|
||||
null(), null(), null(), null(), null(), // 10
|
||||
null(), null(), null(), null(), null(), // 15
|
||||
null(), null(), null(), null(), null(), // 20
|
||||
null(), null(), null(), null(), null(), // 25
|
||||
null(), null(), null(), null(), null(), // 30
|
||||
null(), null(), null(), null(), null(), // 35
|
||||
null(), null(), null(), null(), null()) // 40
|
||||
}
|
||||
};
|
||||
return f;
|
||||
}
|
||||
|
||||
pub fn instance_jsclass(name: ~str, finalize: *u8)
|
||||
-> @fn(compartment: &bare_compartment) -> JSClass {
|
||||
let f: @fn(&bare_compartment) -> JSClass =
|
||||
|compartment: &bare_compartment, move name| {
|
||||
{name: compartment.add_name(copy name),
|
||||
flags: JSCLASS_HAS_RESERVED_SLOTS(1),
|
||||
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
|
||||
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
|
||||
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
|
||||
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
|
||||
finalize: finalize,
|
||||
checkAccess: null(),
|
||||
call: null(),
|
||||
hasInstance: has_instance,
|
||||
construct: null(),
|
||||
trace: null(),
|
||||
reserved: (null(), null(), null(), null(), null(), // 05
|
||||
null(), null(), null(), null(), null(), // 10
|
||||
null(), null(), null(), null(), null(), // 15
|
||||
null(), null(), null(), null(), null(), // 20
|
||||
null(), null(), null(), null(), null(), // 25
|
||||
null(), null(), null(), null(), null(), // 30
|
||||
null(), null(), null(), null(), null(), // 35
|
||||
null(), null(), null(), null(), null())} // 40
|
||||
-> @fn(compartment: @mut Compartment) -> JSClass {
|
||||
let f: @fn(@mut Compartment) -> JSClass = |compartment: @mut Compartment, move name| {
|
||||
JSClass {
|
||||
name: compartment.add_name(copy name),
|
||||
flags: JSCLASS_HAS_RESERVED_SLOTS(1),
|
||||
addProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
delProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
getProperty: GetJSClassHookStubPointer(PROPERTY_STUB) as *u8,
|
||||
setProperty: GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as *u8,
|
||||
enumerate: GetJSClassHookStubPointer(ENUMERATE_STUB) as *u8,
|
||||
resolve: GetJSClassHookStubPointer(RESOLVE_STUB) as *u8,
|
||||
convert: GetJSClassHookStubPointer(CONVERT_STUB) as *u8,
|
||||
finalize: finalize,
|
||||
checkAccess: null(),
|
||||
call: null(),
|
||||
hasInstance: has_instance,
|
||||
construct: null(),
|
||||
trace: null(),
|
||||
reserved: (null(), null(), null(), null(), null(), // 05
|
||||
null(), null(), null(), null(), null(), // 10
|
||||
null(), null(), null(), null(), null(), // 15
|
||||
null(), null(), null(), null(), null(), // 20
|
||||
null(), null(), null(), null(), null(), // 25
|
||||
null(), null(), null(), null(), null(), // 30
|
||||
null(), null(), null(), null(), null(), // 35
|
||||
null(), null(), null(), null(), null()) // 40
|
||||
}
|
||||
};
|
||||
return f;
|
||||
}
|
||||
|
||||
// FIXME: A lot of string copies here
|
||||
pub fn define_empty_prototype(name: ~str, proto: Option<~str>, compartment: &bare_compartment)
|
||||
pub fn define_empty_prototype(name: ~str, proto: Option<~str>, compartment: @mut Compartment)
|
||||
-> js::rust::jsobj {
|
||||
compartment.register_class(prototype_jsclass(copy name));
|
||||
|
||||
|
@ -1,23 +1,29 @@
|
||||
use js::rust::{bare_compartment, methods};
|
||||
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL,
|
||||
JS_THIS_OBJECT, JS_SET_RVAL};
|
||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp};
|
||||
use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError,
|
||||
JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN,
|
||||
JS_DefineFunctions, JS_DefineProperty, JS_DefineProperties, JS_EncodeString, JS_free};
|
||||
use js::glue::bindgen::*;
|
||||
use js::global::jsval_to_rust_str;
|
||||
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub, JS_ResolveStub};
|
||||
use js::glue::bindgen::RUST_JSVAL_TO_INT;
|
||||
use ptr::null;
|
||||
use libc::c_uint;
|
||||
use dom::bindings::utils::{rust_box, squirrel_away, jsval_to_str};
|
||||
// DOM bindings for the Window object.
|
||||
|
||||
use dom::bindings::node::create;
|
||||
use dom::window::{Window, TimerMessage_Fire};
|
||||
use dom::bindings::utils::{rust_box, squirrel_away, jsval_to_str};
|
||||
use dom::node::Node;
|
||||
use core::dvec::DVec;
|
||||
use dom::window::{Window, TimerMessage_Fire};
|
||||
use super::utils;
|
||||
|
||||
use core::dvec::DVec;
|
||||
use core::libc::c_uint;
|
||||
use core::ptr::null;
|
||||
use js::crust::{JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub, JS_ConvertStub};
|
||||
use js::crust::{JS_ResolveStub};
|
||||
use js::global::jsval_to_rust_str;
|
||||
use js::glue::bindgen::*;
|
||||
use js::glue::bindgen::RUST_JSVAL_TO_INT;
|
||||
use js::jsapi::bindgen::{JS_DefineFunctions, JS_DefineProperty, JS_DefineProperties};
|
||||
use js::jsapi::bindgen::{JS_EncodeString, JS_free};
|
||||
use js::jsapi::bindgen::{JS_GetReservedSlot, JS_SetReservedSlot, JS_NewStringCopyN};
|
||||
use js::jsapi::bindgen::{JS_ValueToString, JS_GetStringCharsZAndLength, JS_ReportError};
|
||||
use js::jsapi::{JSContext, JSVal, JSObject, JSBool, jsid, JSClass, JSFreeOp, JSFunctionSpec};
|
||||
use js::jsapi::{JSNativeWrapper};
|
||||
use js::rust::Compartment;
|
||||
use js::{JS_ARGV, JSCLASS_HAS_RESERVED_SLOTS, JSPROP_ENUMERATE, JSPROP_SHARED, JSVAL_NULL};
|
||||
use js::{JS_THIS_OBJECT, JS_SET_RVAL};
|
||||
|
||||
extern fn alert(cx: *JSContext, argc: c_uint, vp: *JSVal) -> JSBool {
|
||||
unsafe {
|
||||
let argv = JS_ARGV(cx, vp);
|
||||
@ -69,7 +75,7 @@ extern fn finalize(_fop: *JSFreeOp, obj: *JSObject) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(compartment: &bare_compartment, win: @Window) {
|
||||
pub fn init(compartment: @mut Compartment, win: @Window) {
|
||||
let proto = utils::define_empty_prototype(~"Window", None, compartment);
|
||||
compartment.register_class(utils::instance_jsclass(~"WindowInstance", finalize));
|
||||
|
||||
@ -78,27 +84,40 @@ pub fn init(compartment: &bare_compartment, win: @Window) {
|
||||
~"Window", null()));
|
||||
|
||||
/* Define methods on a window */
|
||||
let methods = ~[{name: compartment.add_name(~"alert"),
|
||||
call: {op: alert, info: null()},
|
||||
nargs: 1,
|
||||
flags: 0,
|
||||
selfHostedName: null()},
|
||||
{name: compartment.add_name(~"setTimeout"),
|
||||
call: {op: setTimeout, info: null()},
|
||||
nargs: 2,
|
||||
flags: 0,
|
||||
selfHostedName: null()},
|
||||
{name: compartment.add_name(~"close"),
|
||||
call: {op: close, info: null()},
|
||||
nargs: 2,
|
||||
flags: 0,
|
||||
selfHostedName: null()}];
|
||||
|
||||
vec::as_imm_buf(methods, |fns, _len| {
|
||||
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, fns);
|
||||
});
|
||||
let methods = [
|
||||
JSFunctionSpec {
|
||||
name: compartment.add_name(~"alert"),
|
||||
call: JSNativeWrapper { op: alert, info: null() },
|
||||
nargs: 1,
|
||||
flags: 0,
|
||||
selfHostedName: null()
|
||||
},
|
||||
JSFunctionSpec {
|
||||
name: compartment.add_name(~"setTimeout"),
|
||||
call: JSNativeWrapper { op: setTimeout, info: null() },
|
||||
nargs: 2,
|
||||
flags: 0,
|
||||
selfHostedName: null()
|
||||
},
|
||||
JSFunctionSpec {
|
||||
name: compartment.add_name(~"close"),
|
||||
call: JSNativeWrapper { op: close, info: null() },
|
||||
nargs: 2,
|
||||
flags: 0,
|
||||
selfHostedName: null()
|
||||
},
|
||||
JSFunctionSpec {
|
||||
name: null(),
|
||||
call: JSNativeWrapper { op: null(), info: null() },
|
||||
nargs: 0,
|
||||
flags: 0,
|
||||
selfHostedName: null()
|
||||
}
|
||||
];
|
||||
|
||||
unsafe {
|
||||
JS_DefineFunctions(compartment.cx.ptr, proto.ptr, &methods[0]);
|
||||
|
||||
let raw_ptr: *libc::c_void = cast::reinterpret_cast(&squirrel_away(win));
|
||||
JS_SetReservedSlot(obj.ptr, 0, RUST_PRIVATE_TO_JSVAL(raw_ptr));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use geom::size::Size2D;
|
||||
use js::crust::*;
|
||||
use js::glue::bindgen::RUST_OBJECT_TO_JSVAL;
|
||||
use js::jsapi::{JSClass, JSObject, JSPropertySpec, JSContext, jsid, JSVal, JSBool};
|
||||
use js::rust::{bare_compartment, compartment, methods};
|
||||
use js::rust::Compartment;
|
||||
use js::{JSPROP_ENUMERATE, JSPROP_SHARED};
|
||||
use layout::debug::DebugMethods;
|
||||
use layout::flow::FlowContext;
|
||||
@ -115,8 +115,7 @@ pub fn DoctypeData(name: ~str, public_id: Option<~str>,
|
||||
|
||||
|
||||
|
||||
pub fn define_bindings(compartment: &bare_compartment, doc: @Document,
|
||||
win: @Window) {
|
||||
pub fn define_bindings(compartment: @mut Compartment, doc: @Document, win: @Window) {
|
||||
bindings::window::init(compartment, win);
|
||||
bindings::document::init(compartment, doc);
|
||||
bindings::node::init(compartment);
|
||||
@ -142,7 +141,7 @@ pub fn NodeScope() -> NodeScope {
|
||||
cow::Scope()
|
||||
}
|
||||
|
||||
trait NodeScopeExtensions {
|
||||
pub trait NodeScopeExtensions {
|
||||
fn new_node(+k: NodeKind) -> Node;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use oldcomm::{Port, Chan};
|
||||
use core::pipes::{Port, Chan};
|
||||
use content::content_task::{ControlMsg, Timer, ExitMsg};
|
||||
use js::jsapi::JSVal;
|
||||
use dvec::DVec;
|
||||
@ -62,8 +62,9 @@ impl Window {
|
||||
|
||||
// Post a delayed message to the per-window timer task; it will dispatch it
|
||||
// to the relevant content handler that will deal with it.
|
||||
timer::delayed_send(uv_global_loop::get(),
|
||||
timeout, self.timer_chan,
|
||||
timer::delayed_send(&uv_global_loop::get(),
|
||||
timeout,
|
||||
&self.timer_chan,
|
||||
TimerMessage_Fire(~TimerData(argc, argv)));
|
||||
}
|
||||
}
|
||||
|
@ -16,15 +16,15 @@ use gfx::render_task;
|
||||
use std::cell::Cell;
|
||||
use std::net::url::Url;
|
||||
|
||||
pub type EngineTask = oldcomm::Chan<Msg>;
|
||||
pub type EngineTask = Chan<Msg>;
|
||||
|
||||
pub enum Msg {
|
||||
LoadURLMsg(Url),
|
||||
ExitMsg(Chan<()>)
|
||||
}
|
||||
|
||||
pub struct Engine<C:Compositor Owned Copy> {
|
||||
request_port: oldcomm::Port<Msg>,
|
||||
pub struct Engine<C> {
|
||||
request_port: Port<Msg>,
|
||||
compositor: C,
|
||||
render_task: RenderTask,
|
||||
resource_task: ResourceTask,
|
||||
@ -33,30 +33,31 @@ pub struct Engine<C:Compositor Owned Copy> {
|
||||
content_task: ContentTask
|
||||
}
|
||||
|
||||
pub fn Engine<C:Compositor Owned Copy>(compositor: C,
|
||||
opts: &Opts,
|
||||
dom_event_port: pipes::Port<Event>,
|
||||
dom_event_chan: pipes::SharedChan<Event>,
|
||||
resource_task: ResourceTask,
|
||||
image_cache_task: ImageCacheTask) -> EngineTask {
|
||||
|
||||
let dom_event_port = Cell(move dom_event_port);
|
||||
let dom_event_chan = Cell(move dom_event_chan);
|
||||
pub fn Engine<C:Compositor + Owned + Clone>(compositor: C,
|
||||
opts: &Opts,
|
||||
dom_event_port: pipes::Port<Event>,
|
||||
dom_event_chan: pipes::SharedChan<Event>,
|
||||
resource_task: ResourceTask,
|
||||
image_cache_task: ImageCacheTask)
|
||||
-> EngineTask {
|
||||
let dom_event_port = Cell(dom_event_port);
|
||||
let dom_event_chan = Cell(dom_event_chan);
|
||||
|
||||
let opts = Cell(copy *opts);
|
||||
do spawn_listener::<Msg> |request, move dom_event_port, move dom_event_chan,
|
||||
move image_cache_task, move opts| {
|
||||
let render_task = RenderTask(compositor, opts.with_ref(|o| copy *o));
|
||||
let layout_task = LayoutTask(render_task, image_cache_task.clone(), opts.take());
|
||||
let content_task = ContentTask(layout_task,
|
||||
dom_event_port.take(), dom_event_chan.take(),
|
||||
resource_task, image_cache_task.clone());
|
||||
do spawn_listener::<Msg> |request| {
|
||||
let render_task = RenderTask(compositor.clone(), opts.with_ref(|o| copy *o));
|
||||
let layout_task = LayoutTask(render_task.clone(), image_cache_task.clone(), opts.take());
|
||||
let content_task = ContentTask(layout_task.clone(),
|
||||
dom_event_port.take(),
|
||||
dom_event_chan.take(),
|
||||
resource_task.clone(),
|
||||
image_cache_task.clone());
|
||||
|
||||
Engine {
|
||||
request_port: request,
|
||||
compositor: compositor,
|
||||
compositor: compositor.clone(),
|
||||
render_task: render_task,
|
||||
resource_task: resource_task,
|
||||
resource_task: resource_task.clone(),
|
||||
image_cache_task: image_cache_task.clone(),
|
||||
layout_task: move layout_task,
|
||||
content_task: move content_task
|
||||
@ -64,7 +65,7 @@ pub fn Engine<C:Compositor Owned Copy>(compositor: C,
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Compositor Copy Owned> Engine<C> {
|
||||
impl<C:Compositor + Owned + Clone> Engine<C> {
|
||||
fn run() {
|
||||
while self.handle_request(self.request_port.recv()) {
|
||||
// Go on...
|
||||
|
@ -4,13 +4,14 @@ Some little helpers for hooking up the HTML parser with the CSS parser
|
||||
|
||||
use resource::resource_task::{ResourceTask, ProgressMsg, Load, Payload, Done};
|
||||
|
||||
use core::pipes::{Port, Chan};
|
||||
use core::pipes;
|
||||
use core::str;
|
||||
use newcss::stylesheet::Stylesheet;
|
||||
use newcss::util::DataStream;
|
||||
use std::cell::Cell;
|
||||
use std::net::url::Url;
|
||||
use std::net::url;
|
||||
use core::oldcomm::{Port, Chan};
|
||||
|
||||
/// Where a style sheet comes from.
|
||||
pub enum StylesheetProvenance {
|
||||
@ -19,9 +20,9 @@ pub enum StylesheetProvenance {
|
||||
}
|
||||
|
||||
pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
||||
resource_task: ResourceTask) -> oldcomm::Port<Stylesheet> {
|
||||
let result_port = oldcomm::Port();
|
||||
let result_chan = oldcomm::Chan(&result_port);
|
||||
resource_task: ResourceTask)
|
||||
-> Port<Stylesheet> {
|
||||
let (result_port, result_chan) = pipes::stream();
|
||||
|
||||
let provenance_cell = Cell(move provenance);
|
||||
do task::spawn |move provenance_cell, copy resource_task| {
|
||||
@ -32,8 +33,9 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
||||
}
|
||||
};
|
||||
|
||||
let sheet = Stylesheet::new(move url, data_stream(provenance_cell.take(), resource_task));
|
||||
result_chan.send(move sheet);
|
||||
let sheet = Stylesheet::new(url, data_stream(provenance_cell.take(),
|
||||
resource_task.clone()));
|
||||
result_chan.send(sheet);
|
||||
}
|
||||
|
||||
return result_port;
|
||||
@ -42,8 +44,8 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
|
||||
fn data_stream(provenance: StylesheetProvenance, resource_task: ResourceTask) -> DataStream {
|
||||
match move provenance {
|
||||
UrlProvenance(move url) => {
|
||||
let input_port = Port();
|
||||
resource_task.send(Load(move url, input_port.chan()));
|
||||
let (input_port, input_chan) = pipes::stream();
|
||||
resource_task.send(Load(move url, input_chan));
|
||||
resource_port_to_data_stream(input_port)
|
||||
}
|
||||
InlineProvenance(_, move data) => {
|
||||
@ -52,7 +54,7 @@ fn data_stream(provenance: StylesheetProvenance, resource_task: ResourceTask) ->
|
||||
}
|
||||
}
|
||||
|
||||
fn resource_port_to_data_stream(input_port: oldcomm::Port<ProgressMsg>) -> DataStream {
|
||||
fn resource_port_to_data_stream(input_port: Port<ProgressMsg>) -> DataStream {
|
||||
return || {
|
||||
match input_port.recv() {
|
||||
Payload(move data) => Some(move data),
|
||||
|
@ -4,13 +4,14 @@ use content::content_task::ContentTask;
|
||||
use dom::cow;
|
||||
use dom::element::*;
|
||||
use dom::event::{Event, ReflowEvent};
|
||||
use dom::node::{Comment, Doctype, DoctypeData, Element, Node, NodeScope, Text};
|
||||
use dom::node::{Comment, Doctype, DoctypeData, Element, Node, NodeScope, NodeScopeExtensions};
|
||||
use dom::node::{Text};
|
||||
use resource::image_cache_task::ImageCacheTask;
|
||||
use resource::image_cache_task;
|
||||
use resource::resource_task::{Done, Load, Payload, ResourceTask};
|
||||
use util::task::{spawn_listener, spawn_conversation};
|
||||
|
||||
use core::oldcomm::{Chan, Port};
|
||||
use core::pipes::{Chan, Port, SharedChan};
|
||||
use html::cssparse::{InlineProvenance, StylesheetProvenance, UrlProvenance, spawn_css_parser};
|
||||
use hubbub::hubbub::Attribute;
|
||||
use hubbub::hubbub;
|
||||
@ -32,8 +33,8 @@ enum JSMessage {
|
||||
|
||||
struct HtmlParserResult {
|
||||
root: Node,
|
||||
style_port: oldcomm::Port<Option<Stylesheet>>,
|
||||
js_port: oldcomm::Port<JSResult>,
|
||||
style_port: Port<Option<Stylesheet>>,
|
||||
js_port: Port<JSResult>,
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,15 +52,15 @@ spawned, collates them, and sends them to the given result channel.
|
||||
* `from_parent` - A port on which to receive new links.
|
||||
|
||||
*/
|
||||
fn css_link_listener(to_parent : oldcomm::Chan<Option<Stylesheet>>,
|
||||
from_parent : oldcomm::Port<CSSMessage>,
|
||||
fn css_link_listener(to_parent: Chan<Option<Stylesheet>>,
|
||||
from_parent: Port<CSSMessage>,
|
||||
resource_task: ResourceTask) {
|
||||
let mut result_vec = ~[];
|
||||
|
||||
loop {
|
||||
match from_parent.recv() {
|
||||
CSSTaskNewFile(move provenance) => {
|
||||
result_vec.push(spawn_css_parser(move provenance, copy resource_task));
|
||||
CSSTaskNewFile(provenance) => {
|
||||
result_vec.push(spawn_css_parser(provenance, resource_task.clone()));
|
||||
}
|
||||
CSSTaskExit => {
|
||||
break;
|
||||
@ -75,19 +76,20 @@ fn css_link_listener(to_parent : oldcomm::Chan<Option<Stylesheet>>,
|
||||
to_parent.send(None);
|
||||
}
|
||||
|
||||
fn js_script_listener(to_parent : oldcomm::Chan<~[~[u8]]>, from_parent : oldcomm::Port<JSMessage>,
|
||||
fn js_script_listener(to_parent: Chan<~[~[u8]]>,
|
||||
from_parent: Port<JSMessage>,
|
||||
resource_task: ResourceTask) {
|
||||
let mut result_vec = ~[];
|
||||
|
||||
loop {
|
||||
match from_parent.recv() {
|
||||
JSTaskNewFile(move url) => {
|
||||
let result_port = oldcomm::Port();
|
||||
let result_chan = oldcomm::Chan(&result_port);
|
||||
do task::spawn |move url| {
|
||||
let input_port = Port();
|
||||
let (result_port, result_chan) = pipes::stream();
|
||||
let resource_task = resource_task.clone();
|
||||
do task::spawn {
|
||||
let (input_port, input_chan) = pipes::stream();
|
||||
// TODO: change copy to move once we can move into closures
|
||||
resource_task.send(Load(copy url, input_port.chan()));
|
||||
resource_task.send(Load(copy url, input_chan));
|
||||
|
||||
let mut buf = ~[];
|
||||
loop {
|
||||
@ -166,18 +168,22 @@ pub fn parse_html(scope: NodeScope,
|
||||
resource_task: ResourceTask,
|
||||
image_cache_task: ImageCacheTask) -> HtmlParserResult {
|
||||
// Spawn a CSS parser to receive links to CSS style sheets.
|
||||
let (css_port, css_chan): (oldcomm::Port<Option<Stylesheet>>, oldcomm::Chan<CSSMessage>) =
|
||||
do spawn_conversation |css_port: oldcomm::Port<CSSMessage>,
|
||||
css_chan: oldcomm::Chan<Option<Stylesheet>>| {
|
||||
css_link_listener(css_chan, css_port, resource_task);
|
||||
let resource_task2 = resource_task.clone();
|
||||
let (css_port, css_chan): (Port<Option<Stylesheet>>, Chan<CSSMessage>) =
|
||||
do spawn_conversation |css_port: Port<CSSMessage>,
|
||||
css_chan: Chan<Option<Stylesheet>>| {
|
||||
css_link_listener(css_chan, css_port, resource_task2.clone());
|
||||
};
|
||||
let css_chan = SharedChan(css_chan);
|
||||
|
||||
// Spawn a JS parser to receive JavaScript.
|
||||
let (js_port, js_chan): (oldcomm::Port<JSResult>, oldcomm::Chan<JSMessage>) =
|
||||
do spawn_conversation |js_port: oldcomm::Port<JSMessage>,
|
||||
js_chan: oldcomm::Chan<JSResult>| {
|
||||
js_script_listener(js_chan, js_port, resource_task);
|
||||
let resource_task2 = resource_task.clone();
|
||||
let (js_port, js_chan): (Port<JSResult>, Chan<JSMessage>) =
|
||||
do spawn_conversation |js_port: Port<JSMessage>,
|
||||
js_chan: Chan<JSResult>| {
|
||||
js_script_listener(js_chan, js_port, resource_task2.clone());
|
||||
};
|
||||
let js_chan = SharedChan(js_chan);
|
||||
|
||||
let (scope, url) = (@copy scope, @move url);
|
||||
|
||||
@ -192,6 +198,7 @@ pub fn parse_html(scope: NodeScope,
|
||||
|
||||
// Performs various actions necessary after appending has taken place. Currently, this consists
|
||||
// of processing inline stylesheets, but in the future it might perform prefetching, etc.
|
||||
let css_chan2 = css_chan.clone();
|
||||
let append_hook: @fn(Node, Node) = |parent_node, child_node| {
|
||||
do scope.read(&parent_node) |parent_node_contents| {
|
||||
do scope.read(&child_node) |child_node_contents| {
|
||||
@ -203,7 +210,7 @@ pub fn parse_html(scope: NodeScope,
|
||||
let url = url::from_str("http://example.com/"); // FIXME
|
||||
let provenance = InlineProvenance(result::unwrap(move url),
|
||||
copy *data);
|
||||
css_chan.send(CSSTaskNewFile(move provenance));
|
||||
css_chan2.send(CSSTaskNewFile(move provenance));
|
||||
}
|
||||
_ => {} // Nothing to do.
|
||||
}
|
||||
@ -214,6 +221,7 @@ pub fn parse_html(scope: NodeScope,
|
||||
}
|
||||
};
|
||||
|
||||
let (css_chan2, js_chan2) = (css_chan.clone(), js_chan.clone());
|
||||
parser.set_tree_handler(@hubbub::TreeHandler {
|
||||
create_comment: |data: ~str| {
|
||||
debug!("create comment");
|
||||
@ -257,8 +265,8 @@ pub fn parse_html(scope: NodeScope,
|
||||
(Some(move rel), Some(move href)) => {
|
||||
if rel == ~"stylesheet" {
|
||||
debug!("found CSS stylesheet: %s", href);
|
||||
css_chan.send(CSSTaskNewFile(UrlProvenance(make_url(move href,
|
||||
Some(copy *url)))));
|
||||
css_chan2.send(CSSTaskNewFile(UrlProvenance(make_url(
|
||||
href, Some(copy *url)))));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -341,7 +349,10 @@ pub fn parse_html(scope: NodeScope,
|
||||
complete_script: |script| {
|
||||
// A little function for holding this lint attr
|
||||
#[allow(non_implicitly_copyable_typarams)]
|
||||
fn complete_script(scope: &NodeScope, script: hubbub::NodeDataPtr, url: &Url, js_chan: &oldcomm::Chan<JSMessage>) {
|
||||
fn complete_script(scope: &NodeScope,
|
||||
script: hubbub::NodeDataPtr,
|
||||
url: &Url,
|
||||
js_chan: SharedChan<JSMessage>) {
|
||||
unsafe {
|
||||
do scope.read(&cow::wrap(cast::transmute(script))) |node_contents| {
|
||||
match *node_contents.kind {
|
||||
@ -360,14 +371,14 @@ pub fn parse_html(scope: NodeScope,
|
||||
}
|
||||
}
|
||||
}
|
||||
complete_script(scope, script, url, &js_chan);
|
||||
complete_script(scope, script, url, js_chan2.clone());
|
||||
debug!("complete script");
|
||||
}
|
||||
});
|
||||
debug!("set tree handler");
|
||||
|
||||
let input_port = Port();
|
||||
resource_task.send(Load(copy *url, input_port.chan()));
|
||||
let (input_port, input_chan) = pipes::stream();
|
||||
resource_task.send(Load(copy *url, input_chan));
|
||||
debug!("loaded page");
|
||||
loop {
|
||||
match input_port.recv() {
|
||||
|
@ -1,16 +1,20 @@
|
||||
use au = gfx::geometry;
|
||||
// Block layout.
|
||||
|
||||
use layout::box::{RenderBox};
|
||||
use layout::context::LayoutContext;
|
||||
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
|
||||
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
|
||||
use layout::inline::InlineLayout;
|
||||
use newcss::values::*;
|
||||
use util::tree;
|
||||
|
||||
use au = gfx::geometry;
|
||||
use core::mutable::Mut;
|
||||
use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
use geom::size::Size2D;
|
||||
use gfx::display_list::DisplayList;
|
||||
use gfx::geometry::Au;
|
||||
use layout::box::{RenderBox};
|
||||
use layout::context::LayoutContext;
|
||||
use layout::display_list_builder::DisplayListBuilder;
|
||||
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
|
||||
use util::tree;
|
||||
use core::mutable::Mut;
|
||||
|
||||
pub struct BlockFlowData {
|
||||
mut box: Option<@RenderBox>
|
||||
@ -22,15 +26,18 @@ pub fn BlockFlowData() -> BlockFlowData {
|
||||
}
|
||||
}
|
||||
|
||||
trait BlockLayout {
|
||||
pub trait BlockLayout {
|
||||
pure fn starts_block_flow() -> bool;
|
||||
pure fn with_block_box(@self, fn(box: &@RenderBox) -> ()) -> ();
|
||||
|
||||
fn bubble_widths_block(@self, ctx: &LayoutContext);
|
||||
fn assign_widths_block(@self, ctx: &LayoutContext);
|
||||
fn assign_height_block(@self, ctx: &LayoutContext);
|
||||
fn build_display_list_block(@self, a: &DisplayListBuilder, b: &Rect<Au>,
|
||||
c: &Point2D<Au>, d: &Mut<DisplayList>);
|
||||
fn build_display_list_block(@self,
|
||||
a: &DisplayListBuilder,
|
||||
b: &Rect<Au>,
|
||||
c: &Point2D<Au>,
|
||||
d: &Mut<DisplayList>);
|
||||
}
|
||||
|
||||
impl FlowContext : BlockLayout {
|
||||
@ -54,7 +61,7 @@ impl FlowContext : BlockLayout {
|
||||
let mut box = self.root().box;
|
||||
box.iter(cb);
|
||||
},
|
||||
_ => fail fmt!("Tried to do something with_block_box(), but this is a %?", self)
|
||||
_ => fail!(fmt!("Tried to do something with_block_box(), but this is a %?", self))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* Fundamental layout structures and algorithms. */
|
||||
|
||||
use css::node_style::StyledNode;
|
||||
use dom::element::{ElementKind, HTMLDivElement, HTMLImageElement};
|
||||
use dom::node::{Element, Node, NodeData, NodeKind, NodeTree};
|
||||
use layout::context::LayoutContext;
|
||||
@ -8,23 +9,6 @@ use layout::display_list_builder::DisplayListBuilder;
|
||||
use layout::flow::FlowContext;
|
||||
use layout::text::TextBoxData;
|
||||
use layout;
|
||||
use util::tree::ReadMethods;
|
||||
use core::mutable::Mut;
|
||||
use arc = std::arc;
|
||||
use core::managed;
|
||||
use core::dvec::DVec;
|
||||
use core::to_str::ToStr;
|
||||
use core::rand;
|
||||
use core::task::spawn;
|
||||
use geom::{Point2D, Rect, Size2D};
|
||||
use gfx;
|
||||
use gfx::display_list::{DisplayItem, DisplayList};
|
||||
use gfx::font::{FontStyle, FontWeight300};
|
||||
use gfx::geometry::Au;
|
||||
use gfx::image::base::Image;
|
||||
use gfx::image::holder::ImageHolder;
|
||||
use gfx::text::text_run::TextRun;
|
||||
use gfx::util::range::*;
|
||||
use newcss::color::{Color, rgba, rgb};
|
||||
use newcss::complete::CompleteStyle;
|
||||
use newcss::units::{BoxSizing, Cursive, Em, Fantasy, Length, Monospace, Pt, Px, SansSerif, Serif};
|
||||
@ -33,7 +17,25 @@ use newcss::values::{CSSBorderWidthLength, CSSBorderWidthMedium, CSSDisplay};
|
||||
use newcss::values::{CSSFontFamilyFamilyName, CSSFontFamilyGenericFamily, CSSPositionAbsolute};
|
||||
use newcss::values::{CSSFontSizeLength, CSSFontStyleItalic, CSSFontStyleNormal};
|
||||
use newcss::values::{CSSFontStyleOblique, CSSTextAlign, Specified};
|
||||
use util::tree::ReadMethods;
|
||||
|
||||
use core::dvec::DVec;
|
||||
use core::managed;
|
||||
use core::mutable::Mut;
|
||||
use core::rand;
|
||||
use core::task::spawn;
|
||||
use core::to_str::ToStr;
|
||||
use geom::{Point2D, Rect, Size2D};
|
||||
use gfx::display_list::{DisplayItem, DisplayList};
|
||||
use gfx::font::{FontStyle, FontWeight300};
|
||||
use gfx::geometry::Au;
|
||||
use gfx::image::base::Image;
|
||||
use gfx::image::holder::ImageHolder;
|
||||
use gfx::text::text_run::TextRun;
|
||||
use gfx::util::range::*;
|
||||
use gfx;
|
||||
use std::arc::ARC;
|
||||
use std::arc;
|
||||
use std::net::url::Url;
|
||||
|
||||
/**
|
||||
@ -165,7 +167,7 @@ impl RenderBox {
|
||||
match self {
|
||||
@GenericBox(*) => CannotSplit(self),
|
||||
@ImageBox(*) => CannotSplit(self),
|
||||
@UnscannedTextBox(*) => fail ~"WAT: shouldn't be an unscanned text box here.",
|
||||
@UnscannedTextBox(*) => fail!(~"WAT: shouldn't be an unscanned text box here."),
|
||||
@TextBox(_,data) => {
|
||||
|
||||
let mut pieces_processed_count : uint = 0;
|
||||
@ -249,7 +251,7 @@ impl RenderBox {
|
||||
// TODO: If image isn't available, consult 'width'.
|
||||
&ImageBox(_, ref i) => Au::from_px(i.get_size().get_or_default(Size2D(0,0)).width),
|
||||
&TextBox(_,d) => d.run.min_width_for_range(&const d.range),
|
||||
&UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here."
|
||||
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +283,7 @@ impl RenderBox {
|
||||
|
||||
max_line_width
|
||||
},
|
||||
&UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here."
|
||||
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +335,7 @@ impl RenderBox {
|
||||
&TextBox(*) => {
|
||||
copy self.d().position
|
||||
},
|
||||
&UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here."
|
||||
&UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,7 +403,7 @@ impl RenderBox {
|
||||
self.add_bgcolor_to_list(list, &abs_box_bounds);
|
||||
|
||||
match self {
|
||||
@UnscannedTextBox(*) => fail ~"Shouldn't see unscanned boxes here.",
|
||||
@UnscannedTextBox(*) => fail!(~"Shouldn't see unscanned boxes here."),
|
||||
@TextBox(_,data) => {
|
||||
do list.borrow_mut |list| {
|
||||
let nearest_ancestor_element = self.nearest_ancestor_element();
|
||||
@ -606,7 +608,7 @@ impl RenderBox {
|
||||
let mut node = self.d().node;
|
||||
while !node.is_element() {
|
||||
match NodeTree.get_parent(&node) {
|
||||
None => fail ~"no nearest element?!",
|
||||
None => fail!(~"no nearest element?!"),
|
||||
Some(move parent) => node = move parent,
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use dom::node::{Comment, Doctype, Element, Text, Node, LayoutData};
|
||||
use layout::box::*;
|
||||
use layout::block::BlockFlowData;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::debug::{BoxedDebugMethods, DebugMethods};
|
||||
use layout::flow::*;
|
||||
use layout::inline::InlineFlowData;
|
||||
use layout::root::RootFlowData;
|
||||
@ -370,7 +371,7 @@ impl LayoutTreeBuilder {
|
||||
|
||||
fn fixup_split_inline(_foo: @FlowContext) {
|
||||
// TODO: finish me.
|
||||
fail ~"TODO: handle case where an inline is split by a block"
|
||||
fail!(~"TODO: handle case where an inline is split by a block")
|
||||
}
|
||||
|
||||
/** entry point for box creation. Should only be
|
||||
@ -435,9 +436,9 @@ impl LayoutTreeBuilder {
|
||||
self.make_generic_box(layout_ctx, node, ctx)
|
||||
}
|
||||
},
|
||||
_ => fail ~"WAT error: why couldn't we make an image box?"
|
||||
_ => fail!(~"WAT error: why couldn't we make an image box?")
|
||||
},
|
||||
_ => fail ~"WAT error: why couldn't we make an image box?"
|
||||
_ => fail!(~"WAT error: why couldn't we make an image box?")
|
||||
}
|
||||
}
|
||||
|
||||
@ -447,7 +448,7 @@ impl LayoutTreeBuilder {
|
||||
do node.read |n| {
|
||||
match n.kind {
|
||||
~Text(ref string) => @UnscannedTextBox(RenderBoxData(node, ctx, self.next_box_id()), copy *string),
|
||||
_ => fail ~"WAT error: why couldn't we make a text box?"
|
||||
_ => fail!(~"WAT error: why couldn't we make a text box?")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -455,14 +456,19 @@ impl LayoutTreeBuilder {
|
||||
fn decide_box_type(node: Node, display: CSSDisplay) -> RenderBoxType {
|
||||
do node.read |n| {
|
||||
match n.kind {
|
||||
~Doctype(*) | ~Comment(*) => fail ~"Hey, doctypes and comments shouldn't get here! They are display:none!",
|
||||
~Doctype(*) | ~Comment(*) => {
|
||||
fail!(~"Hey, doctypes and comments shouldn't get here! \
|
||||
They are display:none!")
|
||||
}
|
||||
~Text(*) => RenderBox_Text,
|
||||
~Element(ref element) => {
|
||||
match (&element.kind, display) {
|
||||
(&~HTMLImageElement(ref d), _) if d.image.is_some() => RenderBox_Image,
|
||||
// (_, Specified(_)) => GenericBox,
|
||||
(_, _) => RenderBox_Generic // TODO: replace this with the commented lines
|
||||
// (_, _) => fail ~"Can't create box for Node with non-specified 'display' type"
|
||||
//(_, _) => {
|
||||
// fail!(~"Can't create box for Node with non-specified 'display' type")
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,3 @@
|
||||
export DisplayListBuilder;
|
||||
|
||||
use newcss::values::Specified;
|
||||
use newcss::values::{CSSBackgroundColorColor, CSSBackgroundColorTransparent};
|
||||
use dom::node::{Text, NodeScope};
|
||||
@ -31,16 +29,20 @@ pub struct DisplayListBuilder {
|
||||
ctx: &LayoutContext,
|
||||
}
|
||||
|
||||
|
||||
trait FlowDisplayListBuilderMethods {
|
||||
pub trait FlowDisplayListBuilderMethods {
|
||||
fn build_display_list(@self, a: &DisplayListBuilder, b: &Rect<Au>, c: &Mut<DisplayList>);
|
||||
|
||||
fn build_display_list_for_child(@self, a: &DisplayListBuilder, b: @FlowContext,
|
||||
c: &Rect<Au>, d: &Point2D<Au>, e: &Mut<DisplayList>);
|
||||
fn build_display_list_for_child(@self,
|
||||
a: &DisplayListBuilder,
|
||||
b: @FlowContext,
|
||||
c: &Rect<Au>,
|
||||
d: &Point2D<Au>,
|
||||
e: &Mut<DisplayList>);
|
||||
}
|
||||
|
||||
impl FlowContext: FlowDisplayListBuilderMethods {
|
||||
fn build_display_list(@self, builder: &DisplayListBuilder, dirty: &Rect<Au>,
|
||||
impl FlowDisplayListBuilderMethods for FlowContext {
|
||||
fn build_display_list(@self,
|
||||
builder: &DisplayListBuilder,
|
||||
dirty: &Rect<Au>,
|
||||
list: &Mut<DisplayList>) {
|
||||
let zero = gfx::geometry::zero_point();
|
||||
self.build_display_list_recurse(builder, dirty, &zero, list);
|
||||
|
@ -1,12 +1,12 @@
|
||||
use core;
|
||||
use dom::node::Node;
|
||||
use layout::block::BlockFlowData;
|
||||
use layout::block::{BlockFlowData, BlockLayout};
|
||||
use layout::box::RenderBox;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::debug::BoxedDebugMethods;
|
||||
use layout::display_list_builder::DisplayListBuilder;
|
||||
use layout::inline::{InlineFlowData, NodeRange};
|
||||
use layout::root::RootFlowData;
|
||||
use layout::inline::{InlineFlowData, InlineLayout, NodeRange};
|
||||
use layout::root::{RootFlowData, RootLayout};
|
||||
use util::tree;
|
||||
use core::mutable::Mut;
|
||||
use core::dvec::DVec;
|
||||
@ -109,21 +109,21 @@ impl FlowContext {
|
||||
pure fn inline(&self) -> &self/InlineFlowData {
|
||||
match *self {
|
||||
InlineFlow(_, ref i) => i,
|
||||
_ => fail fmt!("Tried to access inline data of non-inline: f%d", self.d().id)
|
||||
_ => fail!(fmt!("Tried to access inline data of non-inline: f%d", self.d().id))
|
||||
}
|
||||
}
|
||||
|
||||
pure fn block(&self) -> &self/BlockFlowData {
|
||||
match *self {
|
||||
BlockFlow(_, ref b) => b,
|
||||
_ => fail fmt!("Tried to access block data of non-block: f%d", self.d().id)
|
||||
_ => fail!(fmt!("Tried to access block data of non-block: f%d", self.d().id))
|
||||
}
|
||||
}
|
||||
|
||||
pure fn root(&self) -> &self/RootFlowData {
|
||||
match *self {
|
||||
RootFlow(_, ref r) => r,
|
||||
_ => fail fmt!("Tried to access root data of non-root: f%d", self.d().id)
|
||||
_ => fail!(fmt!("Tried to access root data of non-root: f%d", self.d().id))
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ impl FlowContext {
|
||||
@BlockFlow(*) => self.bubble_widths_block(ctx),
|
||||
@InlineFlow(*) => self.bubble_widths_inline(ctx),
|
||||
@RootFlow(*) => self.bubble_widths_root(ctx),
|
||||
_ => fail fmt!("Tried to bubble_widths of flow: f%d", self.d().id)
|
||||
_ => fail!(fmt!("Tried to bubble_widths of flow: f%d", self.d().id))
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ impl FlowContext {
|
||||
@BlockFlow(*) => self.assign_widths_block(ctx),
|
||||
@InlineFlow(*) => self.assign_widths_inline(ctx),
|
||||
@RootFlow(*) => self.assign_widths_root(ctx),
|
||||
_ => fail fmt!("Tried to assign_widths of flow: f%d", self.d().id)
|
||||
_ => fail!(fmt!("Tried to assign_widths of flow: f%d", self.d().id))
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ impl FlowContext {
|
||||
@BlockFlow(*) => self.assign_height_block(ctx),
|
||||
@InlineFlow(*) => self.assign_height_inline(ctx),
|
||||
@RootFlow(*) => self.assign_height_root(ctx),
|
||||
_ => fail fmt!("Tried to assign_height of flow: f%d", self.d().id)
|
||||
_ => fail!(fmt!("Tried to assign_height of flow: f%d", self.d().id))
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ impl FlowContext {
|
||||
@RootFlow(*) => self.build_display_list_root(builder, dirty, offset, list),
|
||||
@BlockFlow(*) => self.build_display_list_block(builder, dirty, offset, list),
|
||||
@InlineFlow(*) => self.build_display_list_inline(builder, dirty, offset, list),
|
||||
_ => fail fmt!("Tried to build_display_list_recurse of flow: %?", self)
|
||||
_ => fail!(fmt!("Tried to build_display_list_recurse of flow: %?", self))
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ impl FlowContext {
|
||||
RootFlow(*) => option::map_default(&self.root().box, seed, |box| { cb(seed, *box) }),
|
||||
BlockFlow(*) => option::map_default(&self.block().box, seed, |box| { cb(seed, *box) }),
|
||||
InlineFlow(*) => do self.inline().boxes.foldl(seed) |acc, box| { cb(*acc, *box) },
|
||||
_ => fail fmt!("Don't know how to iterate node's RenderBoxes for %?", self)
|
||||
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ impl FlowContext {
|
||||
RootFlow(*) => do self.root().box.iter |box| { cb(*box); },
|
||||
BlockFlow(*) => do self.block().box.iter |box| { cb(*box); },
|
||||
InlineFlow(*) => for self.inline().boxes.each |box| { cb(*box); },
|
||||
_ => fail fmt!("Don't know how to iterate node's RenderBoxes for %?", self)
|
||||
_ => fail!(fmt!("Don't know how to iterate node's RenderBoxes for %?", self))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,13 +2,13 @@ use core;
|
||||
use dom::node::Node;
|
||||
use layout::box::*;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::debug::{BoxedDebugMethods, DebugMethods};
|
||||
use layout::flow::{FlowContext, InlineFlow};
|
||||
use layout::text::TextBoxData;
|
||||
use layout::text::{TextBoxData, UnscannedMethods};
|
||||
use util::tree;
|
||||
|
||||
use core::dlist::DList;
|
||||
use core::dvec::DVec;
|
||||
use core::num::Num;
|
||||
use geom::{Point2D, Rect, Size2D};
|
||||
use gfx::font::FontStyle;
|
||||
use gfx::geometry::Au;
|
||||
@ -227,7 +227,9 @@ priv impl TextRunScanner {
|
||||
};
|
||||
|
||||
match (is_singleton, is_text_clump) {
|
||||
(false, false) => fail ~"WAT: can't coalesce non-text nodes in flush_clump_to_list()!",
|
||||
(false, false) => {
|
||||
fail!(~"WAT: can't coalesce non-text nodes in flush_clump_to_list()!")
|
||||
}
|
||||
(true, false) => {
|
||||
debug!("TextRunScanner: pushing single non-text box in range: %?", self.clump);
|
||||
out_boxes.push(in_boxes[self.clump.begin()]);
|
||||
@ -323,7 +325,7 @@ priv impl TextRunScanner {
|
||||
struct LineboxScanner {
|
||||
flow: @FlowContext,
|
||||
new_boxes: DVec<@RenderBox>,
|
||||
work_list: @DList<@RenderBox>,
|
||||
work_list: @mut DList<@RenderBox>,
|
||||
pending_line: {mut range: Range, mut width: Au},
|
||||
line_spans: DVec<Range>,
|
||||
}
|
||||
@ -341,19 +343,19 @@ fn LineboxScanner(inline: @FlowContext) -> LineboxScanner {
|
||||
}
|
||||
|
||||
impl LineboxScanner {
|
||||
priv fn reset_scanner() {
|
||||
priv fn reset_scanner(&mut self) {
|
||||
debug!("Resetting line box scanner's state for flow f%d.", self.flow.d().id);
|
||||
self.line_spans.set(~[]);
|
||||
self.new_boxes.set(~[]);
|
||||
self.reset_linebox();
|
||||
}
|
||||
|
||||
priv fn reset_linebox() {
|
||||
priv fn reset_linebox(&mut self) {
|
||||
self.pending_line.range.reset(0,0);
|
||||
self.pending_line.width = Au(0);
|
||||
}
|
||||
|
||||
pub fn scan_for_lines(ctx: &LayoutContext) {
|
||||
pub fn scan_for_lines(&mut self, ctx: &LayoutContext) {
|
||||
self.reset_scanner();
|
||||
|
||||
let boxes = &self.flow.inline().boxes;
|
||||
@ -362,7 +364,7 @@ impl LineboxScanner {
|
||||
loop {
|
||||
// acquire the next box to lay out from work list or box list
|
||||
let cur_box = match self.work_list.pop() {
|
||||
Some(box) => {
|
||||
Some(box) => {
|
||||
debug!("LineboxScanner: Working with box from work list: b%d", box.d().id);
|
||||
box
|
||||
},
|
||||
@ -394,7 +396,7 @@ impl LineboxScanner {
|
||||
self.swap_out_results();
|
||||
}
|
||||
|
||||
priv fn swap_out_results() {
|
||||
priv fn swap_out_results(&mut self) {
|
||||
debug!("LineboxScanner: Propagating scanned lines[n=%u] to inline flow f%d",
|
||||
self.line_spans.len(), self.flow.d().id);
|
||||
|
||||
@ -408,7 +410,7 @@ impl LineboxScanner {
|
||||
};
|
||||
}
|
||||
|
||||
priv fn flush_current_line() {
|
||||
priv fn flush_current_line(&mut self) {
|
||||
debug!("LineboxScanner: Flushing line %u: %?",
|
||||
self.line_spans.len(), self.pending_line);
|
||||
// set box horizontal offsets
|
||||
@ -465,7 +467,7 @@ impl LineboxScanner {
|
||||
}
|
||||
|
||||
// return value: whether any box was appended.
|
||||
priv fn try_append_to_line(ctx: &LayoutContext, in_box: @RenderBox) -> bool {
|
||||
priv fn try_append_to_line(&mut self, ctx: &LayoutContext, in_box: @RenderBox) -> bool {
|
||||
let remaining_width = self.flow.d().position.size.width - self.pending_line.width;
|
||||
let in_box_width = in_box.d().position.size.width;
|
||||
let line_is_empty: bool = self.pending_line.range.length() == 0;
|
||||
@ -545,7 +547,7 @@ impl LineboxScanner {
|
||||
}
|
||||
|
||||
// unconditional push
|
||||
priv fn push_box_to_line(box: @RenderBox) {
|
||||
priv fn push_box_to_line(&mut self, box: @RenderBox) {
|
||||
debug!("LineboxScanner: Pushing box b%d to line %u", box.d().id, self.line_spans.len());
|
||||
|
||||
if self.pending_line.range.length() == 0 {
|
||||
@ -579,7 +581,7 @@ pub fn InlineFlowData() -> InlineFlowData {
|
||||
}
|
||||
}
|
||||
|
||||
trait InlineLayout {
|
||||
pub trait InlineLayout {
|
||||
pure fn starts_inline_flow() -> bool;
|
||||
|
||||
fn bubble_widths_inline(@self, ctx: &LayoutContext);
|
||||
@ -630,7 +632,7 @@ impl FlowContext : InlineLayout {
|
||||
},
|
||||
// TODO(Issue #225): different cases for 'inline-block', other replaced content
|
||||
@GenericBox(*) => Au::from_px(45),
|
||||
_ => fail fmt!("Tried to assign width to unknown Box variant: %?", box)
|
||||
_ => fail!(fmt!("Tried to assign width to unknown Box variant: %?", box))
|
||||
};
|
||||
} // for boxes.each |box|
|
||||
|
||||
@ -670,7 +672,10 @@ impl FlowContext : InlineLayout {
|
||||
},
|
||||
// TODO(Issue #225): different cases for 'inline-block', other replaced content
|
||||
@GenericBox(*) => Au::from_px(30),
|
||||
_ => fail fmt!("Tried to assign height to unknown Box variant: %s", cur_box.debug_str())
|
||||
_ => {
|
||||
fail!(fmt!("Tried to assign height to unknown Box variant: %s",
|
||||
cur_box.debug_str()))
|
||||
}
|
||||
};
|
||||
|
||||
// compute bounding rect, with left baseline as origin.
|
||||
@ -691,7 +696,10 @@ impl FlowContext : InlineLayout {
|
||||
let text_bounds = data.run.metrics_for_range(&const data.range).bounding_box;
|
||||
text_bounds.translate(&Point2D(cur_box.d().position.origin.x, Au(0)))
|
||||
},
|
||||
_ => fail fmt!("Tried to compute bounding box of unknown Box variant: %s", cur_box.debug_str())
|
||||
_ => {
|
||||
fail!(fmt!("Tried to compute bounding box of unknown Box variant: %s",
|
||||
cur_box.debug_str()))
|
||||
}
|
||||
};
|
||||
debug!("assign_height_inline: bounding box for box b%d = %?", cur_box.d().id, bounding_box);
|
||||
linebox_bounding_box = linebox_bounding_box.union(&bounding_box);
|
||||
|
@ -1,23 +1,24 @@
|
||||
/**
|
||||
The layout task. Performs layout on the DOM, builds display lists and sends them to be
|
||||
rendered.
|
||||
*/
|
||||
/// The layout task. Performs layout on the DOM, builds display lists and sends them to be
|
||||
/// rendered.
|
||||
|
||||
use content::content_task;
|
||||
use css::matching::MatchMethods;
|
||||
use css::select::new_css_select_ctx;
|
||||
use dom::event::{Event, ReflowEvent};
|
||||
use dom::node::{Node, LayoutData};
|
||||
use layout::aux::LayoutAuxMethods;
|
||||
use layout::box::RenderBox;
|
||||
use layout::box_builder::LayoutTreeBuilder;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::display_list_builder::DisplayListBuilder;
|
||||
use layout::debug::{BoxedDebugMethods, DebugMethods};
|
||||
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
|
||||
use layout::traverse::*;
|
||||
use resource::image_cache_task::{ImageCacheTask, ImageResponseMsg};
|
||||
use resource::local_image_cache::LocalImageCache;
|
||||
use util::time::time;
|
||||
use util::task::spawn_listener;
|
||||
use util::time::time;
|
||||
|
||||
use core::oldcomm::*; // FIXME: Bad! Pipe-ify me.
|
||||
use core::pipes::{Chan, Port, SharedChan};
|
||||
use core::dvec::DVec;
|
||||
use core::mutable::Mut;
|
||||
use core::task::*;
|
||||
@ -34,12 +35,11 @@ use gfx::render_task::{RenderMsg, RenderTask};
|
||||
use newcss::select::SelectCtx;
|
||||
use newcss::stylesheet::Stylesheet;
|
||||
use newcss::types::OriginAuthor;
|
||||
use opt = core::option;
|
||||
use std::arc::ARC;
|
||||
use std::cell::Cell;
|
||||
use std::net::url::Url;
|
||||
|
||||
pub type LayoutTask = oldcomm::Chan<Msg>;
|
||||
pub type LayoutTask = SharedChan<Msg>;
|
||||
|
||||
pub enum LayoutQuery {
|
||||
ContentBox(Node)
|
||||
@ -54,7 +54,7 @@ enum LayoutQueryResponse_ {
|
||||
pub enum Msg {
|
||||
AddStylesheet(Stylesheet),
|
||||
BuildMsg(BuildData),
|
||||
QueryMsg(LayoutQuery, oldcomm::Chan<LayoutQueryResponse>),
|
||||
QueryMsg(LayoutQuery, Chan<LayoutQueryResponse>),
|
||||
ExitMsg
|
||||
}
|
||||
|
||||
@ -86,18 +86,18 @@ pub struct BuildData {
|
||||
}
|
||||
|
||||
pub fn LayoutTask(render_task: RenderTask,
|
||||
img_cache_task: ImageCacheTask,
|
||||
opts: Opts) -> LayoutTask {
|
||||
do spawn_listener::<Msg> |from_content, move img_cache_task, move opts| {
|
||||
Layout(render_task, img_cache_task.clone(), from_content, &opts).start();
|
||||
}
|
||||
img_cache_task: ImageCacheTask,
|
||||
opts: Opts) -> LayoutTask {
|
||||
SharedChan(spawn_listener::<Msg>(|from_content| {
|
||||
Layout(render_task.clone(), img_cache_task.clone(), from_content, &opts).start();
|
||||
}))
|
||||
}
|
||||
|
||||
struct Layout {
|
||||
render_task: RenderTask,
|
||||
image_cache_task: ImageCacheTask,
|
||||
local_image_cache: @LocalImageCache,
|
||||
from_content: oldcomm::Port<Msg>,
|
||||
from_content: Port<Msg>,
|
||||
|
||||
font_ctx: @FontContext,
|
||||
// This is used to root auxilliary RCU reader data
|
||||
@ -107,9 +107,9 @@ struct Layout {
|
||||
|
||||
fn Layout(render_task: RenderTask,
|
||||
image_cache_task: ImageCacheTask,
|
||||
from_content: oldcomm::Port<Msg>,
|
||||
opts: &Opts) -> Layout {
|
||||
|
||||
from_content: Port<Msg>,
|
||||
opts: &Opts)
|
||||
-> Layout {
|
||||
let fctx = @FontContext::new(opts.render_backend, true);
|
||||
|
||||
Layout {
|
||||
@ -146,8 +146,9 @@ impl Layout {
|
||||
|
||||
}
|
||||
QueryMsg(query, chan) => {
|
||||
let chan = Cell(chan);
|
||||
do time("layout: querying layout") {
|
||||
self.handle_query(query, chan)
|
||||
self.handle_query(query, chan.take())
|
||||
}
|
||||
}
|
||||
ExitMsg => {
|
||||
@ -213,7 +214,7 @@ impl Layout {
|
||||
let layout_root: @FlowContext = match builder.construct_trees(&layout_ctx,
|
||||
*node) {
|
||||
Ok(root) => root,
|
||||
Err(*) => fail ~"Root flow should always exist"
|
||||
Err(*) => fail!(~"Root flow should always exist")
|
||||
};
|
||||
|
||||
debug!("layout: constructed Flow tree");
|
||||
@ -238,7 +239,8 @@ impl Layout {
|
||||
|
||||
// TODO: set options on the builder before building
|
||||
// TODO: be smarter about what needs painting
|
||||
layout_root.build_display_list(&builder, © layout_root.d().position,
|
||||
layout_root.build_display_list(&builder,
|
||||
© layout_root.d().position,
|
||||
&display_list);
|
||||
|
||||
let render_layer = RenderLayer {
|
||||
@ -256,7 +258,7 @@ impl Layout {
|
||||
|
||||
|
||||
fn handle_query(query: LayoutQuery,
|
||||
reply_chan: oldcomm::Chan<LayoutQueryResponse>) {
|
||||
reply_chan: Chan<LayoutQueryResponse>) {
|
||||
match query {
|
||||
ContentBox(node) => {
|
||||
let response = do node.aux |a| {
|
||||
|
@ -4,6 +4,7 @@ use geom::point::Point2D;
|
||||
use geom::rect::Rect;
|
||||
use gfx::display_list::DisplayList;
|
||||
use gfx::geometry::Au;
|
||||
use layout::block::BlockLayout;
|
||||
use layout::box::RenderBox;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::flow::{FlowContext, FlowTree, InlineBlockFlow, BlockFlow, RootFlow};
|
||||
@ -21,7 +22,7 @@ pub fn RootFlowData() -> RootFlowData {
|
||||
}
|
||||
}
|
||||
|
||||
trait RootLayout {
|
||||
pub trait RootLayout {
|
||||
pure fn starts_root_flow() -> bool;
|
||||
|
||||
fn bubble_widths_root(@self, ctx: &LayoutContext);
|
||||
|
@ -32,15 +32,15 @@ pub fn adapt_textbox_with_range(box_data: &RenderBoxData, run: @TextRun,
|
||||
@TextBox(move new_box_data, move new_text_data)
|
||||
}
|
||||
|
||||
trait UnscannedMethods {
|
||||
pure fn raw_text() -> ~str;
|
||||
pub trait UnscannedMethods {
|
||||
pure fn raw_text(&self) -> ~str;
|
||||
}
|
||||
|
||||
impl RenderBox : UnscannedMethods {
|
||||
pure fn raw_text() -> ~str {
|
||||
match &self {
|
||||
pure fn raw_text(&self) -> ~str {
|
||||
match self {
|
||||
&UnscannedTextBox(_, ref s) => copy *s,
|
||||
_ => fail ~"unsupported operation: box.raw_text() on non-unscanned text box."
|
||||
_ => fail!(~"unsupported operation: box.raw_text() on non-unscanned text box.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use platform::resize_rate_limiter::ResizeRateLimiter;
|
||||
|
||||
use azure::azure_hl::{BackendType, B8G8R8A8, DataSourceSurface, DrawTarget, SourceSurfaceMethods};
|
||||
use core::dvec::DVec;
|
||||
use core::pipes::Chan;
|
||||
use core::pipes::{Chan, SharedChan, Port};
|
||||
use core::task::TaskBuilder;
|
||||
use core::util;
|
||||
use geom::matrix::{Matrix4, identity};
|
||||
@ -23,7 +23,15 @@ use sharegl;
|
||||
use sharegl::ShareGlContext;
|
||||
|
||||
pub struct OSMain {
|
||||
chan: oldcomm::Chan<Msg>
|
||||
chan: SharedChan<Msg>
|
||||
}
|
||||
|
||||
impl Clone for OSMain {
|
||||
fn clone(&self) -> OSMain {
|
||||
OSMain {
|
||||
chan: self.chan.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Move me over to opts.rs.
|
||||
@ -45,9 +53,10 @@ pub enum Msg {
|
||||
}
|
||||
|
||||
pub fn OSMain(dom_event_chan: pipes::SharedChan<Event>, opts: Opts) -> OSMain {
|
||||
let dom_event_chan = Cell(move dom_event_chan);
|
||||
let dom_event_chan = Cell(dom_event_chan);
|
||||
OSMain {
|
||||
chan: do on_osmain::<Msg> |po, move dom_event_chan, move opts| {
|
||||
chan: SharedChan(on_osmain::<Msg>(|po, move dom_event_chan, move opts| {
|
||||
let po = Cell(po);
|
||||
do platform::runmain {
|
||||
debug!("preparing to enter main loop");
|
||||
|
||||
@ -58,9 +67,9 @@ pub fn OSMain(dom_event_chan: pipes::SharedChan<Event>, opts: Opts) -> OSMain {
|
||||
None => mode = GlutMode
|
||||
}
|
||||
|
||||
mainloop(mode, po, dom_event_chan.take(), &opts);
|
||||
mainloop(mode, po.take(), dom_event_chan.take(), &opts);
|
||||
}
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,10 +95,10 @@ impl AzureDrawTargetImageData : layers::layers::ImageData {
|
||||
}
|
||||
|
||||
fn mainloop(mode: Mode,
|
||||
po: oldcomm::Port<Msg>,
|
||||
dom_event_chan: pipes::SharedChan<Event>,
|
||||
po: Port<Msg>,
|
||||
dom_event_chan: SharedChan<Event>,
|
||||
opts: &Opts) {
|
||||
let key_handlers: @DVec<pipes::Chan<()>> = @DVec();
|
||||
let key_handlers: @DVec<Chan<()>> = @DVec();
|
||||
|
||||
let window;
|
||||
match mode {
|
||||
@ -101,7 +110,8 @@ fn mainloop(mode: Mode,
|
||||
window = GlutWindow(move glut_window);
|
||||
}
|
||||
ShareMode => {
|
||||
let share_context: ShareGlContext = sharegl::base::ShareContext::new(Size2D(800, 600));
|
||||
let size = Size2D(800, 600);
|
||||
let share_context: ShareGlContext = sharegl::base::ShareContext::new(size);
|
||||
io::println(fmt!("Sharing ID is %d", share_context.id()));
|
||||
window = ShareWindow(move share_context);
|
||||
}
|
||||
@ -114,20 +124,21 @@ fn mainloop(mode: Mode,
|
||||
let root_layer = @layers::layers::ContainerLayer();
|
||||
let original_layer_transform;
|
||||
{
|
||||
let image_data = @layers::layers::BasicImageData::new(
|
||||
Size2D(0u, 0u), 0, layers::layers::RGB24Format, ~[]);
|
||||
let image_data = @layers::layers::BasicImageData::new(Size2D(0u, 0u),
|
||||
0,
|
||||
layers::layers::RGB24Format,
|
||||
~[]);
|
||||
let image = @layers::layers::Image::new(image_data as @layers::layers::ImageData);
|
||||
let image_layer = @layers::layers::ImageLayer(image);
|
||||
original_layer_transform = image_layer.common.transform;
|
||||
image_layer.common.set_transform(original_layer_transform.scale(&800.0f32, &600.0f32,
|
||||
&1f32));
|
||||
image_layer.common.set_transform(original_layer_transform.scale(800.0, 600.0, 1.0));
|
||||
root_layer.add_child(layers::layers::ImageLayerKind(image_layer));
|
||||
}
|
||||
|
||||
|
||||
let scene = @layers::scene::Scene(layers::layers::ContainerLayerKind(root_layer),
|
||||
Size2D(800.0f32, 600.0f32),
|
||||
identity(0.0f32));
|
||||
Size2D(800.0, 600.0),
|
||||
identity());
|
||||
|
||||
let done = @mut false;
|
||||
let resize_rate_limiter = @ResizeRateLimiter(move dom_event_chan);
|
||||
@ -185,7 +196,7 @@ fn mainloop(mode: Mode,
|
||||
}
|
||||
}
|
||||
Some(_) => {
|
||||
fail ~"found unexpected layer kind"
|
||||
fail!(~"found unexpected layer kind")
|
||||
}
|
||||
};
|
||||
|
||||
@ -193,8 +204,8 @@ fn mainloop(mode: Mode,
|
||||
let x = buffer.rect.origin.x as f32;
|
||||
let y = buffer.rect.origin.y as f32;
|
||||
image_layer.common.set_transform(
|
||||
original_layer_transform.translate(&x, &y, &0.0f32)
|
||||
.scale(&(width as f32), &(height as f32), &1.0f32));
|
||||
original_layer_transform.translate(x, y, 0.0)
|
||||
.scale(width as f32, height as f32, 1.0));
|
||||
}
|
||||
surfaces.front.layer_buffer_set.buffers = move buffers;
|
||||
}
|
||||
@ -264,7 +275,7 @@ fn mainloop(mode: Mode,
|
||||
Implementation to allow the osmain channel to be used as a graphics
|
||||
compositor for the renderer
|
||||
*/
|
||||
impl OSMain : Compositor {
|
||||
impl Compositor for OSMain {
|
||||
fn begin_drawing(next_dt: pipes::Chan<LayerBufferSet>) {
|
||||
self.chan.send(BeginDrawing(move next_dt))
|
||||
}
|
||||
@ -337,16 +348,14 @@ fn Surface(backend: BackendType) -> Surface {
|
||||
}
|
||||
|
||||
/// A function for spawning into the platform's main thread
|
||||
fn on_osmain<T: Owned>(f: fn~(po: oldcomm::Port<T>)) -> oldcomm::Chan<T> {
|
||||
let setup_po = oldcomm::Port();
|
||||
let setup_ch = oldcomm::Chan(&setup_po);
|
||||
fn on_osmain<T: Owned>(f: fn~(po: Port<T>)) -> Chan<T> {
|
||||
let (setup_po, setup_ch) = pipes::stream();
|
||||
do task::task().sched_mode(task::PlatformThread).spawn |move f| {
|
||||
let po = oldcomm::Port();
|
||||
let ch = oldcomm::Chan(&po);
|
||||
oldcomm::send(setup_ch, ch);
|
||||
let (po, ch) = pipes::stream();
|
||||
setup_ch.send(ch);
|
||||
f(move po);
|
||||
}
|
||||
oldcomm::recv(setup_po)
|
||||
setup_po.recv()
|
||||
}
|
||||
|
||||
// #[cfg(target_os = "linux")]
|
||||
|
@ -7,6 +7,8 @@
|
||||
#[license = "MPL"];
|
||||
#[crate_type = "lib"];
|
||||
|
||||
#[legacy_records];
|
||||
|
||||
extern mod azure;
|
||||
extern mod cairo;
|
||||
extern mod geom;
|
||||
@ -94,7 +96,6 @@ extern mod core_text;
|
||||
use engine::{Engine, ExitMsg, LoadURLMsg}; // FIXME: "ExitMsg" is pollution.
|
||||
use platform::osmain::{AddKeyHandler, OSMain};
|
||||
|
||||
use core::oldcomm::*; // FIXME: Bad!
|
||||
use core::option::swap_unwrap;
|
||||
use core::pipes::{Port, Chan};
|
||||
|
||||
@ -115,9 +116,9 @@ fn run(opts: &Opts) {
|
||||
match &opts.render_mode {
|
||||
&Screen => run_pipeline_screen(opts),
|
||||
&Png(ref outfile) => {
|
||||
assert opts.urls.is_not_empty();
|
||||
assert !opts.urls.is_empty();
|
||||
if opts.urls.len() > 1u {
|
||||
fail ~"servo asks that you stick to a single URL in PNG output mode"
|
||||
fail!(~"servo asks that you stick to a single URL in PNG output mode")
|
||||
}
|
||||
run_pipeline_png(opts, *outfile)
|
||||
}
|
||||
@ -137,9 +138,13 @@ fn run_pipeline_screen(opts: &Opts) {
|
||||
|
||||
// Create a servo instance
|
||||
let resource_task = ResourceTask();
|
||||
let image_cache_task = ImageCacheTask(copy resource_task);
|
||||
let engine_task = Engine(osmain, opts, move dom_event_port, move dom_event_chan,
|
||||
move resource_task, move image_cache_task);
|
||||
let image_cache_task = ImageCacheTask(resource_task.clone());
|
||||
let engine_task = Engine(osmain.clone(),
|
||||
opts,
|
||||
dom_event_port,
|
||||
dom_event_chan,
|
||||
resource_task,
|
||||
image_cache_task);
|
||||
|
||||
for opts.urls.each |filename| {
|
||||
let url = make_url(copy *filename, None);
|
||||
@ -163,7 +168,7 @@ fn run_pipeline_screen(opts: &Opts) {
|
||||
}
|
||||
|
||||
fn run_pipeline_png(_opts: &Opts, _outfile: &str) {
|
||||
fail ~"PNG compositor is broken";
|
||||
fail!(~"PNG compositor is broken");
|
||||
}
|
||||
|
||||
#[cfg(broken)]
|
||||
@ -190,7 +195,7 @@ fn run_pipeline_png(url: ~str, outfile: &str) {
|
||||
|
||||
match buffered_file_writer(&Path(outfile)) {
|
||||
Ok(writer) => writer.write(pngdata_from_compositor.recv()),
|
||||
Err(e) => fail e
|
||||
Err(e) => fail!(e)
|
||||
}
|
||||
|
||||
let (exit_chan, exit_response_from_engine) = pipes::stream();
|
||||
|
@ -1,25 +1,23 @@
|
||||
use core::pipes::{Chan, Port};
|
||||
use core::pipes;
|
||||
use core::task;
|
||||
use std::cell::Cell;
|
||||
|
||||
pub fn spawn_listener<A: Owned>(
|
||||
f: fn~(oldcomm::Port<A>)) -> oldcomm::Chan<A> {
|
||||
let setup_po = oldcomm::Port();
|
||||
let setup_ch = oldcomm::Chan(&setup_po);
|
||||
do task::spawn |move f| {
|
||||
let po = oldcomm::Port();
|
||||
let ch = oldcomm::Chan(&po);
|
||||
oldcomm::send(setup_ch, ch);
|
||||
f(move po);
|
||||
pub fn spawn_listener<A: Owned>(f: fn~(Port<A>)) -> Chan<A> {
|
||||
let (setup_po, setup_ch) = pipes::stream();
|
||||
do task::spawn {
|
||||
let (po, ch) = pipes::stream();
|
||||
setup_ch.send(ch);
|
||||
f(po);
|
||||
}
|
||||
oldcomm::recv(setup_po)
|
||||
setup_po.recv()
|
||||
}
|
||||
|
||||
pub fn spawn_conversation<A: Owned, B: Owned>
|
||||
(f: fn~(oldcomm::Port<A>, oldcomm::Chan<B>))
|
||||
-> (oldcomm::Port<B>, oldcomm::Chan<A>) {
|
||||
let from_child = oldcomm::Port();
|
||||
let to_parent = oldcomm::Chan(&from_child);
|
||||
let to_child = do spawn_listener |move f, from_parent| {
|
||||
f(from_parent, to_parent)
|
||||
pub fn spawn_conversation<A: Owned, B: Owned>(f: fn~(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) {
|
||||
let (from_child, to_parent) = pipes::stream();
|
||||
let to_parent = Cell(to_parent);
|
||||
let to_child = do spawn_listener |from_parent| {
|
||||
f(from_parent, to_parent.take())
|
||||
};
|
||||
(from_child, to_child)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ pub fn add_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
|
||||
|
||||
ops.with_tree_fields(&child, |child_tf| {
|
||||
match child_tf.parent {
|
||||
Some(_) => { fail ~"Already has a parent"; }
|
||||
Some(_) => { fail!(~"Already has a parent"); }
|
||||
None => { child_tf.parent = Some(parent); }
|
||||
}
|
||||
|
||||
@ -100,14 +100,14 @@ pub fn add_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
|
||||
pub fn remove_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
|
||||
do ops.with_tree_fields(&child) |child_tf| {
|
||||
match copy child_tf.parent {
|
||||
None => { fail ~"Not a child"; }
|
||||
None => { fail!(~"Not a child"); }
|
||||
Some(parent_n) => {
|
||||
assert ops.tree_eq(&parent, &parent_n);
|
||||
|
||||
// adjust parent fields
|
||||
do ops.with_tree_fields(&parent) |parent_tf| {
|
||||
match copy parent_tf.first_child {
|
||||
None => { fail ~"parent had no first child??" },
|
||||
None => { fail!(~"parent had no first child??") },
|
||||
Some(first_child) if ops.tree_eq(&child, &first_child) => {
|
||||
parent_tf.first_child = child_tf.next_sibling;
|
||||
},
|
||||
@ -115,7 +115,7 @@ pub fn remove_child<T:Copy,O:WriteMethods<T>>(ops: &O, parent: T, child: T) {
|
||||
};
|
||||
|
||||
match copy parent_tf.last_child {
|
||||
None => { fail ~"parent had no last child??" },
|
||||
None => { fail!(~"parent had no last child??") },
|
||||
Some(last_child) if ops.tree_eq(&child, &last_child) => {
|
||||
parent_tf.last_child = child_tf.prev_sibling;
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user