aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbors-servo <release+servo@mozilla.com>2014-01-12 19:16:21 -0800
committerbors-servo <release+servo@mozilla.com>2014-01-12 19:16:21 -0800
commit943ab4a4f0e3074e78d96ad94b7e96a46edacf79 (patch)
tree0a086f0bf0f5f1f0b9fde7c9e971c096cb1708cb /src
parente8b0eae09e531674fb6cd7ea0b341f77ae551aa2 (diff)
parenta7ef1cd35e9347a285f245041db4eb94047f4ab0 (diff)
downloadservo-943ab4a4f0e3074e78d96ad94b7e96a46edacf79.tar.gz
servo-943ab4a4f0e3074e78d96ad94b7e96a46edacf79.zip
auto merge of #1473 : metajack/servo/rustup-20131219, r=jdm
Diffstat (limited to 'src')
m---------src/compiler/rust0
-rw-r--r--src/compiler/rust-auto-clean-trigger2
-rw-r--r--src/components/gfx/display_list.rs20
-rw-r--r--src/components/gfx/font.rs65
-rw-r--r--src/components/gfx/font_context.rs53
-rw-r--r--src/components/gfx/font_list.rs24
-rw-r--r--src/components/gfx/gfx.rc11
-rw-r--r--src/components/gfx/opts.rs4
-rw-r--r--src/components/gfx/platform/android/font.rs28
-rw-r--r--src/components/gfx/platform/android/font_context.rs6
-rw-r--r--src/components/gfx/platform/android/font_list.rs56
-rw-r--r--src/components/gfx/platform/linux/font.rs28
-rw-r--r--src/components/gfx/platform/linux/font_context.rs6
-rw-r--r--src/components/gfx/platform/linux/font_list.rs56
-rw-r--r--src/components/gfx/platform/macos/font.rs9
-rw-r--r--src/components/gfx/platform/macos/font_context.rs4
-rw-r--r--src/components/gfx/render_context.rs15
-rw-r--r--src/components/gfx/render_task.rs58
-rw-r--r--src/components/gfx/text/glyph.rs69
-rw-r--r--src/components/gfx/text/shaping/harfbuzz.rs45
-rw-r--r--src/components/gfx/text/text_run.rs26
-rw-r--r--src/components/gfx/text/util.rs4
-rw-r--r--src/components/main/compositing/compositor.rs64
-rw-r--r--src/components/main/compositing/compositor_layer.rs66
-rw-r--r--src/components/main/compositing/compositor_task.rs19
-rw-r--r--src/components/main/compositing/headless.rs11
-rw-r--r--src/components/main/compositing/quadtree.rs134
-rw-r--r--src/components/main/constellation.rs115
-rw-r--r--src/components/main/css/matching.rs69
-rw-r--r--src/components/main/css/node_style.rs2
-rw-r--r--src/components/main/css/node_util.rs28
-rw-r--r--src/components/main/layout/block.rs172
-rw-r--r--src/components/main/layout/box_.rs (renamed from src/components/main/layout/box.rs)122
-rw-r--r--src/components/main/layout/construct.rs63
-rw-r--r--src/components/main/layout/display_list_builder.rs12
-rw-r--r--src/components/main/layout/extra.rs28
-rw-r--r--src/components/main/layout/float_context.rs46
-rw-r--r--src/components/main/layout/flow.rs45
-rw-r--r--src/components/main/layout/inline.rs78
-rw-r--r--src/components/main/layout/layout_task.rs98
-rw-r--r--src/components/main/layout/text.rs22
-rw-r--r--src/components/main/layout/util.rs49
-rw-r--r--src/components/main/layout/wrapper.rs72
-rw-r--r--src/components/main/macros.rs16
-rw-r--r--src/components/main/pipeline.rs118
-rw-r--r--src/components/main/platform/common/glfw_windowing.rs115
-rw-r--r--src/components/main/platform/common/glut_windowing.rs108
-rwxr-xr-xsrc/components/main/servo.rc96
-rw-r--r--src/components/main/util/task.rs22
-rw-r--r--src/components/msg/constellation_msg.rs6
-rw-r--r--src/components/msg/msg.rc5
-rw-r--r--src/components/net/data_loader.rs9
-rw-r--r--src/components/net/file_loader.rs29
-rw-r--r--src/components/net/http_loader.rs13
-rw-r--r--src/components/net/image/holder.rs4
-rw-r--r--src/components/net/image_cache_task.rs500
-rw-r--r--src/components/net/local_image_cache.rs15
-rw-r--r--src/components/net/net.rc7
-rw-r--r--src/components/net/resource_task.rs25
-rw-r--r--src/components/net/util.rs7
-rw-r--r--src/components/script/dom/bindings/callback.rs2
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py22
-rw-r--r--src/components/script/dom/bindings/conversions.rs12
-rw-r--r--src/components/script/dom/bindings/node.rs9
-rw-r--r--src/components/script/dom/bindings/proxyhandler.rs6
-rw-r--r--src/components/script/dom/bindings/utils.rs92
-rw-r--r--src/components/script/dom/document.rs48
-rw-r--r--src/components/script/dom/element.rs21
-rw-r--r--src/components/script/dom/event.rs12
-rw-r--r--src/components/script/dom/eventtarget.rs20
-rw-r--r--src/components/script/dom/htmliframeelement.rs2
-rw-r--r--src/components/script/dom/htmlimageelement.rs4
-rw-r--r--src/components/script/dom/node.rs205
-rw-r--r--src/components/script/dom/window.rs96
-rw-r--r--src/components/script/html/cssparse.rs24
-rw-r--r--src/components/script/html/hubbub_html_parser.rs107
-rw-r--r--src/components/script/layout_interface.rs6
-rw-r--r--src/components/script/script.rc14
-rw-r--r--src/components/script/script_task.rs129
-rw-r--r--src/components/style/common_types.rs3
-rw-r--r--src/components/style/errors.rs2
-rw-r--r--src/components/style/media_queries.rs4
-rw-r--r--src/components/style/node.rs2
-rw-r--r--src/components/style/properties.rs.mako42
-rw-r--r--src/components/style/selector_matching.rs112
-rw-r--r--src/components/style/selectors.rs19
-rw-r--r--src/components/style/style.rc9
-rw-r--r--src/components/style/stylesheets.rs2
-rw-r--r--src/components/util/cache.rs10
-rw-r--r--src/components/util/debug.rs4
-rw-r--r--src/components/util/geometry.rs4
-rw-r--r--src/components/util/io.rs4
-rw-r--r--src/components/util/slot.rs141
-rw-r--r--src/components/util/time.rs72
-rw-r--r--src/components/util/url.rs2
-rw-r--r--src/components/util/util.rc6
-rw-r--r--src/components/util/vec.rs17
m---------src/platform/android/fontconfig0
m---------src/platform/linux/rust-fontconfig0
m---------src/platform/linux/rust-freetype0
m---------src/platform/linux/rust-xlib0
m---------src/platform/macos/rust-cocoa0
m---------src/platform/macos/rust-core-foundation0
m---------src/platform/macos/rust-core-graphics0
m---------src/platform/macos/rust-core-text0
m---------src/platform/macos/rust-io-surface0
m---------src/support/alert/rust-alert0
m---------src/support/azure/rust-azure0
m---------src/support/css/rust-cssparser0
m---------src/support/egl/rust-egl0
m---------src/support/encoding/rust-encoding0
m---------src/support/geom/rust-geom0
m---------src/support/glfw/glfw-rs0
m---------src/support/glut/rust-glut0
m---------src/support/harfbuzz/rust-harfbuzz0
m---------src/support/http/rust-http0
m---------src/support/hubbub/rust-hubbub0
m---------src/support/layers/rust-layers0
m---------src/support/opengles/rust-opengles0
m---------src/support/png/rust-png0
m---------src/support/sharegl/sharegl0
m---------src/support/spidermonkey/rust-mozjs0
m---------src/support/stb-image/rust-stb-image0
-rw-r--r--src/test/harness/contenttest/contenttest.rs20
-rw-r--r--src/test/harness/reftest/reftest.rs32
125 files changed, 1864 insertions, 2473 deletions
diff --git a/src/compiler/rust b/src/compiler/rust
-Subproject f6b236b9d2780edc1336ea5f62c2ba0fed6e34c
+Subproject d3b3c66a3a54a0455b068ede8fe2f48ed99ca90
diff --git a/src/compiler/rust-auto-clean-trigger b/src/compiler/rust-auto-clean-trigger
index 6474e73f600..da7e8de4e9a 100644
--- a/src/compiler/rust-auto-clean-trigger
+++ b/src/compiler/rust-auto-clean-trigger
@@ -1,4 +1,4 @@
# If this file is modified, then rust will be forcibly cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime.
-2014-01-02
+2014-01-08
diff --git a/src/components/gfx/display_list.rs b/src/components/gfx/display_list.rs
index 5a5300aabf3..7a5004c0325 100644
--- a/src/components/gfx/display_list.rs
+++ b/src/components/gfx/display_list.rs
@@ -150,14 +150,14 @@ pub struct ClipDisplayItem<E> {
need_clip: bool
}
-pub enum DisplayItemIterator<'self,E> {
+pub enum DisplayItemIterator<'a,E> {
EmptyDisplayItemIterator,
- ParentDisplayItemIterator(VecIterator<'self,DisplayItem<E>>),
+ ParentDisplayItemIterator(VecIterator<'a,DisplayItem<E>>),
}
-impl<'self,E> Iterator<&'self DisplayItem<E>> for DisplayItemIterator<'self,E> {
+impl<'a,E> Iterator<&'a DisplayItem<E>> for DisplayItemIterator<'a,E> {
#[inline]
- fn next(&mut self) -> Option<&'self DisplayItem<E>> {
+ fn next(&mut self) -> Option<&'a DisplayItem<E>> {
match *self {
EmptyDisplayItemIterator => None,
ParentDisplayItemIterator(ref mut subiterator) => subiterator.next(),
@@ -192,12 +192,12 @@ impl<E> DisplayItem<E> {
let text_run = text.text_run.get();
let font = render_context.font_ctx.get_font_by_descriptor(&text_run.font_descriptor).unwrap();
- let font_metrics = font.with_borrow( |font| {
+ let font_metrics = font.borrow().with(|font| {
font.metrics.clone()
});
let origin = text.base.bounds.origin;
let baseline_origin = Point2D(origin.x, origin.y + font_metrics.ascent);
- font.with_mut_borrow( |font| {
+ font.borrow().with_mut(|font| {
font.draw_text_into_context(render_context,
text.text_run.get(),
&text.range,
@@ -264,10 +264,10 @@ impl<E> DisplayItem<E> {
pub fn children<'a>(&'a self) -> DisplayItemIterator<'a,E> {
match *self {
ClipDisplayItemClass(ref clip) => ParentDisplayItemIterator(clip.child_list.iter()),
- SolidColorDisplayItemClass(*) |
- TextDisplayItemClass(*) |
- ImageDisplayItemClass(*) |
- BorderDisplayItemClass(*) => EmptyDisplayItemIterator,
+ SolidColorDisplayItemClass(..) |
+ TextDisplayItemClass(..) |
+ ImageDisplayItemClass(..) |
+ BorderDisplayItemClass(..) => EmptyDisplayItemIterator,
}
}
diff --git a/src/components/gfx/font.rs b/src/components/gfx/font.rs
index ac2d45b6f2b..9c1e729bc12 100644
--- a/src/components/gfx/font.rs
+++ b/src/components/gfx/font.rs
@@ -10,13 +10,11 @@ use geom::{Point2D, Rect, Size2D};
use std::cast;
use std::ptr;
use std::str;
-use std::vec;
-use std::rc::RcMut;
+use std::rc::Rc;
+use std::cell::RefCell;
use servo_util::cache::{Cache, HashCache};
use servo_util::range::Range;
-use servo_util::time::ProfilerChan;
use style::computed_values::{text_decoration, font_weight, font_style};
-
use color::Color;
use font_context::FontContext;
use servo_util::geometry::Au;
@@ -73,7 +71,7 @@ impl FontTableTagConversions for FontTableTag {
}
pub trait FontTableMethods {
- fn with_buffer(&self, &fn(*u8, uint));
+ fn with_buffer(&self, |*u8, uint|);
}
#[deriving(Clone)]
@@ -108,12 +106,6 @@ pub struct FontStyle {
pub type SpecifiedFontStyle = FontStyle;
pub type UsedFontStyle = FontStyle;
-// FIXME: move me to layout
-struct ResolvedFont {
- group: @FontGroup,
- style: SpecifiedFontStyle,
-}
-
// FontDescriptor serializes a specific font and used font style
// options, such as point size.
@@ -153,11 +145,11 @@ pub struct FontGroup {
// style of the first western font in group, which is
// used for purposes of calculating text run metrics.
style: UsedFontStyle,
- fonts: ~[RcMut<Font>]
+ fonts: ~[Rc<RefCell<Font>>]
}
impl FontGroup {
- pub fn new(families: ~[~str], style: &UsedFontStyle, fonts: ~[RcMut<Font>]) -> FontGroup {
+ pub fn new(families: ~[~str], style: &UsedFontStyle, fonts: ~[Rc<RefCell<Font>>]) -> FontGroup {
FontGroup {
families: families,
style: (*style).clone(),
@@ -173,7 +165,7 @@ impl FontGroup {
assert!(self.fonts.len() > 0);
// TODO(Issue #177): Actually fall back through the FontGroup when a font is unsuitable.
- self.fonts[0].with_mut_borrow(|font| {
+ self.fonts[0].borrow().with_mut(|font| {
TextRun::new(font, text.clone(), decoration)
})
}
@@ -218,18 +210,16 @@ pub struct Font {
style: UsedFontStyle,
metrics: FontMetrics,
backend: BackendType,
- profiler_chan: ProfilerChan,
shape_cache: HashCache<~str, Arc<GlyphStore>>,
glyph_advance_cache: HashCache<u32, FractionalPixel>,
}
-impl<'self> Font {
+impl<'a> Font {
pub fn new_from_buffer(ctx: &FontContext,
buffer: ~[u8],
style: &SpecifiedFontStyle,
- backend: BackendType,
- profiler_chan: ProfilerChan)
- -> Result<RcMut<Font>, ()> {
+ backend: BackendType)
+ -> Result<Rc<RefCell<Font>>, ()> {
let handle = FontHandleMethods::new_from_buffer(&ctx.handle, buffer, style);
let handle: FontHandle = if handle.is_ok() {
handle.unwrap()
@@ -240,22 +230,21 @@ impl<'self> Font {
let metrics = handle.get_metrics();
// TODO(Issue #179): convert between specified and used font style here?
- return Ok(RcMut::new(Font {
+ return Ok(Rc::from_mut(RefCell::new(Font {
handle: handle,
azure_font: None,
shaper: None,
style: (*style).clone(),
metrics: metrics,
backend: backend,
- profiler_chan: profiler_chan,
shape_cache: HashCache::new(),
glyph_advance_cache: HashCache::new(),
- }));
+ })));
}
pub fn new_from_adopted_handle(_fctx: &FontContext, handle: FontHandle,
- style: &SpecifiedFontStyle, backend: BackendType,
- profiler_chan: ProfilerChan) -> Font {
+ style: &SpecifiedFontStyle, backend: BackendType)
+ -> Font {
let metrics = handle.get_metrics();
Font {
@@ -265,15 +254,14 @@ impl<'self> Font {
style: (*style).clone(),
metrics: metrics,
backend: backend,
- profiler_chan: profiler_chan,
shape_cache: HashCache::new(),
glyph_advance_cache: HashCache::new(),
}
}
pub fn new_from_existing_handle(fctx: &FontContext, handle: &FontHandle,
- style: &SpecifiedFontStyle, backend: BackendType,
- profiler_chan: ProfilerChan) -> Result<RcMut<Font>,()> {
+ style: &SpecifiedFontStyle, backend: BackendType)
+ -> Result<Rc<RefCell<Font>>,()> {
// TODO(Issue #179): convert between specified and used font style here?
let styled_handle = match handle.clone_with_style(&fctx.handle, style) {
@@ -281,15 +269,15 @@ impl<'self> Font {
Err(()) => return Err(())
};
- return Ok(RcMut::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend, profiler_chan)));
+ return Ok(Rc::from_mut(RefCell::new(Font::new_from_adopted_handle(fctx, styled_handle, style, backend))));
}
- fn make_shaper(&'self mut self) -> &'self Shaper {
+ fn make_shaper(&'a mut self) -> &'a Shaper {
// fast path: already created a shaper
match self.shaper {
- Some(ref shaper) => {
- let s: &'self Shaper = shaper;
- return s;
+ Some(ref shaper) => {
+ let s: &'a Shaper = shaper;
+ return s;
},
None => {}
}
@@ -349,7 +337,6 @@ impl<'self> Font {
impl Font {
- #[fixed_stack_segment]
pub fn draw_text_into_context(&mut self,
rctx: &RenderContext,
run: &~TextRun,
@@ -399,8 +386,8 @@ impl Font {
if azglyph_buf_len == 0 { return; } // Otherwise the Quartz backend will assert.
let glyphbuf = struct__AzGlyphBuffer {
- mGlyphs: vec::raw::to_ptr(azglyphs),
- mNumGlyphs: azglyph_buf_len as uint32_t
+ mGlyphs: azglyphs.as_ptr(),
+ mNumGlyphs: azglyph_buf_len as uint32_t
};
unsafe {
@@ -441,11 +428,11 @@ impl Font {
//FIXME (ksh8281)
self.make_shaper();
- do self.shape_cache.find_or_create(&text) |txt| {
+ self.shape_cache.find_or_create(&text, |txt| {
let mut glyphs = GlyphStore::new(text.char_len(), is_whitespace);
self.shaper.get_ref().shape_text(*txt, &mut glyphs);
Arc::new(glyphs)
- }
+ })
}
pub fn get_descriptor(&self) -> FontDescriptor {
@@ -457,12 +444,12 @@ impl Font {
}
pub fn glyph_h_advance(&mut self, glyph: GlyphIndex) -> FractionalPixel {
- do self.glyph_advance_cache.find_or_create(&glyph) |glyph| {
+ self.glyph_advance_cache.find_or_create(&glyph, |glyph| {
match self.handle.glyph_h_advance(*glyph) {
Some(adv) => adv,
None => /* FIXME: Need fallback strategy */ 10f64 as FractionalPixel
}
- }
+ })
}
}
diff --git a/src/components/gfx/font_context.rs b/src/components/gfx/font_context.rs
index 2ed981994da..a465df11ffd 100644
--- a/src/components/gfx/font_context.rs
+++ b/src/components/gfx/font_context.rs
@@ -15,7 +15,8 @@ use platform::font_context::FontContextHandle;
use azure::azure_hl::BackendType;
use std::hashmap::HashMap;
-use std::rc::RcMut;
+use std::rc::Rc;
+use std::cell::RefCell;
pub trait FontContextHandleMethods {
@@ -23,16 +24,16 @@ pub trait FontContextHandleMethods {
}
pub struct FontContext {
- instance_cache: LRUCache<FontDescriptor, RcMut<Font>>,
+ instance_cache: LRUCache<FontDescriptor, Rc<RefCell<Font>>>,
font_list: Option<FontList>, // only needed by layout
- group_cache: LRUCache<SpecifiedFontStyle, RcMut<FontGroup>>,
+ group_cache: LRUCache<SpecifiedFontStyle, Rc<RefCell<FontGroup>>>,
handle: FontContextHandle,
backend: BackendType,
generic_fonts: HashMap<~str,~str>,
profiler_chan: ProfilerChan,
}
-impl<'self> FontContext {
+impl FontContext {
pub fn new(backend: BackendType,
needs_font_list: bool,
profiler_chan: ProfilerChan)
@@ -61,11 +62,8 @@ impl<'self> FontContext {
}
}
- fn get_font_list(&'self self) -> &'self FontList {
- self.font_list.get_ref()
- }
-
- pub fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle) -> RcMut<FontGroup> {
+ pub fn get_resolved_font_for_style(&mut self, style: &SpecifiedFontStyle)
+ -> Rc<RefCell<FontGroup>> {
match self.group_cache.find(style) {
Some(fg) => {
debug!("font group cache hit");
@@ -80,7 +78,8 @@ impl<'self> FontContext {
}
}
- pub fn get_font_by_descriptor(&mut self, desc: &FontDescriptor) -> Result<RcMut<Font>, ()> {
+ pub fn get_font_by_descriptor(&mut self, desc: &FontDescriptor)
+ -> Result<Rc<RefCell<Font>>, ()> {
match self.instance_cache.find(desc) {
Some(f) => {
debug!("font cache hit");
@@ -107,7 +106,7 @@ impl<'self> FontContext {
}
}
- fn create_font_group(&mut self, style: &SpecifiedFontStyle) -> RcMut<FontGroup> {
+ fn create_font_group(&mut self, style: &SpecifiedFontStyle) -> Rc<RefCell<FontGroup>> {
let mut fonts = ~[];
debug!("(create font group) --- starting ---");
@@ -140,8 +139,7 @@ impl<'self> FontContext {
Some(ref result) => {
found = true;
let instance = self.get_font_by_descriptor(result);
-
- for font in instance.iter() { fonts.push(font.clone()); }
+ instance.map(|font| fonts.push(font.clone()));
},
_ => {}
}
@@ -179,10 +177,7 @@ impl<'self> FontContext {
match font_desc {
Some(ref fd) => {
let instance = self.get_font_by_descriptor(fd);
-
- for font in instance.iter() {
- fonts.push(font.clone());
- }
+ instance.map(|font| fonts.push(font.clone()));
},
None => { }
};
@@ -194,22 +189,28 @@ impl<'self> FontContext {
debug!("(create font group) --- finished ---");
- unsafe { RcMut::new_unchecked(FontGroup::new(style.families.clone(), &used_style, fonts)) }
+ unsafe {
+ Rc::new_unchecked(
+ RefCell::new(
+ FontGroup::new(style.families.to_owned(), &used_style, fonts)))
+ }
}
- fn create_font_instance(&self, desc: &FontDescriptor) -> Result<RcMut<Font>, ()> {
+ fn create_font_instance(&self, desc: &FontDescriptor) -> Result<Rc<RefCell<Font>>, ()> {
return match &desc.selector {
// TODO(Issue #174): implement by-platform-name font selectors.
&SelectorPlatformIdentifier(ref identifier) => {
let result_handle = self.handle.create_font_from_identifier((*identifier).clone(),
desc.style.clone());
- do result_handle.and_then |handle| {
- Ok(RcMut::new(Font::new_from_adopted_handle(self,
- handle,
- &desc.style,
- self.backend,
- self.profiler_chan.clone())))
- }
+ result_handle.and_then(|handle| {
+ Ok(
+ Rc::from_mut(
+ RefCell::new(
+ Font::new_from_adopted_handle(self,
+ handle,
+ &desc.style,
+ self.backend))))
+ })
}
};
}
diff --git a/src/components/gfx/font_list.rs b/src/components/gfx/font_list.rs
index f4aba05c140..cb49d90f148 100644
--- a/src/components/gfx/font_list.rs
+++ b/src/components/gfx/font_list.rs
@@ -29,7 +29,7 @@ pub struct FontList {
prof_chan: ProfilerChan,
}
-impl<'self> FontList {
+impl FontList {
pub fn new(fctx: &FontContextHandle,
prof_chan: ProfilerChan)
-> FontList {
@@ -48,20 +48,20 @@ impl<'self> FontList {
// changed. Does OSX have a notification for this event?
//
// Should font families with entries be invalidated/refreshed too?
- do profile(time::GfxRegenAvailableFontsCategory, self.prof_chan.clone()) {
+ profile(time::GfxRegenAvailableFontsCategory, self.prof_chan.clone(), || {
self.family_map = self.handle.get_available_families();
- }
+ });
}
- pub fn find_font_in_family(&'self mut self,
- family_name: &~str,
- style: &SpecifiedFontStyle) -> Option<&'self FontEntry> {
+ pub fn find_font_in_family<'a>(&'a mut self,
+ family_name: &~str,
+ style: &SpecifiedFontStyle) -> Option<&'a FontEntry> {
// TODO(Issue #188): look up localized font family names if canonical name not found
// look up canonical name
if self.family_map.contains_key(family_name) {
//FIXME call twice!(ksh8281)
debug!("FontList: Found font family with name={:s}", family_name.to_str());
- let s: &'self mut FontFamily = self.family_map.get_mut(family_name);
+ let s: &'a mut FontFamily = self.family_map.get_mut(family_name);
// TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'.
// if such family exists, try to match style to a font
let result = s.find_font_for_style(&mut self.handle, style);
@@ -82,13 +82,13 @@ impl<'self> FontList {
}
}
-// Holds a specific font family, and the various
-pub struct FontFamily<'self> {
+// Holds a specific font family, and the various
+pub struct FontFamily {
family_name: ~str,
entries: ~[FontEntry],
}
-impl<'self> FontFamily {
+impl FontFamily {
pub fn new(family_name: &str) -> FontFamily {
FontFamily {
family_name: family_name.to_str(),
@@ -104,8 +104,8 @@ impl<'self> FontFamily {
assert!(self.entries.len() > 0)
}
- pub fn find_font_for_style(&'self mut self, list: &FontListHandle, style: &SpecifiedFontStyle)
- -> Option<&'self FontEntry> {
+ pub fn find_font_for_style<'a>(&'a mut self, list: &FontListHandle, style: &SpecifiedFontStyle)
+ -> Option<&'a FontEntry> {
self.load_family_variations(list);
// TODO(Issue #189): optimize lookup for
diff --git a/src/components/gfx/gfx.rc b/src/components/gfx/gfx.rc
index 0eb60d63fb5..5f30e60b4aa 100644
--- a/src/components/gfx/gfx.rc
+++ b/src/components/gfx/gfx.rc
@@ -2,10 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#[link(name = "gfx",
- vers = "0.1",
- uuid = "0106bb54-6ea9-45bf-a39e-a738621f15e5",
- url = "http://servo.org/")];
+#[crate_id = "github.com/mozilla/servo#gfx:0.1"];
#[crate_type = "lib"];
#[feature(globs, managed_boxes, macro_rules)];
@@ -16,10 +13,10 @@ extern mod geom;
extern mod layers;
extern mod stb_image;
extern mod png;
-extern mod servo_net (name = "net");
-extern mod servo_util (name = "util");
+extern mod servo_net = "net";
+extern mod servo_util = "util";
extern mod style;
-extern mod servo_msg (name = "msg");
+extern mod servo_msg = "msg";
// Eventually we would like the shaper to be pluggable, as many operating systems have their own
// shapers. For now, however, this is a hard dependency.
diff --git a/src/components/gfx/opts.rs b/src/components/gfx/opts.rs
index ca9c9cc815b..a58b6ed4291 100644
--- a/src/components/gfx/opts.rs
+++ b/src/components/gfx/opts.rs
@@ -113,9 +113,9 @@ pub fn from_cmdline_args(args: &[~str]) -> Opts {
};
// if only flag is present, default to 5 second period
- let profiler_period = do opt_match.opt_default("p", "5").map |period| {
+ let profiler_period = opt_match.opt_default("p", "5").map(|period| {
from_str(period).unwrap()
- };
+ });
let cpu_painting = opt_match.opt_present("c");
diff --git a/src/components/gfx/platform/android/font.rs b/src/components/gfx/platform/android/font.rs
index f8f11eb251d..6df0b9c13c1 100644
--- a/src/components/gfx/platform/android/font.rs
+++ b/src/components/gfx/platform/android/font.rs
@@ -41,7 +41,7 @@ pub struct FontTable {
}
impl FontTableMethods for FontTable {
- fn with_buffer(&self, _blk: &fn(*u8, uint)) {
+ fn with_buffer(&self, _blk: |*u8, uint|) {
fail!()
}
}
@@ -61,7 +61,6 @@ pub struct FontHandle {
#[unsafe_destructor]
impl Drop for FontHandle {
- #[fixed_stack_segment]
fn drop(&mut self) {
assert!(self.face.is_not_null());
unsafe {
@@ -80,9 +79,7 @@ impl FontHandleMethods for FontHandle {
let ft_ctx: FT_Library = fctx.ctx.borrow().ctx;
if ft_ctx.is_null() { return Err(()); }
- let face_result = do buf.as_imm_buf |bytes: *u8, len: uint| {
- create_face_from_buffer(ft_ctx, bytes, len, style.pt_size)
- };
+ let face_result = create_face_from_buffer(ft_ctx, buf.as_ptr(), buf.len(), style.pt_size);
// TODO: this could be more simply written as result::chain
// and moving buf into the struct ctor, but cant' move out of
@@ -99,7 +96,6 @@ impl FontHandleMethods for FontHandle {
Err(()) => Err(())
};
- #[fixed_stack_segment]
fn create_face_from_buffer(lib: FT_Library, cbuf: *u8, cbuflen: uint, pt_size: f64)
-> Result<FT_Face, ()> {
unsafe {
@@ -129,14 +125,12 @@ impl FontHandleMethods for FontHandle {
fn family_name(&self) -> ~str {
unsafe { str::raw::from_c_str((*self.face).family_name) }
}
- #[fixed_stack_segment]
fn face_name(&self) -> ~str {
unsafe { str::raw::from_c_str(FT_Get_Postscript_Name(self.face)) }
}
fn is_italic(&self) -> bool {
unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 }
}
- #[fixed_stack_segment]
fn boldness(&self) -> font_weight::T {
let default_weight = font_weight::Weight400;
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
@@ -179,7 +173,6 @@ impl FontHandleMethods for FontHandle {
}
}
- #[fixed_stack_segment]
fn glyph_index(&self,
codepoint: char) -> Option<GlyphIndex> {
assert!(self.face.is_not_null());
@@ -194,7 +187,6 @@ impl FontHandleMethods for FontHandle {
}
}
- #[fixed_stack_segment]
fn glyph_h_advance(&self,
glyph: GlyphIndex) -> Option<FractionalPixel> {
assert!(self.face.is_not_null());
@@ -216,7 +208,6 @@ impl FontHandleMethods for FontHandle {
}
}
- #[fixed_stack_segment]
fn get_metrics(&self) -> FontMetrics {
/* TODO(Issue #76): complete me */
let face = self.get_face_rec();
@@ -272,8 +263,7 @@ impl FontHandleMethods for FontHandle {
}
}
-impl<'self> FontHandle {
- #[fixed_stack_segment]
+impl<'a> FontHandle {
fn set_char_size(face: FT_Face, pt_size: f64) -> Result<(), ()>{
let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6;
@@ -286,7 +276,6 @@ impl<'self> FontHandle {
}
}
- #[fixed_stack_segment]
pub fn new_from_file(fctx: &FontContextHandle, file: &str,
style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
unsafe {
@@ -295,10 +284,10 @@ impl<'self> FontHandle {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
- do file.to_c_str().with_ref |file_str| {
+ file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
- }
+ });
if face.is_null() {
return Err(());
}
@@ -314,7 +303,6 @@ impl<'self> FontHandle {
}
}
- #[fixed_stack_segment]
pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str)
-> Result<FontHandle, ()> {
unsafe {
@@ -323,10 +311,10 @@ impl<'self> FontHandle {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
- do file.to_c_str().with_ref |file_str| {
+ file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
- }
+ });
if face.is_null() {
return Err(());
}
@@ -339,7 +327,7 @@ impl<'self> FontHandle {
}
}
- fn get_face_rec(&'self self) -> &'self FT_FaceRec {
+ fn get_face_rec(&'a self) -> &'a FT_FaceRec {
unsafe {
&(*self.face)
}
diff --git a/src/components/gfx/platform/android/font_context.rs b/src/components/gfx/platform/android/font_context.rs
index 4b6c74d95c2..3aa9e064281 100644
--- a/src/components/gfx/platform/android/font_context.rs
+++ b/src/components/gfx/platform/android/font_context.rs
@@ -24,7 +24,6 @@ pub struct FontContextHandle {
}
impl Drop for FreeTypeLibraryHandle {
- #[fixed_stack_segment]
fn drop(&mut self) {
assert!(self.ctx.is_not_null());
unsafe { FT_Done_FreeType(self.ctx) };
@@ -32,7 +31,6 @@ impl Drop for FreeTypeLibraryHandle {
}
impl FontContextHandle {
- #[fixed_stack_segment]
pub fn new() -> FontContextHandle {
unsafe {
let ctx: FT_Library = ptr::null();
@@ -49,10 +47,10 @@ impl FontContextHandleMethods for FontContextHandle {
fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle)
-> Result<FontHandle, ()> {
debug!("Creating font handle for {:s}", name);
- do path_from_identifier(name, &style).and_then |file_name| {
+ path_from_identifier(name, &style).and_then(|file_name| {
debug!("Opening font face {:s}", file_name);
FontHandle::new_from_file(self, file_name.to_owned(), &style)
- }
+ })
}
}
diff --git a/src/components/gfx/platform/android/font_list.rs b/src/components/gfx/platform/android/font_list.rs
index b547fb7ca83..132f98c4641 100644
--- a/src/components/gfx/platform/android/font_list.rs
+++ b/src/components/gfx/platform/android/font_list.rs
@@ -40,7 +40,6 @@ impl FontListHandle {
FontListHandle { fctx: fctx.clone() }
}
- #[fixed_stack_segment]
pub fn get_available_families(&self) -> FontFamilyMap {
let mut family_map : FontFamilyMap = HashMap::new();
unsafe {
@@ -50,7 +49,7 @@ impl FontListHandle {
let font = (*fontSet).fonts.offset(i);
let family: *FcChar8 = ptr::null();
let mut v: c_int = 0;
- do "family".to_c_str().with_ref |FC_FAMILY| {
+ "family".to_c_str().with_ref(|FC_FAMILY| {
while FcPatternGetString(*font, FC_FAMILY, v, &family) == FcResultMatch {
let family_name = str::raw::from_c_str(family as *c_char);
debug!("Creating new FontFamily for family: {:s}", family_name);
@@ -58,13 +57,12 @@ impl FontListHandle {
family_map.insert(family_name, new_family);
v += 1;
}
- }
+ });
}
}
return family_map;
}
- #[fixed_stack_segment]
pub fn load_variations_for_family(&self, family: &mut FontFamily) {
debug!("getting variations for {:?}", family);
unsafe {
@@ -73,22 +71,22 @@ impl FontListHandle {
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set);
let pattern = FcPatternCreate();
assert!(pattern.is_not_null());
- do "family".to_c_str().with_ref |FC_FAMILY| {
- do family.family_name.to_c_str().with_ref |family_name| {
+ "family".to_c_str().with_ref(|FC_FAMILY| {
+ family.family_name.to_c_str().with_ref(|family_name| {
let ok = FcPatternAddString(pattern, FC_FAMILY, family_name as *FcChar8);
assert!(ok != 0);
- }
- }
+ });
+ });
let object_set = FcObjectSetCreate();
assert!(object_set.is_not_null());
- do "file".to_c_str().with_ref |FC_FILE| {
+ "file".to_c_str().with_ref(|FC_FILE| {
FcObjectSetAdd(object_set, FC_FILE);
- }
- do "index".to_c_str().with_ref |FC_INDEX| {
+ });
+ "index".to_c_str().with_ref(|FC_INDEX| {
FcObjectSetAdd(object_set, FC_INDEX);
- }
+ });
let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set);
@@ -96,22 +94,22 @@ impl FontListHandle {
for i in range(0, (*matches).nfont as int) {
let font = (*matches).fonts.offset(i);
- let file = do "file".to_c_str().with_ref |FC_FILE| {
+ let file = "file".to_c_str().with_ref(|FC_FILE| {
let file: *FcChar8 = ptr::null();
if FcPatternGetString(*font, FC_FILE, 0, &file) == FcResultMatch {
str::raw::from_c_str(file as *libc::c_char)
} else {
fail!();
}
- };
- let index = do "index".to_c_str().with_ref |FC_INDEX| {
+ });
+ let index = "index".to_c_str().with_ref(|FC_INDEX| {
let index: libc::c_int = 0;
if FcPatternGetInteger(*font, FC_INDEX, 0, &index) == FcResultMatch {
index
} else {
fail!();
}
- };
+ });
debug!("variation file: {}", file);
debug!("variation index: {}", index);
@@ -141,7 +139,6 @@ struct AutoPattern {
}
impl Drop for AutoPattern {
- #[fixed_stack_segment]
fn drop(&mut self) {
unsafe {
FcPatternDestroy(self.pattern);
@@ -149,17 +146,16 @@ impl Drop for AutoPattern {
}
}
-#[fixed_stack_segment]
pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, ()> {
unsafe {
let config = FcConfigGetCurrent();
let wrapper = AutoPattern { pattern: FcPatternCreate() };
let pattern = wrapper.pattern;
- let res = do "family".to_c_str().with_ref |FC_FAMILY| {
- do name.to_c_str().with_ref |family| {
+ let res = "family".to_c_str().with_ref(|FC_FAMILY| {
+ name.to_c_str().with_ref(|family| {
FcPatternAddString(pattern, FC_FAMILY, family as *FcChar8)
- }
- };
+ })
+ });
if res != 1 {
debug!("adding family to pattern failed");
return Err(());
@@ -168,18 +164,18 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
match style.style {
font_style::normal => (),
font_style::italic => {
- let res = do "slant".to_c_str().with_ref |FC_SLANT| {
+ let res = "slant".to_c_str().with_ref(|FC_SLANT| {
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC)
- };
+ });
if res != 1 {
debug!("adding slant to pattern failed");
return Err(());
}
},
font_style::oblique => {
- let res = do "slant".to_c_str().with_ref |FC_SLANT| {
+ let res = "slant".to_c_str().with_ref(|FC_SLANT| {
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE)
- };
+ });
if res != 1 {
debug!("adding slant(oblique) to pattern failed");
return Err(());
@@ -188,9 +184,9 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
}
if style.weight.is_bold() {
- let res = do "weight".to_c_str().with_ref |FC_WEIGHT| {
+ let res = "weight".to_c_str().with_ref(|FC_WEIGHT| {
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD)
- };
+ });
if res != 1 {
debug!("adding weight to pattern failed");
return Err(());
@@ -211,9 +207,9 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
}
let file: *FcChar8 = ptr::null();
- let res = do "file".to_c_str().with_ref |FC_FILE| {
+ let res = "file".to_c_str().with_ref(|FC_FILE| {
FcPatternGetString(result_pattern, FC_FILE, 0, &file)
- };
+ });
if res != FcResultMatch {
debug!("getting filename for font failed");
return Err(());
diff --git a/src/components/gfx/platform/linux/font.rs b/src/components/gfx/platform/linux/font.rs
index f8f11eb251d..6df0b9c13c1 100644
--- a/src/components/gfx/platform/linux/font.rs
+++ b/src/components/gfx/platform/linux/font.rs
@@ -41,7 +41,7 @@ pub struct FontTable {
}
impl FontTableMethods for FontTable {
- fn with_buffer(&self, _blk: &fn(*u8, uint)) {
+ fn with_buffer(&self, _blk: |*u8, uint|) {
fail!()
}
}
@@ -61,7 +61,6 @@ pub struct FontHandle {
#[unsafe_destructor]
impl Drop for FontHandle {
- #[fixed_stack_segment]
fn drop(&mut self) {
assert!(self.face.is_not_null());
unsafe {
@@ -80,9 +79,7 @@ impl FontHandleMethods for FontHandle {
let ft_ctx: FT_Library = fctx.ctx.borrow().ctx;
if ft_ctx.is_null() { return Err(()); }
- let face_result = do buf.as_imm_buf |bytes: *u8, len: uint| {
- create_face_from_buffer(ft_ctx, bytes, len, style.pt_size)
- };
+ let face_result = create_face_from_buffer(ft_ctx, buf.as_ptr(), buf.len(), style.pt_size);
// TODO: this could be more simply written as result::chain
// and moving buf into the struct ctor, but cant' move out of
@@ -99,7 +96,6 @@ impl FontHandleMethods for FontHandle {
Err(()) => Err(())
};
- #[fixed_stack_segment]
fn create_face_from_buffer(lib: FT_Library, cbuf: *u8, cbuflen: uint, pt_size: f64)
-> Result<FT_Face, ()> {
unsafe {
@@ -129,14 +125,12 @@ impl FontHandleMethods for FontHandle {
fn family_name(&self) -> ~str {
unsafe { str::raw::from_c_str((*self.face).family_name) }
}
- #[fixed_stack_segment]
fn face_name(&self) -> ~str {
unsafe { str::raw::from_c_str(FT_Get_Postscript_Name(self.face)) }
}
fn is_italic(&self) -> bool {
unsafe { (*self.face).style_flags & FT_STYLE_FLAG_ITALIC != 0 }
}
- #[fixed_stack_segment]
fn boldness(&self) -> font_weight::T {
let default_weight = font_weight::Weight400;
if unsafe { (*self.face).style_flags & FT_STYLE_FLAG_BOLD == 0 } {
@@ -179,7 +173,6 @@ impl FontHandleMethods for FontHandle {
}
}
- #[fixed_stack_segment]
fn glyph_index(&self,
codepoint: char) -> Option<GlyphIndex> {
assert!(self.face.is_not_null());
@@ -194,7 +187,6 @@ impl FontHandleMethods for FontHandle {
}
}
- #[fixed_stack_segment]
fn glyph_h_advance(&self,
glyph: GlyphIndex) -> Option<FractionalPixel> {
assert!(self.face.is_not_null());
@@ -216,7 +208,6 @@ impl FontHandleMethods for FontHandle {
}
}
- #[fixed_stack_segment]
fn get_metrics(&self) -> FontMetrics {
/* TODO(Issue #76): complete me */
let face = self.get_face_rec();
@@ -272,8 +263,7 @@ impl FontHandleMethods for FontHandle {
}
}
-impl<'self> FontHandle {
- #[fixed_stack_segment]
+impl<'a> FontHandle {
fn set_char_size(face: FT_Face, pt_size: f64) -> Result<(), ()>{
let char_width = float_to_fixed_ft(pt_size) as FT_F26Dot6;
let char_height = float_to_fixed_ft(pt_size) as FT_F26Dot6;
@@ -286,7 +276,6 @@ impl<'self> FontHandle {
}
}
- #[fixed_stack_segment]
pub fn new_from_file(fctx: &FontContextHandle, file: &str,
style: &SpecifiedFontStyle) -> Result<FontHandle, ()> {
unsafe {
@@ -295,10 +284,10 @@ impl<'self> FontHandle {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
- do file.to_c_str().with_ref |file_str| {
+ file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
- }
+ });
if face.is_null() {
return Err(());
}
@@ -314,7 +303,6 @@ impl<'self> FontHandle {
}
}
- #[fixed_stack_segment]
pub fn new_from_file_unstyled(fctx: &FontContextHandle, file: ~str)
-> Result<FontHandle, ()> {
unsafe {
@@ -323,10 +311,10 @@ impl<'self> FontHandle {
let mut face: FT_Face = ptr::null();
let face_index = 0 as FT_Long;
- do file.to_c_str().with_ref |file_str| {
+ file.to_c_str().with_ref(|file_str| {
FT_New_Face(ft_ctx, file_str,
face_index, ptr::to_mut_unsafe_ptr(&mut face));
- }
+ });
if face.is_null() {
return Err(());
}
@@ -339,7 +327,7 @@ impl<'self> FontHandle {
}
}
- fn get_face_rec(&'self self) -> &'self FT_FaceRec {
+ fn get_face_rec(&'a self) -> &'a FT_FaceRec {
unsafe {
&(*self.face)
}
diff --git a/src/components/gfx/platform/linux/font_context.rs b/src/components/gfx/platform/linux/font_context.rs
index 4b6c74d95c2..3aa9e064281 100644
--- a/src/components/gfx/platform/linux/font_context.rs
+++ b/src/components/gfx/platform/linux/font_context.rs
@@ -24,7 +24,6 @@ pub struct FontContextHandle {
}
impl Drop for FreeTypeLibraryHandle {
- #[fixed_stack_segment]
fn drop(&mut self) {
assert!(self.ctx.is_not_null());
unsafe { FT_Done_FreeType(self.ctx) };
@@ -32,7 +31,6 @@ impl Drop for FreeTypeLibraryHandle {
}
impl FontContextHandle {
- #[fixed_stack_segment]
pub fn new() -> FontContextHandle {
unsafe {
let ctx: FT_Library = ptr::null();
@@ -49,10 +47,10 @@ impl FontContextHandleMethods for FontContextHandle {
fn create_font_from_identifier(&self, name: ~str, style: UsedFontStyle)
-> Result<FontHandle, ()> {
debug!("Creating font handle for {:s}", name);
- do path_from_identifier(name, &style).and_then |file_name| {
+ path_from_identifier(name, &style).and_then(|file_name| {
debug!("Opening font face {:s}", file_name);
FontHandle::new_from_file(self, file_name.to_owned(), &style)
- }
+ })
}
}
diff --git a/src/components/gfx/platform/linux/font_list.rs b/src/components/gfx/platform/linux/font_list.rs
index 61838a44683..7fbc7323f68 100644
--- a/src/components/gfx/platform/linux/font_list.rs
+++ b/src/components/gfx/platform/linux/font_list.rs
@@ -40,7 +40,6 @@ impl FontListHandle {
FontListHandle { fctx: fctx.clone() }
}
- #[fixed_stack_segment]
pub fn get_available_families(&self) -> FontFamilyMap {
let mut family_map : FontFamilyMap = HashMap::new();
unsafe {
@@ -50,7 +49,7 @@ impl FontListHandle {
let font = (*fontSet).fonts.offset(i);
let family: *FcChar8 = ptr::null();
let mut v: c_int = 0;
- do "family".to_c_str().with_ref |FC_FAMILY| {
+ "family".to_c_str().with_ref(|FC_FAMILY| {
while FcPatternGetString(*font, FC_FAMILY, v, &family) == FcResultMatch {
let family_name = str::raw::from_c_str(family as *c_char);
debug!("Creating new FontFamily for family: {:s}", family_name);
@@ -58,13 +57,12 @@ impl FontListHandle {
family_map.insert(family_name, new_family);
v += 1;
}
- }
+ });
}
}
return family_map;
}
- #[fixed_stack_segment]
pub fn load_variations_for_family(&self, family: &mut FontFamily) {
debug!("getting variations for {:?}", family);
unsafe {
@@ -73,22 +71,22 @@ impl FontListHandle {
let font_set_array_ptr = ptr::to_unsafe_ptr(&font_set);
let pattern = FcPatternCreate();
assert!(pattern.is_not_null());
- do "family".to_c_str().with_ref |FC_FAMILY| {
- do family.family_name.to_c_str().with_ref |family_name| {
+ "family".to_c_str().with_ref(|FC_FAMILY| {
+ family.family_name.to_c_str().with_ref(|family_name| {
let ok = FcPatternAddString(pattern, FC_FAMILY, family_name as *FcChar8);
assert!(ok != 0);
- }
- }
+ });
+ });
let object_set = FcObjectSetCreate();
assert!(object_set.is_not_null());
- do "file".to_c_str().with_ref |FC_FILE| {
+ "file".to_c_str().with_ref(|FC_FILE| {
FcObjectSetAdd(object_set, FC_FILE);
- }
- do "index".to_c_str().with_ref |FC_INDEX| {
+ });
+ "index".to_c_str().with_ref(|FC_INDEX| {
FcObjectSetAdd(object_set, FC_INDEX);
- }
+ });
let matches = FcFontSetList(config, font_set_array_ptr, 1, pattern, object_set);
@@ -96,22 +94,22 @@ impl FontListHandle {
for i in range(0, (*matches).nfont as int) {
let font = (*matches).fonts.offset(i);
- let file = do "file".to_c_str().with_ref |FC_FILE| {
+ let file = "file".to_c_str().with_ref(|FC_FILE| {
let file: *FcChar8 = ptr::null();
if FcPatternGetString(*font, FC_FILE, 0, &file) == FcResultMatch {
str::raw::from_c_str(file as *libc::c_char)
} else {
fail!();
}
- };
- let index = do "index".to_c_str().with_ref |FC_INDEX| {
+ });
+ let index = "index".to_c_str().with_ref(|FC_INDEX| {
let index: libc::c_int = 0;
if FcPatternGetInteger(*font, FC_INDEX, 0, &index) == FcResultMatch {
index
} else {
fail!();
}
- };
+ });
debug!("variation file: {}", file);
debug!("variation index: {}", index);
@@ -141,7 +139,6 @@ struct AutoPattern {
}
impl Drop for AutoPattern {
- #[fixed_stack_segment]
fn drop(&mut self) {
unsafe {
FcPatternDestroy(self.pattern);
@@ -149,17 +146,16 @@ impl Drop for AutoPattern {
}
}
-#[fixed_stack_segment]
pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, ()> {
unsafe {
let config = FcConfigGetCurrent();
let wrapper = AutoPattern { pattern: FcPatternCreate() };
let pattern = wrapper.pattern;
- let res = do "family".to_c_str().with_ref |FC_FAMILY| {
- do name.to_c_str().with_ref |family| {
+ let res = "family".to_c_str().with_ref(|FC_FAMILY| {
+ name.to_c_str().with_ref(|family| {
FcPatternAddString(pattern, FC_FAMILY, family as *FcChar8)
- }
- };
+ })
+ });
if res != 1 {
debug!("adding family to pattern failed");
return Err(());
@@ -168,18 +164,18 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
match style.style {
font_style::normal => (),
font_style::italic => {
- let res = do "slant".to_c_str().with_ref |FC_SLANT| {
+ let res = "slant".to_c_str().with_ref(|FC_SLANT| {
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC)
- };
+ });
if res != 1 {
debug!("adding slant to pattern failed");
return Err(());
}
},
font_style::oblique => {
- let res = do "slant".to_c_str().with_ref |FC_SLANT| {
+ let res = "slant".to_c_str().with_ref(|FC_SLANT| {
FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE)
- };
+ });
if res != 1 {
debug!("adding slant(oblique) to pattern failed");
return Err(());
@@ -188,9 +184,9 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
}
if style.weight.is_bold() {
- let res = do "weight".to_c_str().with_ref |FC_WEIGHT| {
+ let res = "weight".to_c_str().with_ref(|FC_WEIGHT| {
FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD)
- };
+ });
if res != 1 {
debug!("adding weight to pattern failed");
return Err(());
@@ -211,9 +207,9 @@ pub fn path_from_identifier(name: ~str, style: &UsedFontStyle) -> Result<~str, (
}
let file: *FcChar8 = ptr::null();
- let res = do "file".to_c_str().with_ref |FC_FILE| {
+ let res = "file".to_c_str().with_ref(|FC_FILE| {
FcPatternGetString(result_pattern, FC_FILE, 0, &file)
- };
+ });
if res != FcResultMatch {
debug!("getting filename for font failed");
return Err(());
diff --git a/src/components/gfx/platform/macos/font.rs b/src/components/gfx/platform/macos/font.rs
index 3b6b60e9235..e3b292b2a63 100644
--- a/src/components/gfx/platform/macos/font.rs
+++ b/src/components/gfx/platform/macos/font.rs
@@ -29,7 +29,6 @@ use core_text::font_descriptor::{kCTFontDefaultOrientation};
use core_text;
use std::ptr;
-use std::vec;
pub struct FontTable {
data: CFData,
@@ -47,8 +46,8 @@ impl FontTable {
}
impl FontTableMethods for FontTable {
- fn with_buffer(&self, blk: &fn(*u8, uint)) {
- blk(vec::raw::to_ptr(self.data.bytes()), self.data.len() as uint);
+ fn with_buffer(&self, blk: |*u8, uint|) {
+ blk(self.data.bytes().as_ptr(), self.data.len() as uint);
}
}
@@ -185,9 +184,9 @@ impl FontHandleMethods for FontHandle {
fn get_table_for_tag(&self, tag: FontTableTag) -> Option<FontTable> {
let result: Option<CFData> = self.ctfont.get_font_table(tag);
- do result.and_then |data| {
+ result.and_then(|data| {
Some(FontTable::wrap(data))
- }
+ })
}
fn face_identifier(&self) -> ~str {
diff --git a/src/components/gfx/platform/macos/font_context.rs b/src/components/gfx/platform/macos/font_context.rs
index 4a4afe6cefb..ef9ea06c447 100644
--- a/src/components/gfx/platform/macos/font_context.rs
+++ b/src/components/gfx/platform/macos/font_context.rs
@@ -27,8 +27,8 @@ impl FontContextHandleMethods for FontContextHandle {
style: UsedFontStyle)
-> Result<FontHandle, ()> {
let ctfont_result = core_text::font::new_from_name(name, style.pt_size);
- do ctfont_result.and_then |ctfont| {
+ ctfont_result.and_then(|ctfont| {
FontHandle::new_from_CTFont(self, ctfont)
- }
+ })
}
}
diff --git a/src/components/gfx/render_context.rs b/src/components/gfx/render_context.rs
index d13d709acce..fc12c1133fc 100644
--- a/src/components/gfx/render_context.rs
+++ b/src/components/gfx/render_context.rs
@@ -18,14 +18,13 @@ use geom::side_offsets::SideOffsets2D;
use servo_net::image::base::Image;
use png::{RGBA8, K8, KA8};
use servo_util::geometry::Au;
-use std::vec;
use std::libc::types::common::c99::uint16_t;
use std::libc::size_t;
-pub struct RenderContext<'self> {
- draw_target: &'self DrawTarget,
- font_ctx: &'self mut ~FontContext,
- opts: &'self Opts,
+pub struct RenderContext<'a> {
+ draw_target: &'a DrawTarget,
+ font_ctx: &'a mut ~FontContext,
+ opts: &'a Opts,
/// The rectangle that this context encompasses in page coordinates.
page_rect: Rect<f32>,
/// The rectangle that this context encompasses in screen coordinates (pixels).
@@ -39,8 +38,8 @@ enum Direction {
Bottom
}
-impl<'self> RenderContext<'self> {
- pub fn get_draw_target(&self) -> &'self DrawTarget {
+impl<'a> RenderContext<'a> {
+ pub fn get_draw_target(&self) -> &'a DrawTarget {
self.draw_target
}
@@ -167,7 +166,7 @@ impl<'self> RenderContext<'self> {
stroke_opts.line_width = border_width;
dash[0] = border_width * 3 as AzFloat;
dash[1] = border_width * 3 as AzFloat;
- stroke_opts.mDashPattern = vec::raw::to_ptr(dash);
+ stroke_opts.mDashPattern = dash.as_ptr();
stroke_opts.mDashLength = dash.len() as size_t;
let (start, end) = match direction {
diff --git a/src/components/gfx/render_task.rs b/src/components/gfx/render_task.rs
index 88da24cc396..0f1dd7913c9 100644
--- a/src/components/gfx/render_task.rs
+++ b/src/components/gfx/render_task.rs
@@ -20,7 +20,6 @@ use servo_util::time::{ProfilerChan, profile};
use servo_util::time;
use std::comm::{Chan, Port, SharedChan};
-use std::task::spawn_with;
use extra::arc::Arc;
use buffer_map::BufferMap;
@@ -63,24 +62,32 @@ pub fn BufferRequest(screen_rect: Rect<uint>, page_rect: Rect<f32>) -> BufferReq
// FIXME(rust#9155): this should be a newtype struct, but
// generic newtypes ICE when compiled cross-crate
-#[deriving(Clone)]
pub struct RenderChan<T> {
chan: SharedChan<Msg<T>>,
}
-impl<T: Send> RenderChan<T> {
- pub fn new(chan: Chan<Msg<T>>) -> RenderChan<T> {
+
+impl<T: Send> Clone for RenderChan<T> {
+ fn clone(&self) -> RenderChan<T> {
RenderChan {
- chan: SharedChan::new(chan),
+ chan: self.chan.clone(),
}
}
}
-impl<T: Send> GenericChan<Msg<T>> for RenderChan<T> {
- fn send(&self, msg: Msg<T>) {
+
+impl<T: Send> RenderChan<T> {
+ pub fn new() -> (Port<Msg<T>>, RenderChan<T>) {
+ let (port, chan) = SharedChan::new();
+ let render_chan = RenderChan {
+ chan: chan,
+ };
+ (port, render_chan)
+ }
+
+ pub fn send(&self, msg: Msg<T>) {
assert!(self.try_send(msg), "RenderChan.send: render port closed")
}
-}
-impl<T: Send> GenericSmartChan<Msg<T>> for RenderChan<T> {
- fn try_send(&self, msg: Msg<T>) -> bool {
+
+ pub fn try_send(&self, msg: Msg<T>) -> bool {
self.chan.try_send(msg)
}
}
@@ -138,9 +145,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
opts: Opts,
profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) {
- do spawn_with((port, compositor, constellation_chan, opts, profiler_chan, shutdown_chan))
- |(port, compositor, constellation_chan, opts, profiler_chan, shutdown_chan)| {
-
+ spawn(proc() {
{ // Ensures RenderTask and graphics context are destroyed before shutdown msg
let native_graphics_context = compositor.get_graphics_metadata().map(
|md| NativePaintingGraphicsContext::from_metadata(&md));
@@ -153,8 +158,8 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
compositor: compositor,
constellation_chan: constellation_chan,
font_ctx: ~FontContext::new(opts.render_backend.clone(),
- false,
- profiler_chan.clone()),
+ false,
+ profiler_chan.clone()),
opts: opts,
profiler_chan: profiler_chan,
@@ -176,13 +181,12 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
render_task.start();
// Destroy all the buffers.
- render_task.native_graphics_context.as_ref().map(|ctx|
- render_task.buffer_map.clear(ctx)
- );
+ render_task.native_graphics_context.as_ref().map(
+ |ctx| render_task.buffer_map.clear(ctx));
}
shutdown_chan.send(());
- }
+ });
}
fn start(&mut self) {
@@ -243,12 +247,12 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
}
self.compositor.set_render_state(RenderingRenderState);
- do time::profile(time::RenderingCategory, self.profiler_chan.clone()) {
+ time::profile(time::RenderingCategory, self.profiler_chan.clone(), || {
// FIXME: Try not to create a new array here.
let mut new_buffers = ~[];
// Divide up the layer into tiles.
- do time::profile(time::RenderingPrepBuffCategory, self.profiler_chan.clone()) {
+ time::profile(time::RenderingPrepBuffCategory, self.profiler_chan.clone(), || {
for tile in tiles.iter() {
let width = tile.screen_rect.size.width;
let height = tile.screen_rect.size.height;
@@ -293,10 +297,10 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
ctx.clear();
// Draw the display list.
- do profile(time::RenderingDrawingCategory, self.profiler_chan.clone()) {
+ profile(time::RenderingDrawingCategory, self.profiler_chan.clone(), || {
render_layer.display_list.get().draw_into_context(&mut ctx);
ctx.draw_target.flush();
- }
+ });
}
// Extract the texture from the draw target and place it into its slot in the
@@ -335,11 +339,11 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
}
};
- do draw_target.snapshot().get_data_surface().with_data |data| {
+ draw_target.snapshot().get_data_surface().with_data(|data| {
buffer.native_surface.upload(native_graphics_context!(self), data);
debug!("RENDERER uploading to native surface {:d}",
buffer.native_surface.get_id() as int);
- }
+ });
buffer
}
@@ -367,7 +371,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
new_buffers.push(buffer);
}
- }
+ });
let layer_buffer_set = ~LayerBufferSet {
buffers: new_buffers,
@@ -380,7 +384,7 @@ impl<C: RenderListener + Send,T:Send+Freeze> RenderTask<C,T> {
self.constellation_chan.send(RendererReadyMsg(self.id));
}
self.compositor.set_render_state(IdleRenderState);
- }
+ })
}
}
diff --git a/src/components/gfx/text/glyph.rs b/src/components/gfx/text/glyph.rs
index 6a72582c4d1..541ae815e85 100644
--- a/src/components/gfx/text/glyph.rs
+++ b/src/components/gfx/text/glyph.rs
@@ -14,7 +14,6 @@ use std::vec;
use std::util;
use std::iter;
use geom::point::Point2D;
-use extra::sort;
/// GlyphEntry is a port of Gecko's CompressedGlyph scheme for storing glyph data compactly.
///
@@ -149,8 +148,8 @@ static FLAG_NOT_LIGATURE_GROUP_START: u32 = 0x00000004;
static FLAG_CHAR_IS_TAB: u32 = 0x00000008;
static FLAG_CHAR_IS_NEWLINE: u32 = 0x00000010;
-static FLAG_CHAR_IS_LOW_SURROGATE: u32 = 0x00000020;
-static CHAR_IDENTITY_FLAGS_MASK: u32 = 0x00000038;
+//static FLAG_CHAR_IS_LOW_SURROGATE: u32 = 0x00000020;
+//static CHAR_IDENTITY_FLAGS_MASK: u32 = 0x00000038;
fn is_simple_glyph_id(glyphId: GlyphIndex) -> bool {
((glyphId as u32) & GLYPH_ID_MASK) == glyphId
@@ -176,10 +175,6 @@ impl GlyphEntry {
self.value & GLYPH_ID_MASK
}
- fn offset(&self) -> Point2D<Au> {
- Point2D(Au(0), Au(0))
- }
-
fn is_ligature_start(&self) -> bool {
self.has_flag(!FLAG_NOT_LIGATURE_GROUP_START)
}
@@ -312,7 +307,7 @@ struct DetailedGlyphStore {
lookup_is_sorted: bool,
}
-impl<'self> DetailedGlyphStore {
+impl<'a> DetailedGlyphStore {
fn new() -> DetailedGlyphStore {
DetailedGlyphStore {
detail_buffer: ~[], // TODO: default size?
@@ -345,8 +340,8 @@ impl<'self> DetailedGlyphStore {
self.lookup_is_sorted = false;
}
- fn get_detailed_glyphs_for_entry(&'self self, entry_offset: uint, count: u16)
- -> &'self [DetailedGlyph] {
+ fn get_detailed_glyphs_for_entry(&'a self, entry_offset: uint, count: u16)
+ -> &'a [DetailedGlyph] {
debug!("Requesting detailed glyphs[n={:u}] for entry[off={:u}]", count as uint, entry_offset);
// FIXME: Is this right? --pcwalton
@@ -375,10 +370,10 @@ impl<'self> DetailedGlyphStore {
}
}
- fn get_detailed_glyph_with_index(&'self self,
+ fn get_detailed_glyph_with_index(&'a self,
entry_offset: uint,
detail_offset: u16)
- -> &'self DetailedGlyph {
+ -> &'a DetailedGlyph {
assert!((detail_offset as uint) <= self.detail_buffer.len());
assert!(self.lookup_is_sorted);
@@ -411,7 +406,13 @@ impl<'self> DetailedGlyphStore {
let mut unsorted_records: ~[DetailedGlyphRecord] = ~[];
util::swap(&mut self.detail_lookup, &mut unsorted_records);
let mut mut_records : ~[DetailedGlyphRecord] = unsorted_records;
- sort::quick_sort3(mut_records);
+ mut_records.sort_by(|a, b| {
+ if a < b {
+ Less
+ } else {
+ Greater
+ }
+ });
let mut sorted_records = mut_records;
util::swap(&mut self.detail_lookup, &mut sorted_records);
@@ -458,12 +459,12 @@ impl GlyphData {
// through glyphs (either for a particular TextRun offset, or all glyphs).
// Rather than eagerly assembling and copying glyph data, it only retrieves
// values as they are needed from the GlyphStore, using provided offsets.
-enum GlyphInfo<'self> {
- SimpleGlyphInfo(&'self GlyphStore, uint),
- DetailGlyphInfo(&'self GlyphStore, uint, u16)
+enum GlyphInfo<'a> {
+ SimpleGlyphInfo(&'a GlyphStore, uint),
+ DetailGlyphInfo(&'a GlyphStore, uint, u16)
}
-impl<'self> GlyphInfo<'self> {
+impl<'a> GlyphInfo<'a> {
pub fn index(self) -> GlyphIndex {
match self {
SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].index(),
@@ -492,20 +493,6 @@ impl<'self> GlyphInfo<'self> {
}
}
}
-
- pub fn is_ligature_start(self) -> bool {
- match self {
- SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].is_ligature_start(),
- DetailGlyphInfo(store, entry_i, _) => store.entry_buffer[entry_i].is_ligature_start()
- }
- }
-
- pub fn is_cluster_start(self) -> bool {
- match self {
- SimpleGlyphInfo(store, entry_i) => store.entry_buffer[entry_i].is_cluster_start(),
- DetailGlyphInfo(store, entry_i, _) => store.entry_buffer[entry_i].is_cluster_start()
- }
- }
}
// Public data structure and API for storing and retrieving glyph data
@@ -519,7 +506,7 @@ pub struct GlyphStore {
is_whitespace: bool,
}
-impl<'self> GlyphStore {
+impl<'a> GlyphStore {
// Initializes the glyph store, but doesn't actually shape anything.
// Use the set_glyph, set_glyphs() methods to store glyph data.
pub fn new(length: uint, is_whitespace: bool) -> GlyphStore {
@@ -606,12 +593,12 @@ impl<'self> GlyphStore {
self.entry_buffer[i] = entry;
}
- pub fn iter_glyphs_for_char_index(&'self self, i: uint) -> GlyphIterator<'self> {
+ pub fn iter_glyphs_for_char_index(&'a self, i: uint) -> GlyphIterator<'a> {
self.iter_glyphs_for_char_range(&Range::new(i, 1))
}
#[inline]
- pub fn iter_glyphs_for_char_range(&'self self, rang: &Range) -> GlyphIterator<'self> {
+ pub fn iter_glyphs_for_char_range(&'a self, rang: &Range) -> GlyphIterator<'a> {
if rang.begin() >= self.entry_buffer.len() {
fail!("iter_glyphs_for_range: range.begin beyond length!");
}
@@ -684,17 +671,17 @@ impl<'self> GlyphStore {
}
}
-pub struct GlyphIterator<'self> {
- priv store: &'self GlyphStore,
+pub struct GlyphIterator<'a> {
+ priv store: &'a GlyphStore,
priv char_index: uint,
priv char_range: iter::Range<uint>,
priv glyph_range: Option<iter::Range<uint>>,
}
-impl<'self> GlyphIterator<'self> {
+impl<'a> GlyphIterator<'a> {
// Slow path when there is a glyph range.
#[inline(never)]
- fn next_glyph_range(&mut self) -> Option<(uint, GlyphInfo<'self>)> {
+ fn next_glyph_range(&mut self) -> Option<(uint, GlyphInfo<'a>)> {
match self.glyph_range.get_mut_ref().next() {
Some(j) => Some((self.char_index,
DetailGlyphInfo(self.store, self.char_index, j as u16))),
@@ -709,14 +696,14 @@ impl<'self> GlyphIterator<'self> {
// Slow path when there is a complex glyph.
#[inline(never)]
fn next_complex_glyph(&mut self, entry: &GlyphEntry, i: uint)
- -> Option<(uint, GlyphInfo<'self>)> {
+ -> Option<(uint, GlyphInfo<'a>)> {
let glyphs = self.store.detail_store.get_detailed_glyphs_for_entry(i, entry.glyph_count());
self.glyph_range = Some(range(0, glyphs.len()));
self.next()
}
}
-impl<'self> Iterator<(uint, GlyphInfo<'self>)> for GlyphIterator<'self> {
+impl<'a> Iterator<(uint, GlyphInfo<'a>)> for GlyphIterator<'a> {
// I tried to start with something simpler and apply FlatMap, but the
// inability to store free variables in the FlatMap struct was problematic.
//
@@ -724,7 +711,7 @@ impl<'self> Iterator<(uint, GlyphInfo<'self>)> for GlyphIterator<'self> {
// slow paths, which should not be inlined, are `next_glyph_range()` and
// `next_complex_glyph()`.
#[inline(always)]
- fn next(&mut self) -> Option<(uint, GlyphInfo<'self>)> {
+ fn next(&mut self) -> Option<(uint, GlyphInfo<'a>)> {
// Would use 'match' here but it borrows contents in a way that
// interferes with mutation.
if self.glyph_range.is_some() {
diff --git a/src/components/gfx/text/shaping/harfbuzz.rs b/src/components/gfx/text/shaping/harfbuzz.rs
index d8dc5fd14ae..93d590fba9a 100644
--- a/src/components/gfx/text/shaping/harfbuzz.rs
+++ b/src/components/gfx/text/shaping/harfbuzz.rs
@@ -10,15 +10,14 @@ use platform::font::FontTable;
use text::glyph::{GlyphStore, GlyphIndex, GlyphData};
use text::shaping::ShaperMethods;
use servo_util::range::Range;
-use text::util::{float_to_fixed, fixed_to_float, fixed_to_rounded_int};
+use text::util::{float_to_fixed, fixed_to_float};
use std::cast::transmute;
use std::char;
use std::libc::{c_uint, c_int, c_void, c_char};
use std::ptr;
use std::ptr::null;
-use std::uint;
-use std::util::ignore;
+use std::num;
use std::vec;
use geom::Point2D;
use harfbuzz::{hb_blob_create, hb_face_create_for_tables};
@@ -63,7 +62,6 @@ pub struct ShapedGlyphEntry {
}
impl ShapedGlyphData {
- #[fixed_stack_segment]
pub fn new(buffer: *hb_buffer_t) -> ShapedGlyphData {
unsafe {
let glyph_count = 0;
@@ -143,7 +141,6 @@ pub struct Shaper {
#[unsafe_destructor]
impl Drop for Shaper {
- #[fixed_stack_segment]
fn drop(&mut self) {
unsafe {
assert!(self.hb_face.is_not_null());
@@ -159,7 +156,6 @@ impl Drop for Shaper {
}
impl Shaper {
- #[fixed_stack_segment]
pub fn new(font: &mut Font) -> Shaper {
unsafe {
// Indirection for Rust Issue #6248, dynamic freeze scope artifically extended
@@ -200,29 +196,22 @@ impl Shaper {
fn fixed_to_float(i: hb_position_t) -> f64 {
fixed_to_float(16, i)
}
-
- fn fixed_to_rounded_int(f: hb_position_t) -> int {
- fixed_to_rounded_int(16, f)
- }
}
impl ShaperMethods for Shaper {
/// Calculate the layout metrics associated with the given text when rendered in a specific
/// font.
- #[fixed_stack_segment]
fn shape_text(&self, text: &str, glyphs: &mut GlyphStore) {
unsafe {
let hb_buffer: *hb_buffer_t = hb_buffer_create();
hb_buffer_set_direction(hb_buffer, HB_DIRECTION_LTR);
// Using as_imm_buf because it never does a copy - we don't need the trailing null
- do text.as_imm_buf |ctext: *u8, _: uint| {
- hb_buffer_add_utf8(hb_buffer,
- ctext as *c_char,
- text.len() as c_int,
- 0,
- text.len() as c_int);
- }
+ hb_buffer_add_utf8(hb_buffer,
+ text.as_ptr() as *c_char,
+ text.len() as c_int,
+ 0,
+ text.len() as c_int);
hb_shape(self.hb_font, hb_buffer, null(), 0);
self.save_glyph_results(text, glyphs, hb_buffer);
@@ -261,7 +250,7 @@ impl Shaper {
byteToGlyph = vec::from_elem(byte_max, NO_GLYPH);
} else {
byteToGlyph = vec::from_elem(byte_max, CONTINUATION_BYTE);
- for (i, _) in text.char_offset_iter() {
+ for (i, _) in text.char_indices() {
byteToGlyph[i] = NO_GLYPH;
}
}
@@ -283,7 +272,7 @@ impl Shaper {
debug!("text: {:s}", text);
debug!("(char idx): char->(glyph index):");
- for (i, ch) in text.char_offset_iter() {
+ for (i, ch) in text.char_indices() {
debug!("{:u}: {} --> {:d}", i, ch, byteToGlyph[i] as int);
}
@@ -309,7 +298,7 @@ impl Shaper {
// any trailing chars that do not have associated glyphs.
while char_byte_span.end() < byte_max {
let range = text.char_range_at(char_byte_span.end());
- ignore(range.ch);
+ drop(range.ch);
char_byte_span.extend_to(range.next);
debug!("Processing char byte span: off={:u}, len={:u} for glyph idx={:u}",
@@ -320,7 +309,7 @@ impl Shaper {
debug!("Extending char byte span to include byte offset={:u} with no associated \
glyph", char_byte_span.end());
let range = text.char_range_at(char_byte_span.end());
- ignore(range.ch);
+ drop(range.ch);
char_byte_span.extend_to(range.next);
}
@@ -329,7 +318,7 @@ impl Shaper {
let mut max_glyph_idx = glyph_span.end();
for i in char_byte_span.eachi() {
if byteToGlyph[i] > NO_GLYPH {
- max_glyph_idx = uint::max(byteToGlyph[i] as uint + 1, max_glyph_idx);
+ max_glyph_idx = num::max(byteToGlyph[i] as uint + 1, max_glyph_idx);
}
}
@@ -390,7 +379,7 @@ impl Shaper {
while covered_byte_span.end() < byte_max
&& byteToGlyph[covered_byte_span.end()] == NO_GLYPH {
let range = text.char_range_at(covered_byte_span.end());
- ignore(range.ch);
+ drop(range.ch);
covered_byte_span.extend_to(range.next);
}
@@ -404,7 +393,7 @@ impl Shaper {
// clamp to end of text. (I don't think this will be necessary, but..)
let end = covered_byte_span.end(); // FIXME: borrow checker workaround
- covered_byte_span.extend_to(uint::min(end, byte_max));
+ covered_byte_span.extend_to(num::min(end, byte_max));
// fast path: 1-to-1 mapping of single char and single glyph.
if glyph_span.length() == 1 {
@@ -443,7 +432,7 @@ impl Shaper {
let mut i = covered_byte_span.begin();
loop {
let range = text.char_range_at(i);
- ignore(range.ch);
+ drop(range.ch);
i = range.next;
if i >= covered_byte_span.end() { break; }
char_idx += 1;
@@ -514,14 +503,14 @@ extern fn get_font_table_func(_: *hb_face_t, tag: hb_tag_t, user_data: *c_void)
let skinny_font_table_ptr: *FontTable = font_table; // private context
let mut blob: *hb_blob_t = null();
- do (*skinny_font_table_ptr).with_buffer |buf: *u8, len: uint| {
+ (*skinny_font_table_ptr).with_buffer(|buf: *u8, len: uint| {
// HarfBuzz calls `destroy_blob_func` when the buffer is no longer needed.
blob = hb_blob_create(buf as *c_char,
len as c_uint,
HB_MEMORY_MODE_READONLY,
transmute(skinny_font_table_ptr),
destroy_blob_func);
- }
+ });
assert!(blob.is_not_null());
blob
diff --git a/src/components/gfx/text/text_run.rs b/src/components/gfx/text/text_run.rs
index 2e5a06e5079..0bde3607d3f 100644
--- a/src/components/gfx/text/text_run.rs
+++ b/src/components/gfx/text/text_run.rs
@@ -22,16 +22,16 @@ pub struct TextRun {
glyphs: Arc<~[Arc<GlyphStore>]>,
}
-pub struct SliceIterator<'self> {
- priv glyph_iter: VecIterator<'self, Arc<GlyphStore>>,
+pub struct SliceIterator<'a> {
+ priv glyph_iter: VecIterator<'a, Arc<GlyphStore>>,
priv range: Range,
priv offset: uint,
}
-impl<'self> Iterator<(&'self GlyphStore, uint, Range)> for SliceIterator<'self> {
+impl<'a> Iterator<(&'a GlyphStore, uint, Range)> for SliceIterator<'a> {
// inline(always) due to the inefficient rt failures messing up inline heuristics, I think.
#[inline(always)]
- fn next(&mut self) -> Option<(&'self GlyphStore, uint, Range)> {
+ fn next(&mut self) -> Option<(&'a GlyphStore, uint, Range)> {
loop {
let slice_glyphs = self.glyph_iter.next();
if slice_glyphs.is_none() {
@@ -52,13 +52,13 @@ impl<'self> Iterator<(&'self GlyphStore, uint, Range)> for SliceIterator<'self>
}
}
-pub struct LineIterator<'self> {
+pub struct LineIterator<'a> {
priv range: Range,
priv clump: Option<Range>,
- priv slices: SliceIterator<'self>,
+ priv slices: SliceIterator<'a>,
}
-impl<'self> Iterator<Range> for LineIterator<'self> {
+impl<'a> Iterator<Range> for LineIterator<'a> {
fn next(&mut self) -> Option<Range> {
// Loop until we hit whitespace and are in a clump.
loop {
@@ -96,7 +96,7 @@ impl<'self> Iterator<Range> for LineIterator<'self> {
}
}
-impl<'self> TextRun {
+impl<'a> TextRun {
pub fn new(font: &mut Font, text: ~str, decoration: text_decoration::T) -> TextRun {
let glyphs = TextRun::break_and_shape(font, text);
@@ -170,12 +170,12 @@ impl<'self> TextRun {
}
pub fn char_len(&self) -> uint {
- do self.glyphs.get().iter().fold(0u) |len, slice_glyphs| {
+ self.glyphs.get().iter().fold(0u, |len, slice_glyphs| {
len + slice_glyphs.get().char_len()
- }
+ })
}
- pub fn glyphs(&'self self) -> &'self ~[Arc<GlyphStore>] {
+ pub fn glyphs(&'a self) -> &'a ~[Arc<GlyphStore>] {
self.glyphs.get()
}
@@ -216,7 +216,7 @@ impl<'self> TextRun {
max_piece_width
}
- pub fn iter_slices_for_range(&'self self, range: &Range) -> SliceIterator<'self> {
+ pub fn iter_slices_for_range(&'a self, range: &Range) -> SliceIterator<'a> {
SliceIterator {
glyph_iter: self.glyphs.get().iter(),
range: *range,
@@ -224,7 +224,7 @@ impl<'self> TextRun {
}
}
- pub fn iter_natural_lines_for_range(&'self self, range: &Range) -> LineIterator<'self> {
+ pub fn iter_natural_lines_for_range(&'a self, range: &Range) -> LineIterator<'a> {
LineIterator {
range: *range,
clump: None,
diff --git a/src/components/gfx/text/util.rs b/src/components/gfx/text/util.rs
index 7b741e11a6f..924d6273ea0 100644
--- a/src/components/gfx/text/util.rs
+++ b/src/components/gfx/text/util.rs
@@ -24,7 +24,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
let mut out_str: ~str = ~"";
let out_whitespace = match mode {
CompressNone | DiscardNewline => {
- for ch in text.iter() {
+ for ch in text.chars() {
if is_discardable_char(ch, mode) {
// TODO: record skipped char
} else {
@@ -40,7 +40,7 @@ pub fn transform_text(text: &str, mode: CompressionMode, incoming_whitespace: bo
CompressWhitespace | CompressWhitespaceNewline => {
let mut in_whitespace: bool = incoming_whitespace;
- for ch in text.iter() {
+ for ch in text.chars() {
// TODO: discard newlines between CJK chars
let mut next_in_whitespace: bool = is_in_whitespace(ch, mode);
diff --git a/src/components/main/compositing/compositor.rs b/src/components/main/compositing/compositor.rs
index f2a86e9ad81..3790664b73f 100644
--- a/src/components/main/compositing/compositor.rs
+++ b/src/components/main/compositing/compositor.rs
@@ -34,13 +34,11 @@ use png;
use servo_msg::compositor_msg::{Epoch, IdleRenderState, LayerBufferSet, RenderState};
use servo_msg::constellation_msg::{ConstellationChan, NavigateMsg, ResizedWindowMsg, LoadUrlMsg, PipelineId};
use servo_msg::constellation_msg;
-use servo_util::time::{profile, ProfilerChan};
+use servo_util::time::{profile, ProfilerChan, Timer};
use servo_util::{time, url};
use std::comm::Port;
use std::num::Orderable;
use std::path::Path;
-use std::rt::io::timer::Timer;
-use std::vec;
pub struct IOCompositor {
@@ -157,11 +155,17 @@ impl IOCompositor {
self.constellation_chan.send(ResizedWindowMsg(self.window_size));
// Enter the main event loop.
- let mut tm = Timer::new().unwrap();
while !self.done {
// Check for new messages coming from the rendering task.
self.handle_message();
+ if (self.done) {
+ // We have exited the compositor and passing window
+ // messages to script may crash.
+ debug!("Exiting the compositor due to a request from script.");
+ break;
+ }
+
// Check for messages coming from the windowing system.
self.handle_window_message(self.window.recv());
@@ -171,7 +175,7 @@ impl IOCompositor {
self.composite();
}
- tm.sleep(10);
+ Timer::sleep(10);
// If a pinch-zoom happened recently, ask for tiles at the new resolution
if self.zoom_action && precise_time_s() - self.zoom_time > 0.3 {
@@ -189,62 +193,65 @@ impl IOCompositor {
// Drain compositor port, sometimes messages contain channels that are blocking
// another task from finishing (i.e. SetIds)
- while self.port.peek() { self.port.recv(); }
+ while self.port.try_recv().is_some() {}
}
fn handle_message(&mut self) {
- while self.port.peek() {
- match self.port.recv() {
- Exit => {
- self.done = true
- },
+ loop {
+ match self.port.try_recv() {
+ None => break,
- ChangeReadyState(ready_state) => {
+ Some(Exit(chan)) => {
+ self.done = true;
+ chan.send(());
+ }
+
+ Some(ChangeReadyState(ready_state)) => {
self.window.set_ready_state(ready_state);
}
- ChangeRenderState(render_state) => {
+ Some(ChangeRenderState(render_state)) => {
self.change_render_state(render_state);
}
- SetUnRenderedColor(_id, color) => {
+ Some(SetUnRenderedColor(_id, color)) => {
self.set_unrendered_color(_id, color);
}
- SetIds(frame_tree, response_chan, new_constellation_chan) => {
+ Some(SetIds(frame_tree, response_chan, new_constellation_chan)) => {
self.set_ids(frame_tree, response_chan, new_constellation_chan);
}
- GetGraphicsMetadata(chan) => {
+ Some(GetGraphicsMetadata(chan)) => {
chan.send(Some(azure_hl::current_graphics_metadata()));
}
- NewLayer(_id, new_size) => {
+ Some(NewLayer(_id, new_size)) => {
self.create_new_layer(_id, new_size);
}
- SetLayerPageSize(id, new_size, epoch) => {
+ Some(SetLayerPageSize(id, new_size, epoch)) => {
self.set_layer_page_size(id, new_size, epoch);
}
- SetLayerClipRect(id, new_rect) => {
+ Some(SetLayerClipRect(id, new_rect)) => {
self.set_layer_clip_rect(id, new_rect);
}
- DeleteLayer(id) => {
+ Some(DeleteLayer(id)) => {
self.delete_layer(id);
}
- Paint(id, new_layer_buffer_set, epoch) => {
+ Some(Paint(id, new_layer_buffer_set, epoch)) => {
self.paint(id, new_layer_buffer_set, epoch);
}
- InvalidateRect(id, rect) => {
+ Some(InvalidateRect(id, rect)) => {
self.invalidate_rect(id, rect);
}
- ScrollFragmentPoint(id, point) => {
+ Some(ScrollFragmentPoint(id, point)) => {
self.scroll_fragment_to_point(id, point);
}
}
@@ -601,7 +608,7 @@ impl IOCompositor {
}
fn composite(&mut self) {
- do profile(time::CompositingCategory, self.profiler_chan.clone()) {
+ profile(time::CompositingCategory, self.profiler_chan.clone(), || {
debug!("compositor: compositing");
// Adjust the layer dimensions as necessary to correspond to the size of the window.
self.scene.size = self.window.size();
@@ -616,7 +623,7 @@ impl IOCompositor {
None => {}
}
rendergl::render_scene(self.context, &self.scene);
- }
+ });
// Render to PNG. We must read from the back buffer (ie, before
// self.window.present()) as OpenGL ES 2 does not have glReadBuffer().
@@ -634,9 +641,10 @@ impl IOCompositor {
for y in range(0, height) {
let dst_start = y * stride;
let src_start = (height - y - 1) * stride;
- vec::bytes::copy_memory(pixels.mut_slice(dst_start, dst_start + stride),
- orig_pixels.slice(src_start, src_start + stride),
- stride);
+ unsafe {
+ pixels.mut_slice(dst_start, dst_start + stride)
+ .copy_memory(orig_pixels.slice(src_start, src_start + stride).slice_to(stride));
+ }
}
let img = png::Image {
width: width as u32,
diff --git a/src/components/main/compositing/compositor_layer.rs b/src/components/main/compositing/compositor_layer.rs
index 9e1784bba8d..a04638dd09e 100644
--- a/src/components/main/compositing/compositor_layer.rs
+++ b/src/components/main/compositing/compositor_layer.rs
@@ -22,7 +22,6 @@ use script::dom::event::{ClickEvent, MouseDownEvent, MouseUpEvent};
use script::script_task::SendEventMsg;
use servo_msg::compositor_msg::{LayerBuffer, LayerBufferSet, Epoch, Tile};
use servo_msg::constellation_msg::PipelineId;
-use std::cell::Cell;
use windowing::{MouseWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent};
use windowing::{MouseWindowMouseUpEvent};
use azure::azure_hl::Color;
@@ -141,7 +140,7 @@ impl CompositorLayer {
-> CompositorLayer {
let SendableFrameTree { pipeline, children } = frame_tree;
let mut layer = CompositorLayer::new(pipeline, None, tile_size, max_mem, cpu_painting);
- layer.children = (do children.move_iter().map |child| {
+ layer.children = (children.move_iter().map(|child| {
let SendableChildFrameTree { frame_tree, rect } = child;
let container = @mut ContainerLayer();
match rect {
@@ -165,7 +164,7 @@ impl CompositorLayer {
child: child_layer,
container: container,
}
- }).collect();
+ })).collect();
layer.set_occlusions();
layer
}
@@ -267,7 +266,7 @@ impl CompositorLayer {
let mut redisplay: bool;
{ // block here to prevent double mutable borrow of self
let quadtree = match self.quadtree {
- NoTree(*) => fail!("CompositorLayer: cannot get buffer request for {:?},
+ NoTree(..) => fail!("CompositorLayer: cannot get buffer request for {:?},
no quadtree initialized", self.pipeline.id),
Tree(ref mut quadtree) => quadtree,
};
@@ -327,7 +326,7 @@ impl CompositorLayer {
let old_rect = con.scissor;
con.scissor = Some(new_rect);
match self.quadtree {
- NoTree(*) => {} // Nothing to do
+ NoTree(..) => {} // Nothing to do
Tree(ref mut quadtree) => {
match old_rect {
Some(old_rect) => {
@@ -494,15 +493,15 @@ impl CompositorLayer {
// Delete old layer.
while current_layer_child.is_some() {
let trash = current_layer_child.unwrap();
- do current_layer_child.unwrap().with_common |common| {
+ current_layer_child.unwrap().with_common(|common| {
current_layer_child = common.next_sibling;
- }
+ });
self.root_layer.remove_child(trash);
}
// Add new tiles.
let quadtree = match self.quadtree {
- NoTree(*) => fail!("CompositorLayer: cannot build layer tree for {:?},
+ NoTree(..) => fail!("CompositorLayer: cannot build layer tree for {:?},
no quadtree initialized", self.pipeline.id),
Tree(ref mut quadtree) => quadtree,
};
@@ -544,9 +543,9 @@ impl CompositorLayer {
buffer.native_surface.bind_to_texture(graphics_context, texture, size);
// Move on to the next sibling.
- do current_layer_child.unwrap().with_common |common| {
+ current_layer_child.unwrap().with_common(|common| {
common.next_sibling
- }
+ })
}
Some(_) => fail!(~"found unexpected layer kind"),
};
@@ -584,29 +583,29 @@ impl CompositorLayer {
pub fn add_buffers(&mut self,
graphics_context: &NativeCompositingGraphicsContext,
pipeline_id: PipelineId,
- new_buffers: ~LayerBufferSet,
+ mut new_buffers: ~LayerBufferSet,
epoch: Epoch)
-> Option<~LayerBufferSet> {
- let cell = Cell::new(new_buffers);
if self.pipeline.id == pipeline_id {
if self.epoch != epoch {
debug!("compositor epoch mismatch: {:?} != {:?}, id: {:?}",
self.epoch,
epoch,
self.pipeline.id);
- self.pipeline.render_chan.send(UnusedBufferMsg(cell.take().buffers));
+ self.pipeline.render_chan.send(UnusedBufferMsg(new_buffers.buffers));
return None;
}
+
{
// Block here to prevent double mutable borrow of self.
let quadtree = match self.quadtree {
- NoTree(*) => fail!("CompositorLayer: cannot add buffers, no quadtree initialized"),
+ NoTree(..) => fail!("CompositorLayer: cannot add buffers, no quadtree initialized"),
Tree(ref mut quadtree) => quadtree,
};
let mut unused_tiles = ~[];
// move_rev_iter is more efficient
- for buffer in cell.take().buffers.move_rev_iter() {
+ for buffer in new_buffers.buffers.move_rev_iter() {
unused_tiles.push_all_move(quadtree.add_tile_pixel(buffer.screen_pos.origin.x,
buffer.screen_pos.origin.y,
buffer.resolution, buffer));
@@ -623,15 +622,15 @@ impl CompositorLayer {
for child_layer in self.children.mut_iter() {
match child_layer.child.add_buffers(graphics_context,
pipeline_id,
- cell.take(),
+ new_buffers,
epoch) {
None => return None,
- Some(buffers) => cell.put_back(buffers),
+ Some(buffers) => new_buffers = buffers,
}
}
// Not found. Give the caller the buffers back.
- Some(cell.take())
+ Some(new_buffers)
}
// Deletes a specified sublayer, including hidden children. Returns false if the layer is not found.
@@ -643,7 +642,7 @@ impl CompositorLayer {
Some(i) => {
let mut child = self.children.remove(i);
match self.quadtree {
- NoTree(*) => {} // Nothing to do
+ NoTree(..) => {} // Nothing to do
Tree(ref mut quadtree) => {
match child.container.scissor {
Some(rect) => {
@@ -670,7 +669,7 @@ impl CompositorLayer {
pub fn invalidate_rect(&mut self, pipeline_id: PipelineId, rect: Rect<f32>) -> bool {
if self.pipeline.id == pipeline_id {
let quadtree = match self.quadtree {
- NoTree(*) => return true, // Nothing to do
+ NoTree(..) => return true, // Nothing to do
Tree(ref mut quadtree) => quadtree,
};
quadtree.set_status_page(rect, Invalid, true);
@@ -681,32 +680,11 @@ impl CompositorLayer {
}
}
- // Adds a child.
- pub fn add_child(&mut self, pipeline: CompositionPipeline, page_size: Option<Size2D<f32>>, tile_size: uint,
- max_mem: Option<uint>, clipping_rect: Rect<f32>) {
- let container = @mut ContainerLayer();
- container.scissor = Some(clipping_rect);
- container.common.set_transform(identity().translate(clipping_rect.origin.x,
- clipping_rect.origin.y,
- 0.0));
- let child = ~CompositorLayer::new(pipeline,
- page_size,
- tile_size,
- max_mem,
- self.cpu_painting);
- container.add_child_start(ContainerLayerKind(child.root_layer));
- self.children.push(CompositorLayerChild {
- child: child,
- container: container,
- });
- self.set_occlusions();
- }
-
// Recursively sets occluded portions of quadtrees to Hidden, so that they do not ask for
// tile requests. If layers are moved, resized, or deleted, these portions may be updated.
fn set_occlusions(&mut self) {
let quadtree = match self.quadtree {
- NoTree(*) => return, // Cannot calculate occlusions
+ NoTree(..) => return, // Cannot calculate occlusions
Tree(ref mut quadtree) => quadtree,
};
for child in self.children.iter().filter(|x| !x.child.hidden) {
@@ -726,7 +704,7 @@ impl CompositorLayer {
/// reused.
fn clear(&mut self) {
match self.quadtree {
- NoTree(*) => {}
+ NoTree(..) => {}
Tree(ref mut quadtree) => {
let mut tiles = quadtree.collect_tiles();
@@ -759,7 +737,7 @@ impl CompositorLayer {
/// This is used during shutdown, when we know the render task is going away.
pub fn forget_all_tiles(&mut self) {
match self.quadtree {
- NoTree(*) => {}
+ NoTree(..) => {}
Tree(ref mut quadtree) => {
let tiles = quadtree.collect_tiles();
for tile in tiles.move_iter() {
diff --git a/src/components/main/compositing/compositor_task.rs b/src/components/main/compositing/compositor_task.rs
index 5cdf310ce59..6e01b3d64e3 100644
--- a/src/components/main/compositing/compositor_task.rs
+++ b/src/components/main/compositing/compositor_task.rs
@@ -19,7 +19,6 @@ use servo_msg::compositor_msg::{ScriptListener, Tile};
use servo_msg::constellation_msg::{ConstellationChan, PipelineId, ExitMsg};
use servo_util::time::ProfilerChan;
use std::comm::{Chan, SharedChan, Port};
-use std::comm;
use std::num::Orderable;
#[cfg(target_os="linux")]
@@ -54,7 +53,9 @@ impl ScriptListener for CompositorChan {
}
fn close(&self) {
- self.chan.send(Exit);
+ let (port, chan) = Chan::new();
+ self.chan.send(Exit(chan));
+ port.recv();
}
}
@@ -62,7 +63,7 @@ impl ScriptListener for CompositorChan {
/// Implementation of the abstract `RenderListener` interface.
impl RenderListener for CompositorChan {
fn get_graphics_metadata(&self) -> Option<NativeGraphicsMetadata> {
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
self.chan.send(GetGraphicsMetadata(chan));
port.recv()
}
@@ -99,10 +100,12 @@ impl RenderListener for CompositorChan {
}
impl CompositorChan {
- pub fn new(chan: Chan<Msg>) -> CompositorChan {
- CompositorChan {
- chan: SharedChan::new(chan),
- }
+ pub fn new() -> (Port<Msg>, CompositorChan) {
+ let (port, chan) = SharedChan::new();
+ let compositor_chan = CompositorChan {
+ chan: chan,
+ };
+ (port, compositor_chan)
}
pub fn send(&self, msg: Msg) {
@@ -113,7 +116,7 @@ impl CompositorChan {
/// Messages from the painting task and the constellation task to the compositor task.
pub enum Msg {
/// Requests that the compositor shut down.
- Exit,
+ Exit(Chan<()>),
/// Requests the compositor's graphics metadata. Graphics metadata is what the renderer needs
/// to create surfaces that the compositor can see. On Linux this is the X display; on Mac this
/// is the pixel format.
diff --git a/src/components/main/compositing/headless.rs b/src/components/main/compositing/headless.rs
index 4ec179c7e05..07a2e973868 100644
--- a/src/components/main/compositing/headless.rs
+++ b/src/components/main/compositing/headless.rs
@@ -38,7 +38,10 @@ impl NullCompositor {
fn handle_message(&self) {
loop {
match self.port.recv() {
- Exit => break,
+ Exit(chan) => {
+ chan.send(());
+ break
+ }
GetGraphicsMetadata(chan) => {
chan.send(None);
@@ -52,9 +55,9 @@ impl NullCompositor {
// we'll notice and think about whether it needs a response, like
// SetIds.
- NewLayer(*) | SetLayerPageSize(*) | SetLayerClipRect(*) | DeleteLayer(*) |
- Paint(*) | InvalidateRect(*) | ChangeReadyState(*) | ChangeRenderState(*)|
- ScrollFragmentPoint(*) | SetUnRenderedColor(*)
+ NewLayer(..) | SetLayerPageSize(..) | SetLayerClipRect(..) | DeleteLayer(..) |
+ Paint(..) | InvalidateRect(..) | ChangeReadyState(..) | ChangeRenderState(..)|
+ ScrollFragmentPoint(..) | SetUnRenderedColor(..)
=> ()
}
}
diff --git a/src/components/main/compositing/quadtree.rs b/src/components/main/compositing/quadtree.rs
index 5ad48c1988e..b874335db2b 100644
--- a/src/components/main/compositing/quadtree.rs
+++ b/src/components/main/compositing/quadtree.rs
@@ -18,8 +18,6 @@ use servo_msg::compositor_msg::Tile;
#[cfg(test)]
use layers::platform::surface::NativePaintingGraphicsContext;
-static HEADER: &'static str = "<!DOCTYPE html><html>";
-
/// Parent to all quadtree nodes. Stores variables needed at all levels. All method calls
/// at this level are in pixel coordinates.
pub struct Quadtree<T> {
@@ -101,20 +99,6 @@ impl<T: Tile> Quadtree<T> {
}
}
- /// Return the maximum allowed tile size
- pub fn get_tile_size(&self) -> uint {
- self.max_tile_size
- }
- /// Get a tile at a given pixel position and scale.
- pub fn get_tile_pixel<'r>(&'r self, x: uint, y: uint, scale: f32) -> &'r Option<T> {
- self.root.get_tile(x as f32 / scale, y as f32 / scale)
- }
-
- /// Get a tile at a given page position.
- pub fn get_tile_page<'r>(&'r self, x: f32, y: f32) -> &'r Option<T> {
- self.root.get_tile(x, y)
- }
-
/// Add a tile associated with a given pixel position and scale.
/// If the tile pushes the total memory over its maximum, tiles will be removed
/// until total memory is below the maximum again. These tiles are returned.
@@ -137,73 +121,17 @@ impl<T: Tile> Quadtree<T> {
tiles
}
- /// Add a tile associated with a given page position.
- /// If the tile pushes the total memory over its maximum, tiles will be removed
- /// until total memory is below the maximum again. These tiles are returned.
- pub fn add_tile_page(&mut self, x: f32, y: f32, scale: f32, tile: T) -> ~[T] {
- let (_, tiles) = self.root.add_tile(x, y, tile, self.max_tile_size as f32 / scale);
- let mut tiles = tiles;
- match self.max_mem {
- Some(max) => {
- while self.root.tile_mem > max {
- let r = self.root.remove_tile(x, y);
- match r {
- (Some(tile), _, _) => tiles.push(tile),
- _ => fail!("Quadtree: No valid tiles to remove"),
- }
- }
- }
- None => {} // Nothing to do
- }
- tiles
- }
-
- /// Get the tile rect in screen and page coordinates for a given pixel position.
- pub fn get_tile_rect_pixel(&mut self, x: uint, y: uint, scale: f32) -> BufferRequest {
- self.root.get_tile_rect(x as f32 / scale, y as f32 / scale,
- self.clip_size.width as f32,
- self.clip_size.height as f32,
- scale, self.max_tile_size as f32 / scale)
- }
-
- /// Get the tile rect in screen and page coordinates for a given page position.
- pub fn get_tile_rect_page(&mut self, x: f32, y: f32, scale: f32) -> BufferRequest {
- self.root.get_tile_rect(x, y,
- self.clip_size.width as f32,
- self.clip_size.height as f32,
- scale, self.max_tile_size as f32 / scale)
- }
-
/// Get all the tiles in the tree.
pub fn get_all_tiles<'r>(&'r self) -> ~[&'r T] {
self.root.get_all_tiles()
}
- /// Ask a tile to be deleted from the quadtree. This tries to delete a tile that is far from the
- /// given point in pixel coordinates.
- pub fn remove_tile_pixel(&mut self, x: uint, y: uint, scale: f32) -> T {
- let r = self.root.remove_tile(x as f32 / scale, y as f32 / scale);
- match r {
- (Some(tile), _, _) => tile,
- _ => fail!("Quadtree: No valid tiles to remove"),
- }
- }
-
- /// Ask a tile to be deleted from the quadtree. This tries to delete a tile that is far from the
- /// given point in page coordinates.
- pub fn remove_tile_page(&mut self, x: f32, y: f32) -> T {
- let r = self.root.remove_tile(x, y);
- match r {
- (Some(tile), _, _) => tile,
- _ => fail!("Quadtree: No valid tiles to remove"),
- }
- }
-
/// Given a window rect in pixel coordinates, this function returns a list of BufferRequests for tiles that
/// need to be rendered. It also returns a vector of tiles if the window needs to be redisplayed, i.e. if
/// no tiles need to be rendered, but the display tree needs to be rebuilt. This can occur when the
/// user zooms out and cached tiles need to be displayed on top of higher resolution tiles.
/// When this happens, higher resolution tiles will be removed from the quadtree.
+ #[cfg(test)]
pub fn get_tile_rects_pixel(&mut self, window: Rect<int>, scale: f32) -> (~[BufferRequest], ~[T]) {
let (ret, unused, _) = self.root.get_tile_rects(
Rect(Point2D(window.origin.x as f32 / scale, window.origin.y as f32 / scale),
@@ -245,6 +173,7 @@ impl<T: Tile> Quadtree<T> {
/// Resize the underlying quadtree without removing tiles already in place.
/// Might be useful later on, but resize() should be used for now.
/// TODO: return tiles after shrinking
+ #[cfg(test)]
pub fn bad_resize(&mut self, width: uint, height: uint) {
self.clip_size = Size2D(width, height);
let longer = width.max(&height);
@@ -301,11 +230,6 @@ impl<T: Tile> Quadtree<T> {
pub fn collect_tiles(&mut self) -> ~[T] {
self.root.collect_tiles()
}
-
- /// Generate html to visualize the tree. For debugging purposes only.
- pub fn get_html(&self) -> ~str {
- format!("{:s}<body>{:s}</body></html>", HEADER, self.root.get_html())
- }
}
impl<T: Tile> QuadtreeNode<T> {
@@ -336,20 +260,6 @@ impl<T: Tile> QuadtreeNode<T> {
}
}
- /// Get the lowest-level (highest resolution) tile associated with a given position in page coords.
- fn get_tile<'r> (&'r self, x: f32, y: f32) -> &'r Option<T> {
- if x >= self.origin.x + self.size || x < self.origin.x
- || y >= self.origin.y + self.size || y < self.origin.y {
- fail!("Quadtree: Tried to get a tile outside of range");
- }
-
- let index = self.get_quadrant(x, y) as int;
- match self.quadrants[index] {
- None => &'r self.tile,
- Some(ref child) => child.get_tile(x, y),
- }
- }
-
/// Get all tiles in the tree, parents first.
fn get_all_tiles<'r>(&'r self) -> ~[&'r T] {
let mut ret = ~[];
@@ -602,7 +512,7 @@ impl<T: Tile> QuadtreeNode<T> {
let w_br_quad = self.get_quadrant(w_x + w_width, w_y + w_height);
// Figure out which quadrants the window is in
- let builder = |push: &fn(Quadrant)| {
+ let builder = |push: |Quadrant|| {
match (w_tl_quad, w_br_quad) {
(tl, br) if tl as int == br as int => {
push(tl);
@@ -734,44 +644,6 @@ impl<T: Tile> QuadtreeNode<T> {
}
}
}
-
- /// Generate html to visualize the tree.
- /// This is really inefficient, but it's for testing only.
- fn get_html(&self) -> ~str {
- let mut ret = ~"";
- match self.tile {
- Some(ref tile) => {
- ret = format!("{:s}{:?}", ret, tile);
- }
- None => {
- ret = format!("{:s}NO TILE", ret);
- }
- }
- match self.quadrants {
- [None, None, None, None] => {}
- _ => {
- ret = format!("{:s}<table border=1><tr>", ret);
- // FIXME: This should be inline, but currently won't compile
- let quads = [TL, TR, BL, BR];
- for quad in quads.iter() {
- match self.quadrants[*quad as int] {
- Some(ref child) => {
- ret = format!("{:s}<td>{:s}</td>", ret, child.get_html());
- }
- None => {
- ret = format!("{:s}<td>EMPTY CHILD</td>", ret);
- }
- }
- match *quad {
- TR => ret = format!("{:s}</tr><tr>", ret),
- _ => {}
- }
- }
- ret = format!("{:s}</table>\n", ret);
- }
- }
- return ret;
- }
}
#[test]
diff --git a/src/components/main/constellation.rs b/src/components/main/constellation.rs
index 8408063890e..66303f41545 100644
--- a/src/components/main/constellation.rs
+++ b/src/components/main/constellation.rs
@@ -20,10 +20,7 @@ use servo_net::resource_task::ResourceTask;
use servo_net::resource_task;
use servo_util::time::ProfilerChan;
use servo_util::url::make_url;
-use std::comm::Port;
-use std::comm;
use std::hashmap::{HashMap, HashSet};
-use std::task::spawn_with;
use std::util::replace;
/// Maintains the pipelines and navigation context and grants permission to composite
@@ -53,9 +50,9 @@ struct FrameTree {
// Need to clone the FrameTrees, but _not_ the Pipelines
impl Clone for FrameTree {
fn clone(&self) -> FrameTree {
- let mut children = do self.children.iter().map |child_frame_tree| {
+ let mut children = self.children.iter().map(|child_frame_tree| {
child_frame_tree.clone()
- };
+ });
FrameTree {
pipeline: self.pipeline,
parent: self.parent.clone(),
@@ -90,41 +87,46 @@ pub struct SendableChildFrameTree {
rect: Option<Rect<f32>>,
}
-impl SendableFrameTree {
- fn contains(&self, id: PipelineId) -> bool {
- self.pipeline.id == id ||
- do self.children.iter().any |&SendableChildFrameTree { frame_tree: ref frame_tree, _ }| {
- frame_tree.contains(id)
- }
- }
+// impl SendableFrameTree {
+// fn contains(&self, id: PipelineId) -> bool {
+// self.pipeline.id == id ||
+// self.children.iter().any(|&SendableChildFrameTree { frame_tree: ref frame_tree, .. }| {
+// frame_tree.contains(id)
+// })
+// }
+// }
+
+enum ReplaceResult {
+ ReplacedNode(@mut FrameTree),
+ OriginalNode(@mut FrameTree),
}
impl FrameTree {
fn contains(@mut self, id: PipelineId) -> bool {
- do self.iter().any |frame_tree| {
+ self.iter().any(|frame_tree| {
id == frame_tree.pipeline.id
- }
+ })
}
/// Returns the frame tree whose key is id
fn find(@mut self, id: PipelineId) -> Option<@mut FrameTree> {
- do self.iter().find |frame_tree| {
+ self.iter().find(|frame_tree| {
id == frame_tree.pipeline.id
- }
+ })
}
/// Replaces a node of the frame tree in place. Returns the node that was removed or the original node
/// if the node to replace could not be found.
- fn replace_child(@mut self, id: PipelineId, new_child: @mut FrameTree) -> Either<@mut FrameTree, @mut FrameTree> {
+ fn replace_child(@mut self, id: PipelineId, new_child: @mut FrameTree) -> ReplaceResult {
for frame_tree in self.iter() {
let mut child = frame_tree.children.mut_iter()
.find(|child| child.frame_tree.pipeline.id == id);
for child in child.mut_iter() {
new_child.parent = child.frame_tree.parent;
- return Left(replace(&mut child.frame_tree, new_child));
+ return ReplacedNode(replace(&mut child.frame_tree, new_child));
}
}
- Right(new_child)
+ OriginalNode(new_child)
}
fn to_sendable(&self) -> SendableFrameTree {
@@ -162,7 +164,7 @@ impl Iterator<@mut FrameTree> for FrameTreeIterator {
fn next(&mut self) -> Option<@mut FrameTree> {
if !self.stack.is_empty() {
let next = self.stack.pop();
- for &ChildFrameTree { frame_tree, _ } in next.children.rev_iter() {
+ for &ChildFrameTree { frame_tree, .. } in next.children.rev_iter() {
self.stack.push(frame_tree);
}
Some(next)
@@ -223,15 +225,15 @@ impl NavigationContext {
/// Returns the frame trees whose keys are pipeline_id.
pub fn find_all(&mut self, pipeline_id: PipelineId) -> ~[@mut FrameTree] {
- let from_current = do self.current.iter().filter_map |frame_tree| {
+ let from_current = self.current.iter().filter_map(|frame_tree| {
frame_tree.find(pipeline_id)
- };
- let from_next = do self.next.iter().filter_map |frame_tree| {
+ });
+ let from_next = self.next.iter().filter_map(|frame_tree| {
frame_tree.find(pipeline_id)
- };
- let from_prev = do self.previous.iter().filter_map |frame_tree| {
+ });
+ let from_prev = self.previous.iter().filter_map(|frame_tree| {
frame_tree.find(pipeline_id)
- };
+ });
from_prev.chain(from_current).chain(from_next).collect()
}
@@ -241,36 +243,25 @@ impl NavigationContext {
let from_prev = self.previous.iter();
let mut all_contained = from_prev.chain(from_current).chain(from_next);
- do all_contained.any |frame_tree| {
+ all_contained.any(|frame_tree| {
frame_tree.contains(pipeline_id)
- }
+ })
}
}
impl Constellation {
- pub fn start(constellation_port: Port<Msg>,
- constellation_chan: ConstellationChan,
- compositor_chan: CompositorChan,
+ pub fn start(compositor_chan: CompositorChan,
opts: &Opts,
resource_task: ResourceTask,
image_cache_task: ImageCacheTask,
- profiler_chan: ProfilerChan) {
- do spawn_with((constellation_port,
- constellation_chan.clone(),
- compositor_chan,
- resource_task,
- image_cache_task,
- profiler_chan,
- opts.clone()))
- |(constellation_port,
- constellation_chan,
- compositor_chan,
- resource_task,
- image_cache_task,
- profiler_chan,
- opts)| {
+ profiler_chan: ProfilerChan)
+ -> ConstellationChan {
+ let (constellation_port, constellation_chan) = ConstellationChan::new();
+ let constellation_chan_clone = constellation_chan.clone();
+ let opts_clone = opts.clone();
+ spawn(proc() {
let mut constellation = Constellation {
- chan: constellation_chan,
+ chan: constellation_chan_clone,
request_port: constellation_port,
compositor_chan: compositor_chan,
resource_task: resource_task,
@@ -282,10 +273,11 @@ impl Constellation {
pending_sizes: HashMap::new(),
profiler_chan: profiler_chan,
window_size: Size2D(500u, 500u),
- opts: opts
+ opts: opts_clone,
};
constellation.run();
- }
+ });
+ constellation_chan
}
fn run(&mut self) {
@@ -313,9 +305,9 @@ impl Constellation {
/// Returns both the navigation context and pending frame trees whose keys are pipeline_id.
pub fn find_all(&mut self, pipeline_id: PipelineId) -> ~[@mut FrameTree] {
let matching_navi_frames = self.navigation_context.find_all(pipeline_id);
- let matching_pending_frames = do self.pending_frames.iter().filter_map |frame_change| {
+ let matching_pending_frames = self.pending_frames.iter().filter_map(|frame_change| {
frame_change.after.find(pipeline_id)
- };
+ });
matching_navi_frames.move_iter().chain(matching_pending_frames).collect()
}
@@ -323,6 +315,7 @@ impl Constellation {
fn handle_request(&mut self, request: Msg) -> bool {
match request {
ExitMsg(sender) => {
+ debug!("constellation exiting");
self.handle_exit(sender);
return false;
}
@@ -499,9 +492,9 @@ impl Constellation {
// and add the new pipeline to their sub frames.
let frame_trees: ~[@mut FrameTree] = {
let matching_navi_frames = self.navigation_context.find_all(source_pipeline_id);
- let matching_pending_frames = do self.pending_frames.iter().filter_map |frame_change| {
+ let matching_pending_frames = self.pending_frames.iter().filter_map(|frame_change| {
frame_change.after.find(source_pipeline_id)
- };
+ });
matching_navi_frames.move_iter().chain(matching_pending_frames).collect()
};
@@ -681,9 +674,9 @@ impl Constellation {
// Find the pending frame change whose new pipeline id is pipeline_id.
// If it is not found, it simply means that this pipeline will not receive
// permission to paint.
- let pending_index = do self.pending_frames.iter().rposition |frame_change| {
+ let pending_index = self.pending_frames.iter().rposition(|frame_change| {
frame_change.after.pipeline.id == pipeline_id
- };
+ });
for &pending_index in pending_index.iter() {
let frame_change = self.pending_frames.swap_remove(pending_index);
let to_add = frame_change.after;
@@ -742,9 +735,9 @@ impl Constellation {
/// Called when the window is resized.
fn handle_resized_window_msg(&mut self, new_size: Size2D<uint>) {
let mut already_seen = HashSet::new();
- for &@FrameTree { pipeline: pipeline, _ } in self.current_frame().iter() {
+ for &@FrameTree { pipeline: pipeline, .. } in self.current_frame().iter() {
debug!("constellation sending resize message to active frame");
- pipeline.script_chan.send(ResizeMsg(pipeline.id, new_size));
+ pipeline.script_chan.try_send(ResizeMsg(pipeline.id, new_size));
already_seen.insert(pipeline.id);
}
for frame_tree in self.navigation_context.previous.iter()
@@ -752,7 +745,7 @@ impl Constellation {
let pipeline = &frame_tree.pipeline;
if !already_seen.contains(&pipeline.id) {
debug!("constellation sending resize message to inactive frame");
- pipeline.script_chan.send(ResizeInactiveMsg(pipeline.id, new_size));
+ pipeline.script_chan.try_send(ResizeInactiveMsg(pipeline.id, new_size));
already_seen.insert(pipeline.id);
}
}
@@ -774,7 +767,7 @@ impl Constellation {
fn close_pipelines(&mut self, frame_tree: @mut FrameTree) {
// TODO(tkuehn): should only exit once per unique script task,
// and then that script task will handle sub-exits
- for @FrameTree { pipeline, _ } in frame_tree.iter() {
+ for @FrameTree { pipeline, .. } in frame_tree.iter() {
pipeline.exit();
self.pipelines.remove(&pipeline.id);
}
@@ -809,9 +802,9 @@ impl Constellation {
}
fn set_ids(&self, frame_tree: @mut FrameTree) {
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
self.compositor_chan.send(SetIds(frame_tree.to_sendable(), chan, self.chan.clone()));
- match port.try_recv() {
+ match port.recv_opt() {
Some(()) => {
for frame in frame_tree.iter() {
frame.pipeline.grant_paint_permission();
diff --git a/src/components/main/css/matching.rs b/src/components/main/css/matching.rs
index cace6ffd5f1..f25f92874c1 100644
--- a/src/components/main/css/matching.rs
+++ b/src/components/main/css/matching.rs
@@ -11,11 +11,8 @@ use layout::wrapper::LayoutNode;
use extra::arc::{Arc, RWArc};
use std::cast;
-use std::cell::Cell;
-use std::comm;
use std::libc::uintptr_t;
use std::rt;
-use std::task;
use std::vec;
use style::{TNode, Stylist, cascade};
use style::{Before, After};
@@ -27,22 +24,23 @@ pub trait MatchMethods {
fn cascade_subtree(&self, parent: Option<LayoutNode>);
}
-impl<'self> MatchMethods for LayoutNode<'self> {
+impl<'ln> MatchMethods for LayoutNode<'ln> {
fn match_node(&self, stylist: &Stylist) {
- let style_attribute = do self.with_element |element| {
+ let style_attribute = self.with_element(|element| {
match *element.style_attribute() {
None => None,
Some(ref style_attribute) => Some(style_attribute)
}
- };
+ });
- match *self.mutate_layout_data().ptr {
+ let mut layout_data_ref = self.mutate_layout_data();
+ match *layout_data_ref.get() {
Some(ref mut layout_data) => {
- layout_data.applicable_declarations = stylist.get_applicable_declarations(
+ layout_data.data.applicable_declarations = stylist.get_applicable_declarations(
self, style_attribute, None);
- layout_data.before_applicable_declarations = stylist.get_applicable_declarations(
+ layout_data.data.before_applicable_declarations = stylist.get_applicable_declarations(
self, None, Some(Before));
- layout_data.after_applicable_declarations = stylist.get_applicable_declarations(
+ layout_data.data.after_applicable_declarations = stylist.get_applicable_declarations(
self, None, Some(After));
}
None => fail!("no layout data")
@@ -60,8 +58,7 @@ impl<'self> MatchMethods for LayoutNode<'self> {
}
}
- let (port, chan) = comm::stream();
- let chan = comm::SharedChan::new(chan);
+ let (port, chan) = SharedChan::new();
let mut num_spawned = 0;
for nodes in nodes_per_task.move_iter() {
@@ -77,20 +74,20 @@ impl<'self> MatchMethods for LayoutNode<'self> {
cast::transmute(nodes)
};
- do task::spawn_with((evil, stylist)) |(evil, stylist)| {
+ let evil = Some(evil);
+ spawn(proc() {
+ let mut evil = evil;
let nodes: ~[LayoutNode] = unsafe {
- cast::transmute(evil)
+ cast::transmute(evil.take_unwrap())
};
- let nodes = Cell::new(nodes);
- do stylist.read |stylist| {
- let nodes = nodes.take();
+ stylist.read(|stylist| {
for node in nodes.iter() {
node.match_node(stylist);
}
- }
+ });
chan.send(());
- }
+ });
num_spawned += 1;
}
}
@@ -100,9 +97,6 @@ impl<'self> MatchMethods for LayoutNode<'self> {
}
fn cascade_subtree(&self, parent: Option<LayoutNode>) {
- let layout_data = unsafe {
- self.borrow_layout_data_unchecked().as_ref().unwrap()
- };
macro_rules! cascade_node(
($applicable_declarations: ident, $style: ident) => {{
let parent_style = match parent {
@@ -110,18 +104,21 @@ impl<'self> MatchMethods for LayoutNode<'self> {
None => None
};
- let computed_values = Arc::new(cascade(
- layout_data.$applicable_declarations,
- parent_style.map(|parent_style| parent_style.get())));
+ let computed_values = {
+ let layout_data_ref = self.borrow_layout_data();
+ let layout_data = layout_data_ref.get().as_ref().unwrap();
+ Arc::new(cascade(layout_data.data.$applicable_declarations, parent_style.map(|parent_style| parent_style.get())))
+ };
- match *self.mutate_layout_data().ptr {
+ let mut layout_data_ref = self.mutate_layout_data();
+ match *layout_data_ref.get() {
None => fail!("no layout data"),
Some(ref mut layout_data) => {
- let style = &mut layout_data.$style;
+ let style = &mut layout_data.data.$style;
match *style {
None => (),
Some(ref previous_style) => {
- layout_data.restyle_damage = Some(incremental::compute_damage(
+ layout_data.data.restyle_damage = Some(incremental::compute_damage(
previous_style.get(), computed_values.get()).to_int())
}
}
@@ -131,14 +128,22 @@ impl<'self> MatchMethods for LayoutNode<'self> {
}}
);
- unsafe {
- if self.borrow_layout_data_unchecked().as_ref().unwrap().before_applicable_declarations.len() > 0 {
+ {
+ let before_len = {
+ let layout_data_ref = self.borrow_layout_data();
+ layout_data_ref.get().as_ref().unwrap().data.before_applicable_declarations.len()
+ };
+ if before_len > 0 {
cascade_node!(before_applicable_declarations, before_style);
}
}
cascade_node!(applicable_declarations, style);
- unsafe {
- if self.borrow_layout_data_unchecked().as_ref().unwrap().after_applicable_declarations.len() > 0 {
+ {
+ let after_len = {
+ let layout_data_ref = self.borrow_layout_data();
+ layout_data_ref.get().as_ref().unwrap().data.after_applicable_declarations.len()
+ };
+ if after_len > 0 {
cascade_node!(after_applicable_declarations, after_style);
}
}
diff --git a/src/components/main/css/node_style.rs b/src/components/main/css/node_style.rs
index 6810d9187ea..f9b561425bb 100644
--- a/src/components/main/css/node_style.rs
+++ b/src/components/main/css/node_style.rs
@@ -17,7 +17,7 @@ pub trait StyledNode {
fn restyle_damage(&self) -> RestyleDamage;
}
-impl<'self> StyledNode for LayoutNode<'self> {
+impl<'ln> StyledNode for LayoutNode<'ln> {
#[inline]
fn style<'a>(&'a self) -> &'a Arc<ComputedValues> {
self.get_css_select_results()
diff --git a/src/components/main/css/node_util.rs b/src/components/main/css/node_util.rs
index a84fb5cc061..3a2b83ccab3 100644
--- a/src/components/main/css/node_util.rs
+++ b/src/components/main/css/node_util.rs
@@ -18,7 +18,7 @@ pub trait NodeUtil {
fn set_restyle_damage(self, damage: RestyleDamage);
}
-impl<'self> NodeUtil for LayoutNode<'self> {
+impl<'ln> NodeUtil for LayoutNode<'ln> {
/**
* Provides the computed style for the given node. If CSS selector
* Returns the style results for the given node. If CSS selector
@@ -27,18 +27,15 @@ impl<'self> NodeUtil for LayoutNode<'self> {
#[inline]
fn get_css_select_results<'a>(&'a self) -> &'a Arc<ComputedValues> {
unsafe {
- cast::transmute_region(self.borrow_layout_data_unchecked()
- .as_ref()
- .unwrap()
- .style
- .as_ref()
- .unwrap())
+ let layout_data_ref = self.borrow_layout_data();
+ cast::transmute_region(layout_data_ref.get().as_ref().unwrap().data.style.as_ref().unwrap())
}
}
/// Does this node have a computed style yet?
fn have_css_select_results(self) -> bool {
- self.borrow_layout_data().ptr.as_ref().unwrap().style.is_some()
+ let layout_data_ref = self.borrow_layout_data();
+ layout_data_ref.get().get_ref().data.style.is_some()
}
/// Get the description of how to account for recent style changes.
@@ -52,10 +49,11 @@ impl<'self> NodeUtil for LayoutNode<'self> {
RestyleDamage::none()
};
- self.borrow_layout_data()
- .ptr
- .as_ref()
- .unwrap()
+ let layout_data_ref = self.borrow_layout_data();
+ layout_data_ref
+ .get()
+ .get_ref()
+ .data
.restyle_damage
.map(|x| RestyleDamage::from_int(x))
.unwrap_or(default)
@@ -63,10 +61,10 @@ impl<'self> NodeUtil for LayoutNode<'self> {
/// Set the restyle damage field.
fn set_restyle_damage(self, damage: RestyleDamage) {
- match *self.mutate_layout_data().ptr {
- Some(ref mut data) => data.restyle_damage = Some(damage.to_int()),
+ let mut layout_data_ref = self.mutate_layout_data();
+ match *layout_data_ref.get() {
+ Some(ref mut layout_data) => layout_data.data.restyle_damage = Some(damage.to_int()),
_ => fail!("no layout data for this node"),
}
}
}
-
diff --git a/src/components/main/layout/block.rs b/src/components/main/layout/block.rs
index ff85f4e14ad..276e6a38e1d 100644
--- a/src/components/main/layout/block.rs
+++ b/src/components/main/layout/block.rs
@@ -4,7 +4,7 @@
//! CSS block formatting contexts.
-use layout::box::Box;
+use layout::box_::Box;
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::flow::{BlockFlowClass, FlowClass, Flow, FlowData, ImmutableFlowUtils};
@@ -12,7 +12,7 @@ use layout::flow;
use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified};
use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType};
-use std::cell::Cell;
+use std::cell::RefCell;
use geom::{Point2D, Rect, SideOffsets2D};
use gfx::display_list::DisplayList;
use servo_util::geometry::Au;
@@ -53,7 +53,7 @@ pub struct BlockFlow {
base: FlowData,
/// The associated box.
- box: Option<Box>,
+ box_: Option<Box>,
/// Whether this block flow is the root flow.
is_root: bool,
@@ -66,25 +66,25 @@ impl BlockFlow {
pub fn new(base: FlowData) -> BlockFlow {
BlockFlow {
base: base,
- box: None,
+ box_: None,
is_root: false,
float: None
}
}
- pub fn from_box(base: FlowData, box: Box) -> BlockFlow {
+ pub fn from_box(base: FlowData, box_: Box) -> BlockFlow {
BlockFlow {
base: base,
- box: Some(box),
+ box_: Some(box_),
is_root: false,
float: None
}
}
- pub fn float_from_box(base: FlowData, float_type: FloatType, box: Box) -> BlockFlow {
+ pub fn float_from_box(base: FlowData, float_type: FloatType, box_: Box) -> BlockFlow {
BlockFlow {
base: base,
- box: Some(box),
+ box_: Some(box_),
is_root: false,
float: Some(~FloatedBlockInfo::new(float_type))
}
@@ -93,7 +93,7 @@ impl BlockFlow {
pub fn new_root(base: FlowData) -> BlockFlow {
BlockFlow {
base: base,
- box: None,
+ box_: None,
is_root: true,
float: None
}
@@ -102,7 +102,7 @@ impl BlockFlow {
pub fn new_float(base: FlowData, float_type: FloatType) -> BlockFlow {
BlockFlow {
base: base,
- box: None,
+ box_: None,
is_root: false,
float: Some(~FloatedBlockInfo::new(float_type))
}
@@ -113,10 +113,10 @@ impl BlockFlow {
}
pub fn teardown(&mut self) {
- for box in self.box.iter() {
- box.teardown();
+ for box_ in self.box_.iter() {
+ box_.teardown();
}
- self.box = None;
+ self.box_ = None;
self.float = None;
}
@@ -172,9 +172,9 @@ impl BlockFlow {
(width_Au, left_margin_Au, right_margin_Au)
}
- fn compute_block_margins(&self, box: &Box, remaining_width: Au, available_width: Au)
+ fn compute_block_margins(&self, box_: &Box, remaining_width: Au, available_width: Au)
-> (Au, Au, Au) {
- let style = box.style();
+ let style = box_.style();
let (width, maybe_margin_left, maybe_margin_right) =
(MaybeAuto::from_style(style.Box.width, remaining_width),
@@ -215,8 +215,8 @@ impl BlockFlow {
return (width, margin_left, margin_right);
}
- fn compute_float_margins(&self, box: &Box, remaining_width: Au) -> (Au, Au, Au) {
- let style = box.style();
+ fn compute_float_margins(&self, box_: &Box, remaining_width: Au) -> (Au, Au, Au) {
+ let style = box_.style();
let margin_left = MaybeAuto::from_style(style.Margin.margin_left,
remaining_width).specified_or_zero();
let margin_right = MaybeAuto::from_style(style.Margin.margin_right,
@@ -240,20 +240,20 @@ impl BlockFlow {
let mut left_offset = Au::new(0);
let mut float_ctx = Invalid;
- for box in self.box.iter() {
- clearance = match box.clear() {
+ for box_ in self.box_.iter() {
+ clearance = match box_.clear() {
None => Au::new(0),
Some(clear) => {
self.base.floats_in.clearance(clear)
}
};
- top_offset = clearance + box.margin.get().top + box.border.get().top +
- box.padding.get().top;
+ top_offset = clearance + box_.margin.get().top + box_.border.get().top +
+ box_.padding.get().top;
cur_y = cur_y + top_offset;
- bottom_offset = box.margin.get().bottom + box.border.get().bottom +
- box.padding.get().bottom;
- left_offset = box.offset();
+ bottom_offset = box_.margin.get().bottom + box_.border.get().bottom +
+ box_.padding.get().bottom;
+ left_offset = box_.offset();
}
if inorder {
@@ -279,17 +279,17 @@ impl BlockFlow {
let mut top_margin_collapsible = false;
let mut bottom_margin_collapsible = false;
let mut first_in_flow = true;
- for box in self.box.iter() {
- if !self.is_root && box.border.get().top == Au(0) && box.padding.get().top == Au(0) {
- collapsible = box.margin.get().top;
+ for box_ in self.box_.iter() {
+ if !self.is_root && box_.border.get().top == Au(0) && box_.padding.get().top == Au(0) {
+ collapsible = box_.margin.get().top;
top_margin_collapsible = true;
}
- if !self.is_root && box.border.get().bottom == Au(0) &&
- box.padding.get().bottom == Au(0) {
+ if !self.is_root && box_.border.get().bottom == Au(0) &&
+ box_.padding.get().bottom == Au(0) {
bottom_margin_collapsible = true;
}
- margin_top = box.margin.get().top;
- margin_bottom = box.margin.get().bottom;
+ margin_top = box_.margin.get().top;
+ margin_bottom = box_.margin.get().bottom;
}
for kid in self.base.child_iter() {
@@ -332,8 +332,8 @@ impl BlockFlow {
cur_y - top_offset - collapsing
};
- for box in self.box.iter() {
- let style = box.style();
+ for box_ in self.box_.iter() {
+ let style = box_.style();
// At this point, `height` is the height of the containing block, so passing `height`
// as the second argument here effectively makes percentages relative to the containing
@@ -345,9 +345,9 @@ impl BlockFlow {
}
let mut noncontent_height = Au::new(0);
- for box in self.box.iter() {
- let mut position = box.position.get();
- let mut margin = box.margin.get();
+ for box_ in self.box_.iter() {
+ let mut position = box_.position.get();
+ let mut margin = box_.margin.get();
// The associated box is the border box of this flow.
margin.top = margin_top;
@@ -355,14 +355,14 @@ impl BlockFlow {
position.origin.y = clearance + margin.top;
- noncontent_height = box.padding.get().top + box.padding.get().bottom +
- box.border.get().top + box.border.get().bottom;
+ noncontent_height = box_.padding.get().top + box_.padding.get().bottom +
+ box_.border.get().top + box_.border.get().bottom;
position.size.height = height + noncontent_height;
noncontent_height = noncontent_height + clearance + margin.top + margin.bottom;
- box.position.set(position);
- box.margin.set(margin);
+ box_.position.set(position);
+ box_.margin.set(margin);
}
self.base.position.size.height = height + noncontent_height;
@@ -384,19 +384,19 @@ impl BlockFlow {
let mut full_noncontent_width = Au(0);
let mut margin_height = Au(0);
- for box in self.box.iter() {
- height = box.position.get().size.height;
- clearance = match box.clear() {
+ for box_ in self.box_.iter() {
+ height = box_.position.get().size.height;
+ clearance = match box_.clear() {
None => Au(0),
Some(clear) => self.base.floats_in.clearance(clear),
};
- let noncontent_width = box.padding.get().left + box.padding.get().right +
- box.border.get().left + box.border.get().right;
+ let noncontent_width = box_.padding.get().left + box_.padding.get().right +
+ box_.border.get().left + box_.border.get().right;
- full_noncontent_width = noncontent_width + box.margin.get().left +
- box.margin.get().right;
- margin_height = box.margin.get().top + box.margin.get().bottom;
+ full_noncontent_width = noncontent_width + box_.margin.get().left +
+ box_.margin.get().right;
+ margin_height = box_.margin.get().top + box_.margin.get().bottom;
}
let info = PlacementInfo {
@@ -427,8 +427,8 @@ impl BlockFlow {
let mut cur_y = Au(0);
let mut top_offset = Au(0);
- for box in self.box.iter() {
- top_offset = box.margin.get().top + box.border.get().top + box.padding.get().top;
+ for box_ in self.box_.iter() {
+ top_offset = box_.margin.get().top + box_.border.get().top + box_.padding.get().top;
cur_y = cur_y + top_offset;
}
@@ -441,31 +441,31 @@ impl BlockFlow {
let mut height = cur_y - top_offset;
let mut noncontent_height;
- let box = self.box.as_ref().unwrap();
- let mut position = box.position.get();
+ let box_ = self.box_.as_ref().unwrap();
+ let mut position = box_.position.get();
// The associated box is the border box of this flow.
- position.origin.y = box.margin.get().top;
+ position.origin.y = box_.margin.get().top;
- noncontent_height = box.padding.get().top + box.padding.get().bottom +
- box.border.get().top + box.border.get().bottom;
+ noncontent_height = box_.padding.get().top + box_.padding.get().bottom +
+ box_.border.get().top + box_.border.get().bottom;
//TODO(eatkinson): compute heights properly using the 'height' property.
- let height_prop = MaybeAuto::from_style(box.style().Box.height,
+ let height_prop = MaybeAuto::from_style(box_.style().Box.height,
Au::new(0)).specified_or_zero();
height = geometry::max(height, height_prop) + noncontent_height;
debug!("assign_height_float -- height: {}", height);
position.size.height = height;
- box.position.set(position);
+ box_.position.set(position);
}
pub fn build_display_list_block<E:ExtraDisplayListData>(
&mut self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
- list: &Cell<DisplayList<E>>)
+ list: &RefCell<DisplayList<E>>)
-> bool {
if self.is_float() {
return self.build_display_list_float(builder, dirty, list);
@@ -479,8 +479,8 @@ impl BlockFlow {
debug!("build_display_list_block: adding display element");
// add box that starts block context
- for box in self.box.iter() {
- box.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list)
+ for box_ in self.box_.iter() {
+ box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list)
}
// TODO: handle any out-of-flow elements
@@ -497,7 +497,7 @@ impl BlockFlow {
&mut self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
- list: &Cell<DisplayList<E>>)
+ list: &RefCell<DisplayList<E>>)
-> bool {
let abs_rect = Rect(self.base.abs_position, self.base.position.size);
if !abs_rect.intersects(dirty) {
@@ -506,8 +506,8 @@ impl BlockFlow {
let offset = self.base.abs_position + self.float.get_ref().rel_pos;
// add box that starts block context
- for box in self.box.iter() {
- box.build_display_list(builder, dirty, offset, (&*self) as &Flow, list)
+ for box_ in self.box_.iter() {
+ box_.build_display_list(builder, dirty, offset, (&*self) as &Flow, list)
}
@@ -564,13 +564,13 @@ impl Flow for BlockFlow {
/* if not an anonymous block context, add in block box's widths.
these widths will not include child elements, just padding etc. */
- for box in self.box.iter() {
+ for box_ in self.box_.iter() {
{
// Can compute border width here since it doesn't depend on anything.
- box.compute_borders(box.style())
+ box_.compute_borders(box_.style())
}
- let (this_minimum_width, this_preferred_width) = box.minimum_and_preferred_widths();
+ let (this_minimum_width, this_preferred_width) = box_.minimum_and_preferred_widths();
min_width = min_width + this_minimum_width;
pref_width = pref_width + this_preferred_width;
}
@@ -612,17 +612,17 @@ impl Flow for BlockFlow {
self.base.flags.set_inorder(false);
}
- for box in self.box.iter() {
- let style = box.style();
+ for box_ in self.box_.iter() {
+ let style = box_.style();
// The text alignment of a block flow is the text alignment of its box's style.
self.base.flags.set_text_align(style.Text.text_align);
// Can compute padding here since we know containing block width.
- box.compute_padding(style, remaining_width);
+ box_.compute_padding(style, remaining_width);
// Margins are 0 right now so base.noncontent_width() is just borders + padding.
- let available_width = remaining_width - box.noncontent_width();
+ let available_width = remaining_width - box_.noncontent_width();
// Top and bottom margins for blocks are 0 if auto.
let margin_top = MaybeAuto::from_style(style.Margin.margin_top,
@@ -631,25 +631,25 @@ impl Flow for BlockFlow {
remaining_width).specified_or_zero();
let (width, margin_left, margin_right) = if self.is_float() {
- self.compute_float_margins(box, remaining_width)
+ self.compute_float_margins(box_, remaining_width)
} else {
- self.compute_block_margins(box, remaining_width, available_width)
+ self.compute_block_margins(box_, remaining_width, available_width)
};
- box.margin.set(SideOffsets2D::new(margin_top,
+ box_.margin.set(SideOffsets2D::new(margin_top,
margin_right,
margin_bottom,
margin_left));
- x_offset = box.offset();
+ x_offset = box_.offset();
remaining_width = width;
// The associated box is the border box of this flow.
- let position_ref = box.position.mutate();
- position_ref.ptr.origin.x = box.margin.get().left;
- let padding_and_borders = box.padding.get().left + box.padding.get().right +
- box.border.get().left + box.border.get().right;
- position_ref.ptr.size.width = remaining_width + padding_and_borders;
+ let mut position_ref = box_.position.borrow_mut();
+ position_ref.get().origin.x = box_.margin.get().left;
+ let padding_and_borders = box_.padding.get().left + box_.padding.get().right +
+ box_.border.get().left + box_.border.get().right;
+ position_ref.get().size.width = remaining_width + padding_and_borders;
}
if self.is_float() {
@@ -722,24 +722,24 @@ impl Flow for BlockFlow {
return;
}
- for box in self.box.iter() {
+ for box_ in self.box_.iter() {
// The top margin collapses with its first in-flow block-level child's
// top margin if the parent has no top border, no top padding.
if *first_in_flow && top_margin_collapsible {
// If top-margin of parent is less than top-margin of its first child,
// the parent box goes down until its top is aligned with the child.
- if *margin_top < box.margin.get().top {
+ if *margin_top < box_.margin.get().top {
// TODO: The position of child floats should be updated and this
// would influence clearance as well. See #725
- let extra_margin = box.margin.get().top - *margin_top;
+ let extra_margin = box_.margin.get().top - *margin_top;
*top_offset = *top_offset + extra_margin;
- *margin_top = box.margin.get().top;
+ *margin_top = box_.margin.get().top;
}
}
// The bottom margin of an in-flow block-level element collapses
// with the top margin of its next in-flow block-level sibling.
- *collapsing = geometry::min(box.margin.get().top, *collapsible);
- *collapsible = box.margin.get().bottom;
+ *collapsing = geometry::min(box_.margin.get().top, *collapsible);
+ *collapsible = box_.margin.get().bottom;
}
*first_in_flow = false;
@@ -757,7 +757,7 @@ impl Flow for BlockFlow {
} else {
~"BlockFlow: "
};
- txt.append(match self.box {
+ txt.append(match self.box_ {
Some(ref rb) => rb.debug_str(),
None => ~"",
})
diff --git a/src/components/main/layout/box.rs b/src/components/main/layout/box_.rs
index d1ed277a95b..57eed410b6a 100644
--- a/src/components/main/layout/box.rs
+++ b/src/components/main/layout/box_.rs
@@ -22,9 +22,8 @@ use servo_net::local_image_cache::LocalImageCache;
use servo_util::geometry::Au;
use servo_util::geometry;
use servo_util::range::*;
-use servo_util::slot::Slot;
use std::cast;
-use std::cell::Cell;
+use std::cell::RefCell;
use std::cmp::ApproxEq;
use std::num::Zero;
use style::{ComputedValues, TElement, TNode, cascade};
@@ -71,24 +70,24 @@ pub struct Box {
style: Arc<ComputedValues>,
/// The position of this box relative to its owning flow.
- position: Slot<Rect<Au>>,
+ position: RefCell<Rect<Au>>,
/// The border of the content box.
///
/// FIXME(pcwalton): This need not be stored in the box.
- border: Slot<SideOffsets2D<Au>>,
+ border: RefCell<SideOffsets2D<Au>>,
/// The padding of the content box.
- padding: Slot<SideOffsets2D<Au>>,
+ padding: RefCell<SideOffsets2D<Au>>,
/// The margin of the content box.
- margin: Slot<SideOffsets2D<Au>>,
+ margin: RefCell<SideOffsets2D<Au>>,
/// Info specific to the kind of box. Keep this enum small.
specific: SpecificBoxInfo,
/// positioned box offsets
- position_offsets: Slot<SideOffsets2D<Au>>,
+ position_offsets: RefCell<SideOffsets2D<Au>>,
}
/// Info specific to the kind of box. Keep this enum small.
@@ -105,7 +104,7 @@ pub enum SpecificBoxInfo {
#[deriving(Clone)]
pub struct ImageBoxInfo {
/// The image held within this box.
- image: Slot<ImageHolder>,
+ image: RefCell<ImageHolder>,
/// The width attribute supplied by the DOM, if any.
dom_width: Option<Au>,
/// The height attribute supplied by the DOM, if any.
@@ -129,7 +128,7 @@ impl ImageBoxInfo {
}
ImageBoxInfo {
- image: Slot::init(ImageHolder::new(image_url, local_image_cache)),
+ image: RefCell::new(ImageHolder::new(image_url, local_image_cache)),
dom_width: convert_length(node, "width"),
dom_height: convert_length(node, "height"),
}
@@ -139,7 +138,8 @@ impl ImageBoxInfo {
fn image_width(&self) -> Au {
// TODO(brson): Consult margins and borders?
self.dom_width.unwrap_or_else(|| {
- Au::from_px(self.image.mutate().ptr.get_size().unwrap_or(Size2D(0, 0)).width)
+ let mut image_ref = self.image.borrow_mut();
+ Au::from_px(image_ref.get().get_size().unwrap_or(Size2D(0, 0)).width)
})
}
@@ -147,7 +147,8 @@ impl ImageBoxInfo {
pub fn image_height(&self) -> Au {
// TODO(brson): Consult margins and borders?
self.dom_height.unwrap_or_else(|| {
- Au::from_px(self.image.mutate().ptr.get_size().unwrap_or(Size2D(0, 0)).height)
+ let mut image_ref = self.image.borrow_mut();
+ Au::from_px(image_ref.get().get_size().unwrap_or(Size2D(0, 0)).height)
})
}
}
@@ -256,12 +257,12 @@ impl Box {
Box {
node: OpaqueNode::from_layout_node(&node),
style: node_style,
- position: Slot::init(Au::zero_rect()),
- border: Slot::init(Zero::zero()),
- padding: Slot::init(Zero::zero()),
- margin: Slot::init(Zero::zero()),
+ position: RefCell::new(Au::zero_rect()),
+ border: RefCell::new(Zero::zero()),
+ padding: RefCell::new(Zero::zero()),
+ margin: RefCell::new(Zero::zero()),
specific: specific,
- position_offsets: Slot::init(Zero::zero()),
+ position_offsets: RefCell::new(Zero::zero()),
}
}
@@ -279,12 +280,12 @@ impl Box {
Box {
node: self.node,
style: self.style.clone(),
- position: Slot::init(Rect(self.position.get().origin, size)),
- border: Slot::init(self.border.get()),
- padding: Slot::init(self.padding.get()),
- margin: Slot::init(self.margin.get()),
+ position: RefCell::new(Rect(self.position.get().origin, size)),
+ border: RefCell::new(self.border.get()),
+ padding: RefCell::new(self.padding.get()),
+ margin: RefCell::new(self.margin.get()),
specific: specific,
- position_offsets: Slot::init(Zero::zero())
+ position_offsets: RefCell::new(Zero::zero())
}
}
@@ -310,11 +311,6 @@ impl Box {
self.border.get().left + self.border.get().right
}
- /// Sets the size of this box.
- fn set_size(&self, new_size: Size2D<Au>) {
- self.position.set(Rect(self.position.get().origin, new_size))
- }
-
pub fn calculate_line_height(&self, font_size: Au) -> Au {
match self.line_height() {
line_height::Normal => font_size.scale_by(1.14),
@@ -408,11 +404,11 @@ impl Box {
debug!("(font style) start");
// FIXME: Too much allocation here.
- let font_families = do my_style.Font.font_family.map |family| {
+ let font_families = my_style.Font.font_family.map(|family| {
match *family {
font_family::FamilyName(ref name) => (*name).clone(),
}
- };
+ });
debug!("(font style) font families: `{:?}`", font_families);
let font_size = my_style.Font.font_size.to_f64().unwrap() / 60.0;
@@ -465,7 +461,7 @@ impl Box {
/// and so on.
pub fn is_replaced(&self) -> bool {
match self.specific {
- ImageBox(*) => true,
+ ImageBox(..) => true,
_ => false,
}
}
@@ -473,7 +469,7 @@ impl Box {
/// Returns true if this element can be split. This is true for text boxes.
pub fn can_split(&self) -> bool {
match self.specific {
- ScannedTextBox(*) => true,
+ ScannedTextBox(..) => true,
_ => false,
}
}
@@ -496,7 +492,7 @@ impl Box {
/// necessary.
pub fn paint_background_if_applicable<E:ExtraDisplayListData>(
&self,
- list: &Cell<DisplayList<E>>,
+ list: &RefCell<DisplayList<E>>,
absolute_bounds: &Rect<Au>) {
// FIXME: This causes a lot of background colors to be displayed when they are clearly not
// needed. We could use display list optimization to clean this up, but it still seems
@@ -505,7 +501,7 @@ impl Box {
let style = self.style();
let background_color = style.resolve_color(style.Background.background_color);
if !background_color.alpha.approx_eq(&0.0) {
- list.with_mut_ref(|list| {
+ list.with_mut(|list| {
let solid_color_display_item = ~SolidColorDisplayItem {
base: BaseDisplayItem {
bounds: *absolute_bounds,
@@ -523,7 +519,7 @@ impl Box {
/// necessary.
pub fn paint_borders_if_applicable<E:ExtraDisplayListData>(
&self,
- list: &Cell<DisplayList<E>>,
+ list: &RefCell<DisplayList<E>>,
abs_bounds: &Rect<Au>) {
// Fast path.
let border = self.border.get();
@@ -542,7 +538,7 @@ impl Box {
let left_style = style.Border.border_left_style;
// Append the border to the display list.
- do list.with_mut_ref |list| {
+ list.with_mut(|list| {
let border_display_item = ~BorderDisplayItem {
base: BaseDisplayItem {
bounds: *abs_bounds,
@@ -560,7 +556,7 @@ impl Box {
};
list.append_item(BorderDisplayItemClass(border_display_item))
- }
+ });
}
/// Adds the display items for this box to the given display list.
@@ -583,7 +579,7 @@ impl Box {
dirty: &Rect<Au>,
offset: Point2D<Au>,
flow: &Flow,
- list: &Cell<DisplayList<E>>) {
+ list: &RefCell<DisplayList<E>>) {
let box_bounds = self.position.get();
let absolute_box_bounds = box_bounds.translate(&offset);
debug!("Box::build_display_list at rel={}, abs={}: {:s}",
@@ -607,7 +603,7 @@ impl Box {
match self.specific {
UnscannedTextBox(_) => fail!("Shouldn't see unscanned boxes here."),
ScannedTextBox(ref text_box) => {
- do list.with_mut_ref |list| {
+ list.with_mut(|list| {
let item = ~ClipDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
@@ -617,7 +613,7 @@ impl Box {
need_clip: false
};
list.append_item(ClipDisplayItemClass(item));
- }
+ });
let color = self.style().Color.color.to_gfx_color();
@@ -629,7 +625,7 @@ impl Box {
text_flags.set_override_line_through(flow_flags.override_line_through());
// Create the text box.
- do list.with_mut_ref |list| {
+ list.with_mut(|list| {
let text_display_item = ~TextDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
@@ -642,7 +638,7 @@ impl Box {
};
list.append_item(TextDisplayItemClass(text_display_item))
- }
+ });
// Draw debug frames for text bounds.
//
@@ -652,7 +648,7 @@ impl Box {
// Compute the text box bounds and draw a border surrounding them.
let debug_border = SideOffsets2D::new_all_same(Au::from_px(1));
- do list.with_mut_ref |list| {
+ list.with_mut(|list| {
let border_display_item = ~BorderDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
@@ -664,7 +660,7 @@ impl Box {
};
list.append_item(BorderDisplayItemClass(border_display_item))
- }
+ });
// Draw a rectangle representing the baselines.
//
@@ -674,7 +670,7 @@ impl Box {
let baseline = Rect(absolute_box_bounds.origin + Point2D(Au(0), ascent),
Size2D(absolute_box_bounds.size.width, Au(0)));
- do list.with_mut_ref |list| {
+ list.with_mut(|list| {
let border_display_item = ~BorderDisplayItem {
base: BaseDisplayItem {
bounds: baseline,
@@ -686,13 +682,11 @@ impl Box {
};
list.append_item(BorderDisplayItemClass(border_display_item))
- }
-
- ()
+ });
});
},
- GenericBox | IframeBox(_) => {
- do list.with_mut_ref |list| {
+ GenericBox | IframeBox(..) => {
+ list.with_mut(|list| {
let item = ~ClipDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
@@ -702,14 +696,14 @@ impl Box {
need_clip: self.needs_clip()
};
list.append_item(ClipDisplayItemClass(item));
- }
+ });
// FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We
// should have a real `SERVO_DEBUG` system.
debug!("{:?}", {
let debug_border = SideOffsets2D::new_all_same(Au::from_px(1));
- do list.with_mut_ref |list| {
+ list.with_mut(|list| {
let border_display_item = ~BorderDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
@@ -721,13 +715,11 @@ impl Box {
};
list.append_item(BorderDisplayItemClass(border_display_item))
- }
-
- ()
+ });
});
},
ImageBox(ref image_box) => {
- do list.with_mut_ref |list| {
+ list.with_mut(|list| {
let item = ~ClipDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
@@ -737,14 +729,15 @@ impl Box {
need_clip: false
};
list.append_item(ClipDisplayItemClass(item));
- }
+ });
- match image_box.image.mutate().ptr.get_image() {
+ let mut image_ref = image_box.image.borrow_mut();
+ match image_ref.get().get_image() {
Some(image) => {
debug!("(building display list) building image box");
// Place the image into the display list.
- do list.with_mut_ref |list| {
+ list.with_mut(|list| {
let image_display_item = ~ImageDisplayItem {
base: BaseDisplayItem {
bounds: absolute_box_bounds,
@@ -752,8 +745,8 @@ impl Box {
},
image: image.clone(),
};
- list.append_item(ImageDisplayItemClass(image_display_item))
- }
+ list.append_item(ImageDisplayItemClass(image_display_item));
+ });
}
None => {
// No image data at all? Do nothing.
@@ -809,7 +802,7 @@ impl Box {
(min_line_width, max_line_width)
}
- UnscannedTextBox(*) => fail!("Unscanned text boxes should have been scanned by now!"),
+ UnscannedTextBox(..) => fail!("Unscanned text boxes should have been scanned by now!"),
};
(guessed_width + additional_minimum, guessed_width + additional_preferred)
}
@@ -822,11 +815,12 @@ impl Box {
match self.specific {
GenericBox | IframeBox(_) => Au(0),
ImageBox(ref image_box_info) => {
- let size = image_box_info.image.mutate().ptr.get_size();
+ let mut image_ref = image_box_info.image.borrow_mut();
+ let size = image_ref.get().get_size();
let height = Au::from_px(size.unwrap_or(Size2D(0, 0)).height);
// Eww. Refactor this.
- self.position.mutate().ptr.size.height = height;
+ self.position.borrow_mut().get().size.height = height;
debug!("box_height: found image height: {}", height);
height
@@ -955,11 +949,11 @@ impl Box {
match self.specific {
GenericBox | IframeBox(_) => {
// FIXME(pcwalton): This seems clownshoes; can we remove?
- self.position.mutate().ptr.size.width = Au::from_px(45)
+ self.position.borrow_mut().get().size.width = Au::from_px(45)
}
ImageBox(ref image_box_info) => {
let image_width = image_box_info.image_width();
- self.position.mutate().ptr.size.width = image_width
+ self.position.borrow_mut().get().size.width = image_width
}
ScannedTextBox(_) => {
// Scanned text boxes will have already had their widths assigned by this point.
diff --git a/src/components/main/layout/construct.rs b/src/components/main/layout/construct.rs
index 80a8ffb8a1b..a0866cf934c 100644
--- a/src/components/main/layout/construct.rs
+++ b/src/components/main/layout/construct.rs
@@ -22,8 +22,8 @@
use css::node_style::StyledNode;
use layout::block::BlockFlow;
-use layout::box::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo};
-use layout::box::{UnscannedTextBox, UnscannedTextBoxInfo};
+use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBoxInfo};
+use layout::box_::{UnscannedTextBox, UnscannedTextBoxInfo};
use layout::context::LayoutContext;
use layout::float_context::FloatType;
use layout::flow::{Flow, FlowData, MutableFlowUtils};
@@ -35,10 +35,11 @@ use layout::wrapper::{LayoutNode, PostorderNodeMutTraversal};
use script::dom::element::{HTMLIframeElementTypeId, HTMLImageElementTypeId};
use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, TextNodeTypeId};
-use servo_util::slot::Slot;
-use std::util;
use style::computed_values::{display, float};
+use std::cell::RefCell;
+use std::util;
+
/// The results of flow construction for a DOM node.
pub enum ConstructionResult {
/// This node contributes nothing at all (`display: none`). Alternately, this is what newly
@@ -47,7 +48,7 @@ pub enum ConstructionResult {
/// This node contributed a flow at the proper position in the tree. Nothing more needs to be
/// done for this node.
- FlowConstructionResult(~Flow:),
+ FlowConstructionResult(~Flow),
/// This node contributed some object or objects that will be needed to construct a proper flow
/// later up the tree, but these objects have not yet found their home.
@@ -102,7 +103,7 @@ struct InlineBlockSplit {
predecessor_boxes: ~[Box],
/// The flow that caused this {ib} split.
- flow: ~Flow:,
+ flow: ~Flow,
}
/// Methods on optional vectors.
@@ -169,24 +170,24 @@ impl<T> OptVector<T> for Option<~[T]> {
}
/// An object that knows how to create flows.
-pub struct FlowConstructor<'self> {
+pub struct FlowConstructor<'a> {
/// The layout context.
///
/// FIXME(pcwalton): Why does this contain `@`??? That destroys parallelism!!!
- layout_context: &'self mut LayoutContext,
+ layout_context: &'a mut LayoutContext,
/// The next flow ID to assign.
///
/// FIXME(pcwalton): This is going to have to be atomic; can't we do something better?
- next_flow_id: Slot<int>,
+ next_flow_id: RefCell<int>,
}
-impl<'self> FlowConstructor<'self> {
+impl<'fc> FlowConstructor<'fc> {
/// Creates a new flow constructor.
pub fn init<'a>(layout_context: &'a mut LayoutContext) -> FlowConstructor<'a> {
FlowConstructor {
layout_context: layout_context,
- next_flow_id: Slot::init(0),
+ next_flow_id: RefCell::new(0),
}
}
@@ -231,10 +232,10 @@ impl<'self> FlowConstructor<'self> {
/// `#[inline(always)]` because this is performance critical and LLVM will not inline it
/// otherwise.
#[inline(always)]
- fn flush_inline_boxes_to_flow(&mut self, boxes: ~[Box], flow: &mut ~Flow:, node: LayoutNode) {
+ fn flush_inline_boxes_to_flow(&mut self, boxes: ~[Box], flow: &mut ~Flow, node: LayoutNode) {
if boxes.len() > 0 {
let inline_base = FlowData::new(self.next_flow_id(), node);
- let mut inline_flow = ~InlineFlow::from_boxes(inline_base, boxes) as ~Flow:;
+ let mut inline_flow = ~InlineFlow::from_boxes(inline_base, boxes) as ~Flow;
TextRunScanner::new().scan_for_runs(self.layout_context, inline_flow);
flow.add_new_child(inline_flow)
}
@@ -244,7 +245,7 @@ impl<'self> FlowConstructor<'self> {
/// the given flow.
fn flush_inline_boxes_to_flow_if_necessary(&mut self,
opt_boxes: &mut Option<~[Box]>,
- flow: &mut ~Flow:,
+ flow: &mut ~Flow,
node: LayoutNode) {
let opt_boxes = util::replace(opt_boxes, None);
if opt_boxes.len() > 0 {
@@ -256,7 +257,7 @@ impl<'self> FlowConstructor<'self> {
/// other `BlockFlow`s or `InlineFlow`s will be populated underneath this node, depending on
/// whether {ib} splits needed to happen.
fn build_children_of_block_flow(&mut self,
- flow: &mut ~Flow:,
+ flow: &mut ~Flow,
node: LayoutNode) {
// Gather up boxes for the inline flows we might need to create.
let mut opt_boxes_for_inline_flow = None;
@@ -342,10 +343,10 @@ impl<'self> FlowConstructor<'self> {
/// Builds a flow for a node with `display: block`. This yields a `BlockFlow` with possibly
/// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed
/// to happen.
- fn build_flow_for_block(&mut self, node: LayoutNode) -> ~Flow: {
+ fn build_flow_for_block(&mut self, node: LayoutNode) -> ~Flow {
let base = FlowData::new(self.next_flow_id(), node);
- let box = self.build_box_for_node(node);
- let mut flow = ~BlockFlow::from_box(base, box) as ~Flow:;
+ let box_ = self.build_box_for_node(node);
+ let mut flow = ~BlockFlow::from_box(base, box_) as ~Flow;
self.build_children_of_block_flow(&mut flow, node);
flow
}
@@ -353,10 +354,10 @@ impl<'self> FlowConstructor<'self> {
/// Builds the flow for a node with `float: {left|right}`. This yields a float `BlockFlow` with
/// a `BlockFlow` underneath it.
fn build_flow_for_floated_block(&mut self, node: LayoutNode, float_type: FloatType)
- -> ~Flow: {
+ -> ~Flow {
let base = FlowData::new(self.next_flow_id(), node);
- let box = self.build_box_for_node(node);
- let mut flow = ~BlockFlow::float_from_box(base, float_type, box) as ~Flow:;
+ let box_ = self.build_box_for_node(node);
+ let mut flow = ~BlockFlow::float_from_box(base, float_type, box_) as ~Flow;
self.build_children_of_block_flow(&mut flow, node);
flow
}
@@ -458,7 +459,7 @@ impl<'self> FlowConstructor<'self> {
}
}
-impl<'self> PostorderNodeMutTraversal for FlowConstructor<'self> {
+impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// `#[inline(always)]` because this is always called from the traversal function and for some
// reason LLVM's inlining heuristics go awry here.
#[inline(always)]
@@ -528,7 +529,7 @@ trait NodeUtils {
fn swap_out_construction_result(self) -> ConstructionResult;
}
-impl<'self> NodeUtils for LayoutNode<'self> {
+impl<'ln> NodeUtils for LayoutNode<'ln> {
fn is_replaced_content(self) -> bool {
match self.type_id() {
TextNodeTypeId |
@@ -543,17 +544,19 @@ impl<'self> NodeUtils for LayoutNode<'self> {
#[inline(always)]
fn set_flow_construction_result(self, result: ConstructionResult) {
- match *self.mutate_layout_data().ptr {
- Some(ref mut layout_data) => layout_data.flow_construction_result = result,
+ let mut layout_data_ref = self.mutate_layout_data();
+ match *layout_data_ref.get() {
+ Some(ref mut layout_data) => layout_data.data.flow_construction_result = result,
None => fail!("no layout data"),
}
}
#[inline(always)]
fn swap_out_construction_result(self) -> ConstructionResult {
- match *self.mutate_layout_data().ptr {
+ let mut layout_data_ref = self.mutate_layout_data();
+ match *layout_data_ref.get() {
Some(ref mut layout_data) => {
- util::replace(&mut layout_data.flow_construction_result, NoConstructionResult)
+ util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult)
}
None => fail!("no layout data"),
}
@@ -568,14 +571,14 @@ fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) {
// FIXME(pcwalton): This is slow because vector shift is broken. :(
let mut found_nonwhitespace = false;
let mut result = ~[];
- for box in boxes.move_iter() {
- if !found_nonwhitespace && box.is_whitespace_only() {
+ for box_ in boxes.move_iter() {
+ if !found_nonwhitespace && box_.is_whitespace_only() {
debug!("stripping ignorable whitespace from start");
continue
}
found_nonwhitespace = true;
- result.push(box)
+ result.push(box_)
}
*opt_boxes = Some(result)
diff --git a/src/components/main/layout/display_list_builder.rs b/src/components/main/layout/display_list_builder.rs
index 7dd538d493d..dc20f784667 100644
--- a/src/components/main/layout/display_list_builder.rs
+++ b/src/components/main/layout/display_list_builder.rs
@@ -4,7 +4,7 @@
//! Constructs display lists from boxes.
-use layout::box::Box;
+use layout::box_::Box;
use layout::context::LayoutContext;
use layout::util::OpaqueNode;
@@ -12,14 +12,14 @@ use gfx;
use style;
pub trait ExtraDisplayListData {
- fn new(box: &Box) -> Self;
+ fn new(box_: &Box) -> Self;
}
pub type Nothing = ();
impl ExtraDisplayListData for OpaqueNode {
- fn new(box: &Box) -> OpaqueNode {
- box.node
+ fn new(box_: &Box) -> OpaqueNode {
+ box_.node
}
}
@@ -35,8 +35,8 @@ impl ExtraDisplayListData for Nothing {
///
/// Right now, the builder isn't used for much, but it establishes the pattern we'll need once we
/// support display-list-based hit testing and so forth.
-pub struct DisplayListBuilder<'self> {
- ctx: &'self LayoutContext,
+pub struct DisplayListBuilder<'a> {
+ ctx: &'a LayoutContext,
}
//
diff --git a/src/components/main/layout/extra.rs b/src/components/main/layout/extra.rs
index c17bfc4e0e4..ba7cf8a2595 100644
--- a/src/components/main/layout/extra.rs
+++ b/src/components/main/layout/extra.rs
@@ -4,33 +4,39 @@
//! Code for managing the layout data in the DOM.
-use layout::util::{LayoutData, LayoutDataAccess};
+use layout::util::{PrivateLayoutData, LayoutDataAccess, LayoutDataWrapper};
use layout::wrapper::LayoutNode;
+use script::layout_interface::LayoutChan;
/// Functionality useful for querying the layout-specific data on DOM nodes.
pub trait LayoutAuxMethods {
- fn initialize_layout_data(self);
- fn initialize_style_for_subtree(self);
+ fn initialize_layout_data(self, chan: LayoutChan);
+ fn initialize_style_for_subtree(self, chan: LayoutChan);
}
-impl<'self> LayoutAuxMethods for LayoutNode<'self> {
+impl<'ln> LayoutAuxMethods for LayoutNode<'ln> {
/// Resets layout data and styles for the node.
///
/// FIXME(pcwalton): Do this as part of box building instead of in a traversal.
- fn initialize_layout_data(self) {
- let layout_data_handle = self.mutate_layout_data();
- match *layout_data_handle.ptr {
- None => *layout_data_handle.ptr = Some(~LayoutData::new()),
+ fn initialize_layout_data(self, chan: LayoutChan) {
+ let mut layout_data_ref = self.mutate_layout_data();
+ match *layout_data_ref.get() {
+ None => {
+ *layout_data_ref.get() = Some(LayoutDataWrapper {
+ chan: Some(chan),
+ data: ~PrivateLayoutData::new(),
+ });
+ }
Some(_) => {}
}
}
/// Resets layout data and styles for a Node tree.
- ///
+ ///
/// FIXME(pcwalton): Do this as part of box building instead of in a traversal.
- fn initialize_style_for_subtree(self) {
+ fn initialize_style_for_subtree(self, chan: LayoutChan) {
for n in self.traverse_preorder() {
- n.initialize_layout_data();
+ n.initialize_layout_data(chan.clone());
}
}
}
diff --git a/src/components/main/layout/float_context.rs b/src/components/main/layout/float_context.rs
index 7a92554401c..e61d3eb11c7 100644
--- a/src/components/main/layout/float_context.rs
+++ b/src/components/main/layout/float_context.rs
@@ -77,7 +77,7 @@ impl FloatContext {
}
#[inline(always)]
- fn with_mut_base<R>(&mut self, callback: &fn(&mut FloatContextBase) -> R) -> R {
+ fn with_mut_base<R>(&mut self, callback: |&mut FloatContextBase| -> R) -> R {
match *self {
Invalid => fail!("Float context no longer available"),
Valid(ref mut base) => callback(&mut *base)
@@ -85,7 +85,7 @@ impl FloatContext {
}
#[inline(always)]
- pub fn with_base<R>(&self, callback: &fn(&FloatContextBase) -> R) -> R {
+ pub fn with_base<R>(&self, callback: |&FloatContextBase| -> R) -> R {
match *self {
Invalid => fail!("Float context no longer available"),
Valid(ref base) => callback(&*base)
@@ -94,46 +94,46 @@ impl FloatContext {
#[inline(always)]
pub fn translate(&mut self, trans: Point2D<Au>) -> FloatContext {
- do self.with_mut_base |base| {
+ self.with_mut_base(|base| {
base.translate(trans);
- }
+ });
replace(self, Invalid)
}
#[inline(always)]
pub fn available_rect(&mut self, top: Au, height: Au, max_x: Au) -> Option<Rect<Au>> {
- do self.with_base |base| {
+ self.with_base(|base| {
base.available_rect(top, height, max_x)
- }
+ })
}
#[inline(always)]
pub fn add_float(&mut self, info: &PlacementInfo) -> FloatContext{
- do self.with_mut_base |base| {
+ self.with_mut_base(|base| {
base.add_float(info);
- }
+ });
replace(self, Invalid)
}
#[inline(always)]
pub fn place_between_floats(&self, info: &PlacementInfo) -> Rect<Au> {
- do self.with_base |base| {
+ self.with_base(|base| {
base.place_between_floats(info)
- }
+ })
}
#[inline(always)]
pub fn last_float_pos(&mut self) -> Point2D<Au> {
- do self.with_base |base| {
+ self.with_base(|base| {
base.last_float_pos()
- }
+ })
}
#[inline(always)]
pub fn clearance(&self, clear: ClearType) -> Au {
- do self.with_base |base| {
+ self.with_base(|base| {
base.clearance(clear)
- }
+ })
}
}
@@ -288,24 +288,6 @@ impl FloatContextBase {
self.floats_used += 1;
}
- /// Returns true if the given rect overlaps with any floats.
- fn collides_with_float(&self, bounds: &Rect<Au>) -> bool {
- for floats in self.float_data.iter() {
- for float in floats.iter() {
- match *float {
- None => (),
- Some(data) => {
- if data.bounds.translate(&self.offset).intersects(bounds) {
- return true;
- }
- }
- };
- }
- }
-
- return false;
- }
-
/// Given the top 3 sides of the rectange, finds the largest height that
/// will result in the rectange not colliding with any floats. Returns
/// None if that height is infinite.
diff --git a/src/components/main/layout/flow.rs b/src/components/main/layout/flow.rs
index d7d1f602f29..d6b377d92bc 100644
--- a/src/components/main/layout/flow.rs
+++ b/src/components/main/layout/flow.rs
@@ -27,7 +27,7 @@
use css::node_style::StyledNode;
use layout::block::BlockFlow;
-use layout::box::Box;
+use layout::box_::Box;
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::float_context::{FloatContext, Invalid};
@@ -42,7 +42,7 @@ use geom::rect::Rect;
use gfx::display_list::{ClipDisplayItemClass, DisplayList};
use servo_util::geometry::Au;
use std::cast;
-use std::cell::Cell;
+use std::cell::RefCell;
use style::ComputedValues;
use style::computed_values::text_align;
@@ -127,7 +127,7 @@ pub fn base<'a>(this: &'a Flow) -> &'a FlowData {
}
/// Iterates over the children of this immutable flow.
-pub fn imm_child_iter<'a>(flow: &'a Flow) -> DListIterator<'a,~Flow:> {
+pub fn imm_child_iter<'a>(flow: &'a Flow) -> DListIterator<'a,~Flow> {
base(flow).children.iter()
}
@@ -140,12 +140,12 @@ pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut FlowData {
}
/// Returns the last child of this flow.
-pub fn last_child<'a>(flow: &'a mut Flow) -> Option<&'a mut ~Flow:> {
+pub fn last_child<'a>(flow: &'a mut Flow) -> Option<&'a mut ~Flow> {
mut_base(flow).children.back_mut()
}
/// Iterates over the children of this flow.
-pub fn child_iter<'a>(flow: &'a mut Flow) -> MutDListIterator<'a,~Flow:> {
+pub fn child_iter<'a>(flow: &'a mut Flow) -> MutDListIterator<'a,~Flow> {
mut_base(flow).children.mut_iter()
}
@@ -183,13 +183,13 @@ pub trait MutableFlowUtils {
// Mutators
/// Adds a new flow as a child of this flow.
- fn add_new_child(self, new_child: ~Flow:);
+ fn add_new_child(self, new_child: ~Flow);
/// Invokes a closure with the first child of this flow.
- fn with_first_child<R>(self, f: &fn(Option<&mut ~Flow:>) -> R) -> R;
+ fn with_first_child<R>(self, f: |Option<&mut ~Flow>| -> R) -> R;
/// Invokes a closure with the last child of this flow.
- fn with_last_child<R>(self, f: &fn(Option<&mut ~Flow:>) -> R) -> R;
+ fn with_last_child<R>(self, f: |Option<&mut ~Flow>| -> R) -> R;
/// Removes the first child of this flow and destroys it.
fn remove_first(self);
@@ -205,7 +205,7 @@ pub trait MutableFlowUtils {
self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
- list: &Cell<DisplayList<E>>)
+ list: &RefCell<DisplayList<E>>)
-> bool;
}
@@ -385,7 +385,7 @@ pub struct FlowData {
restyle_damage: RestyleDamage,
/// The children of this flow.
- children: DList<~Flow:>,
+ children: DList<~Flow>,
/* TODO (Issue #87): debug only */
id: int,
@@ -454,12 +454,12 @@ impl FlowData {
}
}
- pub fn child_iter<'a>(&'a mut self) -> MutDListIterator<'a,~Flow:> {
+ pub fn child_iter<'a>(&'a mut self) -> MutDListIterator<'a,~Flow> {
self.children.mut_iter()
}
}
-impl<'self> ImmutableFlowUtils for &'self Flow {
+impl<'a> ImmutableFlowUtils for &'a Flow {
/// Returns true if this flow is a block or a float flow.
fn is_block_like(self) -> bool {
match self.class() {
@@ -508,7 +508,7 @@ impl<'self> ImmutableFlowUtils for &'self Flow {
}
}
-impl<'self> MutableFlowUtils for &'self mut Flow {
+impl<'a> MutableFlowUtils for &'a mut Flow {
/// Traverses the tree in preorder.
fn traverse_preorder<T:PreorderFlowTraversal>(self, traversal: &mut T) -> bool {
if traversal.should_prune(self) {
@@ -548,17 +548,17 @@ impl<'self> MutableFlowUtils for &'self mut Flow {
}
/// Adds a new flow as a child of this flow.
- fn add_new_child(self, new_child: ~Flow:) {
+ fn add_new_child(self, new_child: ~Flow) {
mut_base(self).children.push_back(new_child)
}
/// Invokes a closure with the first child of this flow.
- fn with_first_child<R>(self, f: &fn(Option<&mut ~Flow:>) -> R) -> R {
+ fn with_first_child<R>(self, f: |Option<&mut ~Flow>| -> R) -> R {
f(mut_base(self).children.front_mut())
}
/// Invokes a closure with the last child of this flow.
- fn with_last_child<R>(self, f: &fn(Option<&mut ~Flow:>) -> R) -> R {
+ fn with_last_child<R>(self, f: |Option<&mut ~Flow>| -> R) -> R {
f(mut_base(self).children.back_mut())
}
@@ -587,7 +587,7 @@ impl<'self> MutableFlowUtils for &'self mut Flow {
self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
- list: &Cell<DisplayList<E>>)
+ list: &RefCell<DisplayList<E>>)
-> bool {
debug!("Flow: building display list for f{}", base(self).id);
match self.class() {
@@ -596,20 +596,21 @@ impl<'self> MutableFlowUtils for &'self mut Flow {
_ => fail!("Tried to build_display_list_recurse of flow: {:?}", self),
};
- if list.with_mut_ref(|list| list.list.len() == 0) {
+ if list.with_mut(|list| list.list.len() == 0) {
return true;
}
- let child_list = ~Cell::new(DisplayList::new());
+ let child_list = ~RefCell::new(DisplayList::new());
for kid in child_iter(self) {
kid.build_display_list(builder,dirty,child_list);
}
- do list.with_mut_ref |list| {
+ let mut child_list = Some(child_list.unwrap());
+ list.with_mut(|list| {
let result = list.list.mut_rev_iter().position(|item| {
match *item {
ClipDisplayItemClass(ref mut item) => {
- item.child_list.push_all_move(child_list.take().list);
+ item.child_list.push_all_move(child_list.take_unwrap().list);
true
},
_ => false,
@@ -620,7 +621,7 @@ impl<'self> MutableFlowUtils for &'self mut Flow {
fail!("fail to find parent item");
}
- }
+ });
true
}
}
diff --git a/src/components/main/layout/inline.rs b/src/components/main/layout/inline.rs
index 455f05a9249..42af73fab6c 100644
--- a/src/components/main/layout/inline.rs
+++ b/src/components/main/layout/inline.rs
@@ -3,14 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use css::node_style::StyledNode;
-use layout::box::{Box, CannotSplit, GenericBox, IframeBox, ImageBox, ScannedTextBox, SplitDidFit};
-use layout::box::{SplitDidNotFit, UnscannedTextBox};
+use layout::box_::{Box, CannotSplit, GenericBox, IframeBox, ImageBox, ScannedTextBox, SplitDidFit};
+use layout::box_::{SplitDidNotFit, UnscannedTextBox};
use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::flow::{FlowClass, Flow, FlowData, InlineFlowClass};
use layout::flow;
use layout::float_context::FloatContext;
-use layout::util::{ElementMapping};
+use layout::util::ElementMapping;
use layout::float_context::{PlacementInfo, FloatLeft};
use extra::container::Deque;
@@ -19,7 +19,7 @@ use geom::{Point2D, Rect, Size2D};
use gfx::display_list::DisplayList;
use servo_util::geometry::Au;
use servo_util::range::Range;
-use std::cell::Cell;
+use std::cell::RefCell;
use std::u16;
use std::util;
use style::computed_values::{text_align, vertical_align};
@@ -80,18 +80,6 @@ impl LineboxScanner {
}
}
- fn reinitialize(&mut self, float_ctx: FloatContext) {
- self.floats = float_ctx;
- self.new_boxes.truncate(0);
- self.work_list.clear();
- self.pending_line.range = Range::empty();
- self.pending_line.bounds = Rect(Point2D(Au::new(0), Au::new(0)),
- Size2D(Au::new(0), Au::new(0)));
- self.pending_line.green_zone = Size2D(Au::new(0), Au::new(0));
- self.lines.truncate(0);
- self.cur_y = Au::new(0);
- }
-
pub fn floats_out(&mut self) -> FloatContext {
self.floats.clone()
}
@@ -119,13 +107,13 @@ impl LineboxScanner {
if flow.boxes.is_empty() {
break;
}
- let box = flow.boxes.remove(0); // FIXME: use a linkedlist
- debug!("LineboxScanner: Working with box from box list: b{}", box.debug_id());
- box
+ let box_ = flow.boxes.remove(0); // FIXME: use a linkedlist
+ debug!("LineboxScanner: Working with box from box list: b{}", box_.debug_id());
+ box_
} else {
- let box = self.work_list.pop_front().unwrap();
- debug!("LineboxScanner: Working with box from work list: b{}", box.debug_id());
- box
+ let box_ = self.work_list.pop_front().unwrap();
+ debug!("LineboxScanner: Working with box from work list: b{}", box_.debug_id());
+ box_
};
let box_was_appended = self.try_append_to_line(cur_box, flow);
@@ -413,8 +401,8 @@ impl LineboxScanner {
}
// An unconditional push
- fn push_box_to_line(&mut self, box: Box) {
- debug!("LineboxScanner: Pushing box {} to line {:u}", box.debug_id(), self.lines.len());
+ fn push_box_to_line(&mut self, box_: Box) {
+ debug!("LineboxScanner: Pushing box {} to line {:u}", box_.debug_id(), self.lines.len());
if self.pending_line.range.length() == 0 {
assert!(self.new_boxes.len() <= (u16::max_value as uint));
@@ -422,10 +410,10 @@ impl LineboxScanner {
}
self.pending_line.range.extend_by(1);
self.pending_line.bounds.size.width = self.pending_line.bounds.size.width +
- box.position.get().size.width;
+ box_.position.get().size.width;
self.pending_line.bounds.size.height = Au::max(self.pending_line.bounds.size.height,
- box.position.get().size.height);
- self.new_boxes.push(box);
+ box_.position.get().size.height);
+ self.new_boxes.push(box_);
}
}
@@ -467,8 +455,8 @@ impl InlineFlow {
}
pub fn teardown(&mut self) {
- for box in self.boxes.iter() {
- box.teardown();
+ for box_ in self.boxes.iter() {
+ box_.teardown();
}
self.boxes = ~[];
}
@@ -477,7 +465,7 @@ impl InlineFlow {
&self,
builder: &DisplayListBuilder,
dirty: &Rect<Au>,
- list: &Cell<DisplayList<E>>)
+ list: &RefCell<DisplayList<E>>)
-> bool {
let abs_rect = Rect(self.base.abs_position, self.base.position.size);
if !abs_rect.intersects(dirty) {
@@ -490,8 +478,8 @@ impl InlineFlow {
self.base.id,
self.boxes.len());
- for box in self.boxes.iter() {
- box.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list)
+ for box_ in self.boxes.iter() {
+ box_.build_display_list(builder, dirty, self.base.abs_position, (&*self) as &Flow, list)
}
// TODO(#225): Should `inline-block` elements have flows as children of the inline flow or
@@ -590,9 +578,9 @@ impl InlineFlow {
};
for i in line.range.eachi() {
- let box = &boxes[i];
- let size = box.position.get().size;
- box.position.set(Rect(Point2D(offset_x, box.position.get().origin.y), size));
+ let box_ = &boxes[i];
+ let size = box_.position.get().size;
+ box_.position.set(Rect(Point2D(offset_x, box_.position.get().origin.y), size));
offset_x = offset_x + size.width;
}
}
@@ -623,10 +611,10 @@ impl Flow for InlineFlow {
let mut min_width = Au::new(0);
let mut pref_width = Au::new(0);
- for box in self.boxes.iter() {
- debug!("Flow[{:d}]: measuring {:s}", self.base.id, box.debug_str());
+ for box_ in self.boxes.iter() {
+ debug!("Flow[{:d}]: measuring {:s}", self.base.id, box_.debug_str());
let (this_minimum_width, this_preferred_width) =
- box.minimum_and_preferred_widths();
+ box_.minimum_and_preferred_widths();
min_width = Au::max(min_width, this_minimum_width);
pref_width = Au::max(pref_width, this_preferred_width);
}
@@ -647,8 +635,8 @@ impl Flow for InlineFlow {
{
let this = &mut *self;
- for box in this.boxes.iter() {
- box.assign_width();
+ for box_ in this.boxes.iter() {
+ box_.assign_width();
}
}
@@ -736,9 +724,9 @@ impl Flow for InlineFlow {
let noncontent_height = top + bottom;
height = height + noncontent_height;
- let position_ref = cur_box.position.mutate();
- position_ref.ptr.size.height = height;
- position_ref.ptr.translate(&Point2D(Au::new(0), -height));
+ let mut position_ref = cur_box.position.borrow_mut();
+ position_ref.get().size.height = height;
+ position_ref.get().translate(&Point2D(Au::new(0), -height));
let ascent = height + bottom;
(height, Au::new(0), ascent)
@@ -818,7 +806,7 @@ impl Flow for InlineFlow {
bottommost = bottom_from_base;
}
- cur_box.position.mutate().ptr.origin.y = line.bounds.origin.y + offset;
+ cur_box.position.borrow_mut().get().origin.y = line.bounds.origin.y + offset;
}
// Calculate the distance from baseline to the top of the biggest box with 'bottom'
@@ -847,7 +835,7 @@ impl Flow for InlineFlow {
_ => baseline_offset,
};
- cur_box.position.mutate().ptr.origin.y = cur_box.position.get().origin.y +
+ cur_box.position.borrow_mut().get().origin.y = cur_box.position.get().origin.y +
adjust_offset;
}
diff --git a/src/components/main/layout/layout_task.rs b/src/components/main/layout/layout_task.rs
index 2224401188a..740576617fd 100644
--- a/src/components/main/layout/layout_task.rs
+++ b/src/components/main/layout/layout_task.rs
@@ -16,7 +16,7 @@ use layout::flow::{Flow, ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTrave
use layout::flow::{PostorderFlowTraversal};
use layout::flow;
use layout::incremental::{RestyleDamage};
-use layout::util::{LayoutData, LayoutDataAccess, OpaqueNode};
+use layout::util::{LayoutDataAccess, OpaqueNode, LayoutDataWrapper};
use layout::wrapper::LayoutNode;
use extra::arc::{Arc, RWArc, MutexArc};
@@ -34,7 +34,7 @@ use script::dom::element::{HTMLBodyElementTypeId, HTMLHtmlElementTypeId};
use script::layout_interface::{AddStylesheetMsg, ContentBoxQuery};
use script::layout_interface::{ContentBoxesQuery, ContentBoxesResponse, ExitNowMsg, LayoutQuery};
use script::layout_interface::{HitTestQuery, ContentBoxResponse, HitTestResponse};
-use script::layout_interface::{ContentChangedDocumentDamage, Msg, PrepareToExitMsg};
+use script::layout_interface::{ContentChangedDocumentDamage, LayoutChan, Msg, PrepareToExitMsg};
use script::layout_interface::{QueryMsg, ReapLayoutDataMsg, Reflow, ReflowDocumentDamage};
use script::layout_interface::{ReflowForDisplay, ReflowMsg};
use script::script_task::{ReflowCompleteMsg, ScriptChan, SendEventMsg};
@@ -46,20 +46,22 @@ use servo_util::time::{ProfilerChan, profile};
use servo_util::time;
use std::cast::transmute;
use std::cast;
-use std::cell::Cell;
+use std::cell::RefCell;
use std::comm::Port;
-use std::task;
use std::util;
use style::{AuthorOrigin, Stylesheet, Stylist};
/// Information needed by the layout task.
-struct LayoutTask {
+pub struct LayoutTask {
/// The ID of the pipeline that we belong to.
id: PipelineId,
/// The port on which we receive messages.
port: Port<Msg>,
+ //// The channel to send messages to ourself.
+ chan: LayoutChan,
+
/// The channel on which messages can be sent to the constellation.
constellation_chan: ConstellationChan,
@@ -132,9 +134,9 @@ impl PreorderFlowTraversal for PropagateDamageTraversal {
/// The bubble-widths traversal, the first part of layout computation. This computes preferred
/// and intrinsic widths and bubbles them up the tree.
-struct BubbleWidthsTraversal<'self>(&'self mut LayoutContext);
+struct BubbleWidthsTraversal<'a>(&'a mut LayoutContext);
-impl<'self> PostorderFlowTraversal for BubbleWidthsTraversal<'self> {
+impl<'a> PostorderFlowTraversal for BubbleWidthsTraversal<'a> {
#[inline]
fn process(&mut self, flow: &mut Flow) -> bool {
flow.bubble_widths(**self);
@@ -151,9 +153,9 @@ impl<'self> PostorderFlowTraversal for BubbleWidthsTraversal<'self> {
}
/// The assign-widths traversal. In Gecko this corresponds to `Reflow`.
-struct AssignWidthsTraversal<'self>(&'self mut LayoutContext);
+struct AssignWidthsTraversal<'a>(&'a mut LayoutContext);
-impl<'self> PreorderFlowTraversal for AssignWidthsTraversal<'self> {
+impl<'a> PreorderFlowTraversal for AssignWidthsTraversal<'a> {
#[inline]
fn process(&mut self, flow: &mut Flow) -> bool {
flow.assign_widths(**self);
@@ -164,9 +166,9 @@ impl<'self> PreorderFlowTraversal for AssignWidthsTraversal<'self> {
/// The assign-heights-and-store-overflow traversal, the last (and most expensive) part of layout
/// computation. Determines the final heights for all layout objects, computes positions, and
/// computes overflow regions. In Gecko this corresponds to `FinishAndStoreOverflow`.
-struct AssignHeightsAndStoreOverflowTraversal<'self>(&'self mut LayoutContext);
+struct AssignHeightsAndStoreOverflowTraversal<'a>(&'a mut LayoutContext);
-impl<'self> PostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'self> {
+impl<'a> PostorderFlowTraversal for AssignHeightsAndStoreOverflowTraversal<'a> {
#[inline]
fn process(&mut self, flow: &mut Flow) -> bool {
flow.assign_height(**self);
@@ -186,10 +188,10 @@ struct LayoutImageResponder {
}
impl ImageResponder for LayoutImageResponder {
- fn respond(&self) -> ~fn(ImageResponseMsg) {
+ fn respond(&self) -> proc(ImageResponseMsg) {
let id = self.id.clone();
let script_chan = self.script_chan.clone();
- let f: ~fn(ImageResponseMsg) = |_| {
+ let f: proc(ImageResponseMsg) = proc(_) {
script_chan.send(SendEventMsg(id.clone(), ReflowEvent))
};
f
@@ -200,6 +202,7 @@ impl LayoutTask {
/// Spawns a new layout task.
pub fn create(id: PipelineId,
port: Port<Msg>,
+ chan: LayoutChan,
constellation_chan: ConstellationChan,
script_chan: ScriptChan,
render_chan: RenderChan<OpaqueNode>,
@@ -207,11 +210,11 @@ impl LayoutTask {
opts: Opts,
profiler_chan: ProfilerChan,
shutdown_chan: Chan<()>) {
- spawn_with!(task::task(), [port, constellation_chan, script_chan,
- render_chan, img_cache_task, profiler_chan, shutdown_chan], {
- { // Ensures LayoutTask gets destroyed before we send the shutdown message
+ spawn(proc() {
+ { // Ensures layout task is destroyed before we send shutdown message
let mut layout = LayoutTask::new(id,
port,
+ chan,
constellation_chan,
script_chan,
render_chan,
@@ -220,7 +223,6 @@ impl LayoutTask {
profiler_chan);
layout.start();
}
-
shutdown_chan.send(());
});
}
@@ -228,6 +230,7 @@ impl LayoutTask {
/// Creates a new `LayoutTask` structure.
fn new(id: PipelineId,
port: Port<Msg>,
+ chan: LayoutChan,
constellation_chan: ConstellationChan,
script_chan: ScriptChan,
render_chan: RenderChan<OpaqueNode>,
@@ -239,6 +242,7 @@ impl LayoutTask {
LayoutTask {
id: id,
port: port,
+ chan: chan,
constellation_chan: constellation_chan,
script_chan: script_chan,
render_chan: render_chan,
@@ -281,17 +285,15 @@ impl LayoutTask {
match self.port.recv() {
AddStylesheetMsg(sheet) => self.handle_add_stylesheet(sheet),
ReflowMsg(data) => {
- let data = Cell::new(data);
-
- do profile(time::LayoutPerformCategory, self.profiler_chan.clone()) {
- self.handle_reflow(data.take());
- }
+ profile(time::LayoutPerformCategory, self.profiler_chan.clone(), || {
+ self.handle_reflow(data);
+ });
}
QueryMsg(query) => {
- let query = Cell::new(query);
- do profile(time::LayoutQueryCategory, self.profiler_chan.clone()) {
- self.handle_query(query.take());
- }
+ let mut query = Some(query);
+ profile(time::LayoutQueryCategory, self.profiler_chan.clone(), || {
+ self.handle_query(query.take_unwrap());
+ });
}
ReapLayoutDataMsg(dead_layout_data) => {
unsafe {
@@ -340,16 +342,16 @@ impl LayoutTask {
/// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely)
/// crash.
fn exit_now(&mut self) {
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
self.render_chan.send(render_task::ExitMsg(response_chan));
response_port.recv()
}
fn handle_add_stylesheet(&mut self, sheet: Stylesheet) {
- let sheet = Cell::new(sheet);
- do self.stylist.write |stylist| {
- stylist.add_stylesheet(sheet.take(), AuthorOrigin);
- }
+ let mut sheet = Some(sheet);
+ self.stylist.write(|stylist| {
+ stylist.add_stylesheet(sheet.take_unwrap(), AuthorOrigin);
+ });
}
/// Builds the flow tree.
@@ -359,12 +361,13 @@ impl LayoutTask {
/// is intertwined with selector matching, making it difficult to compare directly. It is
/// marked `#[inline(never)]` to aid benchmarking in sampling profilers.
#[inline(never)]
- fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: LayoutNode) -> ~Flow: {
+ fn construct_flow_tree(&self, layout_context: &mut LayoutContext, node: LayoutNode) -> ~Flow {
node.traverse_postorder_mut(&mut FlowConstructor::init(layout_context));
- let result = match *node.mutate_layout_data().ptr {
+ let mut layout_data_ref = node.mutate_layout_data();
+ let result = match *layout_data_ref.get() {
Some(ref mut layout_data) => {
- util::replace(&mut layout_data.flow_construction_result, NoConstructionResult)
+ util::replace(&mut layout_data.data.flow_construction_result, NoConstructionResult)
}
None => fail!("no layout data for root node"),
};
@@ -436,18 +439,18 @@ impl LayoutTask {
// Initialize layout data for each node.
//
// FIXME: This is inefficient. We don't need an entire traversal to do this!
- do profile(time::LayoutAuxInitCategory, self.profiler_chan.clone()) {
- node.initialize_style_for_subtree();
- }
+ profile(time::LayoutAuxInitCategory, self.profiler_chan.clone(), || {
+ node.initialize_style_for_subtree(self.chan.clone());
+ });
// Perform CSS selector matching if necessary.
match data.damage.level {
ReflowDocumentDamage => {}
_ => {
- do profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone()) {
+ profile(time::LayoutSelectorMatchCategory, self.profiler_chan.clone(), || {
node.match_subtree(self.stylist.clone());
node.cascade_subtree(None);
- }
+ });
}
}
@@ -464,25 +467,25 @@ impl LayoutTask {
// Perform the primary layout passes over the flow tree to compute the locations of all
// the boxes.
- do profile(time::LayoutMainCategory, self.profiler_chan.clone()) {
+ profile(time::LayoutMainCategory, self.profiler_chan.clone(), || {
self.solve_constraints(layout_root, &mut layout_ctx)
- }
+ });
debug!("layout: constraint solving done:");
debug!("{:?}", layout_root.dump());
// Build the display list if necessary, and send it to the renderer.
if data.goal == ReflowForDisplay {
- do profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone()) {
+ profile(time::LayoutDispListBuildCategory, self.profiler_chan.clone(), || {
let root_size = flow::base(layout_root).position.size;
- let display_list = ~Cell::new(DisplayList::<OpaqueNode>::new());
+ let display_list = ~RefCell::new(DisplayList::<OpaqueNode>::new());
let dirty = flow::base(layout_root).position.clone();
let display_list_builder = DisplayListBuilder {
ctx: &layout_ctx,
};
layout_root.build_display_list(&display_list_builder, &dirty, display_list);
- let display_list = Arc::new(display_list.take());
+ let display_list = Arc::new(display_list.unwrap());
let mut color = color::rgba(255.0, 255.0, 255.0, 255.0);
@@ -516,7 +519,7 @@ impl LayoutTask {
self.display_list = Some(display_list.clone());
self.render_chan.send(RenderMsg(render_layer));
- } // time(layout: display list building)
+ });
}
// Tell script that we're done.
@@ -663,8 +666,9 @@ impl LayoutTask {
/// Handles a message to destroy layout data. Layout data must be destroyed on *this* task
/// because it contains local managed pointers.
unsafe fn handle_reap_layout_data(&self, layout_data: LayoutDataRef) {
- let ptr: &mut Option<~LayoutData> = cast::transmute(layout_data.borrow_unchecked());
- *ptr = None
+ let mut layout_data_ref = layout_data.borrow_mut();
+ let _: Option<LayoutDataWrapper> = cast::transmute(
+ util::replace(layout_data_ref.get(), None));
}
}
diff --git a/src/components/main/layout/text.rs b/src/components/main/layout/text.rs
index bc3059695d6..72695c691b2 100644
--- a/src/components/main/layout/text.rs
+++ b/src/components/main/layout/text.rs
@@ -4,7 +4,7 @@
//! Text layout.
-use layout::box::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox};
+use layout::box_::{Box, ScannedTextBox, ScannedTextBoxInfo, UnscannedTextBox};
use layout::context::LayoutContext;
use layout::flow::Flow;
@@ -15,7 +15,7 @@ use servo_util::range::Range;
use std::vec;
/// A stack-allocated object for scanning an inline flow into `TextRun`-containing `TextBox`es.
-struct TextRunScanner {
+pub struct TextRunScanner {
clump: Range,
}
@@ -123,7 +123,7 @@ impl TextRunScanner {
// font group fonts. This is probably achieved by creating the font group above
// and then letting `FontGroup` decide which `Font` to stick into the text run.
let fontgroup = ctx.font_ctx.get_resolved_font_for_style(&font_style);
- let run = ~fontgroup.with_borrow(|fg| fg.create_textrun(transformed_text.clone(), decoration));
+ let run = ~fontgroup.borrow().with(|fg| fg.create_textrun(transformed_text.clone(), decoration));
debug!("TextRunScanner: pushing single text box in range: {} ({})",
self.clump,
@@ -142,7 +142,7 @@ impl TextRunScanner {
// First, transform/compress text of all the nodes.
let mut last_whitespace_in_clump = new_whitespace;
- let transformed_strs: ~[~str] = do vec::from_fn(self.clump.length()) |i| {
+ let transformed_strs: ~[~str] = vec::from_fn(self.clump.length(), |i| {
// TODO(#113): We should be passing the compression context between calls to
// `transform_text`, so that boxes starting and/or ending with whitespace can
// be compressed correctly with respect to the text run.
@@ -157,7 +157,7 @@ impl TextRunScanner {
last_whitespace_in_clump);
last_whitespace_in_clump = new_whitespace;
new_str
- };
+ });
new_whitespace = last_whitespace_in_clump;
// Next, concatenate all of the transformed strings together, saving the new
@@ -186,8 +186,8 @@ impl TextRunScanner {
// sequence. If no clump takes ownership, however, it will leak.
let clump = self.clump;
let run = if clump.length() != 0 && run_str.len() > 0 {
- fontgroup.with_borrow( |fg| {
- fg.fonts[0].with_mut_borrow( |font| {
+ fontgroup.borrow().with(|fg| {
+ fg.fonts[0].borrow().with_mut(|font| {
Some(Arc::new(~TextRun::new(font, run_str.clone(), decoration)))
})
})
@@ -216,14 +216,14 @@ impl TextRunScanner {
} // End of match.
debug!("--- In boxes: ---");
- for (i, box) in in_boxes.iter().enumerate() {
- debug!("{:u} --> {:s}", i, box.debug_str());
+ for (i, box_) in in_boxes.iter().enumerate() {
+ debug!("{:u} --> {:s}", i, box_.debug_str());
}
debug!("------------------");
debug!("--- Out boxes: ---");
- for (i, box) in out_boxes.iter().enumerate() {
- debug!("{:u} --> {:s}", i, box.debug_str());
+ for (i, box_) in out_boxes.iter().enumerate() {
+ debug!("{:u} --> {:s}", i, box_.debug_str());
}
debug!("------------------");
diff --git a/src/components/main/layout/util.rs b/src/components/main/layout/util.rs
index a5dc5047968..65cf0b6b676 100644
--- a/src/components/main/layout/util.rs
+++ b/src/components/main/layout/util.rs
@@ -2,15 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use layout::box::Box;
+use layout::box_::Box;
use layout::construct::{ConstructionResult, NoConstructionResult};
use layout::wrapper::LayoutNode;
use extra::arc::Arc;
use script::dom::node::AbstractNode;
+use script::layout_interface::LayoutChan;
use servo_util::range::Range;
-use servo_util::slot::{MutSlotRef, SlotRef};
use std::cast;
+use std::cell::{Ref, RefMut};
use std::iter::Enumerate;
use std::libc::uintptr_t;
use std::vec::VecIterator;
@@ -31,7 +32,7 @@ impl NodeRange {
}
}
-struct ElementMapping {
+pub struct ElementMapping {
priv entries: ~[NodeRange],
}
@@ -46,7 +47,7 @@ impl ElementMapping {
self.entries.push(NodeRange::new(node, range))
}
- pub fn each(&self, callback: &fn(nr: &NodeRange) -> bool) -> bool {
+ pub fn each(&self, callback: |nr: &NodeRange| -> bool) -> bool {
for nr in self.entries.iter() {
if !callback(nr) {
break
@@ -63,14 +64,14 @@ impl ElementMapping {
let entries = &mut self.entries;
debug!("--- Old boxes: ---");
- for (i, box) in old_boxes.iter().enumerate() {
- debug!("{:u} --> {:s}", i, box.debug_str());
+ for (i, box_) in old_boxes.iter().enumerate() {
+ debug!("{:u} --> {:s}", i, box_.debug_str());
}
debug!("------------------");
debug!("--- New boxes: ---");
- for (i, box) in new_boxes.iter().enumerate() {
- debug!("{:u} --> {:s}", i, box.debug_str());
+ for (i, box_) in new_boxes.iter().enumerate() {
+ debug!("{:u} --> {:s}", i, box_.debug_str());
}
debug!("------------------");
@@ -125,7 +126,7 @@ impl ElementMapping {
}
/// Data that layout associates with a node.
-pub struct LayoutData {
+pub struct PrivateLayoutData {
/// The results of CSS matching for this node.
before_applicable_declarations: ~[Arc<~[PropertyDeclaration]>],
@@ -148,10 +149,10 @@ pub struct LayoutData {
flow_construction_result: ConstructionResult,
}
-impl LayoutData {
+impl PrivateLayoutData {
/// Creates new layout data.
- pub fn new() -> LayoutData {
- LayoutData {
+ pub fn new() -> PrivateLayoutData {
+ PrivateLayoutData {
applicable_declarations: ~[],
before_applicable_declarations: ~[],
after_applicable_declarations: ~[],
@@ -164,35 +165,35 @@ impl LayoutData {
}
}
+pub struct LayoutDataWrapper {
+ chan: Option<LayoutChan>,
+ data: ~PrivateLayoutData,
+}
+
/// A trait that allows access to the layout data of a DOM node.
pub trait LayoutDataAccess {
/// Borrows the layout data without checks.
///
/// FIXME(pcwalton): Make safe.
- unsafe fn borrow_layout_data_unchecked<'a>(&'a self) -> &'a Option<~LayoutData>;
+ // unsafe fn borrow_layout_data_unchecked<'a>(&'a self) -> &'a Option<~LayoutData>;
/// Borrows the layout data immutably. Fails on a conflicting borrow.
- fn borrow_layout_data<'a>(&'a self) -> SlotRef<'a,Option<~LayoutData>>;
+ fn borrow_layout_data<'a>(&'a self) -> Ref<'a,Option<LayoutDataWrapper>>;
/// Borrows the layout data mutably. Fails on a conflicting borrow.
- fn mutate_layout_data<'a>(&'a self) -> MutSlotRef<'a,Option<~LayoutData>>;
+ fn mutate_layout_data<'a>(&'a self) -> RefMut<'a,Option<LayoutDataWrapper>>;
}
-impl<'self> LayoutDataAccess for LayoutNode<'self> {
- #[inline(always)]
- unsafe fn borrow_layout_data_unchecked<'a>(&'a self) -> &'a Option<~LayoutData> {
- cast::transmute(self.get().layout_data.borrow_unchecked())
- }
-
+impl<'ln> LayoutDataAccess for LayoutNode<'ln> {
#[inline(always)]
- fn borrow_layout_data<'a>(&'a self) -> SlotRef<'a,Option<~LayoutData>> {
+ fn borrow_layout_data<'a>(&'a self) -> Ref<'a,Option<LayoutDataWrapper>> {
unsafe {
cast::transmute(self.get().layout_data.borrow())
}
}
#[inline(always)]
- fn mutate_layout_data<'a>(&'a self) -> MutSlotRef<'a,Option<~LayoutData>> {
+ fn mutate_layout_data<'a>(&'a self) -> RefMut<'a,Option<LayoutDataWrapper>> {
unsafe {
- cast::transmute(self.get().layout_data.mutate())
+ cast::transmute(self.get().layout_data.borrow_mut())
}
}
}
diff --git a/src/components/main/layout/wrapper.rs b/src/components/main/layout/wrapper.rs
index 619c711329a..f41fdb67d26 100644
--- a/src/components/main/layout/wrapper.rs
+++ b/src/components/main/layout/wrapper.rs
@@ -29,17 +29,17 @@ use style::{PropertyDeclarationBlock, TElement, TNode};
/// A wrapper so that layout can access only the methods that it should have access to. Layout must
/// only ever see these and must never see instances of `AbstractNode`.
#[deriving(Clone, Eq)]
-pub struct LayoutNode<'self> {
+pub struct LayoutNode<'a> {
/// The wrapped node.
priv node: AbstractNode,
/// Being chained to a value prevents `LayoutNode`s from escaping.
- priv chain: &'self (),
+ priv chain: &'a (),
}
-impl<'self> LayoutNode<'self> {
+impl<'ln> LayoutNode<'ln> {
/// Creates a new layout node, scoped to the given closure.
- pub unsafe fn with_layout_node<R>(node: AbstractNode, f: &fn<'a>(LayoutNode<'a>) -> R) -> R {
+ pub unsafe fn with_layout_node<R>(node: AbstractNode, f: <'a> |LayoutNode<'a>| -> R) -> R {
let heavy_iron_ball = ();
f(LayoutNode {
node: node,
@@ -48,7 +48,7 @@ impl<'self> LayoutNode<'self> {
}
/// Creates a new layout node with the same lifetime as this layout node.
- unsafe fn new_with_this_lifetime(&self, node: AbstractNode) -> LayoutNode<'self> {
+ unsafe fn new_with_this_lifetime(&self, node: AbstractNode) -> LayoutNode<'ln> {
LayoutNode {
node: node,
chain: self.chain,
@@ -62,14 +62,14 @@ impl<'self> LayoutNode<'self> {
}
/// Returns the first child of this node.
- pub fn first_child(&self) -> Option<LayoutNode<'self>> {
+ pub fn first_child(&self) -> Option<LayoutNode<'ln>> {
unsafe {
self.node.first_child().map(|node| self.new_with_this_lifetime(node))
}
}
/// Returns the first child of this node.
- pub fn last_child(&self) -> Option<LayoutNode<'self>> {
+ pub fn last_child(&self) -> Option<LayoutNode<'ln>> {
unsafe {
self.node.last_child().map(|node| self.new_with_this_lifetime(node))
}
@@ -78,14 +78,14 @@ impl<'self> LayoutNode<'self> {
/// Iterates over this node and all its descendants, in preorder.
///
/// FIXME(pcwalton): Terribly inefficient. We should use parallelism.
- pub fn traverse_preorder(&self) -> LayoutTreeIterator<'self> {
+ pub fn traverse_preorder(&self) -> LayoutTreeIterator<'ln> {
let mut nodes = ~[];
gather_layout_nodes(self, &mut nodes, false);
LayoutTreeIterator::new(nodes)
}
/// Returns an iterator over this node's children.
- pub fn children(&self) -> LayoutNodeChildrenIterator<'self> {
+ pub fn children(&self) -> LayoutNodeChildrenIterator<'ln> {
LayoutNodeChildrenIterator {
current_node: self.first_child(),
}
@@ -110,7 +110,7 @@ impl<'self> LayoutNode<'self> {
/// Downcasts this node to an image element and calls the given closure.
///
/// FIXME(pcwalton): RAII.
- unsafe fn with_image_element<R>(self, f: &fn(&HTMLImageElement) -> R) -> R {
+ unsafe fn with_image_element<R>(self, f: |&HTMLImageElement| -> R) -> R {
if !self.node.is_image_element() {
fail!(~"node is not an image element");
}
@@ -131,7 +131,7 @@ impl<'self> LayoutNode<'self> {
/// Downcasts this node to an iframe element and calls the given closure.
///
/// FIXME(pcwalton): RAII.
- unsafe fn with_iframe_element<R>(self, f: &fn(&HTMLIFrameElement) -> R) -> R {
+ unsafe fn with_iframe_element<R>(self, f: |&HTMLIFrameElement| -> R) -> R {
if !self.node.is_iframe_element() {
fail!(~"node is not an iframe element");
}
@@ -164,7 +164,7 @@ impl<'self> LayoutNode<'self> {
/// Downcasts this node to a text node and calls the given closure.
///
/// FIXME(pcwalton): RAII.
- unsafe fn with_text<R>(self, f: &fn(&Text) -> R) -> R {
+ unsafe fn with_text<R>(self, f: |&Text| -> R) -> R {
self.node.with_imm_text(f)
}
@@ -228,20 +228,20 @@ impl<'self> LayoutNode<'self> {
}
}
-impl<'self> TNode<LayoutElement<'self>> for LayoutNode<'self> {
- fn parent_node(&self) -> Option<LayoutNode<'self>> {
+impl<'ln> TNode<LayoutElement<'ln>> for LayoutNode<'ln> {
+ fn parent_node(&self) -> Option<LayoutNode<'ln>> {
unsafe {
self.node.node().parent_node.map(|node| self.new_with_this_lifetime(node))
}
}
- fn prev_sibling(&self) -> Option<LayoutNode<'self>> {
+ fn prev_sibling(&self) -> Option<LayoutNode<'ln>> {
unsafe {
self.node.node().prev_sibling.map(|node| self.new_with_this_lifetime(node))
}
}
- fn next_sibling(&self) -> Option<LayoutNode<'self>> {
+ fn next_sibling(&self) -> Option<LayoutNode<'ln>> {
unsafe {
self.node.node().next_sibling.map(|node| self.new_with_this_lifetime(node))
}
@@ -249,21 +249,21 @@ impl<'self> TNode<LayoutElement<'self>> for LayoutNode<'self> {
fn is_element(&self) -> bool {
match self.node.type_id() {
- ElementNodeTypeId(*) => true,
+ ElementNodeTypeId(..) => true,
_ => false
}
}
fn is_document(&self) -> bool {
match self.node.type_id() {
- DocumentNodeTypeId(*) => true,
+ DocumentNodeTypeId(..) => true,
_ => false
}
}
/// If this is an element, accesses the element data. Fails if this is not an element node.
#[inline]
- fn with_element<R>(&self, f: &fn(&LayoutElement<'self>) -> R) -> R {
+ fn with_element<R>(&self, f: |&LayoutElement<'ln>| -> R) -> R {
self.node.with_imm_element(|element| {
// FIXME(pcwalton): Workaround until Rust gets multiple lifetime parameters on
// implementations.
@@ -276,16 +276,16 @@ impl<'self> TNode<LayoutElement<'self>> for LayoutNode<'self> {
}
}
-pub struct LayoutNodeChildrenIterator<'self> {
- priv current_node: Option<LayoutNode<'self>>,
+pub struct LayoutNodeChildrenIterator<'a> {
+ priv current_node: Option<LayoutNode<'a>>,
}
-impl<'self> Iterator<LayoutNode<'self>> for LayoutNodeChildrenIterator<'self> {
- fn next(&mut self) -> Option<LayoutNode<'self>> {
+impl<'a> Iterator<LayoutNode<'a>> for LayoutNodeChildrenIterator<'a> {
+ fn next(&mut self) -> Option<LayoutNode<'a>> {
let node = self.current_node;
- self.current_node = do self.current_node.and_then |node| {
+ self.current_node = self.current_node.and_then(|node| {
node.next_sibling()
- };
+ });
node
}
}
@@ -294,13 +294,13 @@ impl<'self> Iterator<LayoutNode<'self>> for LayoutNodeChildrenIterator<'self> {
// Easy for preorder; harder for postorder.
//
// FIXME(pcwalton): Parallelism! Eventually this should just be nuked.
-pub struct LayoutTreeIterator<'self> {
- priv nodes: ~[LayoutNode<'self>],
+pub struct LayoutTreeIterator<'a> {
+ priv nodes: ~[LayoutNode<'a>],
priv index: uint,
}
-impl<'self> LayoutTreeIterator<'self> {
- fn new(nodes: ~[LayoutNode<'self>]) -> LayoutTreeIterator<'self> {
+impl<'a> LayoutTreeIterator<'a> {
+ fn new(nodes: ~[LayoutNode<'a>]) -> LayoutTreeIterator<'a> {
LayoutTreeIterator {
nodes: nodes,
index: 0,
@@ -308,8 +308,8 @@ impl<'self> LayoutTreeIterator<'self> {
}
}
-impl<'self> Iterator<LayoutNode<'self>> for LayoutTreeIterator<'self> {
- fn next(&mut self) -> Option<LayoutNode<'self>> {
+impl<'a> Iterator<LayoutNode<'a>> for LayoutTreeIterator<'a> {
+ fn next(&mut self) -> Option<LayoutNode<'a>> {
if self.index >= self.nodes.len() {
None
} else {
@@ -360,17 +360,17 @@ pub trait PostorderNodeMutTraversal {
}
/// A wrapper around elements that ensures layout can only ever access safe properties.
-pub struct LayoutElement<'self> {
- priv element: &'self Element,
+pub struct LayoutElement<'le> {
+ priv element: &'le Element,
}
-impl<'self> LayoutElement<'self> {
- pub fn style_attribute(&self) -> &'self Option<PropertyDeclarationBlock> {
+impl<'le> LayoutElement<'le> {
+ pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
&self.element.style_attribute
}
}
-impl<'self> TElement for LayoutElement<'self> {
+impl<'le> TElement for LayoutElement<'le> {
fn get_local_name<'a>(&'a self) -> &'a str {
self.element.tag_name.as_slice()
}
diff --git a/src/components/main/macros.rs b/src/components/main/macros.rs
index 34b0d2ac869..4feab0d94bc 100644
--- a/src/components/main/macros.rs
+++ b/src/components/main/macros.rs
@@ -2,26 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[macro_escape];
-macro_rules! special_stream(
- ($Chan:ident) => (
- {
- let (port, chan) = stream::();
- (port, $Chan::new(chan))
- }
- );
-)
// Spawn a task, capturing the listed variables in a way that avoids the
// move-from-closure error. This is sugar around the function spawn_with,
// taking care of building a tuple and a lambda.
-//
-// FIXME: Once cross-crate macros work, there are a few places outside of
-// the main crate which could benefit from this macro.
-macro_rules! spawn_with(
- ($task:expr, [ $($var:ident),+ ], $body:block) => (
- do ($task).spawn_with(( $($var),+ , () )) |( $($var),+ , () )| $body
- )
-)
macro_rules! bitfield(
($bitfieldname:ident, $getter:ident, $setter:ident, $value:expr) => (
diff --git a/src/components/main/pipeline.rs b/src/components/main/pipeline.rs
index 9fe5094bcbc..8f5aaef929d 100644
--- a/src/components/main/pipeline.rs
+++ b/src/components/main/pipeline.rs
@@ -15,12 +15,10 @@ use script::layout_interface::LayoutChan;
use script::script_task::LoadMsg;
use script::script_task::{AttachLayoutMsg, NewLayoutInfo, ScriptTask, ScriptChan};
use script::script_task;
-use servo_msg::constellation_msg::{ConstellationChan, FailureMsg, PipelineId, SubpageId};
+use servo_msg::constellation_msg::{ConstellationChan, PipelineId, SubpageId};
use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::ResourceTask;
use servo_util::time::ProfilerChan;
-use std::task;
-use std::comm;
/// A uniquely-identifiable pipeline of script task, layout task, and render task.
pub struct Pipeline {
@@ -55,10 +53,10 @@ impl Pipeline {
opts: Opts,
script_pipeline: &Pipeline)
-> Pipeline {
- let (layout_port, layout_chan) = special_stream!(LayoutChan);
- let (render_port, render_chan) = special_stream!(RenderChan);
- let (render_shutdown_port, render_shutdown_chan) = comm::stream();
- let (layout_shutdown_port, layout_shutdown_chan) = comm::stream();
+ let (layout_port, layout_chan) = LayoutChan::new();
+ let (render_port, render_chan) = RenderChan::new();
+ let (render_shutdown_port, render_shutdown_chan) = Chan::new();
+ let (layout_shutdown_port, layout_shutdown_chan) = Chan::new();
RenderTask::create(id,
render_port,
@@ -70,6 +68,7 @@ impl Pipeline {
LayoutTask::create(id,
layout_port,
+ layout_chan.clone(),
constellation_chan,
script_pipeline.script_chan.clone(),
render_chan.clone(),
@@ -105,11 +104,11 @@ impl Pipeline {
window_size: Size2D<uint>,
opts: Opts)
-> Pipeline {
- let (script_port, script_chan) = special_stream!(ScriptChan);
- let (layout_port, layout_chan) = special_stream!(LayoutChan);
- let (render_port, render_chan) = special_stream!(RenderChan);
- let (render_shutdown_port, render_shutdown_chan) = comm::stream();
- let (layout_shutdown_port, layout_shutdown_chan) = comm::stream();
+ let (script_port, script_chan) = ScriptChan::new();
+ let (layout_port, layout_chan) = LayoutChan::new();
+ let (render_port, render_chan) = RenderChan::new();
+ let (render_shutdown_port, render_shutdown_chan) = Chan::new();
+ let (layout_shutdown_port, layout_shutdown_chan) = Chan::new();
let pipeline = Pipeline::new(id,
subpage_id,
script_chan.clone(),
@@ -118,65 +117,36 @@ impl Pipeline {
layout_shutdown_port,
render_shutdown_port);
- // Wrap task creation within a supervised task so that failure will
- // only tear down those tasks instead of ours.
- let hard_fail = opts.hard_fail;
- let failure_chan = constellation_chan.clone();
- let mut supervised_task = task::task();
- let task_port = supervised_task.future_result();
- supervised_task.supervised();
-
- spawn_with!(supervised_task, [
- script_port,
- resource_task,
- render_port,
- layout_port,
- constellation_chan,
- image_cache_task,
- profiler_chan,
- layout_shutdown_chan,
- render_shutdown_chan
- ], {
- ScriptTask::create(id,
- compositor_chan.clone(),
- layout_chan.clone(),
- script_port,
- script_chan.clone(),
- constellation_chan.clone(),
- resource_task,
- image_cache_task.clone(),
- window_size);
-
- RenderTask::create(id,
- render_port,
- compositor_chan.clone(),
- constellation_chan.clone(),
- opts.clone(),
- profiler_chan.clone(),
- render_shutdown_chan);
-
- LayoutTask::create(id,
- layout_port,
- constellation_chan,
- script_chan.clone(),
- render_chan.clone(),
- image_cache_task,
- opts.clone(),
- profiler_chan,
- layout_shutdown_chan);
- });
+ // FIXME(#1434): add back failure supervision
- spawn_with!(task::task(), [failure_chan], {
- match task_port.recv() {
- Ok(*) => (),
- Err(*) => {
- if hard_fail {
- fail!("Pipeline failed in hard-fail mode");
- }
- failure_chan.send(FailureMsg(id, subpage_id));
- }
- }
- });
+ ScriptTask::create(id,
+ compositor_chan.clone(),
+ layout_chan.clone(),
+ script_port,
+ script_chan.clone(),
+ constellation_chan.clone(),
+ resource_task,
+ image_cache_task.clone(),
+ window_size);
+
+ RenderTask::create(id,
+ render_port,
+ compositor_chan.clone(),
+ constellation_chan.clone(),
+ opts.clone(),
+ profiler_chan.clone(),
+ render_shutdown_chan);
+
+ LayoutTask::create(id,
+ layout_port,
+ layout_chan.clone(),
+ constellation_chan,
+ script_chan.clone(),
+ render_chan.clone(),
+ image_cache_task,
+ opts.clone(),
+ profiler_chan,
+ layout_shutdown_chan);
pipeline
}
@@ -215,9 +185,9 @@ impl Pipeline {
}
pub fn reload(&mut self) {
- do self.url.clone().map() |url| {
+ self.url.clone().map(|url| {
self.load(url);
- };
+ });
}
pub fn exit(&self) {
@@ -226,8 +196,8 @@ impl Pipeline {
// Wait until all slave tasks have terminated and run destructors
// NOTE: We don't wait for script task as we don't always own it
- self.render_shutdown_port.try_recv();
- self.layout_shutdown_port.try_recv();
+ self.render_shutdown_port.recv_opt();
+ self.layout_shutdown_port.recv_opt();
}
pub fn to_sendable(&self) -> CompositionPipeline {
diff --git a/src/components/main/platform/common/glfw_windowing.rs b/src/components/main/platform/common/glfw_windowing.rs
index 5b99f5c243b..9c4c8b12f91 100644
--- a/src/components/main/platform/common/glfw_windowing.rs
+++ b/src/components/main/platform/common/glfw_windowing.rs
@@ -30,9 +30,7 @@ impl ApplicationMethods for Application {
fn new() -> Application {
// Per GLFW docs it's safe to set the error callback before calling
// glfwInit(), and this way we notice errors from init too.
- do glfw::set_error_callback |_error_code, description| {
- error!("GLFW error: {:s}", description);
- };
+ glfw::set_error_callback(~glfw::LogErrorHandler);
glfw::init();
Application
}
@@ -45,6 +43,38 @@ impl Drop for Application {
}
}
+macro_rules! glfw_callback(
+ (
+ $callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
+ ) => ({
+ struct GlfwCallback;
+ impl $callback for GlfwCallback {
+ fn call(&self $(, $arg: $arg_ty)*) {
+ $block
+ }
+ }
+ ~GlfwCallback
+ });
+
+ (
+ [$($state:ident: $state_ty:ty),*],
+ $callback:path ($($arg:ident: $arg_ty:ty),*) $block:expr
+ ) => ({
+ struct GlfwCallback {
+ $($state: $state_ty,)*
+ }
+ impl $callback for GlfwCallback {
+ fn call(&self $(, $arg: $arg_ty)*) {
+ $block
+ }
+ }
+ ~GlfwCallback {
+ $($state: $state,)*
+ }
+ });
+)
+
+
/// The type of a window.
pub struct Window {
glfw_window: glfw::Window,
@@ -90,43 +120,50 @@ impl WindowMethods<Application> for Window {
install_local_window(window);
// Register event handlers.
- do window.glfw_window.set_framebuffer_size_callback |_win, width, height| {
- local_window().event_queue.push(ResizeWindowEvent(width as uint, height as uint))
- }
- do window.glfw_window.set_refresh_callback |_win| {
- local_window().event_queue.push(RefreshWindowEvent)
- }
- do window.glfw_window.set_key_callback |_win, key, _scancode, action, mods| {
- if action == glfw::Press {
- local_window().handle_key(key, mods)
- }
- }
- do window.glfw_window.set_mouse_button_callback |win, button, action, _mods| {
- let (x, y) = win.get_cursor_pos();
- //handle hidpi displays, since GLFW returns non-hi-def coordinates.
- let (backing_size, _) = win.get_framebuffer_size();
- let (window_size, _) = win.get_size();
- let hidpi = (backing_size as f32) / (window_size as f32);
- let x = x as f32 * hidpi;
- let y = y as f32 * hidpi;
- if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
- local_window().handle_mouse(button, action, x as i32, y as i32);
- }
- }
- do window.glfw_window.set_scroll_callback |win, x_offset, y_offset| {
- let dx = (x_offset as f32) * 30.0;
- let dy = (y_offset as f32) * 30.0;
+ window.glfw_window.set_framebuffer_size_callback(
+ glfw_callback!(glfw::FramebufferSizeCallback(_win: &glfw::Window, width: i32, height: i32) {
+ local_window().event_queue.push(ResizeWindowEvent(width as uint, height as uint));
+ }));
+ window.glfw_window.set_refresh_callback(
+ glfw_callback!(glfw::WindowRefreshCallback(_win: &glfw::Window) {
+ local_window().event_queue.push(RefreshWindowEvent);
+ }));
+ window.glfw_window.set_key_callback(
+ glfw_callback!(glfw::KeyCallback(_win: &glfw::Window, key: glfw::Key, _scancode: c_int,
+ action: glfw::Action, mods: glfw::Modifiers) {
+ if action == glfw::Press {
+ local_window().handle_key(key, mods)
+ }
+ }));
+ window.glfw_window.set_mouse_button_callback(
+ glfw_callback!(glfw::MouseButtonCallback(win: &glfw::Window, button: glfw::MouseButton,
+ action: glfw::Action, _mods: glfw::Modifiers) {
+ let (x, y) = win.get_cursor_pos();
+ //handle hidpi displays, since GLFW returns non-hi-def coordinates.
+ let (backing_size, _) = win.get_framebuffer_size();
+ let (window_size, _) = win.get_size();
+ let hidpi = (backing_size as f32) / (window_size as f32);
+ let x = x as f32 * hidpi;
+ let y = y as f32 * hidpi;
+ if button == glfw::MouseButtonLeft || button == glfw::MouseButtonRight {
+ local_window().handle_mouse(button, action, x as i32, y as i32);
+ }
+ }));
+ window.glfw_window.set_scroll_callback(
+ glfw_callback!(glfw::ScrollCallback(win: &glfw::Window, xpos: f64, ypos: f64) {
+ let dx = (xpos as f32) * 30.0;
+ let dy = (ypos as f32) * 30.0;
- let (x, y) = win.get_cursor_pos();
- //handle hidpi displays, since GLFW returns non-hi-def coordinates.
- let (backing_size, _) = win.get_framebuffer_size();
- let (window_size, _) = win.get_size();
- let hidpi = (backing_size as f32) / (window_size as f32);
- let x = x as f32 * hidpi;
- let y = y as f32 * hidpi;
-
- local_window().event_queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32)));
- }
+ let (x, y) = win.get_cursor_pos();
+ //handle hidpi displays, since GLFW returns non-hi-def coordinates.
+ let (backing_size, _) = win.get_framebuffer_size();
+ let (window_size, _) = win.get_size();
+ let hidpi = (backing_size as f32) / (window_size as f32);
+ let x = x as f32 * hidpi;
+ let y = y as f32 * hidpi;
+
+ local_window().event_queue.push(ScrollWindowEvent(Point2D(dx, dy), Point2D(x as i32, y as i32)));
+ }));
window
}
diff --git a/src/components/main/platform/common/glut_windowing.rs b/src/components/main/platform/common/glut_windowing.rs
index b781d562a5c..38457aed4e5 100644
--- a/src/components/main/platform/common/glut_windowing.rs
+++ b/src/components/main/platform/common/glut_windowing.rs
@@ -7,22 +7,22 @@
use windowing::{ApplicationMethods, WindowEvent, WindowMethods};
use windowing::{IdleWindowEvent, ResizeWindowEvent, LoadUrlWindowEvent, MouseWindowEventClass};
use windowing::{ScrollWindowEvent, ZoomWindowEvent, NavigationWindowEvent, FinishedWindowEvent};
-use windowing::{QuitWindowEvent, MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
+use windowing::{MouseWindowClickEvent, MouseWindowMouseDownEvent, MouseWindowMouseUpEvent};
use windowing::{Forward, Back};
use alert::{Alert, AlertMethods};
-use std::libc::c_int;
+use std::libc::{c_int, c_uchar};
use std::local_data;
use geom::point::Point2D;
use geom::size::Size2D;
use servo_msg::compositor_msg::{IdleRenderState, RenderState, RenderingRenderState};
-use servo_msg::compositor_msg::{FinishedLoading, Blank, Loading, PerformingLayout, ReadyState};
+use servo_msg::compositor_msg::{FinishedLoading, Blank, ReadyState};
-use glut::glut::{ACTIVE_CTRL, ACTIVE_SHIFT, DOUBLE, HAVE_PRECISE_MOUSE_WHEEL, WindowHeight};
+use glut::glut::{ACTIVE_SHIFT, DOUBLE, WindowHeight};
use glut::glut::WindowWidth;
use glut::glut;
-static THROBBER: [char, ..8] = [ '⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷' ];
+// static THROBBER: [char, ..8] = [ '⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷' ];
/// A structure responsible for setting up and tearing down the entire windowing system.
pub struct Application;
@@ -85,31 +85,47 @@ impl WindowMethods<Application> for Window {
// Register event handlers.
//Added dummy display callback to freeglut. According to freeglut ref, we should register some kind of display callback after freeglut 3.0.
- do glut::display_func || {
- debug!("GLUT display func registered");
- }
- do glut::reshape_func(window.glut_window) |width, height| {
- local_window().event_queue.push(ResizeWindowEvent(width as uint, height as uint))
+
+ struct DisplayCallbackState;
+ impl glut::DisplayCallback for DisplayCallbackState {
+ fn call(&self) {
+ debug!("GLUT display func registgered");
+ }
}
- do glut::keyboard_func |key, _, _| {
- local_window().handle_key(key)
+ glut::display_func(~DisplayCallbackState);
+ struct ReshapeCallbackState;
+ impl glut::ReshapeCallback for ReshapeCallbackState {
+ fn call(&self, width: c_int, height: c_int) {
+ local_window().event_queue.push(ResizeWindowEvent(width as uint, height as uint))
+ }
}
- do glut::mouse_func |button, state, x, y| {
- if button < 3 {
- local_window().handle_mouse(button, state, x, y);
+ glut::reshape_func(glut_window, ~ReshapeCallbackState);
+ struct KeyboardCallbackState;
+ impl glut::KeyboardCallback for KeyboardCallbackState {
+ fn call(&self, key: c_uchar, _x: c_int, _y: c_int) {
+ local_window().handle_key(key)
}
- else {
- match button {
- 3 => {
- local_window().event_queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32)));
- },
- 4 => {
- local_window().event_queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32)));
- },
- _ => {}
+ }
+ glut::keyboard_func(~KeyboardCallbackState);
+ struct MouseCallbackState;
+ impl glut::MouseCallback for MouseCallbackState {
+ fn call(&self, button: c_int, state: c_int, x: c_int, y: c_int) {
+ if button < 3 {
+ local_window().handle_mouse(button, state, x, y);
+ } else {
+ match button {
+ 3 => {
+ local_window().event_queue.push(ScrollWindowEvent(Point2D(0.0, 5.0 as f32), Point2D(0.0 as i32, 5.0 as i32)));
+ },
+ 4 => {
+ local_window().event_queue.push(ScrollWindowEvent(Point2D(0.0, -5.0 as f32), Point2D(0.0 as i32, -5.0 as i32)));
+ },
+ _ => {}
+ }
}
}
}
+ glut::mouse_func(~MouseCallbackState);
window
}
@@ -165,28 +181,28 @@ impl WindowMethods<Application> for Window {
impl Window {
/// Helper function to set the window title in accordance with the ready state.
- fn update_window_title(&self) {
- let throbber = THROBBER[self.throbber_frame];
- match self.ready_state {
- Blank => {
- glut::set_window_title(self.glut_window, "Blank")
- }
- Loading => {
- glut::set_window_title(self.glut_window, format!("{:c} Loading . Servo", throbber))
- }
- PerformingLayout => {
- glut::set_window_title(self.glut_window, format!("{:c} Performing Layout . Servo", throbber))
- }
- FinishedLoading => {
- match self.render_state {
- RenderingRenderState => {
- glut::set_window_title(self.glut_window, format!("{:c} Rendering . Servo", throbber))
- }
- IdleRenderState => glut::set_window_title(self.glut_window, "Servo"),
- }
- }
- }
- }
+ // fn update_window_title(&self) {
+ // let throbber = THROBBER[self.throbber_frame];
+ // match self.ready_state {
+ // Blank => {
+ // glut::set_window_title(self.glut_window, "Blank")
+ // }
+ // Loading => {
+ // glut::set_window_title(self.glut_window, format!("{:c} Loading . Servo", throbber))
+ // }
+ // PerformingLayout => {
+ // glut::set_window_title(self.glut_window, format!("{:c} Performing Layout . Servo", throbber))
+ // }
+ // FinishedLoading => {
+ // match self.render_state {
+ // RenderingRenderState => {
+ // glut::set_window_title(self.glut_window, format!("{:c} Rendering . Servo", throbber))
+ // }
+ // IdleRenderState => glut::set_window_title(self.glut_window, "Servo"),
+ // }
+ // }
+ // }
+ // }
/// Helper function to handle keyboard events.
fn handle_key(&self, key: u8) {
diff --git a/src/components/main/servo.rc b/src/components/main/servo.rc
index 5dc43a3bb4e..6b1bbe37302 100755
--- a/src/components/main/servo.rc
+++ b/src/components/main/servo.rc
@@ -2,21 +2,16 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#[link(name = "servo",
- vers = "0.1",
- uuid = "637ffc98-9058-471d-9de7-abfc49ef0549",
- url = "http://servo.org/")];
-
+#[crate_id = "github.com/mozilla/servo"];
#[comment = "The Servo Parallel Browser Project"];
#[license = "MPL"];
-#[crate_type = "lib"];
#[feature(globs, macro_rules, managed_boxes)];
extern mod alert;
extern mod azure;
extern mod geom;
-extern mod gfx (name = "gfx");
+extern mod gfx;
#[cfg(not(target_os="android"))]
extern mod glfw;
#[cfg(target_os="android")]
@@ -26,39 +21,50 @@ extern mod layers;
extern mod opengles;
extern mod png;
extern mod script;
-extern mod servo_net (name = "net");
-extern mod servo_msg (name = "msg");
-extern mod servo_util (name = "util");
+extern mod servo_net = "net";
+extern mod servo_msg = "msg";
+extern mod servo_util = "util";
extern mod style;
extern mod sharegl;
extern mod stb_image;
+
extern mod extra;
+extern mod green;
+extern mod native;
#[cfg(target_os="macos")]
extern mod core_graphics;
#[cfg(target_os="macos")]
extern mod core_text;
+#[cfg(not(test))]
use compositing::{CompositorChan, CompositorTask};
+#[cfg(not(test))]
use constellation::Constellation;
-use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};
+#[cfg(not(test))]
+use servo_msg::constellation_msg::InitLoadUrlMsg;
#[cfg(not(test))]
use gfx::opts;
+#[cfg(not(test))]
use servo_net::image_cache_task::ImageCacheTask;
+#[cfg(not(test))]
use servo_net::resource_task::ResourceTask;
-use servo_util::time::{Profiler, ProfilerChan};
+#[cfg(not(test))]
+use servo_util::time::Profiler;
pub use gfx::opts::Opts;
pub use gfx::text;
pub use servo_util::url::make_url;
-use std::comm;
+
#[cfg(not(test))]
use std::os;
#[cfg(not(test), target_os="android")]
use std::str;
-use std::task::spawn_with;
+#[cfg(not(test))]
+use std::task::TaskOpts;
+
#[path="compositing/compositor_task.rs"]
pub mod compositing;
@@ -78,7 +84,7 @@ pub mod pipeline;
pub mod layout {
pub mod block;
- pub mod box;
+ pub mod box_;
pub mod construct;
pub mod context;
pub mod display_list_builder;
@@ -106,15 +112,15 @@ pub mod util;
#[cfg(not(test), target_os="macos")]
#[start]
fn start(argc: int, argv: **u8) -> int {
- do std::rt::start_on_main_thread(argc, argv) {
+ native::start(argc, argv, proc() {
run(opts::from_cmdline_args(os::args()))
- }
+ })
}
#[cfg(not(test), target_os="android")]
#[no_mangle]
pub extern "C" fn android_start(argc: int, argv: **u8) -> int {
- do std::rt::start_on_main_thread(argc, argv) {
+ native::start(argc, argv, proc() {
let mut args:~[~str] = ~[];
for i in range(0u, argc as uint) {
unsafe {
@@ -122,53 +128,51 @@ pub extern "C" fn android_start(argc: int, argv: **u8) -> int {
}
}
run(opts::from_cmdline_args(args))
- }
+ })
}
+#[cfg(not(test))]
fn run(opts: Opts) {
- let (exit_response_from_constellation, exit_chan) = comm::stream();
- let (profiler_port, profiler_chan) = special_stream!(ProfilerChan);
- let (compositor_port, compositor_chan) = special_stream!(CompositorChan);
- let (constellation_port, constellation_chan) = special_stream!(ConstellationChan);
-
- Profiler::create(profiler_port, profiler_chan.clone(), opts.profiler_period);
-
- do spawn_with((constellation_port,
- constellation_chan.clone(),
- profiler_chan.clone(),
- compositor_chan,
- opts.clone()))
- |(constellation_port,
- constellation_chan,
- profiler_chan,
- compositor_chan,
- opts)| {
- let opts = &opts;
+ let mut pool = green::SchedPool::new(green::PoolConfig::new());
+ let (exit_response_from_constellation, exit_chan) = Chan::new();
+ let (compositor_port, compositor_chan) = CompositorChan::new();
+ let profiler_chan = Profiler::create(opts.profiler_period);
+
+ let opts_clone = opts.clone();
+ let profiler_chan_clone = profiler_chan.clone();
+
+ let (result_port, result_chan) = Chan::new();
+ pool.spawn(TaskOpts::new(), proc() {
+ let opts = &opts_clone;
// Create a Servo instance.
let resource_task = ResourceTask();
let image_cache_task = ImageCacheTask(resource_task.clone());
- Constellation::start(constellation_port,
- constellation_chan.clone(),
- compositor_chan,
- opts,
- resource_task,
- image_cache_task,
- profiler_chan.clone());
+ let constellation_chan = Constellation::start(compositor_chan,
+ opts,
+ resource_task,
+ image_cache_task,
+ profiler_chan_clone);
+
+ // Send the constallation Chan as the result
+ result_chan.send(constellation_chan.clone());
// Send the URL command to the constellation.
for filename in opts.urls.iter() {
constellation_chan.send(InitLoadUrlMsg(make_url(filename.clone(), None)))
}
- }
+ });
+ let constellation_chan = result_port.recv();
debug!("preparing to enter main loop");
CompositorTask::create(opts,
compositor_port,
- constellation_chan.clone(),
+ constellation_chan,
profiler_chan,
exit_chan,
exit_response_from_constellation);
+
+ pool.shutdown();
}
diff --git a/src/components/main/util/task.rs b/src/components/main/util/task.rs
index 0300fa59200..f85688f7d2f 100644
--- a/src/components/main/util/task.rs
+++ b/src/components/main/util/task.rs
@@ -2,26 +2,20 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use std::cell::Cell;
-use std::comm;
-use std::comm::{Chan, Port};
-use std::task;
-
-pub fn spawn_listener<A: Send>(f: ~fn(Port<A>)) -> Chan<A> {
- let (setup_po, setup_ch) = comm::stream();
- do task::spawn {
- let (po, ch) = comm::stream();
+pub fn spawn_listener<A: Send>(f: proc(Port<A>)) -> Chan<A> {
+ let (setup_po, setup_ch) = Chan::new();
+ spawn(proc() {
+ let (po, ch) = Chan::new();
setup_ch.send(ch);
f(po);
- }
+ });
setup_po.recv()
}
-pub fn spawn_conversation<A: Send, B: Send>(f: ~fn(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) {
- let (from_child, to_parent) = comm::stream();
- let to_parent = Cell::new(to_parent);
+pub fn spawn_conversation<A: Send, B: Send>(f: proc(Port<A>, Chan<B>)) -> (Port<B>, Chan<A>) {
+ let (from_child, to_parent) = Chan::new();
let to_child = do spawn_listener |from_parent| {
- f(from_parent, to_parent.take())
+ f(from_parent, to_parent)
};
(from_child, to_child)
}
diff --git a/src/components/msg/constellation_msg.rs b/src/components/msg/constellation_msg.rs
index 5c91b329379..ee8f2914785 100644
--- a/src/components/msg/constellation_msg.rs
+++ b/src/components/msg/constellation_msg.rs
@@ -14,8 +14,9 @@ use std::comm::{Chan, SharedChan};
pub struct ConstellationChan(SharedChan<Msg>);
impl ConstellationChan {
- pub fn new(chan: Chan<Msg>) -> ConstellationChan {
- ConstellationChan(SharedChan::new(chan))
+ pub fn new() -> (Port<Msg>, ConstellationChan) {
+ let (port, chan) = SharedChan::new();
+ (port, ConstellationChan(chan))
}
}
@@ -53,5 +54,6 @@ pub enum NavigationDirection {
#[deriving(Clone, Eq, IterBytes)]
pub struct PipelineId(uint);
+
#[deriving(Clone, Eq, IterBytes)]
pub struct SubpageId(uint);
diff --git a/src/components/msg/msg.rc b/src/components/msg/msg.rc
index 35c364f6331..e27148b09d7 100644
--- a/src/components/msg/msg.rc
+++ b/src/components/msg/msg.rc
@@ -2,10 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#[link(name = "msg",
- vers = "0.1",
- uuid = "4c6054e4-2a7b-4fae-b0c8-6d04416b2bf2",
- url = "http://servo.org/")];
+#[crate_id = "github.com/mozilla/servo#msg:0.1"];
#[crate_type = "lib"];
extern mod azure;
diff --git a/src/components/net/data_loader.rs b/src/components/net/data_loader.rs
index 09b1accd6e5..881b6b28bf6 100644
--- a/src/components/net/data_loader.rs
+++ b/src/components/net/data_loader.rs
@@ -11,7 +11,7 @@ use http::headers::test_utils::from_stream_with_str;
use http::headers::content_type::MediaType;
pub fn factory() -> LoaderTask {
- |url, start_chan| {
+ proc(url, start_chan) {
// NB: we don't spawn a new task.
// Hypothesis: data URLs are too small for parallel base64 etc. to be worth it.
// Should be tested at some point.
@@ -25,7 +25,7 @@ fn load(url: Url, start_chan: Chan<LoadResponse>) {
let mut metadata = Metadata::default(url.clone());
// Split out content type and data.
- let parts: ~[&str] = url.path.splitn_iter(',', 1).to_owned_vec();
+ let parts: ~[&str] = url.path.splitn(',', 1).to_owned_vec();
if parts.len() != 2 {
start_sending(start_chan, metadata).send(Done(Err(())));
return;
@@ -49,7 +49,7 @@ fn load(url: Url, start_chan: Chan<LoadResponse>) {
if is_base64 {
match parts[1].from_base64() {
- Err(*) => {
+ Err(..) => {
progress_chan.send(Done(Err(())));
}
Ok(data) => {
@@ -71,9 +71,8 @@ fn assert_parse(url: &'static str,
charset: Option<~str>,
data: Option<~[u8]>) {
use std::from_str::FromStr;
- use std::comm;
- let (start_port, start_chan) = comm::stream();
+ let (start_port, start_chan) = Chan::new();
load(FromStr::from_str(url).unwrap(), start_chan);
let response = start_port.recv();
diff --git a/src/components/net/file_loader.rs b/src/components/net/file_loader.rs
index 7225fe8606f..67690b6547a 100644
--- a/src/components/net/file_loader.rs
+++ b/src/components/net/file_loader.rs
@@ -5,45 +5,44 @@
use resource_task::{ProgressMsg, Metadata, Payload, Done, LoaderTask, start_sending};
use servo_util::io::result;
-use std::comm::Chan;
-use std::rt::io::file;
-use std::rt::io::{FileStream, Reader, EndOfFile, Open, Read, ignore_io_error};
-use std::task;
+use std::io;
+use std::io::File;
static READ_SIZE: uint = 1024;
-fn read_all(reader: &mut FileStream, progress_chan: &Chan<ProgressMsg>)
+fn read_all(reader: &mut io::Stream, progress_chan: &SharedChan<ProgressMsg>)
-> Result<(), ()> {
loop {
- match (do result {
+ match (result(|| {
let data = reader.read_bytes(READ_SIZE);
progress_chan.send(Payload(data));
- }) {
+ })) {
Ok(()) => (),
Err(e) => match e.kind {
- EndOfFile => return Ok(()),
- _ => return Err(()),
+ io::EndOfFile => return Ok(()),
+ _ => return Err(()),
}
}
}
}
pub fn factory() -> LoaderTask {
- let f: LoaderTask = |url, start_chan| {
+ let f: LoaderTask = proc(url, start_chan) {
assert!("file" == url.scheme);
let progress_chan = start_sending(start_chan, Metadata::default(url.clone()));
- do task::spawn {
+ spawn(proc() {
// ignore_io_error causes us to get None instead of a task failure.
- match ignore_io_error(|| file::open(&url.path.as_slice(), Open, Read)) {
+ let _guard = io::ignore_io_error();
+ match File::open_mode(&Path::new(url.path), io::Open, io::Read) {
Some(ref mut reader) => {
- let res = read_all(reader, &progress_chan);
+ let res = read_all(reader as &mut io::Stream, &progress_chan);
progress_chan.send(Done(res));
}
None => {
progress_chan.send(Done(Err(())));
}
- }
- }
+ };
+ });
};
f
}
diff --git a/src/components/net/http_loader.rs b/src/components/net/http_loader.rs
index 87c8cf369f1..79b34778245 100644
--- a/src/components/net/http_loader.rs
+++ b/src/components/net/http_loader.rs
@@ -4,19 +4,16 @@
use resource_task::{Metadata, Payload, Done, LoadResponse, LoaderTask, start_sending};
-use std::cell::Cell;
use std::vec;
use extra::url::Url;
use http::client::RequestWriter;
use http::method::Get;
use http::headers::HeaderEnum;
-use std::rt::io::Reader;
+use std::io::Reader;
pub fn factory() -> LoaderTask {
- let f: LoaderTask = |url, start_chan| {
- let url = Cell::new(url);
- let start_chan = Cell::new(start_chan);
- spawn(|| load(url.take(), start_chan.take()))
+ let f: LoaderTask = proc(url, start_chan) {
+ spawn(proc() load(url, start_chan))
};
f
}
@@ -63,10 +60,10 @@ fn load(mut url: Url, start_chan: Chan<LoadResponse>) {
loop {
let mut buf = vec::with_capacity(1024);
- unsafe { vec::raw::set_len(&mut buf, 1024) };
+ unsafe { buf.set_len(1024); }
match response.read(buf) {
Some(len) => {
- unsafe { vec::raw::set_len(&mut buf, len) };
+ unsafe { buf.set_len(len); }
progress_chan.send(Payload(buf));
}
None => {
diff --git a/src/components/net/image/holder.rs b/src/components/net/image/holder.rs
index 5b312fffe4f..7213644551d 100644
--- a/src/components/net/image/holder.rs
+++ b/src/components/net/image/holder.rs
@@ -64,12 +64,12 @@ impl ImageHolder {
/// Query and update the current image size.
pub fn get_size(&mut self) -> Option<Size2D<int>> {
debug!("get_size() {}", self.url.to_str());
- do self.get_image().map |img| {
+ self.get_image().map(|img| {
let img_ref = img.get();
self.cached_size = Size2D(img_ref.width as int,
img_ref.height as int);
self.cached_size.clone()
- }
+ })
}
pub fn get_image(&mut self) -> Option<Arc<~Image>> {
diff --git a/src/components/net/image_cache_task.rs b/src/components/net/image_cache_task.rs
index 7669f09f4d7..8a99ccf4a2c 100644
--- a/src/components/net/image_cache_task.rs
+++ b/src/components/net/image_cache_task.rs
@@ -7,8 +7,7 @@ use resource_task;
use resource_task::ResourceTask;
use servo_util::url::{UrlMap, url_map};
-use std::cell::Cell;
-use std::comm::{Chan, Port, SharedChan, stream};
+use std::comm::{Chan, Port, SharedChan};
use std::task::spawn;
use std::to_str::ToStr;
use std::util::replace;
@@ -24,7 +23,7 @@ pub enum Msg {
// FIXME: We can probably get rid of this Cell now
// FIXME: make this priv after visibility rules change
/// Used be the prefetch tasks to post back image binaries
- StorePrefetchedImageData(Url, Result<Cell<~[u8]>, ()>),
+ StorePrefetchedImageData(Url, Result<~[u8], ()>),
/// Tell the cache to decode an image. Must be posted before GetImage/WaitForImage
Decode(Url),
@@ -40,12 +39,16 @@ pub enum Msg {
/// Wait for an image to become available (or fail to load).
WaitForImage(Url, Chan<ImageResponseMsg>),
+ /// Clients must wait for a response before shutting down the ResourceTask
+ Exit(Chan<()>),
+
/// For testing
// FIXME: make this priv after visibility rules change
- OnMsg(~fn(msg: &Msg)),
+ WaitForStore(Chan<()>),
- /// Clients must wait for a response before shutting down the ResourceTask
- Exit(Chan<()>),
+ /// For testing
+ // FIXME: make this priv after visibility rules change
+ WaitForStorePrefetched(Chan<()>),
}
#[deriving(Clone)]
@@ -59,11 +62,11 @@ impl Eq for ImageResponseMsg {
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,
- (ImageReady(*), _) | (ImageNotReady, _) | (ImageFailed, _) => false
+ (ImageReady(..), _) | (ImageNotReady, _) | (ImageFailed, _) => false
}
}
@@ -72,49 +75,39 @@ impl Eq for ImageResponseMsg {
}
}
-pub type ImageCacheTask = SharedChan<Msg>;
-
-type DecoderFactory = ~fn() -> ~fn(&[u8]) -> Option<Image>;
-
-pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
- ImageCacheTask_(resource_task, default_decoder_factory)
+#[deriving(Clone)]
+pub struct ImageCacheTask {
+ chan: SharedChan<Msg>,
}
-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
- let decoder_factory_cell = Cell::new(decoder_factory);
+type DecoderFactory = fn() -> proc(&[u8]) -> Option<Image>;
- let (port, chan) = stream();
- let chan = SharedChan::new(chan);
- let port_cell = Cell::new(port);
- let chan_cell = Cell::new(chan.clone());
+pub fn ImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
+ let (port, chan) = SharedChan::new();
+ let chan_clone = chan.clone();
- do spawn {
+ spawn(proc() {
let mut cache = ImageCache {
resource_task: resource_task.clone(),
- decoder_factory: decoder_factory_cell.take(),
- port: port_cell.take(),
- chan: chan_cell.take(),
+ port: port,
+ chan: chan_clone,
state_map: url_map(),
wait_map: url_map(),
need_exit: None
};
cache.run();
- }
+ });
- chan
+ ImageCacheTask {
+ chan: chan,
+ }
}
// FIXME: make this priv after visibility rules change
pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
- let (port, chan) = stream();
- let port_cell = Cell::new(port);
+ let (port, chan) = SharedChan::new();
- do spawn {
- let port = port_cell.take();
+ spawn(proc() {
let inner_cache = ImageCacheTask(resource_task.clone());
loop {
@@ -131,16 +124,16 @@ pub fn SyncImageCacheTask(resource_task: ResourceTask) -> ImageCacheTask {
msg => inner_cache.send(msg)
}
}
- }
+ });
- SharedChan::new(chan)
+ ImageCacheTask {
+ chan: chan,
+ }
}
struct ImageCache {
/// A handle to the resource task for fetching the image binaries
resource_task: ResourceTask,
- /// Creates image decoders
- decoder_factory: DecoderFactory,
/// The port on which we'll receive client requests
port: Port<Msg>,
/// A copy of the shared chan to give to child tasks
@@ -156,7 +149,7 @@ struct ImageCache {
enum ImageState {
Init,
Prefetching(AfterPrefetch),
- Prefetched(Cell<~[u8]>),
+ Prefetched(~[u8]),
Decoding,
Decoded(Arc<~Image>),
Failed
@@ -170,29 +163,39 @@ enum AfterPrefetch {
impl ImageCache {
pub fn run(&mut self) {
- let mut msg_handlers: ~[~fn(msg: &Msg)] = ~[];
+ let mut store_chan: Option<Chan<()>> = None;
+ let mut store_prefetched_chan: Option<Chan<()>> = None;
loop {
let msg = self.port.recv();
- for handler in msg_handlers.iter() {
- (*handler)(&msg)
- }
-
debug!("image_cache_task: received: {:?}", msg);
match msg {
Prefetch(url) => self.prefetch(url),
StorePrefetchedImageData(url, data) => {
+ store_prefetched_chan.map(|chan| {
+ chan.send(());
+ });
+ store_prefetched_chan = None;
+
self.store_prefetched_image_data(url, data);
}
Decode(url) => self.decode(url),
- StoreImage(url, image) => self.store_image(url, image),
+ StoreImage(url, image) => {
+ store_chan.map(|chan| {
+ chan.send(());
+ });
+ store_chan = None;
+
+ self.store_image(url, image)
+ }
GetImage(url, response) => self.get_image(url, response),
WaitForImage(url, response) => {
self.wait_for_image(url, response)
}
- OnMsg(handler) => msg_handlers.push(handler),
+ WaitForStore(chan) => store_chan = Some(chan),
+ WaitForStorePrefetched(chan) => store_prefetched_chan = Some(chan),
Exit(response) => {
assert!(self.need_exit.is_none());
self.need_exit = Some(response);
@@ -208,10 +211,10 @@ impl ImageCache {
let mut can_exit = true;
for (_, state) in self.state_map.iter() {
match *state {
- Prefetching(*) => can_exit = false,
+ Prefetching(..) => can_exit = false,
Decoding => can_exit = false,
- Init | Prefetched(*) | Decoded(*) | Failed => ()
+ Init | Prefetched(..) | Decoded(..) | Failed => ()
}
}
@@ -243,45 +246,44 @@ impl ImageCache {
Init => {
let to_cache = self.chan.clone();
let resource_task = self.resource_task.clone();
- let url_cell = Cell::new(url.clone());
+ let url_clone = url.clone();
- do spawn {
- let url = url_cell.take();
+ spawn(proc() {
+ let url = url_clone;
debug!("image_cache_task: started fetch for {:s}", url.to_str());
let image = load_image_data(url.clone(), resource_task.clone());
let result = if image.is_ok() {
- Ok(Cell::new(image.unwrap()))
+ Ok(image.unwrap())
} else {
Err(())
};
to_cache.send(StorePrefetchedImageData(url.clone(), result));
debug!("image_cache_task: ended fetch for {:s}", (url.clone()).to_str());
- }
+ });
self.set_state(url, Prefetching(DoNotDecode));
}
- Prefetching(*) | Prefetched(*) | Decoding | Decoded(*) | Failed => {
+ Prefetching(..) | Prefetched(..) | Decoding | Decoded(..) | Failed => {
// We've already begun working on this image
}
}
}
- fn store_prefetched_image_data(&mut self, url: Url, data: Result<Cell<~[u8]>, ()>) {
+ fn store_prefetched_image_data(&mut self, url: Url, data: Result<~[u8], ()>) {
match self.get_state(url.clone()) {
Prefetching(next_step) => {
match data {
- Ok(data_cell) => {
- let data = data_cell.take();
- self.set_state(url.clone(), Prefetched(Cell::new(data)));
+ Ok(data) => {
+ self.set_state(url.clone(), Prefetched(data));
match next_step {
DoDecode => self.decode(url),
_ => ()
}
}
- Err(*) => {
+ Err(..) => {
self.set_state(url.clone(), Failed);
self.purge_waiters(url, || ImageFailed);
}
@@ -289,9 +291,9 @@ impl ImageCache {
}
Init
- | Prefetched(*)
+ | Prefetched(..)
| Decoding
- | Decoded(*)
+ | Decoded(..)
| Failed => {
fail!(~"wrong state for storing prefetched image")
}
@@ -311,18 +313,14 @@ impl ImageCache {
// We don't have the data yet, but the decode request is queued up
}
- Prefetched(data_cell) => {
- assert!(!data_cell.is_empty());
-
- let data = data_cell.take();
+ Prefetched(data) => {
let to_cache = self.chan.clone();
- let url_cell = Cell::new(url.clone());
- let decode = (self.decoder_factory)();
+ let url_clone = url.clone();
- do spawn {
- let url = url_cell.take();
+ spawn(proc() {
+ let url = url_clone;
debug!("image_cache_task: started image decode for {:s}", url.to_str());
- let image = decode(data);
+ let image = load_from_memory(data);
let image = if image.is_some() {
Some(Arc::new(~image.unwrap()))
} else {
@@ -330,12 +328,12 @@ impl ImageCache {
};
to_cache.send(StoreImage(url.clone(), image));
debug!("image_cache_task: ended image decode for {:s}", url.to_str());
- }
+ });
self.set_state(url, Decoding);
}
- Decoding | Decoded(*) | Failed => {
+ Decoding | Decoded(..) | Failed => {
// We've already begun decoding
}
}
@@ -358,9 +356,9 @@ impl ImageCache {
}
Init
- | Prefetching(*)
- | Prefetched(*)
- | Decoded(*)
+ | Prefetching(..)
+ | Prefetched(..)
+ | Decoded(..)
| Failed => {
fail!(~"incorrect state in store_image")
}
@@ -368,7 +366,7 @@ impl ImageCache {
}
- fn purge_waiters(&mut self, url: Url, f: &fn() -> ImageResponseMsg) {
+ fn purge_waiters(&mut self, url: Url, f: || -> ImageResponseMsg) {
match self.wait_map.pop(&url) {
Some(waiters) => {
unsafe {
@@ -387,7 +385,7 @@ impl ImageCache {
match self.get_state(url.clone()) {
Init => fail!(~"request for image before prefetch"),
Prefetching(DoDecode) => response.send(ImageNotReady),
- Prefetching(DoNotDecode) | Prefetched(*) => fail!(~"request for image before decode"),
+ Prefetching(DoNotDecode) | Prefetched(..) => fail!(~"request for image before decode"),
Decoding => response.send(ImageNotReady),
Decoded(image) => response.send(ImageReady(image.clone())),
Failed => response.send(ImageFailed),
@@ -398,16 +396,16 @@ impl ImageCache {
match self.get_state(url.clone()) {
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
if self.wait_map.contains_key(&url) {
let waiters = self.wait_map.find_mut(&url).unwrap();
+ let mut response = Some(response);
unsafe {
- let res = Cell::new(response);
- waiters.unsafe_access( |waiters| {
- waiters.push(res.take());
+ waiters.unsafe_access(|waiters| {
+ waiters.push(response.take().unwrap());
});
}
} else {
@@ -434,14 +432,34 @@ trait ImageCacheTaskClient {
impl ImageCacheTaskClient for ImageCacheTask {
fn exit(&self) {
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
self.send(Exit(response_chan));
response_port.recv();
}
}
+impl ImageCacheTask {
+ pub fn send(&self, msg: Msg) {
+ self.chan.send(msg);
+ }
+
+ #[cfg(test)]
+ fn wait_for_store(&self) -> Port<()> {
+ let (port, chan) = Chan::new();
+ self.send(WaitForStore(chan));
+ port
+ }
+
+ #[cfg(test)]
+ fn wait_for_store_prefetched(&self) -> Port<()> {
+ let (port, chan) = Chan::new();
+ self.send(WaitForStorePrefetched(chan));
+ port
+ }
+}
+
fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
resource_task.send(resource_task::Load(url, response_chan));
let mut image_data = ~[];
@@ -452,38 +470,29 @@ fn load_image_data(url: Url, resource_task: ResourceTask) -> Result<~[u8], ()> {
resource_task::Payload(data) => {
image_data.push_all(data);
}
- resource_task::Done(result::Ok(*)) => {
+ resource_task::Done(result::Ok(..)) => {
return Ok(image_data);
}
- resource_task::Done(result::Err(*)) => {
+ resource_task::Done(result::Err(..)) => {
return Err(());
}
}
}
}
-fn default_decoder_factory() -> ~fn(&[u8]) -> Option<Image> {
- let foo: ~fn(&[u8]) -> Option<Image> = |data: &[u8]| { load_from_memory(data) };
- foo
-}
#[cfg(test)]
mod tests {
use super::*;
- use std::comm;
- use std::comm::{Port, SharedChan};
- use std::result;
- use std::cell::Cell;
-
use resource_task;
use resource_task::{ResourceTask, Metadata, start_sending};
- use image::base::{Image, test_image_bin, load_from_memory};
+ use image::base::test_image_bin;
use util::spawn_listener;
use servo_util::url::make_url;
- fn mock_resource_task(on_load: ~fn(resource: Chan<resource_task::ProgressMsg>)) -> ResourceTask {
- let chan = do spawn_listener |port: Port<resource_task::ControlMsg>| {
+ fn mock_resource_task(on_load: proc(resource: SharedChan<resource_task::ProgressMsg>)) -> ResourceTask {
+ spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
loop {
match port.recv() {
resource_task::Load(_, response) => {
@@ -493,13 +502,12 @@ mod tests {
resource_task::Exit => break
}
}
- };
- SharedChan::new(chan)
+ })
}
#[test]
fn should_exit_on_request() {
- let mock_resource_task = mock_resource_task(|_response| () );
+ let mock_resource_task = mock_resource_task(proc(_response) {});
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let _url = make_url(~"file", None);
@@ -511,24 +519,24 @@ mod tests {
#[test]
#[should_fail]
fn should_fail_if_unprefetched_image_is_requested() {
- let mock_resource_task = mock_resource_task(|_response| () );
+ let mock_resource_task = mock_resource_task(proc(_response) {});
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
- let (port, chan) = stream();
+ let (port, chan) = Chan::new();
image_cache_task.send(GetImage(url, chan));
port.recv();
}
#[test]
fn should_request_url_from_resource_task_on_prefetch() {
- let (url_requested, url_requested_chan) = comm::stream();
+ let (url_requested, url_requested_chan) = Chan::new();
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
url_requested_chan.send(());
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
@@ -539,47 +547,14 @@ mod tests {
mock_resource_task.send(resource_task::Exit);
}
-
- #[test]
- #[should_fail]
- fn should_fail_if_requesting_decode_of_an_unprefetched_image() {
- let mock_resource_task = mock_resource_task(|_response| () );
-
- let image_cache_task = ImageCacheTask(mock_resource_task.clone());
- let url = make_url(~"file", None);
-
- image_cache_task.send(Decode(url));
- image_cache_task.exit();
- }
-
- #[test]
- #[should_fail]
- fn should_fail_if_requesting_image_before_requesting_decode() {
- let mock_resource_task = do mock_resource_task |response| {
- response.send(resource_task::Done(result::Ok(())));
- };
-
- let image_cache_task = ImageCacheTask(mock_resource_task.clone());
- let url = make_url(~"file", None);
-
- image_cache_task.send(Prefetch(url.clone()));
- // no decode message
-
- let (_port, chan) = stream();
- image_cache_task.send(GetImage(url, chan));
-
- image_cache_task.exit();
- mock_resource_task.send(resource_task::Exit);
- }
-
#[test]
fn should_not_request_url_from_resource_task_on_multiple_prefetches() {
- let (url_requested, url_requested_chan) = comm::stream();
+ let (url_requested, url_requested_chan) = Chan::new();
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
url_requested_chan.send(());
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
@@ -589,27 +564,27 @@ mod tests {
url_requested.recv();
image_cache_task.exit();
mock_resource_task.send(resource_task::Exit);
- assert!(!url_requested.peek())
+ assert!(url_requested.try_recv().is_none())
}
#[test]
fn should_return_image_not_ready_if_data_has_not_arrived() {
- let (wait_port, wait_chan) = comm::stream();
+ let (wait_port, wait_chan) = Chan::new();
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
// Don't send the data until after the client requests
// the image
wait_port.recv();
response.send(resource_task::Payload(test_image_bin()));
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(GetImage(url, response_chan));
assert!(response_port.recv() == ImageNotReady);
wait_chan.send(());
@@ -619,30 +594,23 @@ mod tests {
#[test]
fn should_return_decoded_image_data_if_data_has_arrived() {
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
response.send(resource_task::Payload(test_image_bin()));
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
- let (wait_for_image, wait_for_image_chan) = comm::stream();
-
- image_cache_task.send(OnMsg(|msg| {
- match *msg {
- StoreImage(*) => wait_for_image_chan.send(()),
- _ => ()
- }
- }));
+ let join_port = image_cache_task.wait_for_store();
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
// Wait until our mock resource task has sent the image to the image cache
- wait_for_image.recv();
+ join_port.recv();
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(GetImage(url, response_chan));
match response_port.recv() {
ImageReady(_) => (),
@@ -655,31 +623,24 @@ mod tests {
#[test]
fn should_return_decoded_image_data_for_multiple_requests() {
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
response.send(resource_task::Payload(test_image_bin()));
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
- let (wait_for_image, wait_for_image_chan) = comm::stream();
-
- image_cache_task.send(OnMsg(|msg| {
- match *msg {
- StoreImage(*) => wait_for_image_chan.send(()),
- _ => ()
- }
- }));
+ let join_port = image_cache_task.wait_for_store();
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
// Wait until our mock resource task has sent the image to the image cache
- wait_for_image.recv();
+ join_port.recv();
for _ in range(0,2) {
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(GetImage(url.clone(), response_chan));
match response_port.recv() {
ImageReady(_) => (),
@@ -693,17 +654,17 @@ mod tests {
#[test]
fn should_not_request_image_from_resource_task_if_image_is_already_available() {
- let (image_bin_sent, image_bin_sent_chan) = comm::stream();
+ let (image_bin_sent, image_bin_sent_chan) = Chan::new();
- let (resource_task_exited, resource_task_exited_chan) = comm::stream();
+ let (resource_task_exited, resource_task_exited_chan) = Chan::new();
- let mock_resource_task = do spawn_listener |port: comm::Port<resource_task::ControlMsg>| {
+ let mock_resource_task = spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
loop {
match port.recv() {
resource_task::Load(_, response) => {
let chan = start_sending(response, Metadata::default(make_url(~"file:///fake", None)));
chan.send(resource_task::Payload(test_image_bin()));
- chan.send(resource_task::Done(result::Ok(())));
+ chan.send(resource_task::Done(Ok(())));
image_bin_sent_chan.send(());
}
resource_task::Exit => {
@@ -712,8 +673,7 @@ mod tests {
}
}
}
- };
- let mock_resource_task = SharedChan::new(mock_resource_task);
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
@@ -732,22 +692,22 @@ mod tests {
// Our resource task should not have received another request for the image
// because it's already cached
- assert!(!image_bin_sent.peek());
+ assert!(image_bin_sent.try_recv().is_none());
}
#[test]
fn should_not_request_image_from_resource_task_if_image_fetch_already_failed() {
- let (image_bin_sent, image_bin_sent_chan) = comm::stream();
+ let (image_bin_sent, image_bin_sent_chan) = Chan::new();
- let (resource_task_exited, resource_task_exited_chan) = comm::stream();
+ let (resource_task_exited, resource_task_exited_chan) = Chan::new();
- let mock_resource_task = do spawn_listener |port: comm::Port<resource_task::ControlMsg>| {
+ let mock_resource_task = spawn_listener(proc(port: Port<resource_task::ControlMsg>) {
loop {
match port.recv() {
resource_task::Load(_, response) => {
let chan = start_sending(response, Metadata::default(make_url(~"file:///fake", None)));
chan.send(resource_task::Payload(test_image_bin()));
- chan.send(resource_task::Done(result::Err(())));
+ chan.send(resource_task::Done(Err(())));
image_bin_sent_chan.send(());
}
resource_task::Exit => {
@@ -756,8 +716,7 @@ mod tests {
}
}
}
- };
- let mock_resource_task = SharedChan::new(mock_resource_task);
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
@@ -778,36 +737,29 @@ mod tests {
// Our resource task should not have received another request for the image
// because it's already cached
- assert!(!image_bin_sent.peek());
+ assert!(image_bin_sent.try_recv().is_none());
}
#[test]
fn should_return_failed_if_image_bin_cannot_be_fetched() {
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
response.send(resource_task::Payload(test_image_bin()));
// ERROR fetching image
- response.send(resource_task::Done(result::Err(())));
- };
+ response.send(resource_task::Done(Err(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
- let (wait_for_prefetech, wait_for_prefetech_chan) = comm::stream();
-
- image_cache_task.send(OnMsg(|msg| {
- match *msg {
- StorePrefetchedImageData(*) => wait_for_prefetech_chan.send(()),
- _ => ()
- }
- }));
+ let join_port = image_cache_task.wait_for_store_prefetched();
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
// Wait until our mock resource task has sent the image to the image cache
- wait_for_prefetech.recv();
+ join_port.recv();
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(GetImage(url, response_chan));
match response_port.recv() {
ImageFailed => (),
@@ -820,31 +772,24 @@ mod tests {
#[test]
fn should_return_failed_for_multiple_get_image_requests_if_image_bin_cannot_be_fetched() {
- let mock_resource_task = do mock_resource_task |response | {
+ let mock_resource_task = mock_resource_task(proc(response) {
response.send(resource_task::Payload(test_image_bin()));
// ERROR fetching image
- response.send(resource_task::Done(result::Err(())));
- };
+ response.send(resource_task::Done(Err(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
- let (wait_for_prefetech, wait_for_prefetech_chan) = comm::stream();
-
- image_cache_task.send(OnMsg(|msg| {
- match *msg {
- StorePrefetchedImageData(*) => wait_for_prefetech_chan.send(()),
- _ => ()
- }
- }));
+ let join_port = image_cache_task.wait_for_store_prefetched();
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
// Wait until our mock resource task has sent the image to the image cache
- wait_for_prefetech.recv();
+ join_port.recv();
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(GetImage(url.clone(), response_chan));
match response_port.recv() {
ImageFailed => (),
@@ -852,7 +797,7 @@ mod tests {
}
// And ask again, we should get the same response
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(GetImage(url, response_chan));
match response_port.recv() {
ImageFailed => (),
@@ -864,86 +809,26 @@ mod tests {
}
#[test]
- fn should_return_not_ready_if_image_is_still_decoding() {
- let (wait_to_decode_port, wait_to_decode_chan) = comm::stream();
-
- let mock_resource_task = do mock_resource_task |response| {
- response.send(resource_task::Payload(test_image_bin()));
- response.send(resource_task::Done(result::Ok(())));
- };
-
- let wait_to_decode_port_cell = Cell::new(wait_to_decode_port);
- let decoder_factory: ~fn:Send() -> ~fn:Send(&[u8]) -> Option<Image> = || {
- let wait_to_decode_port = wait_to_decode_port_cell.take();
- |data: &[u8]| {
- // Don't decode until after the client requests the image
- wait_to_decode_port.recv();
- load_from_memory(data)
- }
- };
-
- let image_cache_task = ImageCacheTask_(mock_resource_task.clone(), decoder_factory);
- let url = make_url(~"file", None);
-
- let (wait_for_prefetech, wait_for_prefetech_chan) = comm::stream();
-
- image_cache_task.send(OnMsg(|msg| {
- match *msg {
- StorePrefetchedImageData(*) => wait_for_prefetech_chan.send(()),
- _ => ()
- }
- }));
-
- image_cache_task.send(Prefetch(url.clone()));
- image_cache_task.send(Decode(url.clone()));
-
- // Wait until our mock resource task has sent the image to the image cache
- wait_for_prefetech.recv();
-
- // Make the request
- let (response_port, response_chan) = stream();
- image_cache_task.send(GetImage(url, response_chan));
-
- match response_port.recv() {
- ImageNotReady => (),
- _ => fail!("bleh")
- }
-
- // Now decode
- wait_to_decode_chan.send(());
-
- image_cache_task.exit();
- mock_resource_task.send(resource_task::Exit);
- }
-
- #[test]
fn should_return_failed_if_image_decode_fails() {
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
// Bogus data
response.send(resource_task::Payload(~[]));
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
- let (wait_for_decode, wait_for_decode_chan) = comm::stream();
-
- image_cache_task.send(OnMsg(|msg| {
- match *msg {
- StoreImage(*) => wait_for_decode_chan.send(()),
- _ => ()
- }
- }));
+ let join_port = image_cache_task.wait_for_store();
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
// Wait until our mock resource task has sent the image to the image cache
- wait_for_decode.recv();
+ join_port.recv();
// Make the request
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(GetImage(url, response_chan));
match response_port.recv() {
@@ -957,33 +842,26 @@ mod tests {
#[test]
fn should_return_image_on_wait_if_image_is_already_loaded() {
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
response.send(resource_task::Payload(test_image_bin()));
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
- let (wait_for_decode, wait_for_decode_chan) = comm::stream();
-
- image_cache_task.send(OnMsg(|msg| {
- match *msg {
- StoreImage(*) => wait_for_decode_chan.send(()),
- _ => ()
- }
- }));
+ let join_port = image_cache_task.wait_for_store();
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
// Wait until our mock resource task has sent the image to the image cache
- wait_for_decode.recv();
+ join_port.recv();
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(WaitForImage(url, response_chan));
match response_port.recv() {
- ImageReady(*) => (),
+ ImageReady(..) => (),
_ => fail!("bleh")
}
@@ -993,13 +871,13 @@ mod tests {
#[test]
fn should_return_image_on_wait_if_image_is_not_yet_loaded() {
- let (wait_port, wait_chan) = comm::stream();
+ let (wait_port, wait_chan) = Chan::new();
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
wait_port.recv();
response.send(resource_task::Payload(test_image_bin()));
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
@@ -1007,13 +885,13 @@ mod tests {
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(WaitForImage(url, response_chan));
wait_chan.send(());
match response_port.recv() {
- ImageReady(*) => (),
+ ImageReady(..) => (),
_ => fail!("bleh")
}
@@ -1023,13 +901,13 @@ mod tests {
#[test]
fn should_return_image_failed_on_wait_if_image_fails_to_load() {
- let (wait_port, wait_chan) = comm::stream();
+ let (wait_port, wait_chan) = Chan::new();
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
wait_port.recv();
response.send(resource_task::Payload(test_image_bin()));
- response.send(resource_task::Done(result::Err(())));
- };
+ response.send(resource_task::Done(Err(())));
+ });
let image_cache_task = ImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
@@ -1037,7 +915,7 @@ mod tests {
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(WaitForImage(url, response_chan));
wait_chan.send(());
@@ -1053,10 +931,10 @@ mod tests {
#[test]
fn sync_cache_should_wait_for_images() {
- let mock_resource_task = do mock_resource_task |response| {
+ let mock_resource_task = mock_resource_task(proc(response) {
response.send(resource_task::Payload(test_image_bin()));
- response.send(resource_task::Done(result::Ok(())));
- };
+ response.send(resource_task::Done(Ok(())));
+ });
let image_cache_task = SyncImageCacheTask(mock_resource_task.clone());
let url = make_url(~"file", None);
@@ -1064,7 +942,7 @@ mod tests {
image_cache_task.send(Prefetch(url.clone()));
image_cache_task.send(Decode(url.clone()));
- let (response_port, response_chan) = stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(GetImage(url, response_chan));
match response_port.recv() {
ImageReady(_) => (),
diff --git a/src/components/net/local_image_cache.rs b/src/components/net/local_image_cache.rs
index f1889ff306b..f6dd537e47f 100644
--- a/src/components/net/local_image_cache.rs
+++ b/src/components/net/local_image_cache.rs
@@ -11,14 +11,13 @@ multiple times and thus triggering reflows multiple times.
use image_cache_task::{Decode, GetImage, ImageCacheTask, ImageFailed, ImageNotReady, ImageReady};
use image_cache_task::{ImageResponseMsg, Prefetch, WaitForImage};
-use std::comm;
use std::comm::Port;
use std::task;
use servo_util::url::{UrlMap, url_map};
use extra::url::Url;
pub trait ImageResponder {
- fn respond(&self) -> ~fn(ImageResponseMsg);
+ fn respond(&self) -> proc(ImageResponseMsg);
}
pub fn LocalImageCache(image_cache_task: ImageCacheTask) -> LocalImageCache {
@@ -90,13 +89,13 @@ impl LocalImageCache {
match state.last_response {
ImageReady(ref image) => {
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
chan.send(ImageReady(image.clone()));
return port;
}
ImageNotReady => {
if last_round == self.round_number {
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
chan.send(ImageNotReady);
return port;
} else {
@@ -105,14 +104,14 @@ impl LocalImageCache {
}
}
ImageFailed => {
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
chan.send(ImageFailed);
return port;
}
}
}
- let (response_port, response_chan) = comm::stream();
+ let (response_port, response_chan) = Chan::new();
self.image_cache_task.send(GetImage((*url).clone(), response_chan));
let response = response_port.recv();
@@ -128,7 +127,7 @@ impl LocalImageCache {
let on_image_available = self.on_image_available.as_ref().unwrap().respond();
let url = (*url).clone();
do task::spawn {
- let (response_port, response_chan) = comm::stream();
+ let (response_port, response_chan) = Chan::new();
image_cache_task.send(WaitForImage(url.clone(), response_chan));
on_image_available(response_port.recv());
}
@@ -144,7 +143,7 @@ impl LocalImageCache {
};
self.get_state(url).last_response = response_copy;
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
chan.send(response);
return port;
}
diff --git a/src/components/net/net.rc b/src/components/net/net.rc
index da445e1e964..7378c7c059b 100644
--- a/src/components/net/net.rc
+++ b/src/components/net/net.rc
@@ -2,17 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#[link(name = "net",
- vers = "0.1",
- uuid = "69c2b7b7-0d7d-4514-a48a-0eed61476039",
- url = "http://servo.org/")];
+#[crate_id = "github.com/mozilla/servo#net:0.1"];
#[crate_type = "lib"];
#[feature(globs, managed_boxes)];
extern mod geom;
extern mod http;
-extern mod servo_util (name = "util");
+extern mod servo_util = "util";
extern mod stb_image;
extern mod extra;
extern mod png;
diff --git a/src/components/net/resource_task.rs b/src/components/net/resource_task.rs
index 94d074e91b7..53d5c3ea5ba 100644
--- a/src/components/net/resource_task.rs
+++ b/src/components/net/resource_task.rs
@@ -8,9 +8,7 @@ use file_loader;
use http_loader;
use data_loader;
-use std::cell::Cell;
use std::comm::{Chan, Port, SharedChan};
-use std::comm;
use extra::url::Url;
use util::spawn_listener;
use http::headers::content_type::MediaType;
@@ -87,8 +85,8 @@ pub enum ProgressMsg {
/// For use by loaders in responding to a Load message.
pub fn start_sending(start_chan: Chan<LoadResponse>,
- metadata: Metadata) -> Chan<ProgressMsg> {
- let (progress_port, progress_chan) = comm::stream();
+ metadata: Metadata) -> SharedChan<ProgressMsg> {
+ let (progress_port, progress_chan) = SharedChan::new();
start_chan.send(LoadResponse {
metadata: metadata,
progress_port: progress_port,
@@ -99,7 +97,7 @@ pub fn start_sending(start_chan: Chan<LoadResponse>,
/// Convenience function for synchronously loading a whole resource.
pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
-> Result<(Metadata, ~[u8]), ()> {
- let (start_port, start_chan) = comm::stream();
+ let (start_port, start_chan) = Chan::new();
resource_task.send(Load(url, start_chan));
let response = start_port.recv();
@@ -116,7 +114,7 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
/// Handle to a resource task
pub type ResourceTask = SharedChan<ControlMsg>;
-pub type LoaderTask = ~fn(url: Url, Chan<LoadResponse>);
+pub type LoaderTask = proc(url: Url, Chan<LoadResponse>);
/**
Creates a task to load a specific resource
@@ -137,12 +135,11 @@ pub fn ResourceTask() -> ResourceTask {
}
fn create_resource_task_with_loaders(loaders: ~[(~str, LoaderTaskFactory)]) -> ResourceTask {
- let loaders_cell = Cell::new(loaders);
- let chan = do spawn_listener |from_client| {
+ let chan = spawn_listener(proc(from_client) {
// TODO: change copy to move once we can move out of closures
- ResourceManager(from_client, loaders_cell.take()).start()
- };
- SharedChan::new(chan)
+ ResourceManager(from_client, loaders).start()
+ });
+ chan
}
pub struct ResourceManager {
@@ -211,7 +208,7 @@ fn test_exit() {
#[test]
fn test_bad_scheme() {
let resource_task = ResourceTask();
- let (start, start_chan) = comm::stream();
+ let (start, start_chan) = Chan::new();
resource_task.send(Load(FromStr::from_str("bogus://whatever").unwrap(), start_chan));
let response = start.recv();
match response.progress_port.recv() {
@@ -226,7 +223,7 @@ static snicklefritz_payload: [u8, ..3] = [1, 2, 3];
#[cfg(test)]
fn snicklefritz_loader_factory() -> LoaderTask {
- let f: LoaderTask = |url: Url, start_chan: Chan<LoadResponse>| {
+ let f: LoaderTask = proc(url: Url, start_chan: Chan<LoadResponse>) {
let progress_chan = start_sending(start_chan, Metadata::default(url));
progress_chan.send(Payload(snicklefritz_payload.into_owned()));
progress_chan.send(Done(Ok(())));
@@ -238,7 +235,7 @@ fn snicklefritz_loader_factory() -> LoaderTask {
fn should_delegate_to_scheme_loader() {
let loader_factories = ~[(~"snicklefritz", snicklefritz_loader_factory)];
let resource_task = create_resource_task_with_loaders(loader_factories);
- let (start, start_chan) = comm::stream();
+ let (start, start_chan) = Chan::new();
resource_task.send(Load(FromStr::from_str("snicklefritz://heya").unwrap(), start_chan));
let response = start.recv();
diff --git a/src/components/net/util.rs b/src/components/net/util.rs
index 342f7df5d4e..2fc4a940881 100644
--- a/src/components/net/util.rs
+++ b/src/components/net/util.rs
@@ -2,14 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use std::comm;
use std::comm::{Chan, Port};
use std::task;
-pub fn spawn_listener<A: Send>(f: ~fn(Port<A>)) -> Chan<A> {
- let (setup_port, setup_chan) = comm::stream();
+pub fn spawn_listener<A: Send>(f: proc(Port<A>)) -> SharedChan<A> {
+ let (setup_port, setup_chan) = Chan::new();
do task::spawn {
- let (port, chan) = comm::stream();
+ let (port, chan) = SharedChan::new();
setup_chan.send(chan);
f(port);
}
diff --git a/src/components/script/dom/bindings/callback.rs b/src/components/script/dom/bindings/callback.rs
index f7f519012ea..40b3bd7b5fa 100644
--- a/src/components/script/dom/bindings/callback.rs
+++ b/src/components/script/dom/bindings/callback.rs
@@ -43,7 +43,6 @@ impl CallbackInterface {
}
}
- #[fixed_stack_segment]
pub fn GetCallableProperty(&self, cx: *JSContext, name: *libc::c_char, callable: &mut JSVal) -> bool {
unsafe {
if JS_GetProperty(cx, self.callback, name, &*callable) == 0 {
@@ -65,7 +64,6 @@ pub fn GetJSObjectFromCallback<T: CallbackContainer>(callback: &T) -> *JSObject
callback.callback()
}
-#[fixed_stack_segment]
pub fn WrapCallThisObject<T: 'static + CallbackContainer + Reflectable>(cx: *JSContext,
_scope: *JSObject,
p: @mut T) -> *JSObject {
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index b426c2989ed..b1ba6b9dac4 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1091,7 +1091,7 @@ for (uint32_t i = 0; i < length; ++i) {
return handleDefault(
conversionCode,
("static data: [u8, ..%s] = [ %s ];\n"
- "%s = str::from_utf8(data)" %
+ "%s = str::from_utf8(data).to_owned()" %
(len(defaultValue.value) + 1,
", ".join(["'" + char + "' as u8" for char in defaultValue.value] + ["0"]),
varName)))
@@ -2173,7 +2173,7 @@ class CGImports(CGWrapper):
# Allow unreachable_code because we use 'break' in a way that sometimes produces
# two 'break's in a row. See for example CallbackMember.getArgConversions.
return '\n'.join([
- '#[allow(unreachable_code,non_uppercase_statics,unused_imports,unused_variable,unused_unsafe,unused_mut,dead_assignment)];',
+ '#[allow(unreachable_code,non_uppercase_statics,unused_imports,unused_variable,unused_unsafe,unused_mut,dead_assignment,dead_code)];',
''.join('use %s;\n' % i for i in imports),
''])
CGWrapper.__init__(self, child,
@@ -2454,16 +2454,14 @@ class CGAbstractMethod(CGThing):
def _decorators(self):
decorators = []
if self.alwaysInline:
- # FIXME Rust #8801 #[inline(always)] and #[fixed_stack_segment] not compatible
- # decorators.append('#[inline(always)]')
- pass
+ decorators.append('#[inline(always)]')
elif self.inline:
#decorators.append('inline')
pass
if self.extern:
decorators.append('extern')
if not self.extern:
- decorators.append('#[fixed_stack_segment]')
+ pass
if self.static:
#decorators.append('static')
pass
@@ -3522,6 +3520,7 @@ class CGEnum(CGThing):
def define(self):
return """
+ #[repr(uint)]
pub enum valuelist {
%s
}
@@ -3576,7 +3575,7 @@ class ClassMethod(ClassItem):
ClassItem.__init__(self, name, visibility)
def getDecorators(self, declaring):
- decorators = ['#[fixed_stack_segment]']
+ decorators = []
if self.inline:
decorators.append('inline')
if declaring:
@@ -4150,8 +4149,8 @@ class CGProxyUnwrap(CGAbstractMethod):
obj = js::UnwrapObject(obj);
}*/
//MOZ_ASSERT(IsProxy(obj));
- let box: *Box<%s> = cast::transmute(RUST_JSVAL_TO_PRIVATE(GetProxyPrivate(obj)));
- return ptr::to_unsafe_ptr(&(*box).data);""" % (self.descriptor.concreteType)
+ let box_: *Box<%s> = cast::transmute(RUST_JSVAL_TO_PRIVATE(GetProxyPrivate(obj)));
+ return ptr::to_unsafe_ptr(&(*box_).data);""" % (self.descriptor.concreteType)
class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
def __init__(self, descriptor):
@@ -4443,9 +4442,9 @@ class CGDOMJSProxyHandler_obj_toString(CGAbstractExternMethod):
JSString* jsresult;
return xpc_qsStringToJsstring(cx, result, &jsresult) ? jsresult : NULL;"""
- return """ do "%s".to_c_str().with_ref |s| {
+ return """ "%s".to_c_str().with_ref(|s| {
_obj_toString(cx, s)
- }""" % self.descriptor.name
+ })""" % self.descriptor.name
def definition_body(self):
return self.getBody()
@@ -4907,7 +4906,6 @@ class CGDictionary(CGThing):
" return true;\n"
" }\n"
"\n" if not self.workers else "") +
- " #[fixed_stack_segment]\n" +
" pub fn Init(&mut self, cx: *JSContext, val: JSVal) -> JSBool {\n"
" unsafe {\n" +
# NOTE: jsids are per-runtime, so don't use them in workers
diff --git a/src/components/script/dom/bindings/conversions.rs b/src/components/script/dom/bindings/conversions.rs
index 22bad8cff16..06745217365 100644
--- a/src/components/script/dom/bindings/conversions.rs
+++ b/src/components/script/dom/bindings/conversions.rs
@@ -13,14 +13,12 @@ pub trait JSValConvertible {
impl JSValConvertible for i64 {
- #[fixed_stack_segment]
fn to_jsval(&self) -> JSVal {
unsafe {
RUST_DOUBLE_TO_JSVAL(*self as f64)
}
}
- #[fixed_stack_segment]
fn from_jsval(val: JSVal) -> Option<i64> {
unsafe {
Some(RUST_JSVAL_TO_DOUBLE(val) as i64)
@@ -29,14 +27,12 @@ impl JSValConvertible for i64 {
}
impl JSValConvertible for u32 {
- #[fixed_stack_segment]
fn to_jsval(&self) -> JSVal {
unsafe {
RUST_UINT_TO_JSVAL(*self)
}
}
- #[fixed_stack_segment]
fn from_jsval(val: JSVal) -> Option<u32> {
unsafe {
Some(RUST_JSVAL_TO_INT(val) as u32)
@@ -45,14 +41,12 @@ impl JSValConvertible for u32 {
}
impl JSValConvertible for i32 {
- #[fixed_stack_segment]
fn to_jsval(&self) -> JSVal {
unsafe {
RUST_UINT_TO_JSVAL(*self as u32)
}
}
- #[fixed_stack_segment]
fn from_jsval(val: JSVal) -> Option<i32> {
unsafe {
Some(RUST_JSVAL_TO_INT(val) as i32)
@@ -61,14 +55,12 @@ impl JSValConvertible for i32 {
}
impl JSValConvertible for u16 {
- #[fixed_stack_segment]
fn to_jsval(&self) -> JSVal {
unsafe {
RUST_UINT_TO_JSVAL(*self as u32)
}
}
- #[fixed_stack_segment]
fn from_jsval(val: JSVal) -> Option<u16> {
unsafe {
Some(RUST_JSVAL_TO_INT(val) as u16)
@@ -97,14 +89,12 @@ impl JSValConvertible for bool {
}
impl JSValConvertible for f32 {
- #[fixed_stack_segment]
fn to_jsval(&self) -> JSVal {
unsafe {
RUST_DOUBLE_TO_JSVAL(*self as f64)
}
}
- #[fixed_stack_segment]
fn from_jsval(val: JSVal) -> Option<f32> {
unsafe {
Some(RUST_JSVAL_TO_DOUBLE(val) as f32)
@@ -113,14 +103,12 @@ impl JSValConvertible for f32 {
}
impl JSValConvertible for f64 {
- #[fixed_stack_segment]
fn to_jsval(&self) -> JSVal {
unsafe {
RUST_DOUBLE_TO_JSVAL(*self as f64)
}
}
- #[fixed_stack_segment]
fn from_jsval(val: JSVal) -> Option<f64> {
unsafe {
Some(RUST_JSVAL_TO_DOUBLE(val) as f64)
diff --git a/src/components/script/dom/bindings/node.rs b/src/components/script/dom/bindings/node.rs
index cdc4c58bce0..8bf2ab8a565 100644
--- a/src/components/script/dom/bindings/node.rs
+++ b/src/components/script/dom/bindings/node.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use dom::bindings::utils::{Reflectable, Reflector, Traceable};
+use dom::bindings::utils::{Reflectable, Reflector, Traceable, trace_reflector};
use dom::types::*;
use dom::node::AbstractNode;
@@ -23,7 +23,6 @@ impl Reflectable for AbstractNode {
impl Traceable for Node {
fn trace(&self, tracer: *mut JSTracer) {
- #[fixed_stack_segment]
fn trace_node(tracer: *mut JSTracer, node: Option<AbstractNode>, name: &str) {
if node.is_none() {
return;
@@ -35,10 +34,10 @@ impl Traceable for Node {
unsafe {
(*tracer).debugPrinter = ptr::null();
(*tracer).debugPrintIndex = -1;
- do name.to_c_str().with_ref |name| {
+ name.to_c_str().with_ref(|name| {
(*tracer).debugPrintArg = name as *libc::c_void;
JS_CallTracer(cast::transmute(tracer), obj, JSTRACE_OBJECT as u32);
- }
+ });
}
}
debug!("tracing {:p}?:", self.reflector().get_jsobject());
@@ -47,5 +46,7 @@ impl Traceable for Node {
trace_node(tracer, self.last_child, "last child");
trace_node(tracer, self.next_sibling, "next sibling");
trace_node(tracer, self.prev_sibling, "prev sibling");
+ let owner_doc = self.owner_doc();
+ trace_reflector(tracer, "document", owner_doc.reflector());
}
}
diff --git a/src/components/script/dom/bindings/proxyhandler.rs b/src/components/script/dom/bindings/proxyhandler.rs
index 5201b724070..2f8267d4f29 100644
--- a/src/components/script/dom/bindings/proxyhandler.rs
+++ b/src/components/script/dom/bindings/proxyhandler.rs
@@ -44,7 +44,6 @@ pub extern fn getPropertyDescriptor(cx: *JSContext, proxy: *JSObject, id: jsid,
}
}
-#[fixed_stack_segment]
pub fn defineProperty_(cx: *JSContext, proxy: *JSObject, id: jsid,
desc: *JSPropertyDescriptor) -> JSBool {
unsafe {
@@ -72,7 +71,6 @@ pub extern fn defineProperty(cx: *JSContext, proxy: *JSObject, id: jsid,
defineProperty_(cx, proxy, id, desc)
}
-#[fixed_stack_segment]
pub fn _obj_toString(cx: *JSContext, className: *libc::c_char) -> *JSString {
unsafe {
let name = str::raw::from_c_str(className);
@@ -83,7 +81,7 @@ pub fn _obj_toString(cx: *JSContext, className: *libc::c_char) -> *JSString {
}
let result = ~"[object " + name + "]";
- for (i, c) in result.iter().enumerate() {
+ for (i, c) in result.chars().enumerate() {
*chars.offset(i as int) = c as jschar;
}
*chars.offset(nchars as int) = 0;
@@ -95,7 +93,6 @@ pub fn _obj_toString(cx: *JSContext, className: *libc::c_char) -> *JSString {
}
}
-#[fixed_stack_segment]
pub fn GetExpandoObject(obj: *JSObject) -> *JSObject {
unsafe {
assert!(is_dom_proxy(obj));
@@ -108,7 +105,6 @@ pub fn GetExpandoObject(obj: *JSObject) -> *JSObject {
}
}
-#[fixed_stack_segment]
pub fn EnsureExpandoObject(cx: *JSContext, obj: *JSObject) -> *JSObject {
unsafe {
assert!(is_dom_proxy(obj));
diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs
index 99f0d9f4fa9..f1e69e32021 100644
--- a/src/components/script/dom/bindings/utils.rs
+++ b/src/components/script/dom/bindings/utils.rs
@@ -29,7 +29,7 @@ use js::jsapi::{JS_NewUCStringCopyN, JS_DefineFunctions, JS_DefineProperty};
use js::jsapi::{JS_ValueToString, JS_GetReservedSlot, JS_SetReservedSlot};
use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative, JSTracer};
use js::jsapi::{JSFunctionSpec, JSPropertySpec, JSVal, JSPropertyDescriptor};
-use js::jsapi::{JSPropertyOp, JSStrictPropertyOp, JS_NewGlobalObject, JS_InitStandardClasses};
+use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses};
use js::jsapi::{JSString, JS_CallTracer, JSTRACE_OBJECT};
use js::jsapi::{JS_IsExceptionPending};
use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType;
@@ -47,22 +47,18 @@ mod jsval {
use js::glue::{RUST_JSVAL_IS_STRING, RUST_JSVAL_TO_STRING};
use js::jsapi::{JSVal, JSString};
- #[fixed_stack_segment]
pub fn is_null(v: JSVal) -> bool {
unsafe { RUST_JSVAL_IS_NULL(v) == 1 }
}
- #[fixed_stack_segment]
pub fn is_undefined(v: JSVal) -> bool {
unsafe { RUST_JSVAL_IS_VOID(v) == 1 }
}
- #[fixed_stack_segment]
pub fn is_string(v: JSVal) -> bool {
unsafe { RUST_JSVAL_IS_STRING(v) == 1 }
}
- #[fixed_stack_segment]
pub unsafe fn to_string(v: JSVal) -> *JSString {
RUST_JSVAL_TO_STRING(v)
}
@@ -149,7 +145,6 @@ fn is_dom_class(clasp: *JSClass) -> bool {
}
}
-#[fixed_stack_segment]
pub fn is_dom_proxy(obj: *JSObject) -> bool {
unsafe {
(js_IsObjectProxyClass(obj) || js_IsFunctionProxyClass(obj)) &&
@@ -157,7 +152,6 @@ pub fn is_dom_proxy(obj: *JSObject) -> bool {
}
}
-#[fixed_stack_segment]
pub unsafe fn dom_object_slot(obj: *JSObject) -> u32 {
let clasp = JS_GetClass(obj);
if is_dom_class(clasp) {
@@ -168,14 +162,12 @@ pub unsafe fn dom_object_slot(obj: *JSObject) -> u32 {
}
}
-#[fixed_stack_segment]
pub unsafe fn unwrap<T>(obj: *JSObject) -> T {
let slot = dom_object_slot(obj);
let val = JS_GetReservedSlot(obj, slot);
cast::transmute(RUST_JSVAL_TO_PRIVATE(val))
}
-#[fixed_stack_segment]
pub unsafe fn get_dom_class(obj: *JSObject) -> Result<DOMClass, ()> {
let clasp = JS_GetClass(obj);
if is_dom_class(clasp) {
@@ -194,7 +186,7 @@ pub unsafe fn get_dom_class(obj: *JSObject) -> Result<DOMClass, ()> {
pub fn unwrap_object<T>(obj: *JSObject, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<T, ()> {
unsafe {
- do get_dom_class(obj).and_then |dom_class| {
+ get_dom_class(obj).and_then(|dom_class| {
if dom_class.interface_chain[proto_depth] == proto_id {
debug!("good prototype");
Ok(unwrap(obj))
@@ -202,11 +194,10 @@ pub fn unwrap_object<T>(obj: *JSObject, proto_id: PrototypeList::id::ID, proto_d
debug!("bad prototype");
Err(())
}
- }
+ })
}
}
-#[fixed_stack_segment]
pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth: uint) -> Result<T, ()> {
unsafe {
let obj = RUST_JSVAL_TO_OBJECT(*val);
@@ -216,22 +207,19 @@ pub fn unwrap_value<T>(val: *JSVal, proto_id: PrototypeList::id::ID, proto_depth
pub unsafe fn squirrel_away<T>(x: @mut T) -> *Box<T> {
let y: *Box<T> = cast::transmute(x);
- cast::forget(x);
y
}
-#[fixed_stack_segment]
pub fn jsstring_to_str(cx: *JSContext, s: *JSString) -> ~str {
unsafe {
let length = 0;
let chars = JS_GetStringCharsAndLength(cx, s, &length);
- do vec::raw::buf_as_slice(chars, length as uint) |char_vec| {
+ vec::raw::buf_as_slice(chars, length as uint, |char_vec| {
str::from_utf16(char_vec)
- }
+ })
}
}
-#[fixed_stack_segment]
pub fn jsid_to_str(cx: *JSContext, id: jsid) -> ~str {
unsafe {
assert!(RUST_JSID_IS_STRING(id) != 0);
@@ -245,7 +233,6 @@ pub enum StringificationBehavior {
Empty,
}
-#[fixed_stack_segment]
pub fn jsval_to_str(cx: *JSContext, v: JSVal,
nullBehavior: StringificationBehavior) -> Result<~str, ()> {
if jsval::is_null(v) && nullBehavior == Empty {
@@ -261,7 +248,6 @@ pub fn jsval_to_str(cx: *JSContext, v: JSVal,
}
}
-#[fixed_stack_segment]
pub fn jsval_to_domstring(cx: *JSContext, v: JSVal) -> Result<Option<DOMString>, ()> {
if jsval::is_null(v) || jsval::is_undefined(v) {
Ok(None)
@@ -276,20 +262,17 @@ pub fn jsval_to_domstring(cx: *JSContext, v: JSVal) -> Result<Option<DOMString>,
}
}
-#[fixed_stack_segment]
pub unsafe fn str_to_jsval(cx: *JSContext, string: DOMString) -> JSVal {
- do string.to_utf16().as_imm_buf |buf, len| {
- let jsstr = JS_NewUCStringCopyN(cx, buf, len as libc::size_t);
- if jsstr.is_null() {
- // FIXME: is there something else we should do on failure?
- JSVAL_NULL
- } else {
- RUST_STRING_TO_JSVAL(jsstr)
- }
+ let string_utf16 = string.to_utf16();
+ let jsstr = JS_NewUCStringCopyN(cx, string_utf16.as_ptr(), string_utf16.len() as libc::size_t);
+ if jsstr.is_null() {
+ // FIXME: is there something else we should do on failure?
+ JSVAL_NULL
+ } else {
+ RUST_STRING_TO_JSVAL(jsstr)
}
}
-#[fixed_stack_segment]
pub unsafe fn domstring_to_jsval(cx: *JSContext, string: Option<DOMString>) -> JSVal {
match string {
None => JSVAL_NULL,
@@ -313,7 +296,7 @@ pub static DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT;
// NOTE: This is baked into the Ion JIT as 0 in codegen for LGetDOMProperty and
// LSetDOMProperty. Those constants need to be changed accordingly if this value
// changes.
-static JSCLASS_DOM_GLOBAL: u32 = js::JSCLASS_USERBIT1;
+pub static JSCLASS_DOM_GLOBAL: u32 = js::JSCLASS_USERBIT1;
pub struct NativeProperties {
staticMethods: *JSFunctionSpec,
@@ -379,7 +362,6 @@ pub struct DOMJSClass {
dom_class: DOMClass
}
-#[fixed_stack_segment]
pub fn GetProtoOrIfaceArray(global: *JSObject) -> **JSObject {
unsafe {
/*assert ((*JS_GetClass(global)).flags & JSCLASS_DOM_GLOBAL) != 0;*/
@@ -387,7 +369,6 @@ pub fn GetProtoOrIfaceArray(global: *JSObject) -> **JSObject {
}
}
-#[fixed_stack_segment]
pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSObject,
protoProto: *JSObject, protoClass: *JSClass,
constructorClass: *JSClass, constructor: Option<JSNative>,
@@ -415,11 +396,11 @@ pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSO
let mut interface = ptr::null();
if constructorClass.is_not_null() || constructor.is_some() {
- interface = do name.to_c_str().with_ref |s| {
+ interface = name.to_c_str().with_ref(|s| {
CreateInterfaceObject(cx, global, receiver, constructorClass,
constructor, ctorNargs, proto,
staticMethods, constants, s)
- };
+ });
if interface.is_null() {
return ptr::null();
}
@@ -432,7 +413,6 @@ pub fn CreateInterfaceObjects2(cx: *JSContext, global: *JSObject, receiver: *JSO
}
}
-#[fixed_stack_segment]
fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject,
constructorClass: *JSClass, constructorNative: Option<JSNative>,
ctorNargs: u32, proto: *JSObject,
@@ -467,11 +447,11 @@ fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject,
}
if constructorClass.is_not_null() {
- let toString = do "toString".to_c_str().with_ref |s| {
+ let toString = "toString".to_c_str().with_ref(|s| {
DefineFunctionWithReserved(cx, constructor, s,
InterfaceObjectToString,
0, 0)
- };
+ });
if toString.is_null() {
return ptr::null();
}
@@ -511,7 +491,6 @@ fn CreateInterfaceObject(cx: *JSContext, global: *JSObject, receiver: *JSObject,
}
}
-#[fixed_stack_segment]
fn DefineConstants(cx: *JSContext, obj: *JSObject, constants: *ConstantSpec) -> bool {
let mut i = 0;
loop {
@@ -541,21 +520,18 @@ fn DefineConstants(cx: *JSContext, obj: *JSObject, constants: *ConstantSpec) ->
}
}
-#[fixed_stack_segment]
fn DefineMethods(cx: *JSContext, obj: *JSObject, methods: *JSFunctionSpec) -> bool {
unsafe {
JS_DefineFunctions(cx, obj, methods) != 0
}
}
-#[fixed_stack_segment]
fn DefineProperties(cx: *JSContext, obj: *JSObject, properties: *JSPropertySpec) -> bool {
unsafe {
JS_DefineProperties(cx, obj, properties) != 0
}
}
-#[fixed_stack_segment]
fn CreateInterfacePrototypeObject(cx: *JSContext, global: *JSObject,
parentProto: *JSObject, protoClass: *JSClass,
methods: *JSFunctionSpec,
@@ -592,17 +568,16 @@ pub trait Traceable {
fn trace(&self, trc: *mut JSTracer);
}
-#[fixed_stack_segment]
pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Reflector) {
unsafe {
- do description.to_c_str().with_ref |name| {
+ description.to_c_str().with_ref(|name| {
(*tracer).debugPrinter = ptr::null();
(*tracer).debugPrintIndex = -1;
(*tracer).debugPrintArg = name as *libc::c_void;
debug!("tracing {:s}", description);
JS_CallTracer(tracer as *JSTracer, reflector.get_jsobject(),
JSTRACE_OBJECT as u32);
- }
+ });
}
}
@@ -610,13 +585,12 @@ pub fn trace_option<T: Reflectable>(tracer: *mut JSTracer, description: &str, op
option.map(|some| trace_reflector(tracer, description, some.reflector()));
}
-#[fixed_stack_segment]
pub fn initialize_global(global: *JSObject) {
let protoArray = @mut ([0 as *JSObject, ..PrototypeList::id::_ID_Count as uint]);
unsafe {
//XXXjdm we should be storing the box pointer instead of the inner
- let box = squirrel_away(protoArray);
- let inner = ptr::to_unsafe_ptr(&(*box).data);
+ let box_ = squirrel_away(protoArray);
+ let inner = ptr::to_unsafe_ptr(&(*box_).data);
JS_SetReservedSlot(global,
DOM_PROTOTYPE_SLOT,
RUST_PRIVATE_TO_JSVAL(inner as *libc::c_void));
@@ -668,7 +642,6 @@ impl Reflector {
}
}
-#[fixed_stack_segment]
pub fn GetReflector(cx: *JSContext, reflector: &Reflector,
vp: *mut JSVal) -> JSBool {
let obj = reflector.get_jsobject();
@@ -679,7 +652,6 @@ pub fn GetReflector(cx: *JSContext, reflector: &Reflector,
}
}
-#[fixed_stack_segment]
pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found: *mut bool,
vp: *JSVal) -> bool {
unsafe {
@@ -703,7 +675,6 @@ pub fn GetPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid, found:
}
}
-#[fixed_stack_segment]
pub fn GetArrayIndexFromId(_cx: *JSContext, id: jsid) -> Option<u32> {
unsafe {
if RUST_JSID_IS_INT(id) != 0 {
@@ -727,7 +698,6 @@ pub fn GetArrayIndexFromId(_cx: *JSContext, id: jsid) -> Option<u32> {
}*/
}
-#[fixed_stack_segment]
pub fn XrayResolveProperty(cx: *JSContext,
wrapper: *JSObject,
id: jsid,
@@ -754,7 +724,7 @@ pub fn XrayResolveProperty(cx: *JSContext,
RUST_SET_JITINFO(fun, attr.getter.info);
let funobj = JS_GetFunctionObject(fun);
- (*desc).getter = Some(funobj as JSPropertyOp);
+ (*desc).getter = Some(cast::transmute(funobj));
(*desc).attrs |= JSPROP_GETTER;
if attr.setter.op.is_some() {
let fun = JS_NewFunction(cx, attr.setter.op, 1, 0, global, ptr::null());
@@ -764,7 +734,7 @@ pub fn XrayResolveProperty(cx: *JSContext,
RUST_SET_JITINFO(fun, attr.setter.info);
let funobj = JS_GetFunctionObject(fun);
- (*desc).setter = Some(funobj as JSStrictPropertyOp);
+ (*desc).setter = Some(cast::transmute(funobj));
(*desc).attrs |= JSPROP_SETTER;
} else {
(*desc).setter = None;
@@ -777,7 +747,6 @@ pub fn XrayResolveProperty(cx: *JSContext,
}
}
-#[fixed_stack_segment]
fn InternJSString(cx: *JSContext, chars: *libc::c_char) -> Option<jsid> {
unsafe {
let s = JS_InternString(cx, chars);
@@ -824,7 +793,6 @@ pub struct EnumEntry {
length: uint
}
-#[fixed_stack_segment]
pub fn FindEnumStringIndex(cx: *JSContext,
v: JSVal,
values: &[EnumEntry]) -> Result<uint, ()> {
@@ -865,14 +833,12 @@ pub fn HasPropertyOnPrototype(cx: *JSContext, proxy: *JSObject, id: jsid) -> boo
return !GetPropertyOnPrototype(cx, proxy, id, &mut found, ptr::null()) || found;
}
-#[fixed_stack_segment]
pub fn IsConvertibleToCallbackInterface(cx: *JSContext, obj: *JSObject) -> bool {
unsafe {
JS_ObjectIsDate(cx, obj) == 0 && JS_ObjectIsRegExp(cx, obj) == 0
}
}
-#[fixed_stack_segment]
pub fn CreateDOMGlobal(cx: *JSContext, class: *JSClass) -> *JSObject {
unsafe {
let obj = JS_NewGlobalObject(cx, class, ptr::null());
@@ -886,7 +852,6 @@ pub fn CreateDOMGlobal(cx: *JSContext, class: *JSClass) -> *JSObject {
}
/// Returns the global object of the realm that the given JS object was created in.
-#[fixed_stack_segment]
fn global_object_for_js_object(obj: *JSObject) -> *Box<window::Window> {
unsafe {
let global = GetGlobalForObjectCrossCompartment(obj);
@@ -900,7 +865,6 @@ fn global_object_for_js_object(obj: *JSObject) -> *Box<window::Window> {
}
}
-#[fixed_stack_segment]
fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext {
unsafe {
let win = global_object_for_js_object(obj);
@@ -912,7 +876,6 @@ fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext {
}
/// Returns the global object of the realm that the given DOM object was created in.
-#[fixed_stack_segment]
pub fn global_object_for_dom_object<T: Reflectable>(obj: &mut T) -> *Box<window::Window> {
global_object_for_js_object(obj.reflector().get_jsobject())
}
@@ -921,7 +884,6 @@ pub fn cx_for_dom_object<T: Reflectable>(obj: &mut T) -> *JSContext {
cx_for_dom_reflector(obj.reflector().get_jsobject())
}
-#[fixed_stack_segment]
pub fn throw_method_failed_with_details<T>(cx: *JSContext,
result: Result<T, Error>,
interface: &'static str,
@@ -929,9 +891,9 @@ pub fn throw_method_failed_with_details<T>(cx: *JSContext,
assert!(result.is_err());
assert!(unsafe { JS_IsExceptionPending(cx) } == 0);
let message = format!("Method failed: {}.{}", interface, member);
- do message.with_c_str |string| {
+ message.with_c_str(|string| {
unsafe { ReportError(cx, string) };
- }
+ });
return 0;
}
@@ -979,7 +941,7 @@ pub fn xml_name_type(name: &str) -> XMLName {
}
}
- let mut iter = name.iter();
+ let mut iter = name.chars();
let mut non_qname_colons = false;
let mut seen_colon = false;
match iter.next() {
@@ -994,7 +956,7 @@ pub fn xml_name_type(name: &str) -> XMLName {
}
}
- for c in name.iter() {
+ for c in name.chars() {
if !is_valid_continuation(c) {
return InvalidXMLName;
}
diff --git a/src/components/script/dom/document.rs b/src/components/script/dom/document.rs
index be4a8f06330..15a952cd418 100644
--- a/src/components/script/dom/document.rs
+++ b/src/components/script/dom/document.rs
@@ -55,17 +55,12 @@ impl AbstractDocument {
}
}
- unsafe fn transmute<T, R>(&self, f: &fn(&T) -> R) -> R {
- let box: *Box<T> = cast::transmute(self.document);
- f(&(*box).data)
+ unsafe fn transmute<T, R>(&self, f: |&T| -> R) -> R {
+ let box_: *Box<T> = cast::transmute(self.document);
+ f(&(*box_).data)
}
- unsafe fn transmute_mut<T, R>(&self, f: &fn(&mut T) -> R) -> R {
- let box: *mut Box<T> = cast::transmute(self.document);
- f(&mut (*box).data)
- }
-
- pub fn with_html<R>(&self, callback: &fn(&HTMLDocument) -> R) -> R {
+ pub fn with_html<R>(&self, callback: |&HTMLDocument| -> R) -> R {
match self.document().doctype {
HTML => unsafe { self.transmute(callback) },
_ => fail!("attempt to downcast a non-HTMLDocument to HTMLDocument")
@@ -105,9 +100,9 @@ impl Document {
let document = reflect_dom_object(document, window, wrap_fn);
assert!(document.reflector().get_jsobject().is_not_null());
- // This surrenders memory management of the document!
+ // JS object now owns the Document, so transmute_copy is needed
let abstract = AbstractDocument {
- document: unsafe { cast::transmute(document) }
+ document: unsafe { cast::transmute_copy(&document) }
};
abstract.mut_document().node.set_owner_doc(abstract);
abstract
@@ -165,10 +160,6 @@ impl Document {
self.node.child_elements().next()
}
- fn get_cx(&self) -> *JSContext {
- self.window.get_cx()
- }
-
pub fn GetElementsByTagName(&self, tag: DOMString) -> @mut HTMLCollection {
self.createHTMLCollection(|elem| eq_slice(elem.tag_name, tag))
}
@@ -238,9 +229,9 @@ impl Document {
}
for child in node.children() {
if child.is_text() {
- do child.with_imm_text() |text| {
+ child.with_imm_text(|text| {
title = title + text.element.Data();
- }
+ });
}
}
break;
@@ -249,7 +240,7 @@ impl Document {
}
}
}
- let v: ~[&str] = title.word_iter().collect();
+ let v: ~[&str] = title.words().collect();
title = v.connect(" ");
title = title.trim().to_owned();
title
@@ -295,12 +286,12 @@ impl Document {
}
fn get_html_element(&self) -> Option<AbstractNode> {
- do self.GetDocumentElement().filtered |root| {
+ self.GetDocumentElement().filtered(|root| {
match root.type_id() {
ElementNodeTypeId(HTMLHtmlElementTypeId) => true,
_ => false
}
- }
+ })
}
// http://www.whatwg.org/specs/web-apps/current-work/#dom-document-head
@@ -317,13 +308,13 @@ impl Document {
match self.get_html_element() {
None => None,
Some(root) => {
- do root.children().find |child| {
+ root.children().find(|child| {
match child.type_id() {
ElementNodeTypeId(HTMLBodyElementTypeId) |
ElementNodeTypeId(HTMLFrameSetElementTypeId) => true,
_ => false
}
- }
+ })
}
}
}
@@ -366,18 +357,18 @@ impl Document {
elem.get_attr(Null, "name").is_some() && eq_slice(elem.get_attr(Null, "name").unwrap(), name))
}
- pub fn createHTMLCollection(&self, callback: &fn(elem: &Element) -> bool) -> @mut HTMLCollection {
+ pub fn createHTMLCollection(&self, callback: |elem: &Element| -> bool) -> @mut HTMLCollection {
let mut elements = ~[];
match self.GetDocumentElement() {
None => {},
Some(root) => {
for child in root.traverse_preorder() {
if child.is_element() {
- do child.with_imm_element |elem| {
+ child.with_imm_element(|elem| {
if callback(elem) {
elements.push(child);
}
- }
+ });
}
}
}
@@ -436,25 +427,24 @@ impl Document {
}
#[inline(always)]
-fn foreach_ided_elements(root: &AbstractNode, callback: &fn(&DOMString, &AbstractNode)) {
+fn foreach_ided_elements(root: &AbstractNode, callback: |&DOMString, &AbstractNode|) {
for node in root.traverse_preorder() {
if !node.is_element() {
continue;
}
- do node.with_imm_element |element| {
+ node.with_imm_element(|element| {
match element.get_attr(Null, "id") {
Some(id) => {
callback(&id.to_str(), &node);
}
None => ()
}
- }
+ });
}
}
impl Traceable for Document {
- #[fixed_stack_segment]
fn trace(&self, tracer: *mut JSTracer) {
self.node.trace(tracer);
}
diff --git a/src/components/script/dom/element.rs b/src/components/script/dom/element.rs
index 8e5294d2663..df5e76d2168 100644
--- a/src/components/script/dom/element.rs
+++ b/src/components/script/dom/element.rs
@@ -22,7 +22,6 @@ use layout_interface::{ContentBoxesResponse, ContentChangedDocumentDamage};
use layout_interface::{MatchSelectorsDocumentDamage};
use style;
-use std::comm;
use std::str::eq;
use std::ascii::StrAsciiExt;
@@ -123,7 +122,7 @@ pub enum ElementTypeId {
//
-impl<'self> Element {
+impl Element {
pub fn new_inherited(type_id: ElementTypeId, tag_name: ~str, namespace: Namespace, document: AbstractDocument) -> Element {
Element {
node: Node::new_inherited(ElementNodeTypeId(type_id), document),
@@ -175,7 +174,7 @@ impl<'self> Element {
//FIXME: Throw for XML-invalid names
//FIXME: Throw for XMLNS-invalid names
let (prefix, local_name) = if name.contains(":") {
- let parts: ~[&str] = name.splitn_iter(':', 1).collect();
+ let parts: ~[&str] = name.splitn(':', 1).collect();
(Some(parts[0].to_owned()), parts[1].to_owned())
} else {
(None, name.clone())
@@ -238,14 +237,14 @@ impl<'self> Element {
// This hardcoding is awful.
match abstract_self.type_id() {
ElementNodeTypeId(HTMLImageElementTypeId) => {
- do abstract_self.with_mut_image_element |image| {
+ abstract_self.with_mut_image_element(|image| {
image.AfterSetAttr(local_name.clone(), value.clone());
- }
+ });
}
ElementNodeTypeId(HTMLIframeElementTypeId) => {
- do abstract_self.with_mut_iframe_element |iframe| {
+ abstract_self.with_mut_iframe_element(|iframe| {
iframe.AfterSetAttr(local_name.clone(), value.clone());
- }
+ });
}
_ => ()
}
@@ -390,18 +389,18 @@ impl Element {
let win = self.node.owner_doc().document().window;
let node = abstract_self;
assert!(node.is_element());
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
let rects =
match win.page.query_layout(ContentBoxesQuery(node, chan), port) {
ContentBoxesResponse(rects) => {
- do rects.map |r| {
+ rects.map(|r| {
ClientRect::new(
win,
r.origin.y,
r.origin.y + r.size.height,
r.origin.x,
r.origin.x + r.size.width)
- }
+ })
},
};
@@ -412,7 +411,7 @@ impl Element {
let win = self.node.owner_doc().document().window;
let node = abstract_self;
assert!(node.is_element());
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
match win.page.query_layout(ContentBoxQuery(node, chan), port) {
ContentBoxResponse(rect) => {
ClientRect::new(
diff --git a/src/components/script/dom/event.rs b/src/components/script/dom/event.rs
index 69b96be8660..f2124ea37d9 100644
--- a/src/components/script/dom/event.rs
+++ b/src/components/script/dom/event.rs
@@ -35,9 +35,9 @@ pub enum EventPhase {
}
impl AbstractEvent {
- pub fn from_box(box: *mut Box<Event>) -> AbstractEvent {
+ pub fn from_box(box_: *mut Box<Event>) -> AbstractEvent {
AbstractEvent {
- event: box
+ event: box_
}
}
@@ -47,15 +47,15 @@ impl AbstractEvent {
fn transmute<'a, T>(&'a self) -> &'a T {
unsafe {
- let box: *Box<T> = self.event as *Box<T>;
- &(*box).data
+ let box_: *Box<T> = self.event as *Box<T>;
+ &(*box_).data
}
}
fn transmute_mut<'a, T>(&'a self) -> &'a mut T {
unsafe {
- let box: *mut Box<T> = self.event as *mut Box<T>;
- &mut (*box).data
+ let box_: *mut Box<T> = self.event as *mut Box<T>;
+ &mut (*box_).data
}
}
diff --git a/src/components/script/dom/eventtarget.rs b/src/components/script/dom/eventtarget.rs
index d3768ed656e..9ee4c123870 100644
--- a/src/components/script/dom/eventtarget.rs
+++ b/src/components/script/dom/eventtarget.rs
@@ -44,9 +44,9 @@ pub struct AbstractEventTarget {
}
impl AbstractEventTarget {
- pub fn from_box<T>(box: *mut Box<T>) -> AbstractEventTarget {
+ pub fn from_box<T>(box_: *mut Box<T>) -> AbstractEventTarget {
AbstractEventTarget {
- eventtarget: box as *mut Box<EventTarget>
+ eventtarget: box_ as *mut Box<EventTarget>
}
}
@@ -86,15 +86,15 @@ impl AbstractEventTarget {
fn transmute<'a, T>(&'a self) -> &'a T {
unsafe {
- let box: *Box<T> = self.eventtarget as *Box<T>;
- &(*box).data
+ let box_: *Box<T> = self.eventtarget as *Box<T>;
+ &(*box_).data
}
}
fn transmute_mut<'a, T>(&'a mut self) -> &'a mut T {
unsafe {
- let box: *mut Box<T> = self.eventtarget as *mut Box<T>;
- &mut (*box).data
+ let box_: *mut Box<T> = self.eventtarget as *mut Box<T>;
+ &mut (*box_).data
}
}
@@ -127,17 +127,17 @@ impl EventTarget {
}
pub fn get_listeners(&self, type_: &str) -> Option<~[EventListener]> {
- do self.handlers.find_equiv(&type_).map |listeners| {
+ self.handlers.find_equiv(&type_).map(|listeners| {
listeners.iter().map(|entry| entry.listener).collect()
- }
+ })
}
pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase)
-> Option<~[EventListener]> {
- do self.handlers.find_equiv(&type_).map |listeners| {
+ self.handlers.find_equiv(&type_).map(|listeners| {
let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase);
filtered.map(|entry| entry.listener).collect()
- }
+ })
}
pub fn AddEventListener(&mut self,
diff --git a/src/components/script/dom/htmliframeelement.rs b/src/components/script/dom/htmliframeelement.rs
index f263444a335..5157ab03be7 100644
--- a/src/components/script/dom/htmliframeelement.rs
+++ b/src/components/script/dom/htmliframeelement.rs
@@ -95,7 +95,7 @@ impl HTMLIFrameElement {
pub fn AfterSetAttr(&mut self, name: DOMString, value: DOMString) {
if "sandbox" == name {
let mut modes = AllowNothing as u8;
- for word in value.split_iter(' ') {
+ for word in value.split(' ') {
// FIXME: Workaround for https://github.com/mozilla/rust/issues/10683
let word_lower = word.to_ascii_lower();
modes |= match word_lower.as_slice() {
diff --git a/src/components/script/dom/htmlimageelement.rs b/src/components/script/dom/htmlimageelement.rs
index aa1a02d7ecb..53686661c10 100644
--- a/src/components/script/dom/htmlimageelement.rs
+++ b/src/components/script/dom/htmlimageelement.rs
@@ -112,7 +112,7 @@ impl HTMLImageElement {
pub fn Width(&self, abstract_self: AbstractNode) -> u32 {
let node = &self.htmlelement.element.node;
let page = node.owner_doc().document().window.page;
- let (port, chan) = stream();
+ let (port, chan) = Chan::new();
match page.query_layout(ContentBoxQuery(abstract_self, chan), port) {
ContentBoxResponse(rect) => {
to_px(rect.size.width) as u32
@@ -129,7 +129,7 @@ impl HTMLImageElement {
pub fn Height(&self, abstract_self: AbstractNode) -> u32 {
let node = &self.htmlelement.element.node;
let page = node.owner_doc().document().window.page;
- let (port, chan) = stream();
+ let (port, chan) = Chan::new();
match page.query_layout(ContentBoxQuery(abstract_self, chan), port) {
ContentBoxResponse(rect) => {
to_px(rect.size.height) as u32
diff --git a/src/components/script/dom/node.rs b/src/components/script/dom/node.rs
index b002715eb1c..a98f89b4817 100644
--- a/src/components/script/dom/node.rs
+++ b/src/components/script/dom/node.rs
@@ -7,7 +7,6 @@
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::bindings::utils::{DOMString, null_str_as_empty};
use dom::bindings::utils::{ErrorResult, Fallible, NotFound, HierarchyRequest};
-use dom::bindings::utils;
use dom::characterdata::CharacterData;
use dom::document::{AbstractDocument, DocumentTypeId};
use dom::documenttype::DocumentType;
@@ -20,12 +19,15 @@ use dom::nodelist::{NodeList};
use dom::text::Text;
use js::jsapi::{JSObject, JSContext};
-use servo_util::slot::{MutSlotRef, Slot, SlotRef};
-use std::cast::transmute;
+
+use layout_interface::{LayoutChan, ReapLayoutDataMsg};
+
use std::cast;
-use std::unstable::raw::Box;
-use std::util;
+use std::cast::transmute;
+use std::cell::{RefCell, Ref, RefMut};
use std::iter::Filter;
+use std::util;
+use std::unstable::raw::Box;
//
// The basic Node structure
@@ -37,7 +39,7 @@ use std::iter::Filter;
/// FIXME: This should be replaced with a trait once they can inherit from structs.
#[deriving(Eq)]
pub struct AbstractNode {
- priv obj: *mut Box<Node>,
+ priv obj: *mut (),
}
/// An HTML node.
@@ -109,30 +111,43 @@ impl Drop for Node {
}
/// Encapsulates the abstract layout data.
+pub struct LayoutData {
+ priv chan: Option<LayoutChan>,
+ priv data: *(),
+}
+
pub struct LayoutDataRef {
- priv data: Slot<Option<*()>>,
+ data_cell: RefCell<Option<LayoutData>>,
}
impl LayoutDataRef {
- #[inline]
- pub fn init() -> LayoutDataRef {
+ pub fn new() -> LayoutDataRef {
LayoutDataRef {
- data: Slot::init(None),
+ data_cell: RefCell::new(None),
}
}
- /// Creates a new piece of layout data from a value.
- #[inline]
pub unsafe fn from_data<T>(data: ~T) -> LayoutDataRef {
LayoutDataRef {
- data: Slot::init(Some(cast::transmute(data))),
+ data_cell: RefCell::new(Some(cast::transmute(data))),
}
}
- /// Returns true if this layout data is present or false otherwise.
+ /// Returns true if there is layout data present.
#[inline]
pub fn is_present(&self) -> bool {
- self.data.get().is_some()
+ let data_ref = self.data_cell.borrow();
+ data_ref.get().is_some()
+ }
+
+ /// Take the chan out of the layout data if it is present.
+ pub fn take_chan(&self) -> Option<LayoutChan> {
+ let mut data_ref = self.data_cell.borrow_mut();
+ let layout_data = data_ref.get();
+ match *layout_data {
+ None => None,
+ Some(..) => Some(layout_data.get_mut_ref().chan.take_unwrap()),
+ }
}
/// Borrows the layout data immutably, *asserting that there are no mutators*. Bad things will
@@ -141,17 +156,15 @@ impl LayoutDataRef {
///
/// FIXME(pcwalton): Enforce this invariant via the type system. Will require traversal
/// functions to be trusted, but c'est la vie.
- #[inline]
- pub unsafe fn borrow_unchecked<'a>(&'a self) -> &'a () {
- cast::transmute(self.data.borrow_unchecked())
- }
+ // #[inline]
+ // pub unsafe fn borrow_unchecked<'a>(&'a self) -> &'a () {
+ // self.data.borrow_unchecked()
+ // }
/// Borrows the layout data immutably. This function is *not* thread-safe.
#[inline]
- pub fn borrow<'a>(&'a self) -> SlotRef<'a,()> {
- unsafe {
- cast::transmute(self.data.borrow())
- }
+ pub fn borrow<'a>(&'a self) -> Ref<'a,Option<LayoutData>> {
+ self.data_cell.borrow()
}
/// Borrows the layout data mutably. This function is *not* thread-safe.
@@ -160,10 +173,8 @@ impl LayoutDataRef {
/// prevent CSS selector matching from mutably accessing nodes it's not supposed to and racing
/// on it. This has already resulted in one bug!
#[inline]
- pub fn mutate<'a>(&'a self) -> MutSlotRef<'a,()> {
- unsafe {
- cast::transmute(self.data.mutate())
- }
+ pub fn borrow_mut<'a>(&'a self) -> RefMut<'a,Option<LayoutData>> {
+ self.data_cell.borrow_mut()
}
}
@@ -193,13 +204,15 @@ impl Clone for AbstractNode {
impl AbstractNode {
pub fn node<'a>(&'a self) -> &'a Node {
unsafe {
- &(*self.obj).data
+ let box_: *mut Box<Node> = cast::transmute(self.obj);
+ &(*box_).data
}
}
pub fn mut_node<'a>(&'a self) -> &'a mut Node {
unsafe {
- &mut (*self.obj).data
+ let box_: *mut Box<Node> = cast::transmute(self.obj);
+ &mut (*box_).data
}
}
@@ -217,20 +230,20 @@ impl AbstractNode {
pub fn is_element(&self) -> bool {
match self.type_id() {
- ElementNodeTypeId(*) => true,
+ ElementNodeTypeId(..) => true,
_ => false
}
}
pub fn is_document(&self) -> bool {
match self.type_id() {
- DocumentNodeTypeId(*) => true,
+ DocumentNodeTypeId(..) => true,
_ => false
}
}
}
-impl<'self> AbstractNode {
+impl<'a> AbstractNode {
// Unsafe accessors
pub unsafe fn as_cacheable_wrapper(&self) -> @mut Reflectable {
@@ -252,7 +265,7 @@ impl<'self> AbstractNode {
/// FIXME(pcwalton): Mark unsafe?
pub fn from_box<T>(ptr: *mut Box<T>) -> AbstractNode {
AbstractNode {
- obj: ptr as *mut Box<Node>
+ obj: ptr as *mut ()
}
}
@@ -291,27 +304,27 @@ impl<'self> AbstractNode {
// Downcasting borrows
//
- pub fn transmute<T, R>(self, f: &fn(&T) -> R) -> R {
+ pub fn transmute<'a, T, R>(self, f: |&'a T| -> R) -> R {
unsafe {
let node_box: *mut Box<Node> = transmute(self.obj);
let node = &mut (*node_box).data;
let old = node.abstract;
node.abstract = Some(self);
- let box: *Box<T> = transmute(self.obj);
- let rv = f(&(*box).data);
+ let box_: *Box<T> = transmute(self.obj);
+ let rv = f(&(*box_).data);
node.abstract = old;
rv
}
}
- pub fn transmute_mut<T, R>(self, f: &fn(&mut T) -> R) -> R {
+ pub fn transmute_mut<T, R>(self, f: |&mut T| -> R) -> R {
unsafe {
let node_box: *mut Box<Node> = transmute(self.obj);
let node = &mut (*node_box).data;
let old = node.abstract;
node.abstract = Some(self);
- let box: *Box<T> = transmute(self.obj);
- let rv = f(cast::transmute(&(*box).data));
+ let box_: *Box<T> = transmute(self.obj);
+ let rv = f(cast::transmute(&(*box_).data));
node.abstract = old;
rv
}
@@ -323,14 +336,14 @@ impl<'self> AbstractNode {
self.is_text() || self.is_comment()
}
- pub fn with_imm_characterdata<R>(self, f: &fn(&CharacterData) -> R) -> R {
+ pub fn with_imm_characterdata<R>(self, f: |&CharacterData| -> R) -> R {
if !self.is_characterdata() {
fail!(~"node is not characterdata");
}
self.transmute(f)
}
- pub fn with_mut_characterdata<R>(self, f: &fn(&mut CharacterData) -> R) -> R {
+ pub fn with_mut_characterdata<R>(self, f: |&mut CharacterData| -> R) -> R {
if !self.is_characterdata() {
fail!(~"node is not characterdata");
}
@@ -341,14 +354,14 @@ impl<'self> AbstractNode {
self.type_id() == DoctypeNodeTypeId
}
- pub fn with_imm_doctype<R>(self, f: &fn(&DocumentType) -> R) -> R {
+ pub fn with_imm_doctype<R>(self, f: |&DocumentType| -> R) -> R {
if !self.is_doctype() {
fail!(~"node is not doctype");
}
self.transmute(f)
}
- pub fn with_mut_doctype<R>(self, f: &fn(&mut DocumentType) -> R) -> R {
+ pub fn with_mut_doctype<R>(self, f: |&mut DocumentType| -> R) -> R {
if !self.is_doctype() {
fail!(~"node is not doctype");
}
@@ -375,14 +388,14 @@ impl<'self> AbstractNode {
}
}
- pub fn with_imm_text<R>(self, f: &fn(&Text) -> R) -> R {
+ pub fn with_imm_text<R>(self, f: |&Text| -> R) -> R {
if !self.is_text() {
fail!(~"node is not text");
}
self.transmute(f)
}
- pub fn with_mut_text<R>(self, f: &fn(&mut Text) -> R) -> R {
+ pub fn with_mut_text<R>(self, f: |&mut Text| -> R) -> R {
if !self.is_text() {
fail!(~"node is not text");
}
@@ -390,7 +403,7 @@ impl<'self> AbstractNode {
}
// FIXME: This should be doing dynamic borrow checking for safety.
- pub fn with_imm_element<R>(self, f: &fn(&Element) -> R) -> R {
+ pub fn with_imm_element<R>(self, f: |&Element| -> R) -> R {
if !self.is_element() {
fail!(~"node is not an element");
}
@@ -398,7 +411,7 @@ impl<'self> AbstractNode {
}
// FIXME: This should be doing dynamic borrow checking for safety.
- pub fn as_mut_element<R>(self, f: &fn(&mut Element) -> R) -> R {
+ pub fn as_mut_element<R>(self, f: |&mut Element| -> R) -> R {
if !self.is_element() {
fail!(~"node is not an element");
}
@@ -413,7 +426,7 @@ impl<'self> AbstractNode {
}
}
- pub fn with_mut_image_element<R>(self, f: &fn(&mut HTMLImageElement) -> R) -> R {
+ pub fn with_mut_image_element<R>(self, f: |&mut HTMLImageElement| -> R) -> R {
if !self.is_image_element() {
fail!(~"node is not an image element");
}
@@ -424,7 +437,7 @@ impl<'self> AbstractNode {
self.type_id() == ElementNodeTypeId(HTMLIframeElementTypeId)
}
- pub fn with_mut_iframe_element<R>(self, f: &fn(&mut HTMLIFrameElement) -> R) -> R {
+ pub fn with_mut_iframe_element<R>(self, f: |&mut HTMLIFrameElement| -> R) -> R {
if !self.is_iframe_element() {
fail!(~"node is not an iframe element");
}
@@ -440,12 +453,12 @@ impl<'self> AbstractNode {
}
pub unsafe fn raw_object(self) -> *mut Box<Node> {
- self.obj
+ cast::transmute(self.obj)
}
pub fn from_raw(raw: *mut Box<Node>) -> AbstractNode {
AbstractNode {
- obj: raw
+ obj: raw as *mut ()
}
}
@@ -479,10 +492,6 @@ impl<'self> AbstractNode {
// Convenience accessors
//
- fn is_leaf(&self) -> bool {
- self.first_child().is_none()
- }
-
pub fn children(&self) -> AbstractNodeChildrenIterator {
self.node().children()
}
@@ -610,35 +619,6 @@ impl AbstractNode {
child_node.set_next_sibling(None);
child_node.set_parent_node(None);
}
-
- //
- // Low-level pointer stitching wrappers
- //
-
- fn set_parent_node(&self, new_parent_node: Option<AbstractNode>) {
- let node = self.mut_node();
- node.set_parent_node(new_parent_node)
- }
-
- fn set_first_child(&self, new_first_child: Option<AbstractNode>) {
- let node = self.mut_node();
- node.set_first_child(new_first_child)
- }
-
- fn set_last_child(&self, new_last_child: Option<AbstractNode>) {
- let node = self.mut_node();
- node.set_last_child(new_last_child)
- }
-
- fn set_prev_sibling(&self, new_prev_sibling: Option<AbstractNode>) {
- let node = self.mut_node();
- node.set_prev_sibling(new_prev_sibling)
- }
-
- fn set_next_sibling(&self, new_next_sibling: Option<AbstractNode>) {
- let node = self.mut_node();
- node.set_next_sibling(new_next_sibling)
- }
}
//
@@ -652,9 +632,9 @@ pub struct AbstractNodeChildrenIterator {
impl Iterator<AbstractNode> for AbstractNodeChildrenIterator {
fn next(&mut self) -> Option<AbstractNode> {
let node = self.current_node;
- self.current_node = do self.current_node.and_then |node| {
+ self.current_node = self.current_node.and_then(|node| {
node.next_sibling()
- };
+ });
node
}
}
@@ -766,9 +746,9 @@ impl Node {
assert!(node.reflector().get_jsobject().is_null());
let node = reflect_dom_object(node, document.document().window, wrap_fn);
assert!(node.reflector().get_jsobject().is_not_null());
- // This surrenders memory management of the node!
+ // JS owns the node now, so transmute_copy to not increase the refcount
AbstractNode {
- obj: unsafe { transmute(node) },
+ obj: unsafe { cast::transmute_copy(&node) },
}
}
@@ -798,16 +778,19 @@ impl Node {
flags: NodeFlags::new(type_id),
- layout_data: LayoutDataRef::init(),
+ layout_data: LayoutDataRef::new(),
}
}
/// Sends layout data, if any, back to the script task to be destroyed.
pub unsafe fn reap_layout_data(&mut self) {
if self.layout_data.is_present() {
- let layout_data = util::replace(&mut self.layout_data, LayoutDataRef::init());
- let js_window = utils::global_object_for_dom_object(self);
- (*js_window).data.page.reap_dead_layout_data(layout_data)
+ let layout_data = util::replace(&mut self.layout_data, LayoutDataRef::new());
+ let layout_chan = layout_data.take_chan();
+ match layout_chan {
+ None => {}
+ Some(chan) => chan.send(ReapLayoutDataMsg(layout_data)),
+ }
}
}
@@ -825,17 +808,17 @@ impl Node {
pub fn NodeName(&self, abstract_self: AbstractNode) -> DOMString {
match self.type_id {
- ElementNodeTypeId(*) => {
- do abstract_self.with_imm_element |element| {
+ ElementNodeTypeId(..) => {
+ abstract_self.with_imm_element(|element| {
element.TagName()
- }
+ })
}
CommentNodeTypeId => ~"#comment",
TextNodeTypeId => ~"#text",
DoctypeNodeTypeId => {
- do abstract_self.with_imm_doctype |doctype| {
+ abstract_self.with_imm_doctype(|doctype| {
doctype.name.clone()
- }
+ })
},
DocumentFragmentNodeTypeId => ~"#document-fragment",
DocumentNodeTypeId(_) => ~"#document"
@@ -848,7 +831,7 @@ impl Node {
pub fn GetOwnerDocument(&self) -> Option<AbstractDocument> {
match self.type_id {
- ElementNodeTypeId(*) |
+ ElementNodeTypeId(..) |
CommentNodeTypeId |
TextNodeTypeId |
DoctypeNodeTypeId |
@@ -889,9 +872,9 @@ impl Node {
match self.type_id {
// ProcessingInstruction
CommentNodeTypeId | TextNodeTypeId => {
- do abstract_self.with_imm_characterdata() |characterdata| {
+ abstract_self.with_imm_characterdata(|characterdata| {
Some(characterdata.Data())
- }
+ })
}
_ => {
None
@@ -906,21 +889,21 @@ impl Node {
pub fn GetTextContent(&self, abstract_self: AbstractNode) -> Option<DOMString> {
match self.type_id {
- DocumentFragmentNodeTypeId | ElementNodeTypeId(*) => {
+ DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
let mut content = ~"";
for node in abstract_self.traverse_preorder() {
if node.is_text() {
- do node.with_imm_text() |text| {
+ node.with_imm_text(|text| {
content = content + text.element.Data();
- }
+ })
}
}
Some(content)
}
CommentNodeTypeId | TextNodeTypeId => {
- do abstract_self.with_imm_characterdata() |characterdata| {
+ abstract_self.with_imm_characterdata(|characterdata| {
Some(characterdata.Data())
- }
+ })
}
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {
None
@@ -968,9 +951,9 @@ impl Node {
// Step 1.
match parent.type_id() {
- DocumentNodeTypeId(*) |
+ DocumentNodeTypeId(..) |
DocumentFragmentNodeTypeId |
- ElementNodeTypeId(*) => (),
+ ElementNodeTypeId(..) => (),
_ => {
return Err(HierarchyRequest);
},
@@ -999,7 +982,7 @@ impl Node {
TextNodeTypeId |
// ProcessingInstructionNodeTypeId |
CommentNodeTypeId => (),
- DocumentNodeTypeId(*) => return Err(HierarchyRequest),
+ DocumentNodeTypeId(..) => return Err(HierarchyRequest),
}
// Step 5.
@@ -1241,7 +1224,7 @@ impl Node {
-> ErrorResult {
let value = null_str_as_empty(&value);
match self.type_id {
- DocumentFragmentNodeTypeId | ElementNodeTypeId(*) => {
+ DocumentFragmentNodeTypeId | ElementNodeTypeId(..) => {
// Step 1-2.
let node = if value.len() == 0 {
None
@@ -1255,13 +1238,13 @@ impl Node {
CommentNodeTypeId | TextNodeTypeId => {
self.wait_until_safe_to_modify_dom();
- do abstract_self.with_mut_characterdata() |characterdata| {
+ abstract_self.with_mut_characterdata(|characterdata| {
characterdata.data = value.clone();
// Notify the document that the content of this node is different
let document = self.owner_doc();
document.document().content_changed();
- }
+ })
}
DoctypeNodeTypeId | DocumentNodeTypeId(_) => {}
}
diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs
index 54660c4286a..f9ba483c4f9 100644
--- a/src/components/script/dom/window.rs
+++ b/src/components/script/dom/window.rs
@@ -18,19 +18,17 @@ use servo_msg::compositor_msg::ScriptListener;
use servo_net::image_cache_task::ImageCacheTask;
use js::glue::*;
-use js::jsapi::{JSObject, JSContext, JS_DefineProperty};
-use js::jsapi::{JSPropertyOp, JSStrictPropertyOp, JSTracer};
+use js::jsapi::{JSObject, JSContext, JS_DefineProperty, JSTracer, JSVal};
use js::{JSVAL_NULL, JSPROP_ENUMERATE};
-use std::cell::Cell;
-use std::comm;
+use std::cast;
use std::comm::SharedChan;
+use std::comm::Select;
use std::hashmap::HashSet;
+use std::io::timer::Timer;
+use std::num;
use std::ptr;
-use std::int;
-use std::rt::io::timer::Timer;
-use std::task::spawn_with;
-use js::jsapi::JSVal;
+use std::to_bytes::Cb;
pub enum TimerControlMsg {
TimerMessage_Fire(~TimerData),
@@ -38,6 +36,29 @@ pub enum TimerControlMsg {
TimerMessage_TriggerExit //XXXjdm this is just a quick hack to talk to the script task
}
+pub struct TimerHandle {
+ handle: i32,
+ cancel_chan: Option<Chan<()>>,
+}
+
+impl IterBytes for TimerHandle {
+ fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool {
+ self.handle.iter_bytes(lsb0, f)
+ }
+}
+
+impl Eq for TimerHandle {
+ fn eq(&self, other: &TimerHandle) -> bool {
+ self.handle == other.handle
+ }
+}
+
+impl TimerHandle {
+ fn cancel(&self) {
+ self.cancel_chan.as_ref().map(|chan| chan.send(()));
+ }
+}
+
pub struct Window {
eventtarget: EventTarget,
page: @mut Page,
@@ -47,7 +68,7 @@ pub struct Window {
location: Option<@mut Location>,
navigator: Option<@mut Navigator>,
image_cache_task: ImageCacheTask,
- active_timers: ~HashSet<i32>,
+ active_timers: ~HashSet<TimerHandle>,
next_timer_handle: i32,
}
@@ -61,6 +82,9 @@ impl Window {
impl Drop for Window {
fn drop(&mut self) {
self.timer_chan.send(TimerMessage_Close);
+ for handle in self.active_timers.iter() {
+ handle.cancel();
+ }
}
}
@@ -160,29 +184,40 @@ impl Reflectable for Window {
impl Window {
pub fn SetTimeout(&mut self, _cx: *JSContext, callback: JSVal, timeout: i32) -> i32 {
- let timeout = int::max(0, timeout) as u64;
+ let timeout = num::max(0, timeout) as u64;
let handle = self.next_timer_handle;
self.next_timer_handle += 1;
// Post a delayed message to the per-window timer task; it will dispatch it
// to the relevant script handler that will deal with it.
- let tm = Cell::new(Timer::new().unwrap());
+ let tm = Timer::new().unwrap();
+ let (cancel_port, cancel_chan) = Chan::new();
let chan = self.timer_chan.clone();
- do spawn {
- let mut tm = tm.take();
- tm.sleep(timeout);
- chan.send(TimerMessage_Fire(~TimerData {
- handle: handle,
- funval: callback,
- args: ~[]
- }));
- }
- self.active_timers.insert(handle);
+ spawn(proc() {
+ let mut tm = tm;
+ let mut timeout_port = tm.oneshot(timeout);
+ let mut cancel_port = cancel_port;
+
+ let select = Select::new();
+ let timeout_handle = select.add(&mut timeout_port);
+ let _cancel_handle = select.add(&mut cancel_port);
+ let id = select.wait();
+ if id == timeout_handle.id {
+ chan.send(TimerMessage_Fire(~TimerData {
+ handle: handle,
+ funval: callback,
+ args: ~[],
+ }));
+ }
+ });
+ self.active_timers.insert(TimerHandle { handle: handle, cancel_chan: Some(cancel_chan) });
handle
}
pub fn ClearTimeout(&mut self, handle: i32) {
- self.active_timers.remove(&handle);
+ // FIXME(#1477): active_timers should be a HashMap and this should
+ // cancel the removed timer.
+ self.active_timers.remove(&TimerHandle { handle: handle, cancel_chan: None });
}
pub fn damage_and_reflow(&self, damage: DocumentDamageLevel) {
@@ -199,7 +234,6 @@ impl Window {
self.page.join_layout();
}
- #[fixed_stack_segment]
pub fn new(cx: *JSContext,
page: @mut Page,
script_chan: ScriptChan,
@@ -212,9 +246,9 @@ impl Window {
script_chan: script_chan.clone(),
compositor: compositor,
timer_chan: {
- let (timer_port, timer_chan) = comm::stream::<TimerControlMsg>();
+ let (timer_port, timer_chan): (Port<TimerControlMsg>, SharedChan<TimerControlMsg>) = SharedChan::new();
let id = page.id.clone();
- do spawn_with(script_chan) |script_chan| {
+ spawn(proc() {
loop {
match timer_port.recv() {
TimerMessage_Close => break,
@@ -222,8 +256,8 @@ impl Window {
TimerMessage_TriggerExit => script_chan.send(ExitWindowMsg(id)),
}
}
- }
- SharedChan::new(timer_chan)
+ });
+ timer_chan
},
location: None,
navigator: None,
@@ -236,13 +270,13 @@ impl Window {
unsafe {
let fn_names = ["window","self"];
for str in fn_names.iter() {
- do (*str).to_c_str().with_ref |name| {
+ (*str).to_c_str().with_ref(|name| {
JS_DefineProperty(cx, global, name,
RUST_OBJECT_TO_JSVAL(global),
- Some(GetJSClassHookStubPointer(PROPERTY_STUB) as JSPropertyOp),
- Some(GetJSClassHookStubPointer(STRICT_PROPERTY_STUB) as JSStrictPropertyOp),
+ Some(cast::transmute(GetJSClassHookStubPointer(PROPERTY_STUB))),
+ Some(cast::transmute(GetJSClassHookStubPointer(STRICT_PROPERTY_STUB))),
JSPROP_ENUMERATE);
- }
+ })
}
diff --git a/src/components/script/html/cssparse.rs b/src/components/script/html/cssparse.rs
index 0ba1aadbe03..5f5ba17653b 100644
--- a/src/components/script/html/cssparse.rs
+++ b/src/components/script/html/cssparse.rs
@@ -4,10 +4,7 @@
/// Some little helpers for hooking up the HTML parser with the CSS parser.
-use std::cell::Cell;
-use std::comm;
use std::comm::Port;
-use std::task;
use encoding::EncodingRef;
use encoding::all::UTF_8;
use style::Stylesheet;
@@ -23,25 +20,22 @@ pub enum StylesheetProvenance {
pub fn spawn_css_parser(provenance: StylesheetProvenance,
resource_task: ResourceTask)
-> Port<Stylesheet> {
- let (result_port, result_chan) = comm::stream();
+ let (result_port, result_chan) = Chan::new();
// TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
let environment_encoding = UTF_8 as EncodingRef;
- let provenance_cell = Cell::new(provenance);
- do task::spawn {
+ spawn(proc() {
// TODO: CSS parsing should take a base URL.
- let _url = do provenance_cell.with_ref |p| {
- match *p {
- UrlProvenance(ref the_url) => (*the_url).clone(),
- InlineProvenance(ref the_url, _) => (*the_url).clone()
- }
+ let _url = match provenance {
+ UrlProvenance(ref the_url) => (*the_url).clone(),
+ InlineProvenance(ref the_url, _) => (*the_url).clone()
};
- let sheet = match provenance_cell.take() {
+ let sheet = match provenance {
UrlProvenance(url) => {
debug!("cssparse: loading style sheet at {:s}", url.to_str());
- let (input_port, input_chan) = comm::stream();
+ let (input_port, input_chan) = Chan::new();
resource_task.send(Load(url, input_chan));
let LoadResponse { metadata: metadata, progress_port: progress_port }
= input_port.recv();
@@ -56,7 +50,7 @@ pub fn spawn_css_parser(provenance: StylesheetProvenance,
}
};
result_chan.send(sheet);
- }
+ });
return result_port;
}
@@ -69,7 +63,7 @@ impl Iterator<~[u8]> for ProgressMsgPortIterator {
fn next(&mut self) -> Option<~[u8]> {
match self.progress_port.recv() {
Payload(data) => Some(data),
- Done(*) => None
+ Done(..) => None
}
}
}
diff --git a/src/components/script/html/hubbub_html_parser.rs b/src/components/script/html/hubbub_html_parser.rs
index 94eac3b1bef..c59ef9ab376 100644
--- a/src/components/script/html/hubbub_html_parser.rs
+++ b/src/components/script/html/hubbub_html_parser.rs
@@ -22,9 +22,8 @@ use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::{Load, Payload, Done, ResourceTask, load_whole_resource};
use servo_util::url::make_url;
use std::cast;
-use std::cell::Cell;
+use std::cell::RefCell;
use std::comm::{Port, SharedChan};
-use std::comm;
use std::from_str::FromStr;
use std::str::eq_slice;
use std::str;
@@ -107,11 +106,11 @@ fn css_link_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
let mut result_vec = ~[];
loop {
- match from_parent.recv() {
- CSSTaskNewFile(provenance) => {
+ match from_parent.recv_opt() {
+ Some(CSSTaskNewFile(provenance)) => {
result_vec.push(spawn_css_parser(provenance, resource_task.clone()));
}
- CSSTaskExit => {
+ Some(CSSTaskExit) | None => {
break;
}
}
@@ -120,7 +119,7 @@ fn css_link_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
// Send the sheets back in order
// FIXME: Shouldn't wait until after we've recieved CSSTaskExit to start sending these
for port in result_vec.iter() {
- to_parent.send(HtmlDiscoveredStyle(port.recv()));
+ to_parent.try_send(HtmlDiscoveredStyle(port.recv()));
}
}
@@ -130,30 +129,30 @@ fn js_script_listener(to_parent: SharedChan<HtmlDiscoveryMessage>,
let mut result_vec = ~[];
loop {
- match from_parent.recv() {
- JSTaskNewFile(url) => {
+ match from_parent.recv_opt() {
+ Some(JSTaskNewFile(url)) => {
match load_whole_resource(&resource_task, url.clone()) {
Err(_) => {
error!("error loading script {:s}", url.to_str());
}
Ok((metadata, bytes)) => {
result_vec.push(JSFile {
- data: str::from_utf8(bytes),
+ data: str::from_utf8(bytes).to_owned(),
url: metadata.final_url,
});
}
}
}
- JSTaskNewInlineScript(data, url) => {
+ Some(JSTaskNewInlineScript(data, url)) => {
result_vec.push(JSFile { data: data, url: url });
}
- JSTaskExit => {
+ Some(JSTaskExit) | None => {
break;
}
}
}
- to_parent.send(HtmlDiscoveredScript(result_vec));
+ to_parent.try_send(HtmlDiscoveredScript(result_vec));
}
// Silly macros to handle constructing DOM nodes. This produces bad code and should be optimized
@@ -253,30 +252,23 @@ pub fn parse_html(cx: *JSContext,
// Spawn a CSS parser to receive links to CSS style sheets.
let resource_task2 = resource_task.clone();
- let (discovery_port, discovery_chan) = comm::stream();
- let discovery_chan = SharedChan::new(discovery_chan);
-
- let stylesheet_chan = Cell::new(discovery_chan.clone());
- let (css_msg_port, css_msg_chan) = comm::stream();
- let css_msg_port = Cell::new(css_msg_port);
- do spawn {
- css_link_listener(stylesheet_chan.take(), css_msg_port.take(), resource_task2.clone());
- }
-
- let css_chan = SharedChan::new(css_msg_chan);
+ let (discovery_port, discovery_chan) = SharedChan::new();
+ let stylesheet_chan = discovery_chan.clone();
+ let (css_msg_port, css_chan) = SharedChan::new();
+ spawn(proc() {
+ css_link_listener(stylesheet_chan, css_msg_port, resource_task2.clone());
+ });
// Spawn a JS parser to receive JavaScript.
let resource_task2 = resource_task.clone();
- let js_result_chan = Cell::new(discovery_chan.clone());
- let (js_msg_port, js_msg_chan) = comm::stream();
- let js_msg_port = Cell::new(js_msg_port);
- do spawn {
- js_script_listener(js_result_chan.take(), js_msg_port.take(), resource_task2.clone());
- }
- let js_chan = SharedChan::new(js_msg_chan);
+ let js_result_chan = discovery_chan.clone();
+ let (js_msg_port, js_chan) = SharedChan::new();
+ spawn(proc() {
+ js_script_listener(js_result_chan, js_msg_port, resource_task2.clone());
+ });
// Wait for the LoadResponse so that the parser knows the final URL.
- let (input_port, input_chan) = comm::stream();
+ let (input_port, input_chan) = Chan::new();
resource_task.send(Load(url.clone(), input_chan));
let load_response = input_port.recv();
@@ -305,9 +297,10 @@ pub fn parse_html(cx: *JSContext,
parser.enable_styling(true);
let (css_chan2, css_chan3, js_chan2) = (css_chan.clone(), css_chan.clone(), js_chan.clone());
- let next_subpage_id = Cell::new(next_subpage_id);
-
- parser.set_tree_handler(~hubbub::TreeHandler {
+
+ let next_subpage_id = RefCell::new(next_subpage_id);
+
+ let tree_handler = hubbub::TreeHandler {
create_comment: |data: ~str| {
debug!("create comment");
let comment = Comment::new(data, document);
@@ -333,19 +326,19 @@ pub fn parse_html(cx: *JSContext,
let node = build_element_from_tag(tag.name.clone(), document);
debug!("-- attach attrs");
- do node.as_mut_element |element| {
+ node.as_mut_element(|element| {
for attr in tag.attributes.iter() {
element.set_attr(node,
attr.name.clone(),
attr.value.clone());
}
- }
+ });
// Spawn additional parsing, network loads, etc. from tag and attrs
match node.type_id() {
// Handle CSS style sheets from <link> elements
ElementNodeTypeId(HTMLLinkElementTypeId) => {
- do node.with_imm_element |element| {
+ node.with_imm_element(|element| {
match (element.get_attr(Null, "rel"), element.get_attr(Null, "href")) {
(Some(rel), Some(href)) => {
if "stylesheet" == rel {
@@ -356,13 +349,12 @@ pub fn parse_html(cx: *JSContext,
}
_ => {}
}
- }
+ });
}
ElementNodeTypeId(HTMLIframeElementTypeId) => {
- let iframe_chan = Cell::new(discovery_chan.clone());
- do node.with_mut_iframe_element |iframe_element| {
- let iframe_chan = iframe_chan.take();
+ let iframe_chan = discovery_chan.clone();
+ node.with_mut_iframe_element(|iframe_element| {
let sandboxed = iframe_element.is_sandboxed();
let elem = &mut iframe_element.htmlelement.element;
let src_opt = elem.get_attr(Null, "src").map(|x| x.to_str());
@@ -371,8 +363,8 @@ pub fn parse_html(cx: *JSContext,
iframe_element.frame = Some(iframe_url.clone());
// Subpage Id
- let subpage_id = next_subpage_id.take();
- next_subpage_id.put_back(SubpageId(*subpage_id + 1));
+ let subpage_id = next_subpage_id.get();
+ next_subpage_id.set(SubpageId(*subpage_id + 1));
// Pipeline Id
let pipeline_id = {
@@ -388,15 +380,15 @@ pub fn parse_html(cx: *JSContext,
subpage_id,
sandboxed)));
}
- }
+ });
}
//FIXME: This should be taken care of by set_attr, but we don't have
// access to a window so HTMLImageElement::AfterSetAttr bails.
ElementNodeTypeId(HTMLImageElementTypeId) => {
- do node.with_mut_image_element |image_element| {
+ node.with_mut_image_element(|image_element| {
image_element.update_image(image_cache_task.clone(), Some(url2.clone()));
- }
+ });
}
_ => {}
@@ -460,7 +452,7 @@ pub fn parse_html(cx: *JSContext,
complete_script: |script| {
unsafe {
let scriptnode: AbstractNode = NodeWrapping::from_hubbub_node(script);
- do scriptnode.with_imm_element |script| {
+ scriptnode.with_imm_element(|script| {
match script.get_attr(Null, "src") {
Some(src) => {
debug!("found script: {:s}", src);
@@ -472,16 +464,16 @@ pub fn parse_html(cx: *JSContext,
debug!("iterating over children {:?}", scriptnode.first_child());
for child in scriptnode.children() {
debug!("child = {:?}", child);
- do child.with_imm_text() |text| {
+ child.with_imm_text(|text| {
data.push(text.element.data.to_str()); // FIXME: Bad copy.
- }
+ });
}
debug!("script data = {:?}", data);
js_chan2.send(JSTaskNewInlineScript(data.concat(), url3.clone()));
}
}
- }
+ });
}
debug!("complete script");
},
@@ -490,23 +482,22 @@ pub fn parse_html(cx: *JSContext,
unsafe {
let style: AbstractNode = NodeWrapping::from_hubbub_node(style);
let url = FromStr::from_str("http://example.com/"); // FIXME
- let url_cell = Cell::new(url);
-
let mut data = ~[];
debug!("iterating over children {:?}", style.first_child());
for child in style.children() {
debug!("child = {:?}", child);
- do child.with_imm_text() |text| {
+ child.with_imm_text(|text| {
data.push(text.element.data.to_str()); // FIXME: Bad copy.
- }
+ });
}
debug!("style data = {:?}", data);
- let provenance = InlineProvenance(url_cell.take().unwrap(), data.concat());
+ let provenance = InlineProvenance(url.unwrap(), data.concat());
css_chan3.send(CSSTaskNewFile(provenance));
}
},
- });
+ };
+ parser.set_tree_handler(&tree_handler);
debug!("set tree handler");
debug!("loaded page");
@@ -516,10 +507,10 @@ pub fn parse_html(cx: *JSContext,
debug!("received data");
parser.parse_chunk(data);
}
- Done(Err(*)) => {
+ Done(Err(..)) => {
fail!("Failed to load page URL {:s}", url.to_str());
}
- Done(*) => {
+ Done(..) => {
break;
}
}
diff --git a/src/components/script/layout_interface.rs b/src/components/script/layout_interface.rs
index c0b35ef6a3f..613e61a3429 100644
--- a/src/components/script/layout_interface.rs
+++ b/src/components/script/layout_interface.rs
@@ -122,9 +122,11 @@ pub struct Reflow {
/// Encapsulates a channel to the layout task.
#[deriving(Clone)]
pub struct LayoutChan(SharedChan<Msg>);
+
impl LayoutChan {
- pub fn new(chan: Chan<Msg>) -> LayoutChan {
- LayoutChan(SharedChan::new(chan))
+ pub fn new() -> (Port<Msg>, LayoutChan) {
+ let (port, chan) = SharedChan::new();
+ (port, LayoutChan(chan))
}
}
diff --git a/src/components/script/script.rc b/src/components/script/script.rc
index 1715ff8de8f..0e25bea39e2 100644
--- a/src/components/script/script.rc
+++ b/src/components/script/script.rc
@@ -2,14 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#[link(name = "script",
- vers = "0.1",
- uuid = "536a45e2-b605-4ee0-b54c-466810f1ffc1",
- url = "http://servo.org/")];
+#[crate_id = "github.com/mozilla/servo#script:0.1"];
+#[crate_type = "lib"];
#[comment = "The Servo Parallel Browser Project"];
#[license = "MPL"];
-#[crate_type = "lib"];
#[feature(globs, macro_rules, struct_variant, managed_boxes)];
@@ -17,11 +14,12 @@ extern mod geom;
extern mod hubbub;
extern mod encoding;
extern mod js;
-extern mod servo_net (name = "net");
-extern mod servo_util (name = "util");
+extern mod servo_net = "net";
+extern mod servo_util = "util";
extern mod style;
-extern mod servo_msg (name = "msg");
+extern mod servo_msg = "msg";
extern mod extra;
+extern mod native;
// Macros
mod macros;
diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs
index 1938ef92ff3..4b70c13f0cc 100644
--- a/src/components/script/script_task.rs
+++ b/src/components/script/script_task.rs
@@ -14,15 +14,15 @@ use dom::event::Event;
use dom::eventtarget::AbstractEventTarget;
use dom::htmldocument::HTMLDocument;
use dom::namespace::Null;
-use dom::node::{AbstractNode, LayoutDataRef};
-use dom::window::{TimerData, Window};
+use dom::node::AbstractNode;
+use dom::window::{TimerData, TimerHandle, Window};
use html::hubbub_html_parser::HtmlParserResult;
use html::hubbub_html_parser::{HtmlDiscoveredStyle, HtmlDiscoveredIFrame, HtmlDiscoveredScript};
use html::hubbub_html_parser;
use layout_interface::{AddStylesheetMsg, DocumentDamage};
use layout_interface::{ContentBoxQuery, ContentBoxResponse};
use layout_interface::{DocumentDamageLevel, HitTestQuery, HitTestResponse, LayoutQuery};
-use layout_interface::{LayoutChan, MatchSelectorsDocumentDamage, QueryMsg, ReapLayoutDataMsg};
+use layout_interface::{LayoutChan, MatchSelectorsDocumentDamage, QueryMsg};
use layout_interface::{Reflow, ReflowDocumentDamage, ReflowForDisplay, ReflowGoal, ReflowMsg};
use layout_interface::ContentChangedDocumentDamage;
use layout_interface;
@@ -46,12 +46,9 @@ use servo_net::image_cache_task::ImageCacheTask;
use servo_net::resource_task::ResourceTask;
use servo_util::geometry::to_frac_px;
use servo_util::url::make_url;
-use std::cell::Cell;
use std::comm::{Port, SharedChan};
-use std::comm;
use std::ptr;
use std::str::eq_slice;
-use std::task::{spawn_sched, SingleThreaded};
use std::util::replace;
/// Messages used to control the script task.
@@ -90,8 +87,9 @@ pub struct ScriptChan(SharedChan<ScriptMsg>);
impl ScriptChan {
/// Creates a new script chan.
- pub fn new(chan: Chan<ScriptMsg>) -> ScriptChan {
- ScriptChan(SharedChan::new(chan))
+ pub fn new() -> (Port<ScriptMsg>, ScriptChan) {
+ let (port, chan) = SharedChan::new();
+ (port, ScriptChan(chan))
}
}
@@ -140,8 +138,8 @@ pub struct PageTree {
inner: ~[PageTree],
}
-pub struct PageTreeIterator<'self> {
- priv stack: ~[&'self mut PageTree],
+pub struct PageTreeIterator<'a> {
+ priv stack: ~[&'a mut PageTree],
}
impl PageTree {
@@ -203,7 +201,7 @@ impl PageTree {
}
}
-impl<'self> Iterator<@mut Page> for PageTreeIterator<'self> {
+impl<'a> Iterator<@mut Page> for PageTreeIterator<'a> {
fn next(&mut self) -> Option<@mut Page> {
if !self.stack.is_empty() {
let next = self.stack.pop();
@@ -254,12 +252,14 @@ impl Page {
let join_port = replace(&mut self.layout_join_port, None);
match join_port {
Some(ref join_port) => {
- if !join_port.peek() {
- info!("script: waiting on layout");
+ match join_port.try_recv() {
+ None => {
+ info!("script: waiting on layout");
+ join_port.recv();
+ }
+ Some(_) => {}
}
- join_port.recv();
-
debug!("script: layout joined")
}
None => fail!(~"reader forked but no join port?"),
@@ -307,7 +307,7 @@ impl Page {
compositor.set_ready_state(PerformingLayout);
// Layout will let us know when it's done.
- let (join_port, join_chan) = comm::stream();
+ let (join_port, join_chan) = Chan::new();
self.layout_join_port = Some(join_port);
self.last_reflow_id += 1;
@@ -359,11 +359,6 @@ impl Page {
js_context: js_context,
});
}
-
- /// Sends the given layout data back to the layout task to be destroyed.
- pub unsafe fn reap_dead_layout_data(&self, layout_data: LayoutDataRef) {
- self.layout_chan.send(ReapLayoutDataMsg(layout_data))
- }
}
/// Information for one frame in the browsing context.
@@ -412,7 +407,6 @@ pub struct ScriptTask {
}
/// Returns the relevant page from the associated JS Context.
-#[fixed_stack_segment]
pub fn page_from_context(js_context: *JSContext) -> *mut Page {
unsafe {
JS_GetContextPrivate(js_context) as *mut Page
@@ -468,24 +462,7 @@ impl ScriptTask {
resource_task: ResourceTask,
image_cache_task: ImageCacheTask,
window_size: Size2D<uint>) {
- let parms = Cell::new((compositor,
- layout_chan,
- port,
- chan,
- constellation_chan,
- resource_task,
- image_cache_task));
- // Since SpiderMonkey is blocking it needs to run in its own thread.
- // If we don't do this then we'll just end up with a bunch of SpiderMonkeys
- // starving all the other tasks.
- do spawn_sched(SingleThreaded) {
- let (compositor,
- layout_chan,
- port,
- chan,
- constellation_chan,
- resource_task,
- image_cache_task) = parms.take();
+ spawn(proc() {
let script_task = ScriptTask::new(id,
@compositor as @ScriptListener,
layout_chan,
@@ -496,7 +473,7 @@ impl ScriptTask {
image_cache_task,
window_size);
script_task.start();
- }
+ });
}
/// Handle incoming control messages.
@@ -520,12 +497,13 @@ impl ScriptTask {
// Store new resizes, and gather all other events.
let mut sequential = ~[];
+
+ // Receive at least one message so we don't spinloop.
+ let mut event = self.port.recv();
+
loop {
- // Receive at least one message so we don't spinloop.
- let event = self.port.recv();
match event {
ResizeMsg(id, size) => {
- debug!("script got resize message");
let page = self.page_tree.find(id).expect("resize sent to nonexistent pipeline").page;
page.resize_event = Some(size);
}
@@ -534,9 +512,9 @@ impl ScriptTask {
}
}
- // Break if there are no more messages.
- if !self.port.peek() {
- break;
+ match self.port.try_recv() {
+ None => break,
+ Some(ev) => event = ev,
}
}
@@ -556,7 +534,7 @@ impl ScriptTask {
self.handle_exit_window_msg(id);
return false
},
- ResizeMsg(*) => fail!("should have handled ResizeMsg already"),
+ ResizeMsg(..) => fail!("should have handled ResizeMsg already"),
}
}
@@ -579,14 +557,14 @@ impl ScriptTask {
}
/// Handles a timer that fired.
- #[fixed_stack_segment]
fn handle_fire_timer_msg(&mut self, id: PipelineId, timer_data: ~TimerData) {
let page = self.page_tree.find(id).expect("ScriptTask: received fire timer msg for a
pipeline ID not associated with this script task. This is a bug.").page;
let window = page.frame.expect("ScriptTask: Expect a timeout to have a document").window;
- if !window.active_timers.contains(&timer_data.handle) {
+ if !window.active_timers.contains(&TimerHandle { handle: timer_data.handle, cancel_chan: None }) {
return;
}
+ window.active_timers.remove(&TimerHandle { handle: timer_data.handle, cancel_chan: None });
unsafe {
let this_value = if timer_data.args.len() > 0 {
RUST_JSVAL_TO_OBJECT(timer_data.args[0])
@@ -711,7 +689,6 @@ impl ScriptTask {
//
// Note: We can parse the next document in parallel with any previous documents.
let document = HTMLDocument::new(window);
-
let html_parsing_result = hubbub_html_parser::parse_html(cx.ptr,
document,
url.clone(),
@@ -736,7 +713,7 @@ impl ScriptTask {
let mut js_scripts = None;
loop {
- match discovery_port.try_recv() {
+ match discovery_port.recv_opt() {
Some(HtmlDiscoveredScript(scripts)) => {
assert!(js_scripts.is_none());
js_scripts = Some(scripts);
@@ -805,20 +782,20 @@ impl ScriptTask {
None => {
let doc_node = AbstractNode::from_document(document);
let mut anchors = doc_node.traverse_preorder().filter(|node| node.is_anchor_element());
- do anchors.find |node| {
- do node.with_imm_element |elem| {
+ anchors.find(|node| {
+ node.with_imm_element(|elem| {
match elem.get_attr(Null, "name") {
Some(name) => eq_slice(name, fragid),
None => false
}
- }
- }
+ })
+ })
}
}
}
fn scroll_fragment_point(&self, pipeline_id: PipelineId, page: &mut Page, node: AbstractNode) {
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
match page.query_layout(ContentBoxQuery(node, chan), port) {
ContentBoxResponse(rect) => {
let point = Point2D(to_frac_px(rect.origin.x).to_f32().unwrap(),
@@ -870,7 +847,7 @@ impl ScriptTask {
if root.is_none() {
return;
}
- let (port, chan) = comm::stream();
+ let (port, chan) = Chan::new();
match page.query_layout(HitTestQuery(root.unwrap(), point, chan), port) {
Ok(node) => match node {
HitTestResponse(node) => {
@@ -886,11 +863,11 @@ impl ScriptTask {
}
}
if node.is_element() {
- do node.with_imm_element |element| {
+ node.with_imm_element(|element| {
if "a" == element.tag_name {
self.load_url_from_element(page, element)
}
- }
+ })
}
}
},
@@ -899,8 +876,8 @@ impl ScriptTask {
}
}
}
- MouseDownEvent(*) => {}
- MouseUpEvent(*) => {}
+ MouseDownEvent(..) => {}
+ MouseUpEvent(..) => {}
}
}
@@ -910,9 +887,9 @@ impl ScriptTask {
for href in attr.iter() {
debug!("ScriptTask: clicked on link to {:s}", *href);
let click_frag = href.starts_with("#");
- let current_url = do page.url.as_ref().map |&(ref url, _)| {
+ let current_url = page.url.as_ref().map(|&(ref url, _)| {
url.clone()
- };
+ });
debug!("ScriptTask: current url is {:?}", current_url);
let url = make_url(href.to_owned(), current_url);
@@ -933,29 +910,15 @@ fn shut_down_layout(page: @mut Page) {
page.join_layout();
// Tell the layout task to begin shutting down.
- let (response_port, response_chan) = comm::stream();
+ let (response_port, response_chan) = Chan::new();
page.layout_chan.send(layout_interface::PrepareToExitMsg(response_chan));
response_port.recv();
- // Destroy all nodes.
- //
- // If there was a leak, the layout task will soon crash safely when it detects that local data
- // is missing from its heap.
- //
- // FIXME(pcwalton): *But*, for now, because we use `@mut` boxes to hold onto Nodes, if this
- // didn't destroy all the nodes there will be an *exploitable* security vulnerability as the
- // nodes try to access the destroyed JS context. We need to change this so that the only actor
- // who can judge a JS object dead (and thus run its drop glue) is the JS engine itself; thus it
- // will be impossible (absent a serious flaw in the JS engine) for the JS context to be dead
- // before nodes are.
- unsafe {
- let document_node = AbstractNode::from_document(page.frame.as_ref().unwrap().document);
- for node in document_node.traverse_preorder() {
- node.mut_node().reap_layout_data()
- }
- }
+ // Destroy all nodes. Setting frame and js_info to None will trigger our
+ // compartment to shutdown, run GC, etc.
+ page.frame = None;
+ page.js_info = None;
// Destroy the layout task. If there were node leaks, layout will now crash safely.
page.layout_chan.send(layout_interface::ExitNowMsg);
}
-
diff --git a/src/components/style/common_types.rs b/src/components/style/common_types.rs
index 4eace37554e..eac41697eb1 100644
--- a/src/components/style/common_types.rs
+++ b/src/components/style/common_types.rs
@@ -43,6 +43,7 @@ pub mod specified {
_ => None
}
}
+ #[allow(dead_code)]
pub fn parse(input: &ComponentValue) -> Option<Length> {
Length::parse_internal(input, /* negative_ok = */ true)
}
@@ -87,6 +88,7 @@ pub mod specified {
_ => None
}
}
+ #[allow(dead_code)]
#[inline]
pub fn parse(input: &ComponentValue) -> Option<LengthOrPercentage> {
LengthOrPercentage::parse_internal(input, /* negative_ok = */ true)
@@ -145,6 +147,7 @@ pub mod specified {
_ => None
}
}
+ #[allow(dead_code)]
#[inline]
pub fn parse(input: &ComponentValue) -> Option<LengthOrPercentageOrNone> {
LengthOrPercentageOrNone::parse_internal(input, /* negative_ok = */ true)
diff --git a/src/components/style/errors.rs b/src/components/style/errors.rs
index e43630bb1aa..fa97d5229c9 100644
--- a/src/components/style/errors.rs
+++ b/src/components/style/errors.rs
@@ -31,7 +31,7 @@ pub fn log_css_error(location: SourceLocation, message: &str) {
}
-pub fn with_errors_silenced<T>(f: &fn() -> T) -> T {
+pub fn with_errors_silenced<T>(f: || -> T) -> T {
local_data::set(silence_errors, ());
let result = f();
local_data::pop(silence_errors);
diff --git a/src/components/style/media_queries.rs b/src/components/style/media_queries.rs
index abccc41e7f5..06866736305 100644
--- a/src/components/style/media_queries.rs
+++ b/src/components/style/media_queries.rs
@@ -121,12 +121,12 @@ pub fn parse_media_query_list(input: &[ComponentValue]) -> MediaQueryList {
impl MediaQueryList {
pub fn evaluate(&self, device: &Device) -> bool {
- do self.media_queries.iter().any |mq| {
+ self.media_queries.iter().any(|mq| {
match mq.media_type {
MediaType(media_type) => media_type == device.media_type,
All => true,
}
// TODO: match Level 3 expressions
- }
+ })
}
}
diff --git a/src/components/style/node.rs b/src/components/style/node.rs
index fef83d75810..546ef329795 100644
--- a/src/components/style/node.rs
+++ b/src/components/style/node.rs
@@ -14,7 +14,7 @@ pub trait TNode<E:TElement> : Clone {
fn is_element(&self) -> bool;
/// FIXME(pcwalton): This should not use the `with` pattern.
- fn with_element<R>(&self, f: &fn(&E) -> R) -> R;
+ fn with_element<'a, R>(&self, f: |&E| -> R) -> R;
}
pub trait TElement {
diff --git a/src/components/style/properties.rs.mako b/src/components/style/properties.rs.mako
index 1bf23662020..4c6f2511658 100644
--- a/src/components/style/properties.rs.mako
+++ b/src/components/style/properties.rs.mako
@@ -74,8 +74,8 @@ pub mod longhands {
pub fn parse_declared(input: &[ComponentValue])
-> Option<DeclaredValue<SpecifiedValue>> {
match CSSWideKeyword::parse(input) {
- Some(Left(keyword)) => Some(CSSWideKeyword(keyword)),
- Some(Right(Unset)) => Some(CSSWideKeyword(${
+ Some(Some(keyword)) => Some(CSSWideKeyword(keyword)),
+ Some(None) => Some(CSSWideKeyword(${
"Inherit" if inherited else "Initial"})),
None => parse_specified(input),
}
@@ -118,14 +118,14 @@ pub mod longhands {
${to_rust_ident(values.split()[0])}
}
pub fn from_component_value(v: &ComponentValue) -> Option<SpecifiedValue> {
- do get_ident_lower(v).and_then |keyword| {
+ get_ident_lower(v).and_then(|keyword| {
match keyword.as_slice() {
% for value in values.split():
"${value}" => Some(${to_rust_ident(value)}),
% endfor
_ => None,
}
- }
+ })
}
</%self:single_component_value>
</%def>
@@ -648,12 +648,12 @@ pub mod longhands {
/// <length> | <percentage>
/// TODO: support <absolute-size> and <relative-size>
pub fn from_component_value(input: &ComponentValue) -> Option<SpecifiedValue> {
- do specified::LengthOrPercentage::parse_non_negative(input).map |value| {
+ specified::LengthOrPercentage::parse_non_negative(input).map(|value| {
match value {
specified::LP_Length(value) => value,
specified::LP_Percentage(value) => specified::Em(value),
}
- }
+ })
}
</%self:single_component_value>
@@ -767,9 +767,9 @@ pub mod shorthands {
// TODO: other background-* properties
<%self:shorthand name="background" sub_properties="background-color">
- do one_component_value(input).and_then(specified::CSSColor::parse).map |color| {
+ one_component_value(input).and_then(specified::CSSColor::parse).map(|color| {
Longhands { background_color: Some(color) }
- }
+ })
</%self:shorthand>
${four_sides_shorthand("margin", "margin-%s", "margin_top::from_component_value")}
@@ -818,13 +818,13 @@ pub mod shorthands {
'border-%s-%s' % (side, prop)
for prop in ['color', 'style', 'width']
)}">
- do parse_border(input).map |(color, style, width)| {
+ parse_border(input).map(|(color, style, width)| {
Longhands {
% for prop in ["color", "style", "width"]:
${"border_%s_%s: %s," % (side, prop, prop)}
% endfor
}
- }
+ })
</%self:shorthand>
% endfor
@@ -833,7 +833,7 @@ pub mod shorthands {
for side in ['top', 'right', 'bottom', 'left']
for prop in ['color', 'style', 'width']
)}">
- do parse_border(input).map |(color, style, width)| {
+ parse_border(input).map(|(color, style, width)| {
Longhands {
% for side in ["top", "right", "bottom", "left"]:
% for prop in ["color", "style", "width"]:
@@ -841,7 +841,7 @@ pub mod shorthands {
% endfor
% endfor
}
- }
+ })
</%self:shorthand>
<%self:shorthand name="font" sub_properties="font-style font-variant font-weight
@@ -966,18 +966,16 @@ pub enum CSSWideKeyword {
Inherit,
}
-struct Unset;
-
impl CSSWideKeyword {
- pub fn parse(input: &[ComponentValue]) -> Option<Either<CSSWideKeyword, Unset>> {
- do one_component_value(input).and_then(get_ident_lower).and_then |keyword| {
+ pub fn parse(input: &[ComponentValue]) -> Option<Option<CSSWideKeyword>> {
+ one_component_value(input).and_then(get_ident_lower).and_then(|keyword| {
match keyword.as_slice() {
- "initial" => Some(Left(Initial)),
- "inherit" => Some(Left(Inherit)),
- "unset" => Some(Right(Unset)),
+ "initial" => Some(Some(Initial)),
+ "inherit" => Some(Some(Inherit)),
+ "unset" => Some(None),
_ => None
}
- }
+ })
}
}
@@ -1018,14 +1016,14 @@ impl PropertyDeclaration {
% endfor
% for shorthand in SHORTHANDS:
"${shorthand.name}" => match CSSWideKeyword::parse(value) {
- Some(Left(keyword)) => {
+ Some(Some(keyword)) => {
% for sub_property in shorthand.sub_properties:
result_list.push(${sub_property.ident}_declaration(
CSSWideKeyword(keyword)
));
% endfor
},
- Some(Right(Unset)) => {
+ Some(None) => {
% for sub_property in shorthand.sub_properties:
result_list.push(${sub_property.ident}_declaration(
CSSWideKeyword(${
diff --git a/src/components/style/selector_matching.rs b/src/components/style/selector_matching.rs
index 3d48fd66a57..5d19530fa00 100644
--- a/src/components/style/selector_matching.rs
+++ b/src/components/style/selector_matching.rs
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use extra::arc::Arc;
-use extra::sort::tim_sort;
use std::ascii::StrAsciiExt;
use std::hashmap::HashMap;
use std::str;
@@ -86,11 +85,9 @@ impl SelectorMap {
match element.get_attr(None, "class") {
Some(ref class_attr) => {
- for class in class_attr.split_iter(SELECTOR_WHITESPACE) {
- SelectorMap::get_matching_rules_from_hash(node,
- &self.class_hash,
- class,
- matching_rules_list)
+ for class in class_attr.split(SELECTOR_WHITESPACE) {
+ SelectorMap::get_matching_rules_from_hash(
+ node, &self.class_hash, class, matching_rules_list);
}
}
None => {}
@@ -108,7 +105,13 @@ impl SelectorMap {
});
// Sort only the rules we just added.
- tim_sort(matching_rules_list.mut_slice_from(init_len));
+ matching_rules_list.mut_slice_from(init_len).sort_by(|a, b| {
+ if a < b {
+ Less
+ } else {
+ Greater
+ }
+ });
}
fn get_matching_rules_from_hash<E:TElement,
@@ -292,11 +295,11 @@ impl Stylist {
);
let device = &Device { media_type: Screen }; // TODO, use Print when printing
- do iter_style_rules(stylesheet.rules.as_slice(), device) |style_rule| {
+ iter_style_rules(stylesheet.rules.as_slice(), device, |style_rule| {
append!(normal);
append!(important);
self.rules_source_order += 1;
- }
+ });
}
/// Returns the applicable CSS declarations for the given element. This corresponds to
@@ -344,7 +347,7 @@ impl Stylist {
let mut declaration_iter = matching_rules_list.move_iter().map(|rule| {
let Rule {
declarations,
- _
+ ..
} = rule;
declarations
});
@@ -436,9 +439,9 @@ impl Ord for Rule {
fn matches_compound_selector<E:TElement,N:TNode<E>>(selector: &CompoundSelector, element: &N)
-> bool {
- if !do selector.simple_selectors.iter().all |simple_selector| {
+ if !selector.simple_selectors.iter().all(|simple_selector| {
matches_simple_selector(simple_selector, element)
- } {
+ }) {
return false
}
match selector.next {
@@ -479,77 +482,77 @@ fn matches_simple_selector<E:TElement,N:TNode<E>>(selector: &SimpleSelector, ele
// TODO: case-sensitivity depends on the document type
// TODO: intern element names
LocalNameSelector(ref name) => {
- do element.with_element |element: &E| {
+ element.with_element(|element: &E| {
element.get_local_name().eq_ignore_ascii_case(name.as_slice())
- }
+ })
}
NamespaceSelector(ref url) => {
- do element.with_element |element: &E| {
+ element.with_element(|element: &E| {
element.get_namespace_url() == url.as_slice()
- }
+ })
}
// TODO: case-sensitivity depends on the document type and quirks mode
// TODO: cache and intern IDs on elements.
IDSelector(ref id) => {
- do element.with_element |element: &E| {
+ element.with_element(|element: &E| {
match element.get_attr(None, "id") {
Some(attr) => str::eq_slice(attr, *id),
None => false
}
- }
+ })
}
// TODO: cache and intern classe names on elements.
ClassSelector(ref class) => {
- do element.with_element |element: &E| {
+ element.with_element(|element: &E| {
match element.get_attr(None, "class") {
None => false,
// TODO: case-sensitivity depends on the document type and quirks mode
Some(ref class_attr)
- => class_attr.split_iter(SELECTOR_WHITESPACE).any(|c| c == class.as_slice()),
+ => class_attr.split(SELECTOR_WHITESPACE).any(|c| c == class.as_slice()),
}
- }
+ })
}
AttrExists(ref attr) => match_attribute(attr, element, |_| true),
AttrEqual(ref attr, ref value) => match_attribute(attr, element, |v| v == value.as_slice()),
- AttrIncludes(ref attr, ref value) => do match_attribute(attr, element) |attr_value| {
- attr_value.split_iter(SELECTOR_WHITESPACE).any(|v| v == value.as_slice())
- },
+ AttrIncludes(ref attr, ref value) => match_attribute(attr, element, |attr_value| {
+ attr_value.split(SELECTOR_WHITESPACE).any(|v| v == value.as_slice())
+ }),
AttrDashMatch(ref attr, ref value, ref dashing_value)
- => do match_attribute(attr, element) |attr_value| {
+ => match_attribute(attr, element, |attr_value| {
attr_value == value.as_slice() || attr_value.starts_with(dashing_value.as_slice())
- },
- AttrPrefixMatch(ref attr, ref value) => do match_attribute(attr, element) |attr_value| {
+ }),
+ AttrPrefixMatch(ref attr, ref value) => match_attribute(attr, element, |attr_value| {
attr_value.starts_with(value.as_slice())
- },
- AttrSubstringMatch(ref attr, ref value) => do match_attribute(attr, element) |attr_value| {
+ }),
+ AttrSubstringMatch(ref attr, ref value) => match_attribute(attr, element, |attr_value| {
attr_value.contains(value.as_slice())
- },
- AttrSuffixMatch(ref attr, ref value) => do match_attribute(attr, element) |attr_value| {
+ }),
+ AttrSuffixMatch(ref attr, ref value) => match_attribute(attr, element, |attr_value| {
attr_value.ends_with(value.as_slice())
- },
+ }),
AnyLink => {
- do element.with_element |element: &E| {
+ element.with_element(|element: &E| {
element.get_link().is_some()
- }
+ })
}
Link => {
- do element.with_element |element: &E| {
+ element.with_element(|element: &E| {
match element.get_link() {
Some(url) => !url_is_visited(url),
None => false,
}
- }
+ })
}
Visited => {
- do element.with_element |element: &E| {
+ element.with_element(|element: &E| {
match element.get_link() {
Some(url) => url_is_visited(url),
None => false,
}
- }
+ })
}
FirstChild => matches_first_child(element),
@@ -583,7 +586,8 @@ fn url_is_visited(_url: &str) -> bool {
}
#[inline]
-fn matches_generic_nth_child<E:TElement,
+fn matches_generic_nth_child<'a,
+ E:TElement,
N:TNode<E>>(
element: &N,
a: i32,
@@ -601,15 +605,6 @@ fn matches_generic_nth_child<E:TElement,
None => return false
};
- let mut element_local_name = "";
- let mut element_namespace = "";
- if is_of_type {
- do element.with_element |element: &E| {
- element_local_name = element.get_local_name();
- element_namespace = element.get_namespace_url();
- }
- }
-
let mut index = 1;
loop {
if is_from_end {
@@ -626,12 +621,14 @@ fn matches_generic_nth_child<E:TElement,
if node.is_element() {
if is_of_type {
- do node.with_element |node: &E| {
- if element_local_name == node.get_local_name() &&
- element_namespace == node.get_namespace_url() {
- index += 1;
- }
- }
+ element.with_element(|element: &E| {
+ node.with_element(|node: &E| {
+ if element.get_local_name() == node.get_local_name() &&
+ element.get_namespace_url() == node.get_namespace_url() {
+ index += 1;
+ }
+ })
+ })
} else {
index += 1;
}
@@ -704,18 +701,17 @@ fn match_attribute<E:TElement,
N:TNode<E>>(
attr: &AttrSelector,
element: &N,
- f: &fn(&str) -> bool)
+ f: |&str| -> bool)
-> bool {
- do element.with_element |element: &E| {
+ element.with_element(|element: &E| {
// FIXME: avoid .clone() here? See #1367
match element.get_attr(attr.namespace.clone(), attr.name) {
None => false,
Some(value) => f(value)
}
- }
+ })
}
-
#[cfg(test)]
mod tests {
use extra::arc::Arc;
diff --git a/src/components/style/selectors.rs b/src/components/style/selectors.rs
index 2e401e1a407..860c4a6d6bc 100644
--- a/src/components/style/selectors.rs
+++ b/src/components/style/selectors.rs
@@ -27,9 +27,6 @@ pub struct Selector {
specificity: u32,
}
-pub static STYLE_ATTRIBUTE_SPECIFICITY: u32 = 1 << 31;
-
-
#[deriving(Eq, Clone)]
pub enum PseudoElement {
Before,
@@ -203,19 +200,19 @@ fn compute_specificity(mut selector: &CompoundSelector,
specificity: &mut Specificity) {
for simple_selector in simple_selectors.iter() {
match simple_selector {
- &LocalNameSelector(*) => specificity.element_selectors += 1,
- &IDSelector(*) => specificity.id_selectors += 1,
- &ClassSelector(*)
- | &AttrExists(*) | &AttrEqual(*) | &AttrIncludes(*) | &AttrDashMatch(*)
- | &AttrPrefixMatch(*) | &AttrSubstringMatch(*) | &AttrSuffixMatch(*)
+ &LocalNameSelector(..) => specificity.element_selectors += 1,
+ &IDSelector(..) => specificity.id_selectors += 1,
+ &ClassSelector(..)
+ | &AttrExists(..) | &AttrEqual(..) | &AttrIncludes(..) | &AttrDashMatch(..)
+ | &AttrPrefixMatch(..) | &AttrSubstringMatch(..) | &AttrSuffixMatch(..)
| &AnyLink | &Link | &Visited
| &FirstChild | &LastChild | &OnlyChild | &Root
// | &Empty | &Lang(*)
- | &NthChild(*) | &NthLastChild(*)
- | &NthOfType(*) | &NthLastOfType(*)
+ | &NthChild(..) | &NthLastChild(..)
+ | &NthOfType(..) | &NthLastOfType(..)
| &FirstOfType | &LastOfType | &OnlyOfType
=> specificity.class_like_selectors += 1,
- &NamespaceSelector(*) => (),
+ &NamespaceSelector(..) => (),
&Negation(ref negated)
=> simple_selectors_specificity(negated.as_slice(), specificity),
}
diff --git a/src/components/style/style.rc b/src/components/style/style.rc
index d41e98682fc..a8e39526fa1 100644
--- a/src/components/style/style.rc
+++ b/src/components/style/style.rc
@@ -2,21 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#[link(name = "style",
- vers = "0.1",
- uuid = "4a50ca00-3283-11e3-aa6e-0800200c9a66",
- url = "http://servo.org/")];
+#[crate_id = "github.com/mozilla/servo#style:0.1"];
+#[crate_type = "lib"];
#[comment = "The Servo Parallel Browser Project"];
#[license = "MPL"];
-#[crate_type = "lib"];
#[feature(globs, macro_rules, managed_boxes)];
extern mod extra;
extern mod cssparser;
extern mod encoding;
-extern mod servo_util (name = "util");
+extern mod servo_util = "util";
// Public API
diff --git a/src/components/style/stylesheets.rs b/src/components/style/stylesheets.rs
index 673974961c5..0b5b1406457 100644
--- a/src/components/style/stylesheets.rs
+++ b/src/components/style/stylesheets.rs
@@ -151,7 +151,7 @@ pub fn parse_nested_at_rule(lower_name: &str, rule: AtRule,
pub fn iter_style_rules<'a>(rules: &[CSSRule], device: &media_queries::Device,
- callback: &fn(&StyleRule)) {
+ callback: |&StyleRule|) {
for rule in rules.iter() {
match *rule {
CSSStyleRule(ref rule) => callback(rule),
diff --git a/src/components/util/cache.rs b/src/components/util/cache.rs
index 02859014bbd..b8c89a3ac90 100644
--- a/src/components/util/cache.rs
+++ b/src/components/util/cache.rs
@@ -7,7 +7,7 @@ use std::hashmap::HashMap;
pub trait Cache<K: Eq, V: Clone> {
fn insert(&mut self, key: K, value: V);
fn find(&mut self, key: &K) -> Option<V>;
- fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V;
+ fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V;
fn evict_all(&mut self);
}
@@ -33,7 +33,7 @@ impl<K: Clone + Eq, V: Clone> Cache<K,V> for MonoCache<K,V> {
}
}
- fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V {
+ fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
match self.find(key) {
Some(value) => value,
None => {
@@ -87,7 +87,7 @@ impl<K: Clone + Eq + Hash, V: Clone> Cache<K,V> for HashCache<K,V> {
}
}
- fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V {
+ fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
self.entries.find_or_insert_with(key.clone(), blk).clone()
}
@@ -149,7 +149,7 @@ impl<K: Clone + Eq, V: Clone> Cache<K,V> for LRUCache<K,V> {
}
}
- fn find_or_create(&mut self, key: &K, blk: &fn(&K) -> V) -> V {
+ fn find_or_create(&mut self, key: &K, blk: |&K| -> V) -> V {
match self.entries.iter().position(|&(ref k, _)| *k == *key) {
Some(pos) => self.touch(pos),
None => {
@@ -191,7 +191,7 @@ fn test_lru_cache() {
assert!(cache.find(&4).is_some()); // (2, 4) (no change)
// Test find_or_create.
- do cache.find_or_create(&1) |_| { one }; // (4, 1)
+ cache.find_or_create(&1, |_| { one }); // (4, 1)
assert!(cache.find(&1).is_some()); // (4, 1) (no change)
assert!(cache.find(&2).is_none()); // (4, 1) (no change)
diff --git a/src/components/util/debug.rs b/src/components/util/debug.rs
index 5c9aa700d5b..029db75d129 100644
--- a/src/components/util/debug.rs
+++ b/src/components/util/debug.rs
@@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use std::rt::io;
-use std::rt::io::Writer;
+use std::io;
+use std::io::Writer;
use std::vec::raw::buf_as_slice;
use std::cast::transmute;
use std::mem::size_of;
diff --git a/src/components/util/geometry.rs b/src/components/util/geometry.rs
index 4b2cb0c2e43..71184e5eec1 100644
--- a/src/components/util/geometry.rs
+++ b/src/components/util/geometry.rs
@@ -124,10 +124,6 @@ impl ToPrimitive for Au {
}
}
-pub fn box<T:Clone + 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 {
/// FIXME(pcwalton): Workaround for lack of cross crate inlining of newtype structs!
#[inline]
diff --git a/src/components/util/io.rs b/src/components/util/io.rs
index 45009723774..b034682cf16 100644
--- a/src/components/util/io.rs
+++ b/src/components/util/io.rs
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use std::rt::io::{io_error, IoError};
+use std::io::{io_error, IoError};
/// Helper for catching an I/O error and wrapping it in a Result object. The
/// return result will be the last I/O error that happened or the result of the
@@ -10,7 +10,7 @@ use std::rt::io::{io_error, IoError};
///
/// FIXME: This is a copy of std::rt::io::result which doesn't exist yet in our
/// version of Rust. We should switch after the next Rust upgrade.
-pub fn result<T>(cb: &fn() -> T) -> Result<T, IoError> {
+pub fn result<T>(cb: || -> T) -> Result<T, IoError> {
let mut err = None;
let ret = io_error::cond.trap(|e| err = Some(e)).inside(cb);
match err {
diff --git a/src/components/util/slot.rs b/src/components/util/slot.rs
deleted file mode 100644
index 34c12f2a0f5..00000000000
--- a/src/components/util/slot.rs
+++ /dev/null
@@ -1,141 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//! An in-place, dynamically borrowable slot. Useful for "mutable fields". Assuming this works out
-//! well, this type should be upstreamed to the Rust standard library.
-
-use std::cast;
-use std::util;
-
-#[unsafe_no_drop_flag]
-#[no_freeze]
-pub struct Slot<T> {
- // NB: Must be priv, or else someone could borrow it.
- priv value: T,
- priv immutable_borrow_count: u8,
- priv mutably_borrowed: bool,
-}
-
-impl<T:Clone> Clone for Slot<T> {
- #[inline]
- fn clone(&self) -> Slot<T> {
- Slot {
- value: self.value.clone(),
- immutable_borrow_count: 0,
- mutably_borrowed: false,
- }
- }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for Slot<T> {
- fn drop(&mut self) {
- // Noncopyable.
- }
-}
-
-pub struct SlotRef<'self,T> {
- ptr: &'self T,
- priv immutable_borrow_count: *mut u8,
-}
-
-#[unsafe_destructor]
-impl<'self,T> Drop for SlotRef<'self,T> {
- #[inline]
- fn drop(&mut self) {
- unsafe {
- *self.immutable_borrow_count -= 1
- }
- }
-}
-
-pub struct MutSlotRef<'self,T> {
- ptr: &'self mut T,
- priv mutably_borrowed: *mut bool,
-}
-
-#[unsafe_destructor]
-impl<'self,T> Drop for MutSlotRef<'self,T> {
- #[inline]
- fn drop(&mut self) {
- unsafe {
- *self.mutably_borrowed = false
- }
- }
-}
-
-impl<T> Slot<T> {
- #[inline]
- pub fn init(value: T) -> Slot<T> {
- Slot {
- value: value,
- immutable_borrow_count: 0,
- mutably_borrowed: false,
- }
- }
-
- /// Borrows the data immutably. This function is thread-safe, but *bad things will happen if
- /// you try to mutate the data while one of these pointers is held*.
- #[inline]
- pub unsafe fn borrow_unchecked<'a>(&'a self) -> &'a T {
- &self.value
- }
-
- #[inline]
- pub fn borrow<'a>(&'a self) -> SlotRef<'a,T> {
- unsafe {
- if self.immutable_borrow_count == 255 || self.mutably_borrowed {
- self.fail()
- }
- let immutable_borrow_count = cast::transmute_mut(&self.immutable_borrow_count);
- *immutable_borrow_count += 1;
- SlotRef {
- ptr: &self.value,
- immutable_borrow_count: immutable_borrow_count,
- }
- }
- }
-
- #[inline]
- pub fn mutate<'a>(&'a self) -> MutSlotRef<'a,T> {
- unsafe {
- if self.immutable_borrow_count > 0 || self.mutably_borrowed {
- self.fail()
- }
- let mutably_borrowed = cast::transmute_mut(&self.mutably_borrowed);
- *mutably_borrowed = true;
- MutSlotRef {
- ptr: cast::transmute_mut(&self.value),
- mutably_borrowed: mutably_borrowed,
- }
- }
- }
-
- #[inline]
- pub fn set(&self, value: T) {
- *self.mutate().ptr = value
- }
-
- /// Replaces the slot's value with the given value and returns the old value.
- #[inline]
- pub fn replace(&self, value: T) -> T {
- util::replace(self.mutate().ptr, value)
- }
-
- #[inline(never)]
- pub fn fail(&self) -> ! {
- fail!("slot is borrowed")
- }
-}
-
-impl<T:Clone> Slot<T> {
- #[inline]
- pub fn get(&self) -> T {
- self.value.clone()
- }
-}
-
-
-
-
diff --git a/src/components/util/time.rs b/src/components/util/time.rs
index bfc1a1bd43c..59b01d264e7 100644
--- a/src/components/util/time.rs
+++ b/src/components/util/time.rs
@@ -4,25 +4,36 @@
//! Timing functions.
-use extra::sort::tim_sort;
use extra::time::precise_time_ns;
use extra::treemap::TreeMap;
-use std::comm::{Port, SendDeferred, SharedChan};
+use std::comm::{Port, SharedChan};
use std::iter::AdditiveIterator;
-use std::rt::io::timer::Timer;
-use std::task::spawn_with;
+
+
+// TODO: This code should be changed to use the commented code that uses timers
+// directly, once native timers land in Rust.
+extern {
+ pub fn usleep(secs: u64) -> u32;
+}
+
+pub struct Timer;
+impl Timer {
+ pub fn sleep(ms: u64) {
+ //
+ // let mut timer = Timer::new().unwrap();
+ // timer.sleep(period);
+ unsafe { usleep((ms * 1000)); }
+ }
+}
+
// front-end representation of the profiler used to communicate with the profiler
#[deriving(Clone)]
pub struct ProfilerChan(SharedChan<ProfilerMsg>);
impl ProfilerChan {
- pub fn new(chan: Chan<ProfilerMsg>) -> ProfilerChan {
- ProfilerChan(SharedChan::new(chan))
- }
-
- pub fn send_deferred(&self, msg: ProfilerMsg) {
- (**self).send_deferred(msg);
+ pub fn send(&self, msg: ProfilerMsg) {
+ (**self).send(msg);
}
}
@@ -100,32 +111,35 @@ pub struct Profiler {
}
impl Profiler {
- pub fn create(port: Port<ProfilerMsg>, chan: ProfilerChan, period: Option<f64>) {
+ pub fn create(period: Option<f64>) -> ProfilerChan {
+ let (port, chan) = SharedChan::new();
match period {
Some(period) => {
let period = (period * 1000f64) as u64;
- do spawn {
- let mut timer = Timer::new().unwrap();
+ let chan = chan.clone();
+ spawn(proc() {
loop {
- timer.sleep(period);
+ Timer::sleep(period);
if !chan.try_send(PrintMsg) {
break;
}
}
- }
+ });
// Spawn the profiler
- do spawn_with(port) |port| {
+ spawn(proc() {
let mut profiler = Profiler::new(port);
profiler.start();
- }
+ });
}
None => {
// no-op to handle profiler messages when the profiler is inactive
- do spawn_with(port) |port| {
- while port.try_recv().is_some() {}
- }
+ spawn(proc() {
+ while port.recv_opt().is_some() {}
+ });
}
}
+
+ ProfilerChan(chan)
}
pub fn new(port: Port<ProfilerMsg>) -> Profiler {
@@ -138,7 +152,7 @@ impl Profiler {
pub fn start(&mut self) {
loop {
- let msg = self.port.try_recv();
+ let msg = self.port.recv_opt();
match msg {
Some (msg) => self.handle_msg(msg),
None => break
@@ -151,7 +165,7 @@ impl Profiler {
TimeMsg(category, t) => self.buckets.find_mut(&category).unwrap().push(t),
PrintMsg => match self.last_msg {
// only print if more data has arrived since the last printout
- Some(TimeMsg(*)) => self.print_buckets(),
+ Some(TimeMsg(..)) => self.print_buckets(),
_ => ()
},
};
@@ -165,7 +179,13 @@ impl Profiler {
for (category, data) in self.buckets.iter() {
// FIXME(XXX): TreeMap currently lacks mut_iter()
let mut data = data.clone();
- tim_sort(data);
+ data.sort_by(|a, b| {
+ if a < b {
+ Less
+ } else {
+ Greater
+ }
+ });
let data_len = data.len();
if data_len > 0 {
let (mean, median, &min, &max) =
@@ -184,17 +204,17 @@ impl Profiler {
pub fn profile<T>(category: ProfilerCategory,
profiler_chan: ProfilerChan,
- callback: &fn() -> T)
+ callback: || -> T)
-> T {
let start_time = precise_time_ns();
let val = callback();
let end_time = precise_time_ns();
let ms = ((end_time - start_time) as f64 / 1000000f64);
- profiler_chan.send_deferred(TimeMsg(category, ms));
+ profiler_chan.send(TimeMsg(category, ms));
return val;
}
-pub fn time<T>(msg: &str, callback: &fn() -> T) -> T{
+pub fn time<T>(msg: &str, callback: || -> T) -> T{
let start_time = precise_time_ns();
let val = callback();
let end_time = precise_time_ns();
diff --git a/src/components/util/url.rs b/src/components/util/url.rs
index 74571f84f5b..a3677dd6415 100644
--- a/src/components/util/url.rs
+++ b/src/components/util/url.rs
@@ -73,7 +73,7 @@ pub fn make_url(str_url: ~str, current_url: Option<Url>) -> Url {
// Drop whitespace within data: URLs, e.g. newlines within a base64
// src="..." block. Whitespace intended as content should be
// %-encoded or base64'd.
- str_url.iter().filter(|&c| !c.is_whitespace()).collect()
+ str_url.chars().filter(|&c| !c.is_whitespace()).collect()
},
_ => str_url
}
diff --git a/src/components/util/util.rc b/src/components/util/util.rc
index 95e3b4e4662..9830de81d1a 100644
--- a/src/components/util/util.rc
+++ b/src/components/util/util.rc
@@ -2,10 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#[link(name = "util",
- vers = "0.1",
- uuid = "48421f49-17cf-41c5-a68e-ff669ff2ecd5",
- url = "http://servo.org/")];
+#[crate_id = "github.com/mozilla/servo#util:0.1"];
#[crate_type = "lib"];
#[feature(macro_rules, managed_boxes)];
@@ -16,7 +13,6 @@ extern mod geom;
pub mod cache;
pub mod geometry;
pub mod range;
-pub mod slot;
pub mod time;
pub mod url;
pub mod vec;
diff --git a/src/components/util/vec.rs b/src/components/util/vec.rs
index 7682eeab2ae..2c525c701cc 100644
--- a/src/components/util/vec.rs
+++ b/src/components/util/vec.rs
@@ -4,13 +4,13 @@
use std::cmp::{Ord, Eq};
-pub trait BinarySearchMethods<'self, T: Ord + Eq> {
- fn binary_search(&self, key: &T) -> Option<&'self T>;
+pub trait BinarySearchMethods<'a, T: Ord + Eq> {
+ fn binary_search(&self, key: &T) -> Option<&'a T>;
fn binary_search_index(&self, key: &T) -> Option<uint>;
}
-impl<'self, T: Ord + Eq> BinarySearchMethods<'self, T> for &'self [T] {
- fn binary_search(&self, key: &T) -> Option<&'self T> {
+impl<'a, T: Ord + Eq> BinarySearchMethods<'a, T> for &'a [T] {
+ fn binary_search(&self, key: &T) -> Option<&'a T> {
self.binary_search_index(key).map(|i| &self[i])
}
@@ -39,6 +39,7 @@ impl<'self, T: Ord + Eq> BinarySearchMethods<'self, T> for &'self [T] {
}
}
+#[cfg(test)]
fn test_find_all_elems<T: Eq + Ord>(arr: &[T]) {
let mut i = 0;
while i < arr.len() {
@@ -47,6 +48,7 @@ fn test_find_all_elems<T: Eq + Ord>(arr: &[T]) {
}
}
+#[cfg(test)]
fn test_miss_all_elems<T: Eq + Ord>(arr: &[T], misses: &[T]) {
let mut i = 0;
while i < misses.len() {
@@ -57,6 +59,7 @@ fn test_miss_all_elems<T: Eq + Ord>(arr: &[T], misses: &[T]) {
}
}
+#[cfg(test)]
fn test_match<T: Eq>(b: &T, a: Option<&T>) -> bool {
match a {
None => false,
@@ -70,9 +73,8 @@ pub fn zip_copies<A: Clone, B: Clone>(avec: &[A], bvec: &[B]) -> ~[(A,B)] {
.collect()
}
+#[test]
fn should_find_all_elements() {
- #[test];
-
let arr_odd = [1, 2, 4, 6, 7, 8, 9];
let arr_even = [1, 2, 5, 6, 7, 8, 9, 42];
let arr_double = [1, 1, 2, 2, 6, 8, 22];
@@ -88,9 +90,8 @@ fn should_find_all_elements() {
test_find_all_elems(arr_three);
}
+#[test]
fn should_not_find_missing_elements() {
- #[test];
-
let arr_odd = [1, 2, 4, 6, 7, 8, 9];
let arr_even = [1, 2, 5, 6, 7, 8, 9, 42];
let arr_double = [1, 1, 2, 2, 6, 8, 22];
diff --git a/src/platform/android/fontconfig b/src/platform/android/fontconfig
-Subproject d0c6dd720f90e2e8f8d8a103754195096531b53
+Subproject 3f9c99be6ab7f733ec38e6c566a9cfb441e8f47
diff --git a/src/platform/linux/rust-fontconfig b/src/platform/linux/rust-fontconfig
-Subproject a1e265ebb541c0402d5ce7a1e7dfdeaeac340fe
+Subproject f3d71aa708eb44736c4fe526fbf1bb55010c623
diff --git a/src/platform/linux/rust-freetype b/src/platform/linux/rust-freetype
-Subproject 710a4f1ac7bb5d6732b712574a7cfa098f804d0
+Subproject 03f4454a01cfcdcc8e7a7f6292f79a0d2250a2c
diff --git a/src/platform/linux/rust-xlib b/src/platform/linux/rust-xlib
-Subproject 965cc1f01134e186f01f048639b5ab1593f6d3c
+Subproject 52eb54dc12212f1bf2bef803411f3ce7920f770
diff --git a/src/platform/macos/rust-cocoa b/src/platform/macos/rust-cocoa
-Subproject 809e031c6c423655e3731c15295fb5f6eead53b
+Subproject 0ed9f2272fc44afd20faba02fdf6b264fd7005b
diff --git a/src/platform/macos/rust-core-foundation b/src/platform/macos/rust-core-foundation
-Subproject 0a9090b60dc5ec8516ae73ae4398c91727231df
+Subproject e855f9e03dbdd587092b93446e17eb1dd9313fe
diff --git a/src/platform/macos/rust-core-graphics b/src/platform/macos/rust-core-graphics
-Subproject bfb234fbafb11beeecb81dc763ecf8c7ab53923
+Subproject d6ab449173188761f72080c42660207154928e4
diff --git a/src/platform/macos/rust-core-text b/src/platform/macos/rust-core-text
-Subproject bb5d9a1d1bb6e9720d3cd46b14530f24cccf51b
+Subproject babcfa044f9a646a680c5528ac4aa777fd6d015
diff --git a/src/platform/macos/rust-io-surface b/src/platform/macos/rust-io-surface
-Subproject 516e2c11b4ecc464f166a9b2a16d7bf25044c5d
+Subproject f004673d5d172f2856b31d1b70253cd9dfba753
diff --git a/src/support/alert/rust-alert b/src/support/alert/rust-alert
-Subproject ce3cdc68b942cabfaa766d0cfe34ecf758623fb
+Subproject 906c01fd11e86964621ee55c78e93d9dff2bf76
diff --git a/src/support/azure/rust-azure b/src/support/azure/rust-azure
-Subproject b6fd2d88ad921f6f36fc8ac1fdd5437e0ba1a45
+Subproject 7656f814a61f0b6bf557040b525761279095fc8
diff --git a/src/support/css/rust-cssparser b/src/support/css/rust-cssparser
-Subproject 5178431109f4a51f38c257e36640702320c5495
+Subproject 0688d6ea9cea2b21ffa52286934be4942db7596
diff --git a/src/support/egl/rust-egl b/src/support/egl/rust-egl
-Subproject 2eae43848b0a00d84f43e76b6d310bd69ffc7a3
+Subproject 0c0484e0c07a3e5ef3184f6182c96c354a06eeb
diff --git a/src/support/encoding/rust-encoding b/src/support/encoding/rust-encoding
-Subproject 1a6c011b697fe6d51a1d92a2504d6fac1b67d2d
+Subproject f1cfdd64f6143fdcd864ec8fb607f7c231a723b
diff --git a/src/support/geom/rust-geom b/src/support/geom/rust-geom
-Subproject 928ee9d5055acd84a2f084b40c33e8556cbd008
+Subproject 883dda1f5089c305c5d6e6561ccbe7a0dfbd10f
diff --git a/src/support/glfw/glfw-rs b/src/support/glfw/glfw-rs
-Subproject 0920d683d5321e5d7a686d56d4183a34f7b173b
+Subproject ca679e1cea938cd82d5aedae9fae26551a0cc6d
diff --git a/src/support/glut/rust-glut b/src/support/glut/rust-glut
-Subproject 633324e13f6b565615ef59f4463a4c528c90ba5
+Subproject bdc2aebba9111fafaa7a7b148014bcdeed3c7c0
diff --git a/src/support/harfbuzz/rust-harfbuzz b/src/support/harfbuzz/rust-harfbuzz
-Subproject e29c85ecc7b0d61dcc669ce578c7957e88b617e
+Subproject a3b9cdba9d4f2c3cec78437bd22649e75b59e68
diff --git a/src/support/http/rust-http b/src/support/http/rust-http
-Subproject 9d8db21bfe189f81c0d88706475e282df0a6864
+Subproject 1a9a23b84cc28a7c39700f1c92a4cd1de1c98ce
diff --git a/src/support/hubbub/rust-hubbub b/src/support/hubbub/rust-hubbub
-Subproject 7254f84f81c464dbc78ddac84d7ecd494453a77
+Subproject a06f307be4f8220be14fa9b2203c4a08403851a
diff --git a/src/support/layers/rust-layers b/src/support/layers/rust-layers
-Subproject e8123cee2432c1b430c3df781489493f8ecdb6c
+Subproject 3caa5900ea6f5185f1ca4571a4f0e1215dab693
diff --git a/src/support/opengles/rust-opengles b/src/support/opengles/rust-opengles
-Subproject 60776fdefad6c94fb08ca82b1b853340878c2ff
+Subproject e1aa6d6e6f4412575908d003bb38df0d38cfa3c
diff --git a/src/support/png/rust-png b/src/support/png/rust-png
-Subproject 519c291139813bf6cda192a45745013d543c99f
+Subproject 7a53b3042df5f483967b8bba283806d5f620954
diff --git a/src/support/sharegl/sharegl b/src/support/sharegl/sharegl
-Subproject bb10edb7fb2428322a45664ebe8a9e0ce1679db
+Subproject 64366a70cd162677fbda3c7722da6da4f8bcba0
diff --git a/src/support/spidermonkey/rust-mozjs b/src/support/spidermonkey/rust-mozjs
-Subproject e3c4f8bfbea4f5523493c394576e76660fdf175
+Subproject da846919d0b99d84bffe89c5410b13ae64a969e
diff --git a/src/support/stb-image/rust-stb-image b/src/support/stb-image/rust-stb-image
-Subproject 0f55db952f5e5cd36f0f661e322e6c902ae172b
+Subproject 9d0ae526ecc8fbdbfa29165c1dd634c2c71a858
diff --git a/src/test/harness/contenttest/contenttest.rs b/src/test/harness/contenttest/contenttest.rs
index e7548b24610..1fd08edfdf9 100644
--- a/src/test/harness/contenttest/contenttest.rs
+++ b/src/test/harness/contenttest/contenttest.rs
@@ -13,10 +13,9 @@ extern mod extra;
use extra::test::{TestOpts, run_tests_console, TestDesc, TestDescAndFn, DynTestFn, DynTestName};
use extra::getopts::{getopts, reqopt};
use std::{os, str};
-use std::cell::Cell;
-use std::os::list_dir_path;
-use std::rt::io::Reader;
-use std::rt::io::process::{Process, ProcessConfig, Ignored, CreatePipe, InheritFd};
+use std::io::fs;
+use std::io::Reader;
+use std::io::process::{Process, ProcessConfig, Ignored, CreatePipe, InheritFd, ExitStatus};
#[deriving(Clone)]
struct Config {
@@ -67,20 +66,19 @@ fn test_options(config: Config) -> TestOpts {
}
fn find_tests(config: Config) -> ~[TestDescAndFn] {
- let mut files = list_dir_path(&Path::new(config.source_dir));
+ let mut files = fs::readdir(&Path::new(config.source_dir));
files.retain(|file| file.extension_str() == Some("html") );
return files.map(|file| make_test(file.display().to_str()) );
}
fn make_test(file: ~str) -> TestDescAndFn {
- let f = Cell::new(file.clone());
TestDescAndFn {
desc: TestDesc {
- name: DynTestName(file),
+ name: DynTestName(file.clone()),
ignore: false,
should_fail: false
},
- testfn: DynTestFn(|| { run_test(f.take()) })
+ testfn: DynTestFn(proc() { run_test(file) })
}
}
@@ -113,15 +111,15 @@ fn run_test(file: ~str) {
}
let out = str::from_utf8(output);
- let lines: ~[&str] = out.split_iter('\n').collect();
+ let lines: ~[&str] = out.split('\n').collect();
for &line in lines.iter() {
if line.contains("TEST-UNEXPECTED-FAIL") {
- fail!(line);
+ fail!(line.to_owned());
}
}
let retval = prc.wait();
- if retval != 0 {
+ if retval != ExitStatus(0) {
fail!("Servo exited with non-zero status {}", retval);
}
}
diff --git a/src/test/harness/reftest/reftest.rs b/src/test/harness/reftest/reftest.rs
index 2f83cf88583..fd22203a4e4 100644
--- a/src/test/harness/reftest/reftest.rs
+++ b/src/test/harness/reftest/reftest.rs
@@ -10,12 +10,11 @@
extern mod std;
extern mod extra;
-use std::cell::Cell;
-use std::rt::io;
-use std::rt::io::file;
-use std::rt::io::Reader;
+use std::io;
+use std::io::{File, Reader};
+use std::io::process::ExitStatus;
use std::os;
-use std::run;
+use std::run::{Process, ProcessOptions};
use std::str;
use extra::test::{DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn};
use extra::test::run_tests_console;
@@ -64,13 +63,13 @@ fn parse_lists(filenames: &[~str]) -> ~[TestDescAndFn] {
let mut next_id = 0;
for file in filenames.iter() {
let file_path = Path::new(file.clone());
- let contents = match file::open(&file_path, io::Open, io::Read) {
- Some(mut f) => str::from_utf8(f.read_to_end()),
+ let contents = match File::open_mode(&file_path, io::Open, io::Read) {
+ Some(mut f) => str::from_utf8_owned(f.read_to_end()),
None => fail!("Could not open file")
};
- for line in contents.line_iter() {
- let parts: ~[&str] = line.split_iter(' ').filter(|p| !p.is_empty()).collect();
+ for line in contents.lines() {
+ let parts: ~[&str] = line.split(' ').filter(|p| !p.is_empty()).collect();
if parts.len() != 3 {
fail!("reftest line: '{:s}' doesn't match 'KIND LEFT RIGHT'", line);
@@ -105,15 +104,14 @@ fn parse_lists(filenames: &[~str]) -> ~[TestDescAndFn] {
fn make_test(reftest: Reftest) -> TestDescAndFn {
let name = reftest.name.clone();
- let reftest = Cell::new(reftest);
TestDescAndFn {
desc: TestDesc {
name: DynTestName(name),
ignore: false,
should_fail: false,
},
- testfn: DynTestFn(|| {
- check_reftest(reftest.take());
+ testfn: DynTestFn(proc() {
+ check_reftest(reftest);
}),
}
}
@@ -123,22 +121,22 @@ fn check_reftest(reftest: Reftest) {
let right_filename = format!("/tmp/servo-reftest-{:06u}-right.png", reftest.id);
let args = ~[~"-o", left_filename.clone(), reftest.left.clone()];
- let mut process = run::Process::new("./servo", args, run::ProcessOptions::new());
+ let mut process = Process::new("./servo", args, ProcessOptions::new()).unwrap();
let _retval = process.finish();
// assert!(retval == 0);
let args = ~[~"-o", right_filename.clone(), reftest.right.clone()];
- let mut process = run::Process::new("./servo", args, run::ProcessOptions::new());
+ let mut process = Process::new("./servo", args, ProcessOptions::new()).unwrap();
let _retval = process.finish();
// assert!(retval == 0);
// check the pngs are bit equal
let args = ~[left_filename.clone(), right_filename.clone()];
- let mut process = run::Process::new("cmp", args, run::ProcessOptions::new());
+ let mut process = Process::new("cmp", args, ProcessOptions::new()).unwrap();
let retval = process.finish();
match reftest.kind {
- Same => assert!(retval == 0),
- Different => assert!(retval != 0),
+ Same => assert!(retval == ExitStatus(0)),
+ Different => assert!(retval != ExitStatus(0)),
}
}