mirror of
https://github.com/servo/servo.git
synced 2025-08-11 16:35:33 +01:00
commit
7c1054e6ab
6 changed files with 94 additions and 33 deletions
|
@ -35,6 +35,7 @@ use css::node_style::StyledNode;
|
||||||
use util::{LayoutDataAccess, LayoutDataWrapper, PrivateLayoutData, OpaqueNodeMethods};
|
use util::{LayoutDataAccess, LayoutDataWrapper, PrivateLayoutData, OpaqueNodeMethods};
|
||||||
|
|
||||||
use gfx::display_list::OpaqueNode;
|
use gfx::display_list::OpaqueNode;
|
||||||
|
use script::dom::bindings::cell::{Ref, RefMut};
|
||||||
use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementCast, HTMLImageElementCast};
|
use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElementCast, HTMLImageElementCast};
|
||||||
use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, TextCast};
|
use script::dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, TextCast};
|
||||||
use script::dom::bindings::js::JS;
|
use script::dom::bindings::js::JS;
|
||||||
|
@ -50,7 +51,6 @@ use script::dom::text::Text;
|
||||||
use script::layout_interface::LayoutChan;
|
use script::layout_interface::LayoutChan;
|
||||||
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
||||||
use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace};
|
use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace};
|
||||||
use std::cell::{RefCell, Ref, RefMut};
|
|
||||||
use std::kinds::marker::ContravariantLifetime;
|
use std::kinds::marker::ContravariantLifetime;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style::computed_values::{content, display, white_space};
|
use style::computed_values::{content, display, white_space};
|
||||||
|
@ -445,9 +445,7 @@ pub struct LayoutElement<'le> {
|
||||||
impl<'le> LayoutElement<'le> {
|
impl<'le> LayoutElement<'le> {
|
||||||
pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
|
pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
|
||||||
let style: &Option<PropertyDeclarationBlock> = unsafe {
|
let style: &Option<PropertyDeclarationBlock> = unsafe {
|
||||||
let style: &RefCell<Option<PropertyDeclarationBlock>> = self.element.style_attribute();
|
&*self.element.style_attribute().borrow_for_layout()
|
||||||
// cast to the direct reference to T placed on the head of RefCell<T>
|
|
||||||
mem::transmute(style)
|
|
||||||
};
|
};
|
||||||
style
|
style
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use dom::bindings::cell::{DOMRefCell, Ref};
|
||||||
use dom::bindings::codegen::Bindings::AttrBinding;
|
use dom::bindings::codegen::Bindings::AttrBinding;
|
||||||
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||||
|
@ -15,7 +16,6 @@ use dom::virtualmethods::vtable_for;
|
||||||
|
|
||||||
use devtools_traits::AttrInfo;
|
use devtools_traits::AttrInfo;
|
||||||
use servo_util::str::{DOMString, split_html_space_chars};
|
use servo_util::str::{DOMString, split_html_space_chars};
|
||||||
use std::cell::{Ref, RefCell};
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ impl Str for AttrValue {
|
||||||
pub struct Attr {
|
pub struct Attr {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
local_name: Atom,
|
local_name: Atom,
|
||||||
value: RefCell<AttrValue>,
|
value: DOMRefCell<AttrValue>,
|
||||||
name: Atom,
|
name: Atom,
|
||||||
namespace: Namespace,
|
namespace: Namespace,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
|
@ -97,7 +97,7 @@ impl Attr {
|
||||||
Attr {
|
Attr {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
local_name: local_name,
|
local_name: local_name,
|
||||||
value: RefCell::new(value),
|
value: DOMRefCell::new(value),
|
||||||
name: name,
|
name: name,
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
|
@ -221,15 +221,14 @@ pub trait AttrHelpersForLayout {
|
||||||
impl AttrHelpersForLayout for Attr {
|
impl AttrHelpersForLayout for Attr {
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn value_ref_forever(&self) -> &'static str {
|
unsafe fn value_ref_forever(&self) -> &'static str {
|
||||||
// cast to point to T in RefCell<T> directly
|
// This transmute is used to cheat the lifetime restriction.
|
||||||
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
|
let value = mem::transmute::<&AttrValue, &AttrValue>(self.value.borrow_for_layout());
|
||||||
value.as_slice()
|
value.as_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn value_atom_forever(&self) -> Option<Atom> {
|
unsafe fn value_atom_forever(&self) -> Option<Atom> {
|
||||||
// cast to point to T in RefCell<T> directly
|
let value = self.value.borrow_for_layout();
|
||||||
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
|
|
||||||
match *value {
|
match *value {
|
||||||
AtomAttrValue(ref val) => Some(val.clone()),
|
AtomAttrValue(ref val) => Some(val.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -238,8 +237,8 @@ impl AttrHelpersForLayout for Attr {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]> {
|
unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]> {
|
||||||
// cast to point to T in RefCell<T> directly
|
// This transmute is used to cheat the lifetime restriction.
|
||||||
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
|
let value = mem::transmute::<&AttrValue, &AttrValue>(self.value.borrow_for_layout());
|
||||||
match *value {
|
match *value {
|
||||||
TokenListAttrValue(_, ref tokens) => Some(tokens.as_slice()),
|
TokenListAttrValue(_, ref tokens) => Some(tokens.as_slice()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|
68
components/script/dom/bindings/cell.rs
Normal file
68
components/script/dom/bindings/cell.rs
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
use dom::bindings::trace::JSTraceable;
|
||||||
|
use js::jsapi::{JSTracer};
|
||||||
|
|
||||||
|
use std::cell;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
/// A mutable field in DOM for large sized value.
|
||||||
|
/// This has a special method to return the pointer of itself
|
||||||
|
/// for used in layout task.
|
||||||
|
/// This simply wraps `RefCell<T>` to add the special method.
|
||||||
|
pub struct DOMRefCell<T> {
|
||||||
|
base: RefCell<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Ref<'a, T> = cell::Ref<'a, T>;
|
||||||
|
pub type RefMut<'a, T> = cell::RefMut<'a, T>;
|
||||||
|
|
||||||
|
|
||||||
|
impl<T> DOMRefCell<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn new(value: T) -> DOMRefCell<T> {
|
||||||
|
DOMRefCell {
|
||||||
|
base: RefCell::new(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn unwrap(self) -> T {
|
||||||
|
self.base.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> {
|
||||||
|
self.base.try_borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn borrow<'a>(&'a self) -> Ref<'a, T> {
|
||||||
|
self.base.borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> {
|
||||||
|
self.base.try_borrow_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> {
|
||||||
|
self.base.borrow_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This returns the pointer which refers T in `RefCell<T>` directly.
|
||||||
|
pub unsafe fn borrow_for_layout<'a>(&'a self) -> &'a T {
|
||||||
|
let val = mem::transmute::<&RefCell<T>, &T>(&self.base);
|
||||||
|
val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: JSTraceable> JSTraceable for DOMRefCell<T> {
|
||||||
|
fn trace(&self, trc: *mut JSTracer) {
|
||||||
|
(*self).base.borrow().trace(trc)
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
//! DOM bindings for `CharacterData`.
|
//! DOM bindings for `CharacterData`.
|
||||||
|
|
||||||
|
use dom::bindings::cell::{DOMRefCell, Ref};
|
||||||
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, NodeCast};
|
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, NodeCast};
|
||||||
use dom::bindings::error::{Fallible, ErrorResult, IndexSize};
|
use dom::bindings::error::{Fallible, ErrorResult, IndexSize};
|
||||||
|
@ -14,15 +15,12 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::node::{CommentNodeTypeId, Node, NodeTypeId, TextNodeTypeId, ProcessingInstructionNodeTypeId, NodeHelpers};
|
use dom::node::{CommentNodeTypeId, Node, NodeTypeId, TextNodeTypeId, ProcessingInstructionNodeTypeId, NodeHelpers};
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
use std::cell::{Ref, RefCell};
|
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
#[must_root]
|
#[must_root]
|
||||||
#[privatize]
|
#[privatize]
|
||||||
pub struct CharacterData {
|
pub struct CharacterData {
|
||||||
node: Node,
|
node: Node,
|
||||||
data: RefCell<DOMString>,
|
data: DOMRefCell<DOMString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CharacterDataDerived for EventTarget {
|
impl CharacterDataDerived for EventTarget {
|
||||||
|
@ -40,7 +38,7 @@ impl CharacterData {
|
||||||
pub fn new_inherited(id: NodeTypeId, data: DOMString, document: JSRef<Document>) -> CharacterData {
|
pub fn new_inherited(id: NodeTypeId, data: DOMString, document: JSRef<Document>) -> CharacterData {
|
||||||
CharacterData {
|
CharacterData {
|
||||||
node: Node::new_inherited(id, document),
|
node: Node::new_inherited(id, document),
|
||||||
data: RefCell::new(data),
|
data: DOMRefCell::new(data),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +59,7 @@ impl CharacterData {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn data_for_layout<'a>(&'a self) -> &'a str {
|
pub unsafe fn data_for_layout<'a>(&'a self) -> &'a str {
|
||||||
mem::transmute::<&RefCell<DOMString>, &DOMString>(&self.data).as_slice()
|
self.data.borrow_for_layout().as_slice()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
use dom::attr::{Attr, ReplacedAttr, FirstSetAttr, AttrHelpers, AttrHelpersForLayout};
|
use dom::attr::{Attr, ReplacedAttr, FirstSetAttr, AttrHelpers, AttrHelpersForLayout};
|
||||||
use dom::attr::{AttrValue, StringAttrValue, UIntAttrValue, AtomAttrValue};
|
use dom::attr::{AttrValue, StringAttrValue, UIntAttrValue, AtomAttrValue};
|
||||||
use dom::namednodemap::NamedNodeMap;
|
use dom::namednodemap::NamedNodeMap;
|
||||||
|
use dom::bindings::cell::{DOMRefCell, Ref, RefMut};
|
||||||
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
||||||
use dom::bindings::codegen::Bindings::ElementBinding;
|
use dom::bindings::codegen::Bindings::ElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
|
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
|
||||||
|
@ -39,7 +40,6 @@ use servo_util::namespace;
|
||||||
use servo_util::str::{DOMString, LengthOrPercentageOrAuto};
|
use servo_util::str::{DOMString, LengthOrPercentageOrAuto};
|
||||||
|
|
||||||
use std::ascii::StrAsciiExt;
|
use std::ascii::StrAsciiExt;
|
||||||
use std::cell::{Ref, RefMut, RefCell};
|
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use string_cache::{Atom, Namespace};
|
use string_cache::{Atom, Namespace};
|
||||||
|
@ -53,8 +53,8 @@ pub struct Element {
|
||||||
local_name: Atom,
|
local_name: Atom,
|
||||||
namespace: Namespace,
|
namespace: Namespace,
|
||||||
prefix: Option<DOMString>,
|
prefix: Option<DOMString>,
|
||||||
attrs: RefCell<Vec<JS<Attr>>>,
|
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
||||||
style_attribute: RefCell<Option<style::PropertyDeclarationBlock>>,
|
style_attribute: DOMRefCell<Option<style::PropertyDeclarationBlock>>,
|
||||||
attr_list: MutNullableJS<NamedNodeMap>,
|
attr_list: MutNullableJS<NamedNodeMap>,
|
||||||
class_list: MutNullableJS<DOMTokenList>,
|
class_list: MutNullableJS<DOMTokenList>,
|
||||||
}
|
}
|
||||||
|
@ -160,10 +160,10 @@ impl Element {
|
||||||
local_name: Atom::from_slice(local_name.as_slice()),
|
local_name: Atom::from_slice(local_name.as_slice()),
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
attrs: RefCell::new(vec!()),
|
attrs: DOMRefCell::new(vec!()),
|
||||||
attr_list: Default::default(),
|
attr_list: Default::default(),
|
||||||
class_list: Default::default(),
|
class_list: Default::default(),
|
||||||
style_attribute: RefCell::new(None),
|
style_attribute: DOMRefCell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ impl Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn style_attribute<'a>(&'a self) -> &'a RefCell<Option<style::PropertyDeclarationBlock>> {
|
pub fn style_attribute<'a>(&'a self) -> &'a DOMRefCell<Option<style::PropertyDeclarationBlock>> {
|
||||||
&self.style_attribute
|
&self.style_attribute
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,8 +226,7 @@ impl RawLayoutElementHelpers for Element {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom)
|
unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom)
|
||||||
-> Option<&'a str> {
|
-> Option<&'a str> {
|
||||||
// cast to point to T in RefCell<T> directly
|
let attrs = self.attrs.borrow_for_layout();
|
||||||
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
|
|
||||||
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
||||||
let attr = attr.unsafe_get();
|
let attr = attr.unsafe_get();
|
||||||
*name == (*attr).local_name_atom_forever() &&
|
*name == (*attr).local_name_atom_forever() &&
|
||||||
|
@ -241,8 +240,7 @@ impl RawLayoutElementHelpers for Element {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &Atom) -> Vec<&'a str> {
|
unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &Atom) -> Vec<&'a str> {
|
||||||
// cast to point to T in RefCell<T> directly
|
let attrs = self.attrs.borrow_for_layout();
|
||||||
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
|
|
||||||
(*attrs).iter().filter_map(|attr: &JS<Attr>| {
|
(*attrs).iter().filter_map(|attr: &JS<Attr>| {
|
||||||
let attr = attr.unsafe_get();
|
let attr = attr.unsafe_get();
|
||||||
if *name == (*attr).local_name_atom_forever() {
|
if *name == (*attr).local_name_atom_forever() {
|
||||||
|
@ -257,8 +255,7 @@ impl RawLayoutElementHelpers for Element {
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom)
|
unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom)
|
||||||
-> Option<Atom> {
|
-> Option<Atom> {
|
||||||
// cast to point to T in RefCell<T> directly
|
let attrs = self.attrs.borrow_for_layout();
|
||||||
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
|
|
||||||
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
||||||
let attr = attr.unsafe_get();
|
let attr = attr.unsafe_get();
|
||||||
*name == (*attr).local_name_atom_forever() &&
|
*name == (*attr).local_name_atom_forever() &&
|
||||||
|
@ -272,7 +269,7 @@ impl RawLayoutElementHelpers for Element {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
unsafe fn has_class_for_layout(&self, name: &Atom) -> bool {
|
unsafe fn has_class_for_layout(&self, name: &Atom) -> bool {
|
||||||
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
|
let attrs = self.attrs.borrow_for_layout();
|
||||||
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
||||||
let attr = attr.unsafe_get();
|
let attr = attr.unsafe_get();
|
||||||
(*attr).local_name_atom_forever() == atom!("class")
|
(*attr).local_name_atom_forever() == atom!("class")
|
||||||
|
@ -287,7 +284,7 @@ impl RawLayoutElementHelpers for Element {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]> {
|
unsafe fn get_classes_for_layout(&self) -> Option<&'static [Atom]> {
|
||||||
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
|
let attrs = self.attrs.borrow_for_layout();
|
||||||
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
||||||
let attr = attr.unsafe_get();
|
let attr = attr.unsafe_get();
|
||||||
(*attr).local_name_atom_forever() == atom!("class")
|
(*attr).local_name_atom_forever() == atom!("class")
|
||||||
|
|
|
@ -56,6 +56,7 @@ pub mod dom {
|
||||||
|
|
||||||
/// The code to expose the DOM to JavaScript through IDL bindings.
|
/// The code to expose the DOM to JavaScript through IDL bindings.
|
||||||
pub mod bindings {
|
pub mod bindings {
|
||||||
|
pub mod cell;
|
||||||
pub mod global;
|
pub mod global;
|
||||||
pub mod js;
|
pub mod js;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue