mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
script: Harden layout a bit more by mostly prohibiting it from seeing
`AbstractNode` at all. It can still see it by calling `with_element` for now, although that needs to be fixed.
This commit is contained in:
parent
be69a503fe
commit
ee9873bdb5
3 changed files with 69 additions and 44 deletions
|
@ -164,13 +164,11 @@ pub struct IframeBoxInfo {
|
||||||
impl IframeBoxInfo {
|
impl IframeBoxInfo {
|
||||||
/// Creates the information specific to an iframe box.
|
/// Creates the information specific to an iframe box.
|
||||||
pub fn new(node: &LayoutNode) -> IframeBoxInfo {
|
pub fn new(node: &LayoutNode) -> IframeBoxInfo {
|
||||||
node.with_iframe_element(|iframe_element| {
|
let (pipeline_id, subpage_id) = node.iframe_pipeline_and_subpage_ids();
|
||||||
let size = iframe_element.size.unwrap();
|
IframeBoxInfo {
|
||||||
IframeBoxInfo {
|
pipeline_id: pipeline_id,
|
||||||
pipeline_id: size.pipeline_id,
|
subpage_id: subpage_id,
|
||||||
subpage_id: size.subpage_id,
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,12 +206,10 @@ pub struct UnscannedTextBoxInfo {
|
||||||
impl UnscannedTextBoxInfo {
|
impl UnscannedTextBoxInfo {
|
||||||
/// Creates a new instance of `UnscannedTextBoxInfo` from the given DOM node.
|
/// Creates a new instance of `UnscannedTextBoxInfo` from the given DOM node.
|
||||||
pub fn new(node: &LayoutNode) -> UnscannedTextBoxInfo {
|
pub fn new(node: &LayoutNode) -> UnscannedTextBoxInfo {
|
||||||
node.with_text(|text_node| {
|
// FIXME(pcwalton): Don't copy text; atomically reference count it instead.
|
||||||
// FIXME(pcwalton): Don't copy text; atomically reference count it instead.
|
UnscannedTextBoxInfo {
|
||||||
UnscannedTextBoxInfo {
|
text: node.text(),
|
||||||
text: text_node.element.data.to_str(),
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,11 +200,7 @@ impl<'self> FlowConstructor<'self> {
|
||||||
/// Builds the `ImageBoxInfo` for the given image. This is out of line to guide inlining.
|
/// Builds the `ImageBoxInfo` for the given image. This is out of line to guide inlining.
|
||||||
fn build_box_info_for_image(&mut self, node: LayoutNode) -> Option<ImageBoxInfo> {
|
fn build_box_info_for_image(&mut self, node: LayoutNode) -> Option<ImageBoxInfo> {
|
||||||
// FIXME(pcwalton): Don't copy URLs.
|
// FIXME(pcwalton): Don't copy URLs.
|
||||||
let url = node.with_image_element(|image_element| {
|
match node.image_url() {
|
||||||
image_element.image.as_ref().map(|url| (*url).clone())
|
|
||||||
});
|
|
||||||
|
|
||||||
match url {
|
|
||||||
None => None,
|
None => None,
|
||||||
Some(url) => {
|
Some(url) => {
|
||||||
// FIXME(pcwalton): The fact that image boxes store the cache within them makes
|
// FIXME(pcwalton): The fact that image boxes store the cache within them makes
|
||||||
|
@ -530,10 +526,6 @@ trait NodeUtils {
|
||||||
/// Replaces the flow construction result in a node with `NoConstructionResult` and returns the
|
/// Replaces the flow construction result in a node with `NoConstructionResult` and returns the
|
||||||
/// old value.
|
/// old value.
|
||||||
fn swap_out_construction_result(self) -> ConstructionResult;
|
fn swap_out_construction_result(self) -> ConstructionResult;
|
||||||
|
|
||||||
/// Returns true if this node consists entirely of ignorable whitespace and false otherwise.
|
|
||||||
/// Ignorable whitespace is defined as whitespace that would be removed per CSS 2.1 § 16.6.1.
|
|
||||||
fn is_ignorable_whitespace(self) -> bool;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeUtils for LayoutNode {
|
impl NodeUtils for LayoutNode {
|
||||||
|
@ -566,10 +558,6 @@ impl NodeUtils for LayoutNode {
|
||||||
None => fail!("no layout data"),
|
None => fail!("no layout data"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_ignorable_whitespace(self) -> bool {
|
|
||||||
self.is_text() && self.with_text(|text| text.element.data.is_whitespace())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Strips ignorable whitespace from the start of a list of boxes.
|
/// Strips ignorable whitespace from the start of a list of boxes.
|
||||||
|
|
|
@ -19,7 +19,9 @@ use dom::htmlimageelement::HTMLImageElement;
|
||||||
use dom::htmliframeelement::HTMLIFrameElement;
|
use dom::htmliframeelement::HTMLIFrameElement;
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
|
|
||||||
|
use extra::url::Url;
|
||||||
use js::jsapi::{JSObject, JSContext};
|
use js::jsapi::{JSObject, JSContext};
|
||||||
|
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
||||||
use servo_util::slot::{MutSlotRef, Slot, SlotRef};
|
use servo_util::slot::{MutSlotRef, Slot, SlotRef};
|
||||||
use std::cast::transmute;
|
use std::cast::transmute;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
|
@ -39,20 +41,19 @@ pub struct LayoutNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutNode {
|
impl LayoutNode {
|
||||||
// NB: Do not make this public.
|
/// NB: Do not make this public.
|
||||||
//
|
///
|
||||||
// FIXME(pcwalton): Probably this should be marked `unsafe`.
|
/// FIXME(pcwalton): Probably this should be marked `unsafe`.
|
||||||
fn new(node: AbstractNode) -> LayoutNode {
|
/*PRIVATE-FOR-SECURITY-REASONS*/ fn new(node: AbstractNode) -> LayoutNode {
|
||||||
LayoutNode {
|
LayoutNode {
|
||||||
node: node,
|
node: node,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FIXME(pcwalton): This isn't safe, as it exposes guts, and should be deprecated.
|
/// Returns the interior of this node as a `Node`. This is highly unsafe for layout to call
|
||||||
pub fn get<'a>(&'a self) -> &'a Node<LayoutView> {
|
/// and as such is marked `unsafe`.
|
||||||
unsafe {
|
pub unsafe fn get<'a>(&'a self) -> &'a Node<LayoutView> {
|
||||||
cast::transmute(self.node.node())
|
cast::transmute(self.node.node())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first child of this node.
|
/// Returns the first child of this node.
|
||||||
|
@ -86,24 +87,50 @@ impl LayoutNode {
|
||||||
self.node.type_id()
|
self.node.type_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If this is an image element, returns its URL. If this is not an image element, fails.
|
||||||
|
///
|
||||||
|
/// FIXME(pcwalton): Don't copy URLs.
|
||||||
|
pub fn image_url(&self) -> Option<Url> {
|
||||||
|
self.with_image_element(|image_element| {
|
||||||
|
image_element.image.as_ref().map(|url| (*url).clone())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Downcasts this node to an image element and calls the given closure.
|
/// Downcasts this node to an image element and calls the given closure.
|
||||||
///
|
///
|
||||||
|
/// NB: Do not make this public, as layout will be able to do unsafe things with `AbstractNode`
|
||||||
|
/// otherwise.
|
||||||
|
///
|
||||||
/// FIXME(pcwalton): RAII.
|
/// FIXME(pcwalton): RAII.
|
||||||
/// FIXME(pcwalton): This isn't safe, as it allows layout to access `AbstractNode`s, and should
|
/*PRIVATE-FOR-SECURITY-REASONS*/ fn with_image_element<R>(
|
||||||
/// be deprecated.
|
self,
|
||||||
pub fn with_image_element<R>(self, f: &fn(&HTMLImageElement) -> R) -> R {
|
f: &fn(&HTMLImageElement) -> R)
|
||||||
|
-> R {
|
||||||
if !self.node.is_image_element() {
|
if !self.node.is_image_element() {
|
||||||
fail!(~"node is not an image element");
|
fail!(~"node is not an image element");
|
||||||
}
|
}
|
||||||
self.node.transmute(f)
|
self.node.transmute(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If this node is an iframe element, returns its pipeline and subpage IDs. If this node is
|
||||||
|
/// not an iframe element, fails.
|
||||||
|
pub fn iframe_pipeline_and_subpage_ids(&self) -> (PipelineId, SubpageId) {
|
||||||
|
self.with_iframe_element(|iframe_element| {
|
||||||
|
let size = iframe_element.size.unwrap();
|
||||||
|
(size.pipeline_id, size.subpage_id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Downcasts this node to an iframe element and calls the given closure.
|
/// Downcasts this node to an iframe element and calls the given closure.
|
||||||
///
|
///
|
||||||
|
/// NB: Do not make this public, as layout will be able to do unsafe things with `AbstractNode`
|
||||||
|
/// otherwise.
|
||||||
|
///
|
||||||
/// FIXME(pcwalton): RAII.
|
/// FIXME(pcwalton): RAII.
|
||||||
/// FIXME(pcwalton): This isn't safe, as it allows layout to access `AbstractNode`s, and should
|
/*PRIVATE-FOR-SECURITY-REASONS*/ fn with_iframe_element<R>(
|
||||||
/// be deprecated.
|
self,
|
||||||
pub fn with_iframe_element<R>(self, f: &fn(&HTMLIFrameElement) -> R) -> R {
|
f: &fn(&HTMLIFrameElement) -> R)
|
||||||
|
-> R {
|
||||||
if !self.node.is_iframe_element() {
|
if !self.node.is_iframe_element() {
|
||||||
fail!(~"node is not an iframe element");
|
fail!(~"node is not an iframe element");
|
||||||
}
|
}
|
||||||
|
@ -116,12 +143,26 @@ impl LayoutNode {
|
||||||
self.node.is_text()
|
self.node.is_text()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if this node consists entirely of ignorable whitespace and false otherwise.
|
||||||
|
/// Ignorable whitespace is defined as whitespace that would be removed per CSS 2.1 § 16.6.1.
|
||||||
|
pub fn is_ignorable_whitespace(&self) -> bool {
|
||||||
|
self.is_text() && self.with_text(|text| text.element.data.is_whitespace())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If this is a text node, copies out the text. If this is not a text node, fails.
|
||||||
|
///
|
||||||
|
/// FIXME(pcwalton): Don't copy text. Atomically reference count instead.
|
||||||
|
pub fn text(&self) -> ~str {
|
||||||
|
self.with_text(|text| text.element.data.to_str())
|
||||||
|
}
|
||||||
|
|
||||||
/// Downcasts this node to a text node and calls the given closure.
|
/// Downcasts this node to a text node and calls the given closure.
|
||||||
///
|
///
|
||||||
|
/// NB: Do not make this public, as layout will be able to do unsafe things with `AbstractNode`
|
||||||
|
/// otherwise.
|
||||||
|
///
|
||||||
/// FIXME(pcwalton): RAII.
|
/// FIXME(pcwalton): RAII.
|
||||||
/// FIXME(pcwalton): This isn't safe, as it allows layout to access `AbstractNode`s, and should
|
/*PRIVATE-FOR-SECURITY-REASONS*/ fn with_text<R>(self, f: &fn(&Text) -> R) -> R {
|
||||||
/// be deprecated.
|
|
||||||
pub fn with_text<R>(self, f: &fn(&Text) -> R) -> R {
|
|
||||||
self.node.with_imm_text(f)
|
self.node.with_imm_text(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue