mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
stylo: Convert pseudo-elements to an Atom wrapper.
This commit is contained in:
parent
b1091dff58
commit
d612d9f5ef
3 changed files with 129 additions and 280 deletions
|
@ -12,104 +12,81 @@ use stylesheets::Stylesheet;
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct GeckoSelectorImpl;
|
pub struct GeckoSelectorImpl;
|
||||||
|
|
||||||
|
/// NOTE: The boolean field represents whether this element is an anonymous box.
|
||||||
|
///
|
||||||
|
/// This is just for convenience, instead of recomputing it. Also, note that
|
||||||
|
/// Atom is always a static atom, so if space is a concern, we can use the
|
||||||
|
/// raw pointer and use the lower bit to represent it without space overhead.
|
||||||
|
///
|
||||||
|
/// FIXME(emilio): we know all these atoms are static. Patches are starting to
|
||||||
|
/// pile up, but a further potential optimisation is generating bindings without
|
||||||
|
/// `-no-gen-bitfield-methods` (that was removed to compile on stable, but it no
|
||||||
|
/// longer depends on it), and using the raw *mut nsIAtom (properly asserting
|
||||||
|
/// we're a static atom).
|
||||||
|
///
|
||||||
|
/// This should allow us to avoid random FFI overhead when cloning/dropping
|
||||||
|
/// pseudos.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub enum PseudoElement {
|
pub struct PseudoElement(Atom, bool);
|
||||||
Before,
|
|
||||||
After,
|
|
||||||
|
|
||||||
Backdrop,
|
impl PseudoElement {
|
||||||
FirstLetter,
|
#[inline]
|
||||||
FirstLine,
|
fn as_atom(&self) -> &Atom {
|
||||||
MozSelection,
|
&self.0
|
||||||
MozFocusInner,
|
}
|
||||||
MozFocusOuter,
|
|
||||||
MozListBullet,
|
|
||||||
MozListNumber,
|
|
||||||
MozMathAnonymous,
|
|
||||||
MozNumberWrapper,
|
|
||||||
MozNumberText,
|
|
||||||
MozNumberSpinBox,
|
|
||||||
MozNumberSpinUp,
|
|
||||||
MozNumberSpinDown,
|
|
||||||
MozProgressBar,
|
|
||||||
MozRangeTrack,
|
|
||||||
MozRangeProgress,
|
|
||||||
MozRangeThumb,
|
|
||||||
MozMeterBar,
|
|
||||||
MozPlaceholder,
|
|
||||||
MozColorSwatch,
|
|
||||||
|
|
||||||
AnonBox(AnonBoxPseudoElement),
|
#[inline]
|
||||||
}
|
fn is_anon_box(&self) -> bool {
|
||||||
|
self.1
|
||||||
|
}
|
||||||
|
|
||||||
// https://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
|
#[inline]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
fn from_atom_unchecked(atom: Atom, is_anon_box: bool) -> Self {
|
||||||
pub enum AnonBoxPseudoElement {
|
if cfg!(debug_assertions) {
|
||||||
MozText,
|
match Self::from_atom(&*atom, true) {
|
||||||
MozOtherNonElement,
|
Some(pseudo) => {
|
||||||
MozAnonymousBlock,
|
assert_eq!(pseudo.is_anon_box(), is_anon_box);
|
||||||
MozAnonymousPositionedBlock,
|
return pseudo;
|
||||||
MozMathMLAnonymousBlock,
|
}
|
||||||
MozXULAnonymousBlock,
|
None => panic!("Unknown pseudo: {:?}", atom),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MozHorizontalFramesetBorder,
|
PseudoElement(atom, is_anon_box)
|
||||||
MozVerticalFramesetBorder,
|
}
|
||||||
MozLineFrame,
|
|
||||||
MozButtonContent,
|
|
||||||
MozButtonLabel,
|
|
||||||
MozCellContent,
|
|
||||||
MozDropdownList,
|
|
||||||
MozFieldsetContent,
|
|
||||||
MozFramesetBlank,
|
|
||||||
MozDisplayComboboxControlFrame,
|
|
||||||
|
|
||||||
MozHTMLCanvasContent,
|
#[inline]
|
||||||
MozInlineTable,
|
fn from_atom(atom: &WeakAtom, in_ua: bool) -> Option<Self> {
|
||||||
MozTable,
|
macro_rules! pseudo_element {
|
||||||
MozTableCell,
|
($pseudo_str_with_colon:expr, $atom:expr, $is_anon_box:expr) => {{
|
||||||
MozTableColumnGroup,
|
if atom == &*$atom {
|
||||||
MozTableColumn,
|
return Some(PseudoElement($atom, $is_anon_box));
|
||||||
MozTableWrapper,
|
}
|
||||||
MozTableRowGroup,
|
}}
|
||||||
MozTableRow,
|
}
|
||||||
|
|
||||||
MozCanvas,
|
include!("generated/gecko_pseudo_element_helper.rs");
|
||||||
MozPageBreak,
|
|
||||||
MozPage,
|
|
||||||
MozPageContent,
|
|
||||||
MozPageSequence,
|
|
||||||
MozScrolledContent,
|
|
||||||
MozScrolledCanvas,
|
|
||||||
MozScrolledPageSequence,
|
|
||||||
MozColumnContent,
|
|
||||||
MozViewport,
|
|
||||||
MozViewportScroll,
|
|
||||||
MozAnonymousFlexItem,
|
|
||||||
MozAnonymousGridItem,
|
|
||||||
|
|
||||||
MozRuby,
|
None
|
||||||
MozRubyBase,
|
}
|
||||||
MozRubyBaseContainer,
|
|
||||||
MozRubyText,
|
|
||||||
MozRubyTextContainer,
|
|
||||||
|
|
||||||
MozTreeColumn,
|
#[inline]
|
||||||
MozTreeRow,
|
fn from_slice(s: &str, in_ua_stylesheet: bool) -> Option<Self> {
|
||||||
MozTreeSeparator,
|
use std::ascii::AsciiExt;
|
||||||
MozTreeCell,
|
macro_rules! pseudo_element {
|
||||||
MozTreeIndentation,
|
($pseudo_str_with_colon:expr, $atom:expr, $is_anon_box:expr) => {{
|
||||||
MozTreeLine,
|
if !$is_anon_box || in_ua_stylesheet {
|
||||||
MozTreeTwisty,
|
if s.eq_ignore_ascii_case(&$pseudo_str_with_colon[1..]) {
|
||||||
MozTreeImage,
|
return Some(PseudoElement($atom, $is_anon_box))
|
||||||
MozTreeCellText,
|
}
|
||||||
MozTreeCheckbox,
|
}
|
||||||
MozTreeProgressMeter,
|
}}
|
||||||
MozTreeDropFeedback,
|
}
|
||||||
|
|
||||||
MozSVGMarkerAnonChild,
|
include!("generated/gecko_pseudo_element_helper.rs");
|
||||||
MozSVGOuterSVGAnonChild,
|
|
||||||
MozSVGForeignContent,
|
None
|
||||||
MozSVGText,
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
@ -194,211 +171,44 @@ impl SelectorImpl for GeckoSelectorImpl {
|
||||||
|
|
||||||
fn parse_pseudo_element(context: &ParserContext<Self>,
|
fn parse_pseudo_element(context: &ParserContext<Self>,
|
||||||
name: &str) -> Result<PseudoElement, ()> {
|
name: &str) -> Result<PseudoElement, ()> {
|
||||||
use self::AnonBoxPseudoElement::*;
|
match PseudoElement::from_slice(name, context.in_user_agent_stylesheet) {
|
||||||
use self::PseudoElement::*;
|
Some(pseudo) => Ok(pseudo),
|
||||||
|
None => Err(()),
|
||||||
// The braces here are unfortunate, but they're needed for
|
|
||||||
// match_ignore_ascii_case! to work as expected.
|
|
||||||
match_ignore_ascii_case! { name,
|
|
||||||
"before" => { return Ok(Before) },
|
|
||||||
"after" => { return Ok(After) },
|
|
||||||
"first-line" => { return Ok(FirstLine) },
|
|
||||||
"backdrop" => { return Ok(Backdrop) },
|
|
||||||
"first-letter" => { return Ok(FirstLetter) },
|
|
||||||
"first-line" => { return Ok(FirstLine) },
|
|
||||||
"-moz-selection" => { return Ok(MozSelection) },
|
|
||||||
"-moz-focus-inner" => { return Ok(MozFocusInner) },
|
|
||||||
"-moz-focus-outer" => { return Ok(MozFocusOuter) },
|
|
||||||
"-moz-list-bullet" => { return Ok(MozListBullet) },
|
|
||||||
"-moz-list-number" => { return Ok(MozListNumber) },
|
|
||||||
"-moz-math-anonymous" => { return Ok(MozMathAnonymous) },
|
|
||||||
"-moz-number-wrapper" => { return Ok(MozNumberWrapper) },
|
|
||||||
"-moz-number-text" => { return Ok(MozNumberText) },
|
|
||||||
"-moz-number-spin-box" => { return Ok(MozNumberSpinBox) },
|
|
||||||
"-moz-number-spin-up" => { return Ok(MozNumberSpinUp) },
|
|
||||||
"-moz-number-spin-down" => { return Ok(MozNumberSpinDown) },
|
|
||||||
"-moz-progress-bar" => { return Ok(MozProgressBar) },
|
|
||||||
"-moz-range-track" => { return Ok(MozRangeTrack) },
|
|
||||||
"-moz-range-progress" => { return Ok(MozRangeProgress) },
|
|
||||||
"-moz-range-thumb" => { return Ok(MozRangeThumb) },
|
|
||||||
"-moz-metter-bar" => { return Ok(MozMeterBar) },
|
|
||||||
"-moz-placeholder" => { return Ok(MozPlaceholder) },
|
|
||||||
"-moz-color-swatch" => { return Ok(MozColorSwatch) },
|
|
||||||
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !context.in_user_agent_stylesheet {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(AnonBox(match_ignore_ascii_case! { name,
|
|
||||||
"-moz-text" => MozText,
|
|
||||||
"-moz-other-non-element" => MozOtherNonElement,
|
|
||||||
|
|
||||||
"-moz-anonymous-block" => MozAnonymousBlock,
|
|
||||||
"-moz-anonymous-positioned-block" => MozAnonymousPositionedBlock,
|
|
||||||
"-moz-mathml-anonymous-block" => MozMathMLAnonymousBlock,
|
|
||||||
"-moz-xul-anonymous-block" => MozXULAnonymousBlock,
|
|
||||||
|
|
||||||
"-moz-hframeset-border" => MozHorizontalFramesetBorder,
|
|
||||||
"-moz-vframeset-border" => MozVerticalFramesetBorder,
|
|
||||||
|
|
||||||
"-moz-line-frame" => MozLineFrame,
|
|
||||||
|
|
||||||
"-moz-button-content" => MozButtonContent,
|
|
||||||
"-moz-buttonlabel" => MozButtonLabel,
|
|
||||||
"-moz-cell-content" => MozCellContent,
|
|
||||||
"-moz-dropdown-list" => MozDropdownList,
|
|
||||||
"-moz-fieldset-content" => MozFieldsetContent,
|
|
||||||
"-moz-frameset-blank" => MozFramesetBlank,
|
|
||||||
"-moz-display-comboboxcontrol-frame" => MozDisplayComboboxControlFrame,
|
|
||||||
"-moz-html-canvas-content" => MozHTMLCanvasContent,
|
|
||||||
|
|
||||||
"-moz-inline-table" => MozInlineTable,
|
|
||||||
"-moz-table" => MozTable,
|
|
||||||
"-moz-table-cell" => MozTableCell,
|
|
||||||
"-moz-table-column-group" => MozTableColumnGroup,
|
|
||||||
"-moz-table-column" => MozTableColumn,
|
|
||||||
"-moz-table-wrapper" => MozTableWrapper,
|
|
||||||
"-moz-table-row-group" => MozTableRowGroup,
|
|
||||||
"-moz-table-row" => MozTableRow,
|
|
||||||
|
|
||||||
"-moz-canvas" => MozCanvas,
|
|
||||||
"-moz-pagebreak" => MozPageBreak,
|
|
||||||
"-moz-page" => MozPage,
|
|
||||||
"-moz-pagecontent" => MozPageContent,
|
|
||||||
"-moz-page-sequence" => MozPageSequence,
|
|
||||||
"-moz-scrolled-content" => MozScrolledContent,
|
|
||||||
"-moz-scrolled-canvas" => MozScrolledCanvas,
|
|
||||||
"-moz-scrolled-page-sequence" => MozScrolledPageSequence,
|
|
||||||
"-moz-column-content" => MozColumnContent,
|
|
||||||
"-moz-viewport" => MozViewport,
|
|
||||||
"-moz-viewport-scroll" => MozViewportScroll,
|
|
||||||
"-moz-anonymous-flex-item" => MozAnonymousFlexItem,
|
|
||||||
"-moz-anonymous-grid-item" => MozAnonymousGridItem,
|
|
||||||
"-moz-ruby" => MozRuby,
|
|
||||||
"-moz-ruby-base" => MozRubyBase,
|
|
||||||
"-moz-ruby-base-container" => MozRubyBaseContainer,
|
|
||||||
"-moz-ruby-text" => MozRubyText,
|
|
||||||
"-moz-ruby-text-container" => MozRubyTextContainer,
|
|
||||||
"-moz-tree-column" => MozTreeColumn,
|
|
||||||
"-moz-tree-row" => MozTreeRow,
|
|
||||||
"-moz-tree-separator" => MozTreeSeparator,
|
|
||||||
"-moz-tree-cell" => MozTreeCell,
|
|
||||||
"-moz-tree-indentation" => MozTreeIndentation,
|
|
||||||
"-moz-tree-line" => MozTreeLine,
|
|
||||||
"-moz-tree-twisty" => MozTreeTwisty,
|
|
||||||
"-moz-tree-image" => MozTreeImage,
|
|
||||||
"-moz-tree-cell-text" => MozTreeCellText,
|
|
||||||
"-moz-tree-checkbox" => MozTreeCheckbox,
|
|
||||||
"-moz-tree-progressmeter" => MozTreeProgressMeter,
|
|
||||||
"-moz-tree-drop-feedback" => MozTreeDropFeedback,
|
|
||||||
"-moz-svg-marker-anon-child" => MozSVGMarkerAnonChild,
|
|
||||||
"-moz-svg-outer-svg-anon-child" => MozSVGOuterSVGAnonChild,
|
|
||||||
"-moz-svg-foreign-content" => MozSVGForeignContent,
|
|
||||||
"-moz-svg-text" => MozSVGText,
|
|
||||||
|
|
||||||
_ => return Err(())
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GeckoSelectorImpl {
|
impl GeckoSelectorImpl {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
|
pub fn pseudo_element_cascade_type(pseudo: &PseudoElement) -> PseudoElementCascadeType {
|
||||||
match *pseudo {
|
if Self::pseudo_is_before_or_after(pseudo) {
|
||||||
PseudoElement::Before |
|
return PseudoElementCascadeType::Eager
|
||||||
PseudoElement::After => PseudoElementCascadeType::Eager,
|
|
||||||
PseudoElement::AnonBox(_) => PseudoElementCascadeType::Precomputed,
|
|
||||||
_ => PseudoElementCascadeType::Lazy,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pseudo.is_anon_box() {
|
||||||
|
return PseudoElementCascadeType::Precomputed
|
||||||
|
}
|
||||||
|
|
||||||
|
PseudoElementCascadeType::Lazy
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn each_pseudo_element<F>(mut fun: F)
|
pub fn each_pseudo_element<F>(mut fun: F)
|
||||||
where F: FnMut(PseudoElement) {
|
where F: FnMut(PseudoElement)
|
||||||
use self::AnonBoxPseudoElement::*;
|
{
|
||||||
use self::PseudoElement::*;
|
macro_rules! pseudo_element {
|
||||||
|
($pseudo_str_with_colon:expr, $atom:expr, $is_anon_box:expr) => {{
|
||||||
|
fun(PseudoElement($atom, $is_anon_box));
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
fun(Before);
|
include!("generated/gecko_pseudo_element_helper.rs")
|
||||||
fun(After);
|
|
||||||
fun(FirstLine);
|
|
||||||
|
|
||||||
fun(AnonBox(MozText));
|
|
||||||
fun(AnonBox(MozOtherNonElement));
|
|
||||||
fun(AnonBox(MozAnonymousBlock));
|
|
||||||
fun(AnonBox(MozAnonymousPositionedBlock));
|
|
||||||
fun(AnonBox(MozMathMLAnonymousBlock));
|
|
||||||
fun(AnonBox(MozXULAnonymousBlock));
|
|
||||||
|
|
||||||
fun(AnonBox(MozHorizontalFramesetBorder));
|
|
||||||
fun(AnonBox(MozVerticalFramesetBorder));
|
|
||||||
fun(AnonBox(MozLineFrame));
|
|
||||||
fun(AnonBox(MozButtonContent));
|
|
||||||
fun(AnonBox(MozButtonLabel));
|
|
||||||
fun(AnonBox(MozCellContent));
|
|
||||||
fun(AnonBox(MozDropdownList));
|
|
||||||
fun(AnonBox(MozFieldsetContent));
|
|
||||||
fun(AnonBox(MozFramesetBlank));
|
|
||||||
fun(AnonBox(MozDisplayComboboxControlFrame));
|
|
||||||
|
|
||||||
fun(AnonBox(MozHTMLCanvasContent));
|
|
||||||
fun(AnonBox(MozInlineTable));
|
|
||||||
fun(AnonBox(MozTable));
|
|
||||||
fun(AnonBox(MozTableCell));
|
|
||||||
fun(AnonBox(MozTableColumnGroup));
|
|
||||||
fun(AnonBox(MozTableColumn));
|
|
||||||
fun(AnonBox(MozTableWrapper));
|
|
||||||
fun(AnonBox(MozTableRowGroup));
|
|
||||||
fun(AnonBox(MozTableRow));
|
|
||||||
|
|
||||||
fun(AnonBox(MozCanvas));
|
|
||||||
fun(AnonBox(MozPageBreak));
|
|
||||||
fun(AnonBox(MozPage));
|
|
||||||
fun(AnonBox(MozPageContent));
|
|
||||||
fun(AnonBox(MozPageSequence));
|
|
||||||
fun(AnonBox(MozScrolledContent));
|
|
||||||
fun(AnonBox(MozScrolledCanvas));
|
|
||||||
fun(AnonBox(MozScrolledPageSequence));
|
|
||||||
fun(AnonBox(MozColumnContent));
|
|
||||||
fun(AnonBox(MozViewport));
|
|
||||||
fun(AnonBox(MozViewportScroll));
|
|
||||||
fun(AnonBox(MozAnonymousFlexItem));
|
|
||||||
fun(AnonBox(MozAnonymousGridItem));
|
|
||||||
|
|
||||||
fun(AnonBox(MozRuby));
|
|
||||||
fun(AnonBox(MozRubyBase));
|
|
||||||
fun(AnonBox(MozRubyBaseContainer));
|
|
||||||
fun(AnonBox(MozRubyText));
|
|
||||||
fun(AnonBox(MozRubyTextContainer));
|
|
||||||
|
|
||||||
fun(AnonBox(MozTreeColumn));
|
|
||||||
fun(AnonBox(MozTreeRow));
|
|
||||||
fun(AnonBox(MozTreeSeparator));
|
|
||||||
fun(AnonBox(MozTreeCell));
|
|
||||||
fun(AnonBox(MozTreeIndentation));
|
|
||||||
fun(AnonBox(MozTreeLine));
|
|
||||||
fun(AnonBox(MozTreeTwisty));
|
|
||||||
fun(AnonBox(MozTreeImage));
|
|
||||||
fun(AnonBox(MozTreeCellText));
|
|
||||||
fun(AnonBox(MozTreeCheckbox));
|
|
||||||
fun(AnonBox(MozTreeProgressMeter));
|
|
||||||
fun(AnonBox(MozTreeDropFeedback));
|
|
||||||
|
|
||||||
fun(AnonBox(MozSVGMarkerAnonChild));
|
|
||||||
fun(AnonBox(MozSVGOuterSVGAnonChild));
|
|
||||||
fun(AnonBox(MozSVGForeignContent));
|
|
||||||
fun(AnonBox(MozSVGText));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
|
pub fn pseudo_is_before_or_after(pseudo: &PseudoElement) -> bool {
|
||||||
match *pseudo {
|
*pseudo.as_atom() == atom!(":before") ||
|
||||||
PseudoElement::Before |
|
*pseudo.as_atom() == atom!(":after")
|
||||||
PseudoElement::After => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -42,3 +42,28 @@ fn assert_restyle_hints_match() {
|
||||||
check_enum_value_non_static!(nsRestyleHint::eRestyle_SomeDescendants, RESTYLE_DESCENDANTS.bits());
|
check_enum_value_non_static!(nsRestyleHint::eRestyle_SomeDescendants, RESTYLE_DESCENDANTS.bits());
|
||||||
check_enum_value_non_static!(nsRestyleHint::eRestyle_LaterSiblings, RESTYLE_LATER_SIBLINGS.bits());
|
check_enum_value_non_static!(nsRestyleHint::eRestyle_LaterSiblings, RESTYLE_LATER_SIBLINGS.bits());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that we can't call each_pseudo_element, parse_pseudo_element, or
|
||||||
|
// similar, because we'd need the foreign atom symbols to link.
|
||||||
|
#[test]
|
||||||
|
fn assert_basic_pseudo_elements() {
|
||||||
|
let mut saw_before = false;
|
||||||
|
let mut saw_after = false;
|
||||||
|
|
||||||
|
macro_rules! pseudo_element {
|
||||||
|
(":before", $atom:expr, false) => {
|
||||||
|
saw_before = true;
|
||||||
|
};
|
||||||
|
(":after", $atom:expr, false) => {
|
||||||
|
saw_after = true;
|
||||||
|
};
|
||||||
|
($pseudo_str_with_colon:expr, $atom:expr, $is_anon_box:expr) => {
|
||||||
|
// Do nothing
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
include!("../../components/style/generated/gecko_pseudo_element_helper.rs");
|
||||||
|
|
||||||
|
assert!(saw_before);
|
||||||
|
assert!(saw_after);
|
||||||
|
}
|
||||||
|
|
|
@ -134,6 +134,21 @@ impl WeakAtom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for WeakAtom {
|
||||||
|
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(w, "Gecko WeakAtom({:p}, {})", self, self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for WeakAtom {
|
||||||
|
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
for c in self.chars() {
|
||||||
|
try!(write!(w, "{}", c.unwrap_or(char::REPLACEMENT_CHARACTER)))
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Atom {
|
impl Atom {
|
||||||
pub unsafe fn with<F>(ptr: *mut nsIAtom, callback: &mut F) where F: FnMut(&Atom) {
|
pub unsafe fn with<F>(ptr: *mut nsIAtom, callback: &mut F) where F: FnMut(&Atom) {
|
||||||
let atom = Atom(WeakAtom::new(ptr));
|
let atom = Atom(WeakAtom::new(ptr));
|
||||||
|
@ -217,16 +232,15 @@ impl Deserialize for Atom {
|
||||||
|
|
||||||
impl fmt::Debug for Atom {
|
impl fmt::Debug for Atom {
|
||||||
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(w, "Gecko Atom {:p}", self.0)
|
write!(w, "Gecko Atom({:p}, {})", self.0, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Atom {
|
impl fmt::Display for Atom {
|
||||||
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
|
||||||
for c in self.chars() {
|
unsafe {
|
||||||
try!(write!(w, "{}", c.unwrap_or(char::REPLACEMENT_CHARACTER)))
|
(&*self.0).fmt(w)
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue