mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #15939 - Manishearth:stylo-content-counter, r=heycam
stylo: support all content values r=heycam https://bugzilla.mozilla.org/show_bug.cgi?id=1296477 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/15939) <!-- Reviewable:end -->
This commit is contained in:
commit
628cd7de6d
7 changed files with 234 additions and 86 deletions
|
@ -574,6 +574,8 @@ mod bindings {
|
||||||
"nsStyleColor",
|
"nsStyleColor",
|
||||||
"nsStyleColumn",
|
"nsStyleColumn",
|
||||||
"nsStyleContent",
|
"nsStyleContent",
|
||||||
|
"nsStyleContentData",
|
||||||
|
"nsStyleContentType",
|
||||||
"nsStyleContext",
|
"nsStyleContext",
|
||||||
"nsStyleCoord",
|
"nsStyleCoord",
|
||||||
"nsStyleCoord_Calc",
|
"nsStyleCoord_Calc",
|
||||||
|
|
|
@ -106,26 +106,17 @@ impl nsStyleImage {
|
||||||
self.set_gradient(gradient)
|
self.set_gradient(gradient)
|
||||||
},
|
},
|
||||||
Image::Url(ref url) if with_url => {
|
Image::Url(ref url) if with_url => {
|
||||||
let (ptr, len) = match url.as_slice_components() {
|
|
||||||
Ok(value) | Err(value) => value
|
|
||||||
};
|
|
||||||
let extra_data = url.extra_data();
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_SetUrlImageValue(self,
|
Gecko_SetUrlImageValue(self, url.for_ffi());
|
||||||
ptr,
|
// We unfortunately must make any url() value uncacheable, since
|
||||||
len as u32,
|
// the applicable declarations cache is not per document, but
|
||||||
extra_data.base.get(),
|
// global, and the imgRequestProxy objects we store in the style
|
||||||
extra_data.referrer.get(),
|
// structs don't like to be tracked by more than one document.
|
||||||
extra_data.principal.get());
|
//
|
||||||
|
// FIXME(emilio): With the scoped TLS thing this is no longer
|
||||||
|
// true, remove this line in a follow-up!
|
||||||
|
*cacheable = false;
|
||||||
}
|
}
|
||||||
// We unfortunately must make any url() value uncacheable, since
|
|
||||||
// the applicable declarations cache is not per document, but
|
|
||||||
// global, and the imgRequestProxy objects we store in the style
|
|
||||||
// structs don't like to be tracked by more than one document.
|
|
||||||
//
|
|
||||||
// FIXME(emilio): With the scoped TLS thing this is no longer
|
|
||||||
// true, remove this line in a follow-up!
|
|
||||||
*cacheable = false;
|
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,12 @@ unsafe impl Sync for nsStyleColumn {}
|
||||||
use gecko_bindings::structs::nsStyleContent;
|
use gecko_bindings::structs::nsStyleContent;
|
||||||
unsafe impl Send for nsStyleContent {}
|
unsafe impl Send for nsStyleContent {}
|
||||||
unsafe impl Sync 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;
|
use gecko_bindings::structs::nsStyleContext;
|
||||||
unsafe impl Send for nsStyleContext {}
|
unsafe impl Send for nsStyleContext {}
|
||||||
unsafe impl Sync for nsStyleContext {}
|
unsafe impl Sync for nsStyleContext {}
|
||||||
|
@ -631,10 +637,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_SetUrlImageValue(image: *mut nsStyleImage,
|
pub fn Gecko_SetUrlImageValue(image: *mut nsStyleImage,
|
||||||
url_bytes: *const u8, url_length: u32,
|
uri: ServoBundledURI);
|
||||||
base_uri: *mut ThreadSafeURIHolder,
|
|
||||||
referrer: *mut ThreadSafeURIHolder,
|
|
||||||
principal: *mut ThreadSafePrincipalHolder);
|
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_CopyImageValueFrom(image: *mut nsStyleImage,
|
pub fn Gecko_CopyImageValueFrom(image: *mut nsStyleImage,
|
||||||
|
@ -662,15 +665,20 @@ extern "C" {
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_SetCursorImage(cursor: *mut nsCursorImage,
|
pub fn Gecko_SetCursorImage(cursor: *mut nsCursorImage,
|
||||||
string_bytes: *const u8, string_length: u32,
|
uri: ServoBundledURI);
|
||||||
base_uri: *mut ThreadSafeURIHolder,
|
|
||||||
referrer: *mut ThreadSafeURIHolder,
|
|
||||||
principal: *mut ThreadSafePrincipalHolder);
|
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_CopyCursorArrayFrom(dest: *mut nsStyleUserInterface,
|
pub fn Gecko_CopyCursorArrayFrom(dest: *mut nsStyleUserInterface,
|
||||||
src: *const 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" {
|
extern "C" {
|
||||||
pub fn Gecko_GetNodeFlags(node: RawGeckoNodeBorrowed) -> u32;
|
pub fn Gecko_GetNodeFlags(node: RawGeckoNodeBorrowed) -> u32;
|
||||||
}
|
}
|
||||||
|
@ -709,10 +717,26 @@ extern "C" {
|
||||||
pub fn Gecko_ClearAndResizeStyleContents(content: *mut nsStyleContent,
|
pub fn Gecko_ClearAndResizeStyleContents(content: *mut nsStyleContent,
|
||||||
how_many: u32);
|
how_many: u32);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_ClearAndResizeCounterIncrements(content: *mut nsStyleContent,
|
||||||
|
how_many: u32);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_ClearAndResizeCounterResets(content: *mut nsStyleContent,
|
||||||
|
how_many: u32);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_CopyStyleContentsFrom(content: *mut nsStyleContent,
|
pub fn Gecko_CopyStyleContentsFrom(content: *mut nsStyleContent,
|
||||||
other: *const nsStyleContent);
|
other: *const nsStyleContent);
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_CopyCounterResetsFrom(content: *mut nsStyleContent,
|
||||||
|
other: *const nsStyleContent);
|
||||||
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn Gecko_CopyCounterIncrementsFrom(content: *mut nsStyleContent,
|
||||||
|
other: *const nsStyleContent);
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_EnsureImageLayersLength(layers: *mut nsStyleImageLayers,
|
pub fn Gecko_EnsureImageLayersLength(layers: *mut nsStyleImageLayers,
|
||||||
len: usize,
|
len: usize,
|
||||||
|
@ -898,7 +922,11 @@ extern "C" {
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn Gecko_CSSValue_SetString(css_value: nsCSSValueBorrowedMut,
|
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" {
|
extern "C" {
|
||||||
pub fn Gecko_CSSValue_SetArray(css_value: nsCSSValueBorrowedMut,
|
pub fn Gecko_CSSValue_SetArray(css_value: nsCSSValueBorrowedMut,
|
||||||
|
|
|
@ -5,18 +5,13 @@
|
||||||
//! Little helpers for `nsCSSValue`.
|
//! Little helpers for `nsCSSValue`.
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use gecko_bindings::bindings::Gecko_CSSValue_Drop;
|
use gecko_bindings::bindings;
|
||||||
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::structs::{nsCSSValue, nsCSSUnit, nsCSSValue_Array, nscolor};
|
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit, nsCSSValue_Array, nscolor};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Index;
|
use std::ops::{Index, IndexMut};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use values::computed::LengthOrPercentage;
|
use values::computed::LengthOrPercentage;
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
impl nsCSSValue {
|
impl nsCSSValue {
|
||||||
/// Create a CSSValue with null unit, useful to be used as a return value.
|
/// 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) {
|
pub unsafe fn set_lop(&mut self, lop: LengthOrPercentage) {
|
||||||
match lop {
|
match lop {
|
||||||
LengthOrPercentage::Length(au) => {
|
LengthOrPercentage::Length(au) => {
|
||||||
Gecko_CSSValue_SetAbsoluteLength(self, au.0)
|
bindings::Gecko_CSSValue_SetAbsoluteLength(self, au.0)
|
||||||
}
|
}
|
||||||
LengthOrPercentage::Percentage(pc) => {
|
LengthOrPercentage::Percentage(pc) => {
|
||||||
Gecko_CSSValue_SetPercentage(self, pc)
|
bindings::Gecko_CSSValue_SetPercentage(self, pc)
|
||||||
}
|
}
|
||||||
LengthOrPercentage::Calc(calc) => {
|
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 {
|
pub unsafe fn get_lop(&self) -> LengthOrPercentage {
|
||||||
match self.mUnit {
|
match self.mUnit {
|
||||||
nsCSSUnit::eCSSUnit_Pixel => {
|
nsCSSUnit::eCSSUnit_Pixel => {
|
||||||
LengthOrPercentage::Length(Au(Gecko_CSSValue_GetAbsoluteLength(self)))
|
LengthOrPercentage::Length(Au(bindings::Gecko_CSSValue_GetAbsoluteLength(self)))
|
||||||
},
|
},
|
||||||
nsCSSUnit::eCSSUnit_Percent => {
|
nsCSSUnit::eCSSUnit_Percent => {
|
||||||
LengthOrPercentage::Percentage(Gecko_CSSValue_GetPercentage(self))
|
LengthOrPercentage::Percentage(bindings::Gecko_CSSValue_GetPercentage(self))
|
||||||
},
|
},
|
||||||
nsCSSUnit::eCSSUnit_Calc => {
|
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),
|
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 {
|
impl Drop for nsCSSValue {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe { Gecko_CSSValue_Drop(self) };
|
unsafe { bindings::Gecko_CSSValue_Drop(self) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl nsCSSValue_Array {
|
impl nsCSSValue_Array {
|
||||||
/// Return the length of this `nsCSSShadowArray`
|
/// Return the length of this `nsCSSValue::Array`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.mCount
|
self.mCount
|
||||||
|
@ -128,6 +143,12 @@ impl nsCSSValue_Array {
|
||||||
pub fn as_slice(&self) -> &[nsCSSValue] {
|
pub fn as_slice(&self) -> &[nsCSSValue] {
|
||||||
unsafe { slice::from_raw_parts(self.buffer(), self.len()) }
|
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 {
|
impl Index<usize> for nsCSSValue_Array {
|
||||||
|
@ -137,3 +158,11 @@ impl Index<usize> for nsCSSValue_Array {
|
||||||
&self.as_slice()[i]
|
&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]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -394,11 +394,7 @@ fn color_to_nscolor_zero_currentcolor(color: Color) -> structs::nscolor {
|
||||||
}
|
}
|
||||||
SVGPaintKind::PaintServer(url) => {
|
SVGPaintKind::PaintServer(url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(ffi) = url.for_ffi() {
|
bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, url.for_ffi());
|
||||||
bindings::Gecko_nsStyleSVGPaint_SetURLValue(paint, ffi);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SVGPaintKind::Color(color) => {
|
SVGPaintKind::Color(color) => {
|
||||||
|
@ -511,20 +507,26 @@ fn color_to_nscolor_zero_currentcolor(color: Color) -> structs::nscolor {
|
||||||
% endif
|
% endif
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
<%def name="impl_css_url(ident, gecko_ffi_name, need_clone=False)">
|
<%def name="impl_css_url(ident, gecko_ffi_name, need_clone=False, only_resolved=False)">
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
pub fn set_${ident}(&mut self, v: longhands::${ident}::computed_value::T) {
|
||||||
use gecko_bindings::sugar::refptr::RefPtr;
|
use gecko_bindings::sugar::refptr::RefPtr;
|
||||||
match v {
|
match v {
|
||||||
Either::First(url) => {
|
Either::First(url) => {
|
||||||
let refptr = unsafe {
|
let refptr = unsafe {
|
||||||
if let Some(ffi) = url.for_ffi() {
|
% if only_resolved:
|
||||||
let ptr = bindings::Gecko_NewURLValue(ffi);
|
// -moz-binding can't handle relative URIs
|
||||||
RefPtr::from_addrefed(ptr)
|
if !url.has_resolved() {
|
||||||
} else {
|
self.gecko.${gecko_ffi_name}.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
% endif
|
||||||
|
let ptr = bindings::Gecko_NewURLValue(url.for_ffi());
|
||||||
|
if ptr.is_null() {
|
||||||
self.gecko.${gecko_ffi_name}.clear();
|
self.gecko.${gecko_ffi_name}.clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
RefPtr::from_addrefed(ptr)
|
||||||
};
|
};
|
||||||
self.gecko.${gecko_ffi_name}.set_move(refptr)
|
self.gecko.${gecko_ffi_name}.set_move(refptr)
|
||||||
}
|
}
|
||||||
|
@ -1423,7 +1425,7 @@ fn static_assert() {
|
||||||
page-break-before page-break-after
|
page-break-before page-break-after
|
||||||
scroll-snap-points-x scroll-snap-points-y transform
|
scroll-snap-points-x scroll-snap-points-y transform
|
||||||
scroll-snap-type-y scroll-snap-coordinate
|
scroll-snap-type-y scroll-snap-coordinate
|
||||||
perspective-origin transform-origin""" %>
|
perspective-origin transform-origin -moz-binding""" %>
|
||||||
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
|
<%self:impl_trait style_struct_name="Box" skip_longhands="${skip_box_longhands}">
|
||||||
|
|
||||||
// We manually-implement the |display| property until we get general
|
// We manually-implement the |display| property until we get general
|
||||||
|
@ -1611,6 +1613,8 @@ fn static_assert() {
|
||||||
longhands::scroll_snap_coordinate::computed_value::T(vec)
|
longhands::scroll_snap_coordinate::computed_value::T(vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${impl_css_url('_moz_binding', 'mBinding', only_resolved=True)}
|
||||||
|
|
||||||
<%def name="transform_function_arm(name, keyword, items)">
|
<%def name="transform_function_arm(name, keyword, items)">
|
||||||
<%
|
<%
|
||||||
pattern = None
|
pattern = None
|
||||||
|
@ -2281,12 +2285,8 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
Either::First(ref url) => {
|
Either::First(ref url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(ffi) = url.for_ffi() {
|
Gecko_SetListStyleImage(&mut self.gecko,
|
||||||
Gecko_SetListStyleImage(&mut self.gecko,
|
url.for_ffi());
|
||||||
ffi);
|
|
||||||
} else {
|
|
||||||
Gecko_SetListStyleImageNone(&mut self.gecko);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// We don't need to record this struct as uncacheable, like when setting
|
// We don't need to record this struct as uncacheable, like when setting
|
||||||
// background-image to a url() value, since only properties in reset structs
|
// background-image to a url() value, since only properties in reset structs
|
||||||
|
@ -2575,9 +2575,7 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
Url(ref url) => {
|
Url(ref url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(ffi) = url.for_ffi() {
|
bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, url.for_ffi());
|
||||||
bindings::Gecko_nsStyleFilter_SetURLValue(gecko_filter, ffi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2940,9 +2938,7 @@ clip-path
|
||||||
match v {
|
match v {
|
||||||
ShapeSource::Url(ref url) => {
|
ShapeSource::Url(ref url) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(ffi) = url.for_ffi() {
|
bindings::Gecko_StyleClipPath_SetURLValue(clip_path, url.for_ffi());
|
||||||
bindings::Gecko_StyleClipPath_SetURLValue(clip_path, ffi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ShapeSource::None => {} // don't change the type
|
ShapeSource::None => {} // don't change the type
|
||||||
|
@ -3150,16 +3146,8 @@ clip-path
|
||||||
}
|
}
|
||||||
for i in 0..v.images.len() {
|
for i in 0..v.images.len() {
|
||||||
let image = &v.images[i];
|
let image = &v.images[i];
|
||||||
let extra_data = image.url.extra_data();
|
|
||||||
let (ptr, len) = match image.url.as_slice_components() {
|
|
||||||
Ok(value) | Err(value) => value,
|
|
||||||
};
|
|
||||||
unsafe {
|
unsafe {
|
||||||
Gecko_SetCursorImage(&mut self.gecko.mCursorImages[i],
|
Gecko_SetCursorImage(&mut self.gecko.mCursorImages[i], image.url.for_ffi());
|
||||||
ptr, len as u32,
|
|
||||||
extra_data.base.get(),
|
|
||||||
extra_data.referrer.get(),
|
|
||||||
extra_data.principal.get());
|
|
||||||
}
|
}
|
||||||
// We don't need to record this struct as uncacheable, like when setting
|
// We don't need to record this struct as uncacheable, like when setting
|
||||||
// background-image to a url() value, since only properties in reset structs
|
// background-image to a url() value, since only properties in reset structs
|
||||||
|
@ -3198,10 +3186,11 @@ clip-path
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="Counters"
|
<%self:impl_trait style_struct_name="Counters"
|
||||||
skip_longhands="content">
|
skip_longhands="content counter-increment counter-reset">
|
||||||
pub fn set_content(&mut self, v: longhands::content::computed_value::T) {
|
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::T;
|
||||||
use properties::longhands::content::computed_value::ContentItem;
|
use properties::longhands::content::computed_value::ContentItem;
|
||||||
|
use style_traits::ToCss;
|
||||||
use gecko_bindings::structs::nsStyleContentType::*;
|
use gecko_bindings::structs::nsStyleContentType::*;
|
||||||
use gecko_bindings::bindings::Gecko_ClearAndResizeStyleContents;
|
use gecko_bindings::bindings::Gecko_ClearAndResizeStyleContents;
|
||||||
|
|
||||||
|
@ -3231,7 +3220,6 @@ clip-path
|
||||||
items.len() as u32);
|
items.len() as u32);
|
||||||
}
|
}
|
||||||
for (i, item) in items.into_iter().enumerate() {
|
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
|
// NB: Gecko compares the mString value if type is not image
|
||||||
// or URI independently of whatever gets there. In the quote
|
// or URI independently of whatever gets there. In the quote
|
||||||
// cases, they set it to null, so do the same here.
|
// cases, they set it to null, so do the same here.
|
||||||
|
@ -3247,6 +3235,19 @@ clip-path
|
||||||
as_utf16_and_forget(&value);
|
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
|
ContentItem::OpenQuote
|
||||||
=> self.gecko.mContents[i].mType = eStyleContentType_OpenQuote,
|
=> self.gecko.mContents[i].mType = eStyleContentType_OpenQuote,
|
||||||
ContentItem::CloseQuote
|
ContentItem::CloseQuote
|
||||||
|
@ -3257,9 +3258,30 @@ clip-path
|
||||||
=> self.gecko.mContents[i].mType = eStyleContentType_NoCloseQuote,
|
=> self.gecko.mContents[i].mType = eStyleContentType_NoCloseQuote,
|
||||||
ContentItem::MozAltContent
|
ContentItem::MozAltContent
|
||||||
=> self.gecko.mContents[i].mType = eStyleContentType_AltContent,
|
=> self.gecko.mContents[i].mType = eStyleContentType_AltContent,
|
||||||
ContentItem::Counter(..) |
|
ContentItem::Counter(name, style) => {
|
||||||
ContentItem::Counters(..)
|
unsafe {
|
||||||
=> self.gecko.mContents[i].mType = eStyleContentType_Uninitialized,
|
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()) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3272,6 +3294,25 @@ clip-path
|
||||||
Gecko_CopyStyleContentsFrom(&mut self.gecko, &other.gecko)
|
Gecko_CopyStyleContentsFrom(&mut self.gecko, &other.gecko)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
% for counter_property in ["Increment", "Reset"]:
|
||||||
|
pub fn set_counter_${counter_property.lower()}(&mut self, v: longhands::counter_increment::computed_value::T) {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_ClearAndResizeCounter${counter_property}s(&mut self.gecko,
|
||||||
|
v.0.len() as u32);
|
||||||
|
for (i, item) in v.0.into_iter().enumerate() {
|
||||||
|
self.gecko.m${counter_property}s[i].mCounter.assign_utf8(&item.0);
|
||||||
|
self.gecko.m${counter_property}s[i].mValue = item.1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_counter_${counter_property.lower()}_from(&mut self, other: &Self) {
|
||||||
|
unsafe {
|
||||||
|
bindings::Gecko_CopyCounter${counter_property}sFrom(&mut self.gecko, &other.gecko)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
% endfor
|
||||||
</%self:impl_trait>
|
</%self:impl_trait>
|
||||||
|
|
||||||
<%self:impl_trait style_struct_name="XUL"
|
<%self:impl_trait style_struct_name="XUL"
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
use cssparser::Token;
|
use cssparser::Token;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use values::computed::ComputedValueAsSpecified;
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
use values::HasViewportPercentage;
|
use values::HasViewportPercentage;
|
||||||
|
|
||||||
use super::list_style_type;
|
use super::list_style_type;
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
use cssparser;
|
use cssparser;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
use values::specified::url::SpecifiedUrl;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
|
@ -48,6 +50,10 @@
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
/// `-moz-alt-content`
|
/// `-moz-alt-content`
|
||||||
MozAltContent,
|
MozAltContent,
|
||||||
|
/// `attr([namespace? `|`]? ident)`
|
||||||
|
Attr(Option<String>, String),
|
||||||
|
/// `url(url)`
|
||||||
|
Url(SpecifiedUrl),
|
||||||
% endif
|
% endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +86,16 @@
|
||||||
|
|
||||||
% if product == "gecko":
|
% if product == "gecko":
|
||||||
ContentItem::MozAltContent => dest.write_str("-moz-alt-content"),
|
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
|
% endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +151,12 @@
|
||||||
}
|
}
|
||||||
let mut content = vec![];
|
let mut content = vec![];
|
||||||
loop {
|
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() {
|
match input.next() {
|
||||||
Ok(Token::QuotedString(value)) => {
|
Ok(Token::QuotedString(value)) => {
|
||||||
content.push(ContentItem::String(value.into_owned()))
|
content.push(ContentItem::String(value.into_owned()))
|
||||||
|
@ -159,6 +181,35 @@
|
||||||
}).unwrap_or(list_style_type::computed_value::T::decimal);
|
}).unwrap_or(list_style_type::computed_value::T::decimal);
|
||||||
Ok(ContentItem::Counters(name, separator, style))
|
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(())
|
_ => return Err(())
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -188,7 +239,7 @@
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="counter-increment" products="servo" animatable="False"
|
<%helpers:longhand name="counter-increment" animatable="False"
|
||||||
spec="https://drafts.csswg.org/css-lists/#propdef-counter-increment">
|
spec="https://drafts.csswg.org/css-lists/#propdef-counter-increment">
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::ToCss;
|
use style_traits::ToCss;
|
||||||
|
@ -262,7 +313,7 @@
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
<%helpers:longhand name="counter-reset" products="servo" animatable="False"
|
<%helpers:longhand name="counter-reset" animatable="False"
|
||||||
spec="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset">
|
spec="https://drafts.csswg.org/css-lists-3/#propdef-counter-reset">
|
||||||
pub use super::counter_increment::{SpecifiedValue, computed_value, get_initial_value};
|
pub use super::counter_increment::{SpecifiedValue, computed_value, get_initial_value};
|
||||||
use super::counter_increment::{parse_common};
|
use super::counter_increment::{parse_common};
|
||||||
|
|
|
@ -150,6 +150,11 @@ impl SpecifiedUrl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if it has a resolved URI
|
||||||
|
pub fn has_resolved(&self) -> bool {
|
||||||
|
self.resolved.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates an already specified url value from an already resolved URL
|
/// Creates an already specified url value from an already resolved URL
|
||||||
/// for insertion in the cascade.
|
/// for insertion in the cascade.
|
||||||
pub fn for_cascade(url: ServoUrl, extra_data: UrlExtraData) -> Self {
|
pub fn for_cascade(url: ServoUrl, extra_data: UrlExtraData) -> Self {
|
||||||
|
@ -173,19 +178,20 @@ impl SpecifiedUrl {
|
||||||
/// Create a bundled URI suitable for sending to Gecko
|
/// Create a bundled URI suitable for sending to Gecko
|
||||||
/// to be constructed into a css::URLValue
|
/// to be constructed into a css::URLValue
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub fn for_ffi(&self) -> Option<ServoBundledURI> {
|
pub fn for_ffi(&self) -> ServoBundledURI {
|
||||||
let extra_data = self.extra_data();
|
let extra_data = self.extra_data();
|
||||||
let (ptr, len) = match self.as_slice_components() {
|
let (ptr, len) = match self.as_slice_components() {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(_) => return None,
|
// we're okay with passing down the unresolved relative URI
|
||||||
|
Err(value) => value,
|
||||||
};
|
};
|
||||||
Some(ServoBundledURI {
|
ServoBundledURI {
|
||||||
mURLString: ptr,
|
mURLString: ptr,
|
||||||
mURLStringLength: len as u32,
|
mURLStringLength: len as u32,
|
||||||
mBaseURI: extra_data.base.get(),
|
mBaseURI: extra_data.base.get(),
|
||||||
mReferrer: extra_data.referrer.get(),
|
mReferrer: extra_data.referrer.get(),
|
||||||
mPrincipal: extra_data.principal.get(),
|
mPrincipal: extra_data.principal.get(),
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue