mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
stylo: Implement remaining content
values
MozReview-Commit-ID: 9fLM5bdR8hr
This commit is contained in:
parent
77d7490d59
commit
07723eba7a
5 changed files with 155 additions and 21 deletions
|
@ -574,6 +574,8 @@ mod bindings {
|
|||
"nsStyleColor",
|
||||
"nsStyleColumn",
|
||||
"nsStyleContent",
|
||||
"nsStyleContentData",
|
||||
"nsStyleContentType",
|
||||
"nsStyleContext",
|
||||
"nsStyleCoord",
|
||||
"nsStyleCoord_Calc",
|
||||
|
|
|
@ -56,6 +56,12 @@ unsafe impl Sync for nsStyleColumn {}
|
|||
use gecko_bindings::structs::nsStyleContent;
|
||||
unsafe impl Send for nsStyleContent {}
|
||||
unsafe impl Sync for nsStyleContent {}
|
||||
use gecko_bindings::structs::nsStyleContentData;
|
||||
unsafe impl Send for nsStyleContentData {}
|
||||
unsafe impl Sync for nsStyleContentData {}
|
||||
use gecko_bindings::structs::nsStyleContentType;
|
||||
unsafe impl Send for nsStyleContentType {}
|
||||
unsafe impl Sync for nsStyleContentType {}
|
||||
use gecko_bindings::structs::nsStyleContext;
|
||||
unsafe impl Send for nsStyleContext {}
|
||||
unsafe impl Sync for nsStyleContext {}
|
||||
|
@ -665,6 +671,14 @@ extern "C" {
|
|||
pub fn Gecko_CopyCursorArrayFrom(dest: *mut nsStyleUserInterface,
|
||||
src: *const nsStyleUserInterface);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetContentDataImage(content_data: *mut nsStyleContentData,
|
||||
uri: ServoBundledURI);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetContentDataArray(content_data: *mut nsStyleContentData,
|
||||
type_: nsStyleContentType, len: u32);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_GetNodeFlags(node: RawGeckoNodeBorrowed) -> u32;
|
||||
}
|
||||
|
@ -892,7 +906,11 @@ extern "C" {
|
|||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_SetString(css_value: nsCSSValueBorrowedMut,
|
||||
string: nsString);
|
||||
string: *const u8, len: u32);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_SetIdent(css_value: nsCSSValueBorrowedMut,
|
||||
string: *const u8, len: u32);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_SetArray(css_value: nsCSSValueBorrowedMut,
|
||||
|
|
|
@ -5,18 +5,13 @@
|
|||
//! Little helpers for `nsCSSValue`.
|
||||
|
||||
use app_units::Au;
|
||||
use gecko_bindings::bindings::Gecko_CSSValue_Drop;
|
||||
use gecko_bindings::bindings::Gecko_CSSValue_GetAbsoluteLength;
|
||||
use gecko_bindings::bindings::Gecko_CSSValue_GetCalc;
|
||||
use gecko_bindings::bindings::Gecko_CSSValue_GetPercentage;
|
||||
use gecko_bindings::bindings::Gecko_CSSValue_SetAbsoluteLength;
|
||||
use gecko_bindings::bindings::Gecko_CSSValue_SetCalc;
|
||||
use gecko_bindings::bindings::Gecko_CSSValue_SetPercentage;
|
||||
use gecko_bindings::bindings;
|
||||
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit, nsCSSValue_Array, nscolor};
|
||||
use std::mem;
|
||||
use std::ops::Index;
|
||||
use std::ops::{Index, IndexMut};
|
||||
use std::slice;
|
||||
use values::computed::LengthOrPercentage;
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
|
||||
impl nsCSSValue {
|
||||
/// Create a CSSValue with null unit, useful to be used as a return value.
|
||||
|
@ -77,13 +72,13 @@ impl nsCSSValue {
|
|||
pub unsafe fn set_lop(&mut self, lop: LengthOrPercentage) {
|
||||
match lop {
|
||||
LengthOrPercentage::Length(au) => {
|
||||
Gecko_CSSValue_SetAbsoluteLength(self, au.0)
|
||||
bindings::Gecko_CSSValue_SetAbsoluteLength(self, au.0)
|
||||
}
|
||||
LengthOrPercentage::Percentage(pc) => {
|
||||
Gecko_CSSValue_SetPercentage(self, pc)
|
||||
bindings::Gecko_CSSValue_SetPercentage(self, pc)
|
||||
}
|
||||
LengthOrPercentage::Calc(calc) => {
|
||||
Gecko_CSSValue_SetCalc(self, calc.into())
|
||||
bindings::Gecko_CSSValue_SetCalc(self, calc.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,27 +87,47 @@ impl nsCSSValue {
|
|||
pub unsafe fn get_lop(&self) -> LengthOrPercentage {
|
||||
match self.mUnit {
|
||||
nsCSSUnit::eCSSUnit_Pixel => {
|
||||
LengthOrPercentage::Length(Au(Gecko_CSSValue_GetAbsoluteLength(self)))
|
||||
LengthOrPercentage::Length(Au(bindings::Gecko_CSSValue_GetAbsoluteLength(self)))
|
||||
},
|
||||
nsCSSUnit::eCSSUnit_Percent => {
|
||||
LengthOrPercentage::Percentage(Gecko_CSSValue_GetPercentage(self))
|
||||
LengthOrPercentage::Percentage(bindings::Gecko_CSSValue_GetPercentage(self))
|
||||
},
|
||||
nsCSSUnit::eCSSUnit_Calc => {
|
||||
LengthOrPercentage::Calc(Gecko_CSSValue_GetCalc(self).into())
|
||||
LengthOrPercentage::Calc(bindings::Gecko_CSSValue_GetCalc(self).into())
|
||||
},
|
||||
x => panic!("The unit should not be {:?}", x),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set to a string value
|
||||
pub fn set_string(&mut self, s: &str) {
|
||||
unsafe { bindings::Gecko_CSSValue_SetString(self, s.as_ptr(), s.len() as u32) }
|
||||
}
|
||||
|
||||
/// Set to an identifier value
|
||||
pub fn set_ident(&mut self, s: &str) {
|
||||
unsafe { bindings::Gecko_CSSValue_SetIdent(self, s.as_ptr(), s.len() as u32) }
|
||||
}
|
||||
|
||||
/// Set to a url value
|
||||
pub fn set_url(&mut self, url: &SpecifiedUrl) {
|
||||
unsafe { bindings::Gecko_CSSValue_SetURL(self, url.for_ffi()) }
|
||||
}
|
||||
|
||||
/// Set to an array of given length
|
||||
pub fn set_array(&mut self, len: i32) {
|
||||
unsafe { bindings::Gecko_CSSValue_SetArray(self, len) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for nsCSSValue {
|
||||
fn drop(&mut self) {
|
||||
unsafe { Gecko_CSSValue_Drop(self) };
|
||||
unsafe { bindings::Gecko_CSSValue_Drop(self) };
|
||||
}
|
||||
}
|
||||
|
||||
impl nsCSSValue_Array {
|
||||
/// Return the length of this `nsCSSShadowArray`
|
||||
/// Return the length of this `nsCSSValue::Array`
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.mCount
|
||||
|
@ -128,6 +143,12 @@ impl nsCSSValue_Array {
|
|||
pub fn as_slice(&self) -> &[nsCSSValue] {
|
||||
unsafe { slice::from_raw_parts(self.buffer(), self.len()) }
|
||||
}
|
||||
|
||||
/// Get the array as a mutable slice of nsCSSValues.
|
||||
#[inline]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [nsCSSValue] {
|
||||
unsafe { slice::from_raw_parts_mut(self.buffer() as *mut _, self.len()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<usize> for nsCSSValue_Array {
|
||||
|
@ -137,3 +158,11 @@ impl Index<usize> for nsCSSValue_Array {
|
|||
&self.as_slice()[i]
|
||||
}
|
||||
}
|
||||
|
||||
impl IndexMut<usize> for nsCSSValue_Array {
|
||||
#[inline]
|
||||
fn index_mut(&mut self, i: usize) -> &mut nsCSSValue {
|
||||
&mut self.as_mut_slice()[i]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3190,6 +3190,7 @@ clip-path
|
|||
pub fn set_content(&mut self, v: longhands::content::computed_value::T) {
|
||||
use properties::longhands::content::computed_value::T;
|
||||
use properties::longhands::content::computed_value::ContentItem;
|
||||
use style_traits::ToCss;
|
||||
use gecko_bindings::structs::nsStyleContentType::*;
|
||||
use gecko_bindings::bindings::Gecko_ClearAndResizeStyleContents;
|
||||
|
||||
|
@ -3219,7 +3220,6 @@ clip-path
|
|||
items.len() as u32);
|
||||
}
|
||||
for (i, item) in items.into_iter().enumerate() {
|
||||
// TODO: Servo lacks support for attr(), and URIs.
|
||||
// NB: Gecko compares the mString value if type is not image
|
||||
// or URI independently of whatever gets there. In the quote
|
||||
// cases, they set it to null, so do the same here.
|
||||
|
@ -3235,6 +3235,19 @@ clip-path
|
|||
as_utf16_and_forget(&value);
|
||||
}
|
||||
}
|
||||
ContentItem::Attr(ns, val) => {
|
||||
self.gecko.mContents[i].mType = eStyleContentType_Attr;
|
||||
let s = if let Some(ns) = ns {
|
||||
format!("{}|{}", ns, val)
|
||||
} else {
|
||||
val
|
||||
};
|
||||
unsafe {
|
||||
// NB: we share allocators, so doing this is fine.
|
||||
*self.gecko.mContents[i].mContent.mString.as_mut() =
|
||||
as_utf16_and_forget(&s);
|
||||
}
|
||||
}
|
||||
ContentItem::OpenQuote
|
||||
=> self.gecko.mContents[i].mType = eStyleContentType_OpenQuote,
|
||||
ContentItem::CloseQuote
|
||||
|
@ -3245,9 +3258,30 @@ clip-path
|
|||
=> self.gecko.mContents[i].mType = eStyleContentType_NoCloseQuote,
|
||||
ContentItem::MozAltContent
|
||||
=> self.gecko.mContents[i].mType = eStyleContentType_AltContent,
|
||||
ContentItem::Counter(..) |
|
||||
ContentItem::Counters(..)
|
||||
=> self.gecko.mContents[i].mType = eStyleContentType_Uninitialized,
|
||||
ContentItem::Counter(name, style) => {
|
||||
unsafe {
|
||||
bindings::Gecko_SetContentDataArray(&mut self.gecko.mContents[i],
|
||||
eStyleContentType_Counter, 2)
|
||||
}
|
||||
let mut array = unsafe { &mut **self.gecko.mContents[i].mContent.mCounters.as_mut() };
|
||||
array[0].set_string(&name);
|
||||
// When we support <custom-ident> values for list-style-type this will need to be updated
|
||||
array[1].set_ident(&style.to_css_string());
|
||||
}
|
||||
ContentItem::Counters(name, sep, style) => {
|
||||
unsafe {
|
||||
bindings::Gecko_SetContentDataArray(&mut self.gecko.mContents[i],
|
||||
eStyleContentType_Counters, 3)
|
||||
}
|
||||
let mut array = unsafe { &mut **self.gecko.mContents[i].mContent.mCounters.as_mut() };
|
||||
array[0].set_string(&name);
|
||||
array[1].set_string(&sep);
|
||||
// When we support <custom-ident> values for list-style-type this will need to be updated
|
||||
array[2].set_ident(&style.to_css_string());
|
||||
}
|
||||
ContentItem::Url(url) => {
|
||||
unsafe { bindings::Gecko_SetContentDataImage(&mut self.gecko.mContents[i], url.for_ffi()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
use cssparser::Token;
|
||||
use std::ascii::AsciiExt;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
use values::HasViewportPercentage;
|
||||
|
||||
use super::list_style_type;
|
||||
|
@ -26,6 +27,7 @@
|
|||
use cssparser;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
|
@ -48,6 +50,10 @@
|
|||
% if product == "gecko":
|
||||
/// `-moz-alt-content`
|
||||
MozAltContent,
|
||||
/// `attr([namespace? `|`]? ident)`
|
||||
Attr(Option<String>, String),
|
||||
/// `url(url)`
|
||||
Url(SpecifiedUrl),
|
||||
% endif
|
||||
}
|
||||
|
||||
|
@ -80,6 +86,16 @@
|
|||
|
||||
% if product == "gecko":
|
||||
ContentItem::MozAltContent => dest.write_str("-moz-alt-content"),
|
||||
ContentItem::Attr(ref ns, ref attr) => {
|
||||
dest.write_str("attr(")?;
|
||||
if let Some(ref ns) = *ns {
|
||||
cssparser::Token::Ident((&**ns).into()).to_css(dest)?;
|
||||
dest.write_str("|")?;
|
||||
}
|
||||
cssparser::Token::Ident((&**attr).into()).to_css(dest)?;
|
||||
dest.write_str(")")
|
||||
}
|
||||
ContentItem::Url(ref url) => url.to_css(dest),
|
||||
% endif
|
||||
}
|
||||
}
|
||||
|
@ -135,6 +151,12 @@
|
|||
}
|
||||
let mut content = vec![];
|
||||
loop {
|
||||
% if product == "gecko":
|
||||
if let Ok(url) = input.try(|i| SpecifiedUrl::parse(context, i)) {
|
||||
content.push(ContentItem::Url(url));
|
||||
continue;
|
||||
}
|
||||
% endif
|
||||
match input.next() {
|
||||
Ok(Token::QuotedString(value)) => {
|
||||
content.push(ContentItem::String(value.into_owned()))
|
||||
|
@ -159,6 +181,35 @@
|
|||
}).unwrap_or(list_style_type::computed_value::T::decimal);
|
||||
Ok(ContentItem::Counters(name, separator, style))
|
||||
}),
|
||||
% if product == "gecko":
|
||||
"attr" => input.parse_nested_block(|input| {
|
||||
// Syntax is `[namespace? `|`]? ident`
|
||||
// no spaces allowed
|
||||
// FIXME (bug 1346693) we should be checking that
|
||||
// this is a valid namespace and encoding it as a namespace
|
||||
// number from the map
|
||||
let first = input.try(|i| i.expect_ident()).ok().map(|i| i.into_owned());
|
||||
if let Ok(token) = input.try(|i| i.next_including_whitespace()) {
|
||||
match token {
|
||||
Token::Delim('|') => {
|
||||
// must be followed by an ident
|
||||
let tok2 = input.next_including_whitespace()?;
|
||||
if let Token::Ident(second) = tok2 {
|
||||
return Ok(ContentItem::Attr(first, second.into_owned()))
|
||||
} else {
|
||||
return Err(())
|
||||
}
|
||||
}
|
||||
_ => return Err(())
|
||||
}
|
||||
}
|
||||
if let Some(first) = first {
|
||||
Ok(ContentItem::Attr(None, first))
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}),
|
||||
% endif
|
||||
_ => return Err(())
|
||||
}));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue