mirror of
https://github.com/servo/servo.git
synced 2025-08-11 08:25:32 +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 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::{HTMLInputElementCast, TextCast};
|
||||
use script::dom::bindings::js::JS;
|
||||
|
@ -50,7 +51,6 @@ use script::dom::text::Text;
|
|||
use script::layout_interface::LayoutChan;
|
||||
use servo_msg::constellation_msg::{PipelineId, SubpageId};
|
||||
use servo_util::str::{LengthOrPercentageOrAuto, is_whitespace};
|
||||
use std::cell::{RefCell, Ref, RefMut};
|
||||
use std::kinds::marker::ContravariantLifetime;
|
||||
use std::mem;
|
||||
use style::computed_values::{content, display, white_space};
|
||||
|
@ -445,9 +445,7 @@ pub struct LayoutElement<'le> {
|
|||
impl<'le> LayoutElement<'le> {
|
||||
pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> {
|
||||
let style: &Option<PropertyDeclarationBlock> = unsafe {
|
||||
let style: &RefCell<Option<PropertyDeclarationBlock>> = self.element.style_attribute();
|
||||
// cast to the direct reference to T placed on the head of RefCell<T>
|
||||
mem::transmute(style)
|
||||
&*self.element.style_attribute().borrow_for_layout()
|
||||
};
|
||||
style
|
||||
}
|
||||
|
|
|
@ -2,6 +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::cell::{DOMRefCell, Ref};
|
||||
use dom::bindings::codegen::Bindings::AttrBinding;
|
||||
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
||||
use dom::bindings::codegen::InheritTypes::NodeCast;
|
||||
|
@ -15,7 +16,6 @@ use dom::virtualmethods::vtable_for;
|
|||
|
||||
use devtools_traits::AttrInfo;
|
||||
use servo_util::str::{DOMString, split_html_space_chars};
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::mem;
|
||||
use string_cache::{Atom, Namespace};
|
||||
|
||||
|
@ -75,7 +75,7 @@ impl Str for AttrValue {
|
|||
pub struct Attr {
|
||||
reflector_: Reflector,
|
||||
local_name: Atom,
|
||||
value: RefCell<AttrValue>,
|
||||
value: DOMRefCell<AttrValue>,
|
||||
name: Atom,
|
||||
namespace: Namespace,
|
||||
prefix: Option<DOMString>,
|
||||
|
@ -97,7 +97,7 @@ impl Attr {
|
|||
Attr {
|
||||
reflector_: Reflector::new(),
|
||||
local_name: local_name,
|
||||
value: RefCell::new(value),
|
||||
value: DOMRefCell::new(value),
|
||||
name: name,
|
||||
namespace: namespace,
|
||||
prefix: prefix,
|
||||
|
@ -221,15 +221,14 @@ pub trait AttrHelpersForLayout {
|
|||
impl AttrHelpersForLayout for Attr {
|
||||
#[inline]
|
||||
unsafe fn value_ref_forever(&self) -> &'static str {
|
||||
// cast to point to T in RefCell<T> directly
|
||||
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
|
||||
// This transmute is used to cheat the lifetime restriction.
|
||||
let value = mem::transmute::<&AttrValue, &AttrValue>(self.value.borrow_for_layout());
|
||||
value.as_slice()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn value_atom_forever(&self) -> Option<Atom> {
|
||||
// cast to point to T in RefCell<T> directly
|
||||
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
|
||||
let value = self.value.borrow_for_layout();
|
||||
match *value {
|
||||
AtomAttrValue(ref val) => Some(val.clone()),
|
||||
_ => None,
|
||||
|
@ -238,8 +237,8 @@ impl AttrHelpersForLayout for Attr {
|
|||
|
||||
#[inline]
|
||||
unsafe fn value_tokens_forever(&self) -> Option<&'static [Atom]> {
|
||||
// cast to point to T in RefCell<T> directly
|
||||
let value = mem::transmute::<&RefCell<AttrValue>, &AttrValue>(&self.value);
|
||||
// This transmute is used to cheat the lifetime restriction.
|
||||
let value = mem::transmute::<&AttrValue, &AttrValue>(self.value.borrow_for_layout());
|
||||
match *value {
|
||||
TokenListAttrValue(_, ref tokens) => Some(tokens.as_slice()),
|
||||
_ => 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`.
|
||||
|
||||
use dom::bindings::cell::{DOMRefCell, Ref};
|
||||
use dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{CharacterDataDerived, NodeCast};
|
||||
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 servo_util::str::DOMString;
|
||||
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::mem;
|
||||
|
||||
#[jstraceable]
|
||||
#[must_root]
|
||||
#[privatize]
|
||||
pub struct CharacterData {
|
||||
node: Node,
|
||||
data: RefCell<DOMString>,
|
||||
data: DOMRefCell<DOMString>,
|
||||
}
|
||||
|
||||
impl CharacterDataDerived for EventTarget {
|
||||
|
@ -40,7 +38,7 @@ impl CharacterData {
|
|||
pub fn new_inherited(id: NodeTypeId, data: DOMString, document: JSRef<Document>) -> CharacterData {
|
||||
CharacterData {
|
||||
node: Node::new_inherited(id, document),
|
||||
data: RefCell::new(data),
|
||||
data: DOMRefCell::new(data),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +59,7 @@ impl CharacterData {
|
|||
|
||||
#[inline]
|
||||
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::{AttrValue, StringAttrValue, UIntAttrValue, AtomAttrValue};
|
||||
use dom::namednodemap::NamedNodeMap;
|
||||
use dom::bindings::cell::{DOMRefCell, Ref, RefMut};
|
||||
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
||||
use dom::bindings::codegen::Bindings::ElementBinding;
|
||||
use dom::bindings::codegen::Bindings::ElementBinding::ElementMethods;
|
||||
|
@ -39,7 +40,6 @@ use servo_util::namespace;
|
|||
use servo_util::str::{DOMString, LengthOrPercentageOrAuto};
|
||||
|
||||
use std::ascii::StrAsciiExt;
|
||||
use std::cell::{Ref, RefMut, RefCell};
|
||||
use std::default::Default;
|
||||
use std::mem;
|
||||
use string_cache::{Atom, Namespace};
|
||||
|
@ -53,8 +53,8 @@ pub struct Element {
|
|||
local_name: Atom,
|
||||
namespace: Namespace,
|
||||
prefix: Option<DOMString>,
|
||||
attrs: RefCell<Vec<JS<Attr>>>,
|
||||
style_attribute: RefCell<Option<style::PropertyDeclarationBlock>>,
|
||||
attrs: DOMRefCell<Vec<JS<Attr>>>,
|
||||
style_attribute: DOMRefCell<Option<style::PropertyDeclarationBlock>>,
|
||||
attr_list: MutNullableJS<NamedNodeMap>,
|
||||
class_list: MutNullableJS<DOMTokenList>,
|
||||
}
|
||||
|
@ -160,10 +160,10 @@ impl Element {
|
|||
local_name: Atom::from_slice(local_name.as_slice()),
|
||||
namespace: namespace,
|
||||
prefix: prefix,
|
||||
attrs: RefCell::new(vec!()),
|
||||
attrs: DOMRefCell::new(vec!()),
|
||||
attr_list: Default::default(),
|
||||
class_list: Default::default(),
|
||||
style_attribute: RefCell::new(None),
|
||||
style_attribute: DOMRefCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ impl Element {
|
|||
}
|
||||
|
||||
#[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
|
||||
}
|
||||
}
|
||||
|
@ -226,8 +226,7 @@ impl RawLayoutElementHelpers for Element {
|
|||
#[allow(unrooted_must_root)]
|
||||
unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &Atom)
|
||||
-> Option<&'a str> {
|
||||
// cast to point to T in RefCell<T> directly
|
||||
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
|
||||
let attrs = self.attrs.borrow_for_layout();
|
||||
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
||||
let attr = attr.unsafe_get();
|
||||
*name == (*attr).local_name_atom_forever() &&
|
||||
|
@ -241,8 +240,7 @@ impl RawLayoutElementHelpers for Element {
|
|||
#[inline]
|
||||
#[allow(unrooted_must_root)]
|
||||
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: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
|
||||
let attrs = self.attrs.borrow_for_layout();
|
||||
(*attrs).iter().filter_map(|attr: &JS<Attr>| {
|
||||
let attr = attr.unsafe_get();
|
||||
if *name == (*attr).local_name_atom_forever() {
|
||||
|
@ -257,8 +255,7 @@ impl RawLayoutElementHelpers for Element {
|
|||
#[allow(unrooted_must_root)]
|
||||
unsafe fn get_attr_atom_for_layout(&self, namespace: &Namespace, name: &Atom)
|
||||
-> Option<Atom> {
|
||||
// cast to point to T in RefCell<T> directly
|
||||
let attrs: *const Vec<JS<Attr>> = mem::transmute(&self.attrs);
|
||||
let attrs = self.attrs.borrow_for_layout();
|
||||
(*attrs).iter().find(|attr: & &JS<Attr>| {
|
||||
let attr = attr.unsafe_get();
|
||||
*name == (*attr).local_name_atom_forever() &&
|
||||
|
@ -272,7 +269,7 @@ impl RawLayoutElementHelpers for Element {
|
|||
#[inline]
|
||||
#[allow(unrooted_must_root)]
|
||||
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>| {
|
||||
let attr = attr.unsafe_get();
|
||||
(*attr).local_name_atom_forever() == atom!("class")
|
||||
|
@ -287,7 +284,7 @@ impl RawLayoutElementHelpers for Element {
|
|||
#[inline]
|
||||
#[allow(unrooted_must_root)]
|
||||
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>| {
|
||||
let attr = attr.unsafe_get();
|
||||
(*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.
|
||||
pub mod bindings {
|
||||
pub mod cell;
|
||||
pub mod global;
|
||||
pub mod js;
|
||||
pub mod utils;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue