mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Introduce a phantom type to prevent script from accessing the layout data directly.
Nodes are now parameterized over a "View" type. The particular View type determines which methods can be called. Layout data accessors and mutators are only accessible to nodes with a LayoutView. The only way to convert a `Node<ScriptView>` to a `Node<LayoutView>` is through a transmutation, which is done at the moment the layout task receives nodes. (This should be factored better to contain the unsafety.) We should also lock down DOM node mutation to the ScriptView to forbid data races, but this patch doesn't do that. This also reduces coupling between DOM and layout. Soon I would like to move the DOM into its own crate, and this is a step on the way of doing that.
This commit is contained in:
parent
c7bce98236
commit
4f3ca373d4
23 changed files with 262 additions and 189 deletions
|
@ -8,8 +8,8 @@
|
|||
use css::matching::MatchMethods;
|
||||
use css::select::new_css_select_ctx;
|
||||
use dom::event::ReflowEvent;
|
||||
use dom::node::{AbstractNode, LayoutData};
|
||||
use layout::aux::LayoutAuxMethods;
|
||||
use dom::node::{AbstractNode, LayoutView, ScriptView};
|
||||
use layout::aux::{LayoutData, LayoutAuxMethods};
|
||||
use layout::box_builder::LayoutTreeBuilder;
|
||||
use layout::context::LayoutContext;
|
||||
use layout::debug::{BoxedMutDebugMethods, DebugMethods};
|
||||
|
@ -22,6 +22,7 @@ use servo_util::time::time;
|
|||
use servo_util::time::profile;
|
||||
use servo_util::time::ProfilerChan;
|
||||
|
||||
use core::cast::transmute;
|
||||
use core::cell::Cell;
|
||||
use core::comm::{Chan, Port, SharedChan};
|
||||
use geom::point::Point2D;
|
||||
|
@ -44,8 +45,8 @@ use std::net::url::Url;
|
|||
pub type LayoutTask = SharedChan<Msg>;
|
||||
|
||||
pub enum LayoutQuery {
|
||||
ContentBox(AbstractNode),
|
||||
ContentBoxes(AbstractNode)
|
||||
ContentBox(AbstractNode<ScriptView>),
|
||||
ContentBoxes(AbstractNode<ScriptView>),
|
||||
}
|
||||
|
||||
pub type LayoutQueryResponse = Result<LayoutQueryResponse_, ()>;
|
||||
|
@ -81,7 +82,7 @@ impl Damage {
|
|||
}
|
||||
|
||||
pub struct BuildData {
|
||||
node: AbstractNode,
|
||||
node: AbstractNode<ScriptView>,
|
||||
url: Url,
|
||||
script_chan: SharedChan<ScriptMsg>,
|
||||
window_size: Size2D<uint>,
|
||||
|
@ -180,7 +181,11 @@ impl Layout {
|
|||
|
||||
/// The high-level routine that performs layout tasks.
|
||||
fn handle_build(&mut self, data: &BuildData) {
|
||||
let node = &data.node;
|
||||
// FIXME: Isolate this transmutation into a "bridge" module.
|
||||
let node: &AbstractNode<LayoutView> = unsafe {
|
||||
transmute(&data.node)
|
||||
};
|
||||
|
||||
// FIXME: Bad copy!
|
||||
let doc_url = copy data.url;
|
||||
let script_chan = data.script_chan.clone();
|
||||
|
@ -279,6 +284,11 @@ impl Layout {
|
|||
fn handle_query(&self, query: LayoutQuery, reply_chan: Chan<LayoutQueryResponse>) {
|
||||
match query {
|
||||
ContentBox(node) => {
|
||||
// FIXME: Isolate this transmutation into a single "bridge" module.
|
||||
let node: AbstractNode<LayoutView> = unsafe {
|
||||
transmute(node)
|
||||
};
|
||||
|
||||
let response = match node.layout_data().flow {
|
||||
None => {
|
||||
error!("no flow present");
|
||||
|
@ -306,6 +316,11 @@ impl Layout {
|
|||
reply_chan.send(response)
|
||||
}
|
||||
ContentBoxes(node) => {
|
||||
// FIXME: Isolate this transmutation into a single "bridge" module.
|
||||
let node: AbstractNode<LayoutView> = unsafe {
|
||||
transmute(node)
|
||||
};
|
||||
|
||||
let response = match node.layout_data().flow {
|
||||
None => Err(()),
|
||||
Some(flow) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue