mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Implemented paint worklet arguments.
This commit is contained in:
parent
d859734702
commit
d101f9c945
8 changed files with 78 additions and 27 deletions
|
@ -548,10 +548,15 @@ impl<'a> CanvasPaintThread<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recreate(&mut self, size: Size2D<i32>) {
|
fn recreate(&mut self, size: Size2D<i32>) {
|
||||||
|
// TODO: clear the thread state. https://github.com/servo/servo/issues/17533
|
||||||
self.drawtarget = CanvasPaintThread::create(size);
|
self.drawtarget = CanvasPaintThread::create(size);
|
||||||
self.state = CanvasPaintState::new(self.state.draw_options.antialias);
|
self.state = CanvasPaintState::new(self.state.draw_options.antialias);
|
||||||
self.saved_states.clear();
|
self.saved_states.clear();
|
||||||
// Webrender doesn't let images change size, so we clear the webrender image key.
|
// Webrender doesn't let images change size, so we clear the webrender image key.
|
||||||
|
// TODO: there is an annying race condition here: the display list builder
|
||||||
|
// might still be using the old image key. Really, we should be scheduling the image
|
||||||
|
// for later deletion, not deleting it immediately.
|
||||||
|
// https://github.com/servo/servo/issues/17534
|
||||||
if let Some(image_key) = self.image_key.take() {
|
if let Some(image_key) = self.image_key.take() {
|
||||||
// If this executes, then we are in a new epoch since we last recreated the canvas,
|
// If this executes, then we are in a new epoch since we last recreated the canvas,
|
||||||
// so `old_image_key` must be `None`.
|
// so `old_image_key` must be `None`.
|
||||||
|
@ -582,6 +587,7 @@ impl<'a> CanvasPaintThread<'a> {
|
||||||
|
|
||||||
match self.image_key {
|
match self.image_key {
|
||||||
Some(image_key) => {
|
Some(image_key) => {
|
||||||
|
debug!("Updating image {:?}.", image_key);
|
||||||
self.webrender_api.update_image(image_key,
|
self.webrender_api.update_image(image_key,
|
||||||
descriptor,
|
descriptor,
|
||||||
data,
|
data,
|
||||||
|
@ -589,6 +595,7 @@ impl<'a> CanvasPaintThread<'a> {
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
self.image_key = Some(self.webrender_api.generate_image_key());
|
self.image_key = Some(self.webrender_api.generate_image_key());
|
||||||
|
debug!("New image {:?}.", self.image_key);
|
||||||
self.webrender_api.add_image(self.image_key.unwrap(),
|
self.webrender_api.add_image(self.image_key.unwrap(),
|
||||||
descriptor,
|
descriptor,
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -68,6 +68,7 @@ use style::values::generics::image::{Image, ShapeExtent};
|
||||||
use style::values::generics::image::PaintWorklet;
|
use style::values::generics::image::PaintWorklet;
|
||||||
use style::values::specified::position::{X, Y};
|
use style::values::specified::position::{X, Y};
|
||||||
use style_traits::CSSPixel;
|
use style_traits::CSSPixel;
|
||||||
|
use style_traits::ToCss;
|
||||||
use style_traits::cursor::Cursor;
|
use style_traits::cursor::Cursor;
|
||||||
use table_cell::CollapsedBordersForCell;
|
use table_cell::CollapsedBordersForCell;
|
||||||
use webrender_api::{ClipId, ColorF, ComplexClipRegion, GradientStop, LocalClip, RepeatMode};
|
use webrender_api::{ClipId, ColorF, ComplexClipRegion, GradientStop, LocalClip, RepeatMode};
|
||||||
|
@ -1173,9 +1174,15 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
let device_pixel_ratio = state.layout_context.style_context.device_pixel_ratio();
|
let device_pixel_ratio = state.layout_context.style_context.device_pixel_ratio();
|
||||||
let size_in_au = unbordered_box.size.to_physical(style.writing_mode);
|
let size_in_au = unbordered_box.size.to_physical(style.writing_mode);
|
||||||
let size_in_px = TypedSize2D::new(size_in_au.width.to_f32_px(), size_in_au.height.to_f32_px());
|
let size_in_px = TypedSize2D::new(size_in_au.width.to_f32_px(), size_in_au.height.to_f32_px());
|
||||||
|
|
||||||
|
// TODO: less copying.
|
||||||
let name = paint_worklet.name.clone();
|
let name = paint_worklet.name.clone();
|
||||||
|
let arguments = paint_worklet.arguments.iter()
|
||||||
|
.map(|argument| argument.to_css_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Get the painter, and the computed values for its properties.
|
// Get the painter, and the computed values for its properties.
|
||||||
|
// TODO: less copying.
|
||||||
let (properties, painter) = match state.layout_context.registered_painters.read().get(&name) {
|
let (properties, painter) = match state.layout_context.registered_painters.read().get(&name) {
|
||||||
Some(registered_painter) => (
|
Some(registered_painter) => (
|
||||||
registered_painter.properties
|
registered_painter.properties
|
||||||
|
@ -1191,7 +1198,7 @@ impl FragmentDisplayListBuilding for Fragment {
|
||||||
// TODO: add a one-place cache to avoid drawing the paint image every time.
|
// TODO: add a one-place cache to avoid drawing the paint image every time.
|
||||||
// https://github.com/servo/servo/issues/17369
|
// https://github.com/servo/servo/issues/17369
|
||||||
debug!("Drawing a paint image {}({},{}).", name, size_in_px.width, size_in_px.height);
|
debug!("Drawing a paint image {}({},{}).", name, size_in_px.width, size_in_px.height);
|
||||||
let mut draw_result = painter.draw_a_paint_image(size_in_px, device_pixel_ratio, properties);
|
let mut draw_result = painter.draw_a_paint_image(size_in_px, device_pixel_ratio, properties, arguments);
|
||||||
let webrender_image = WebRenderImageInfo {
|
let webrender_image = WebRenderImageInfo {
|
||||||
width: draw_result.width,
|
width: draw_result.width,
|
||||||
height: draw_result.height,
|
height: draw_result.height,
|
||||||
|
|
|
@ -17,6 +17,7 @@ use dom::bindings::js::JS;
|
||||||
use dom::bindings::js::Root;
|
use dom::bindings::js::Root;
|
||||||
use dom::bindings::reflector::DomObject;
|
use dom::bindings::reflector::DomObject;
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
|
use dom::cssstylevalue::CSSStyleValue;
|
||||||
use dom::paintrenderingcontext2d::PaintRenderingContext2D;
|
use dom::paintrenderingcontext2d::PaintRenderingContext2D;
|
||||||
use dom::paintsize::PaintSize;
|
use dom::paintsize::PaintSize;
|
||||||
use dom::stylepropertymapreadonly::StylePropertyMapReadOnly;
|
use dom::stylepropertymapreadonly::StylePropertyMapReadOnly;
|
||||||
|
@ -38,6 +39,7 @@ use js::jsapi::IsConstructor;
|
||||||
use js::jsapi::JSAutoCompartment;
|
use js::jsapi::JSAutoCompartment;
|
||||||
use js::jsapi::JS_ClearPendingException;
|
use js::jsapi::JS_ClearPendingException;
|
||||||
use js::jsapi::JS_IsExceptionPending;
|
use js::jsapi::JS_IsExceptionPending;
|
||||||
|
use js::jsapi::JS_NewArrayObject;
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
use js::jsval::ObjectValue;
|
use js::jsval::ObjectValue;
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
|
@ -100,9 +102,9 @@ impl PaintWorkletGlobalScope {
|
||||||
|
|
||||||
pub fn perform_a_worklet_task(&self, task: PaintWorkletTask) {
|
pub fn perform_a_worklet_task(&self, task: PaintWorkletTask) {
|
||||||
match task {
|
match task {
|
||||||
PaintWorkletTask::DrawAPaintImage(name, size_in_px, device_pixel_ratio, properties, sender) => {
|
PaintWorkletTask::DrawAPaintImage(name, size_in_px, device_pixel_ratio, properties, arguments, sender) => {
|
||||||
let properties = StylePropertyMapReadOnly::from_iter(self.upcast(), properties);
|
let properties = StylePropertyMapReadOnly::from_iter(self.upcast(), properties);
|
||||||
let result = self.draw_a_paint_image(name, size_in_px, device_pixel_ratio, &*properties);
|
let result = self.draw_a_paint_image(name, size_in_px, device_pixel_ratio, &*properties, arguments);
|
||||||
let _ = sender.send(result);
|
let _ = sender.send(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,11 +115,17 @@ impl PaintWorkletGlobalScope {
|
||||||
name: Atom,
|
name: Atom,
|
||||||
size_in_px: TypedSize2D<f32, CSSPixel>,
|
size_in_px: TypedSize2D<f32, CSSPixel>,
|
||||||
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
|
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
|
||||||
properties: &StylePropertyMapReadOnly)
|
properties: &StylePropertyMapReadOnly,
|
||||||
|
arguments: Vec<String>)
|
||||||
-> DrawAPaintImageResult
|
-> DrawAPaintImageResult
|
||||||
{
|
{
|
||||||
|
let size_in_dpx = size_in_px * device_pixel_ratio;
|
||||||
|
let size_in_dpx = TypedSize2D::new(size_in_dpx.width.abs() as u32, size_in_dpx.height.abs() as u32);
|
||||||
|
|
||||||
|
// TODO: Steps 1-5.
|
||||||
|
|
||||||
// TODO: document paint definitions.
|
// TODO: document paint definitions.
|
||||||
self.invoke_a_paint_callback(name, size_in_px, device_pixel_ratio, properties)
|
self.invoke_a_paint_callback(name, size_in_px, size_in_dpx, device_pixel_ratio, properties, arguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// https://drafts.css-houdini.org/css-paint-api/#invoke-a-paint-callback
|
/// https://drafts.css-houdini.org/css-paint-api/#invoke-a-paint-callback
|
||||||
|
@ -125,12 +133,12 @@ impl PaintWorkletGlobalScope {
|
||||||
fn invoke_a_paint_callback(&self,
|
fn invoke_a_paint_callback(&self,
|
||||||
name: Atom,
|
name: Atom,
|
||||||
size_in_px: TypedSize2D<f32, CSSPixel>,
|
size_in_px: TypedSize2D<f32, CSSPixel>,
|
||||||
|
size_in_dpx: TypedSize2D<u32, DevicePixel>,
|
||||||
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
|
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
|
||||||
properties: &StylePropertyMapReadOnly)
|
properties: &StylePropertyMapReadOnly,
|
||||||
|
mut arguments: Vec<String>)
|
||||||
-> DrawAPaintImageResult
|
-> DrawAPaintImageResult
|
||||||
{
|
{
|
||||||
let size_in_dpx = size_in_px * device_pixel_ratio;
|
|
||||||
let size_in_dpx = TypedSize2D::new(size_in_dpx.width.abs() as u32, size_in_dpx.height.abs() as u32);
|
|
||||||
debug!("Invoking a paint callback {}({},{}) at {}.",
|
debug!("Invoking a paint callback {}({},{}) at {}.",
|
||||||
name, size_in_px.width, size_in_px.height, device_pixel_ratio);
|
name, size_in_px.width, size_in_px.height, device_pixel_ratio);
|
||||||
|
|
||||||
|
@ -198,10 +206,19 @@ impl PaintWorkletGlobalScope {
|
||||||
// TODO: Step 10
|
// TODO: Step 10
|
||||||
// Steps 11-12
|
// Steps 11-12
|
||||||
debug!("Invoking paint function {}.", name);
|
debug!("Invoking paint function {}.", name);
|
||||||
|
rooted_vec!(let arguments_values <- arguments.drain(..)
|
||||||
|
.map(|argument| CSSStyleValue::new(self.upcast(), argument)));
|
||||||
|
let arguments_value_vec: Vec<JSVal> = arguments_values.iter()
|
||||||
|
.map(|argument| ObjectValue(argument.reflector().get_jsobject().get()))
|
||||||
|
.collect();
|
||||||
|
let arguments_value_array = unsafe { HandleValueArray::from_rooted_slice(&*arguments_value_vec) };
|
||||||
|
rooted!(in(cx) let argument_object = unsafe { JS_NewArrayObject(cx, &arguments_value_array) });
|
||||||
|
|
||||||
let args_slice = [
|
let args_slice = [
|
||||||
ObjectValue(rendering_context.reflector().get_jsobject().get()),
|
ObjectValue(rendering_context.reflector().get_jsobject().get()),
|
||||||
ObjectValue(paint_size.reflector().get_jsobject().get()),
|
ObjectValue(paint_size.reflector().get_jsobject().get()),
|
||||||
ObjectValue(properties.reflector().get_jsobject().get()),
|
ObjectValue(properties.reflector().get_jsobject().get()),
|
||||||
|
ObjectValue(argument_object.get()),
|
||||||
];
|
];
|
||||||
let args = unsafe { HandleValueArray::from_rooted_slice(&args_slice) };
|
let args = unsafe { HandleValueArray::from_rooted_slice(&args_slice) };
|
||||||
|
|
||||||
|
@ -252,12 +269,17 @@ impl PaintWorkletGlobalScope {
|
||||||
fn draw_a_paint_image(&self,
|
fn draw_a_paint_image(&self,
|
||||||
size: TypedSize2D<f32, CSSPixel>,
|
size: TypedSize2D<f32, CSSPixel>,
|
||||||
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
|
device_pixel_ratio: ScaleFactor<f32, CSSPixel, DevicePixel>,
|
||||||
properties: Vec<(Atom, String)>)
|
properties: Vec<(Atom, String)>,
|
||||||
-> DrawAPaintImageResult
|
arguments: Vec<String>)
|
||||||
{
|
-> DrawAPaintImageResult {
|
||||||
let name = self.0.clone();
|
let name = self.0.clone();
|
||||||
let (sender, receiver) = mpsc::channel();
|
let (sender, receiver) = mpsc::channel();
|
||||||
let task = PaintWorkletTask::DrawAPaintImage(name, size, device_pixel_ratio, properties, sender);
|
let task = PaintWorkletTask::DrawAPaintImage(name,
|
||||||
|
size,
|
||||||
|
device_pixel_ratio,
|
||||||
|
properties,
|
||||||
|
arguments,
|
||||||
|
sender);
|
||||||
self.1.lock().expect("Locking a painter.")
|
self.1.lock().expect("Locking a painter.")
|
||||||
.schedule_a_worklet_task(WorkletTask::Paint(task));
|
.schedule_a_worklet_task(WorkletTask::Paint(task));
|
||||||
receiver.recv().expect("Worklet thread died?")
|
receiver.recv().expect("Worklet thread died?")
|
||||||
|
@ -296,7 +318,7 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope {
|
||||||
let properties = property_names.drain(..).map(Atom::from).collect();
|
let properties = property_names.drain(..).map(Atom::from).collect();
|
||||||
|
|
||||||
// Step 7-9.
|
// Step 7-9.
|
||||||
let _argument_names: Vec<String> =
|
let input_arguments: Vec<String> =
|
||||||
unsafe { get_property(cx, paint_obj.handle(), "inputArguments", ()) }?
|
unsafe { get_property(cx, paint_obj.handle(), "inputArguments", ()) }?
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
@ -332,6 +354,7 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope {
|
||||||
let definition = PaintDefinition::new(paint_val.handle(),
|
let definition = PaintDefinition::new(paint_val.handle(),
|
||||||
paint_function.handle(),
|
paint_function.handle(),
|
||||||
alpha,
|
alpha,
|
||||||
|
input_arguments.len(),
|
||||||
&*context);
|
&*context);
|
||||||
|
|
||||||
// Step 20.
|
// Step 20.
|
||||||
|
@ -356,6 +379,7 @@ pub enum PaintWorkletTask {
|
||||||
TypedSize2D<f32, CSSPixel>,
|
TypedSize2D<f32, CSSPixel>,
|
||||||
ScaleFactor<f32, CSSPixel, DevicePixel>,
|
ScaleFactor<f32, CSSPixel, DevicePixel>,
|
||||||
Vec<(Atom, String)>,
|
Vec<(Atom, String)>,
|
||||||
|
Vec<String>,
|
||||||
Sender<DrawAPaintImageResult>)
|
Sender<DrawAPaintImageResult>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,6 +394,8 @@ struct PaintDefinition {
|
||||||
paint_function: Heap<JSVal>,
|
paint_function: Heap<JSVal>,
|
||||||
constructor_valid_flag: Cell<bool>,
|
constructor_valid_flag: Cell<bool>,
|
||||||
context_alpha_flag: bool,
|
context_alpha_flag: bool,
|
||||||
|
// TODO: this should be a list of CSS syntaxes.
|
||||||
|
input_arguments_len: usize,
|
||||||
// TODO: the spec calls for fresh rendering contexts each time a paint image is drawn,
|
// TODO: the spec calls for fresh rendering contexts each time a paint image is drawn,
|
||||||
// but to avoid having the primary worklet thread create a new renering context,
|
// but to avoid having the primary worklet thread create a new renering context,
|
||||||
// we recycle them.
|
// we recycle them.
|
||||||
|
@ -380,6 +406,7 @@ impl PaintDefinition {
|
||||||
fn new(class_constructor: HandleValue,
|
fn new(class_constructor: HandleValue,
|
||||||
paint_function: HandleValue,
|
paint_function: HandleValue,
|
||||||
alpha: bool,
|
alpha: bool,
|
||||||
|
input_arguments_len: usize,
|
||||||
context: &PaintRenderingContext2D)
|
context: &PaintRenderingContext2D)
|
||||||
-> Box<PaintDefinition>
|
-> Box<PaintDefinition>
|
||||||
{
|
{
|
||||||
|
@ -388,6 +415,7 @@ impl PaintDefinition {
|
||||||
paint_function: Heap::default(),
|
paint_function: Heap::default(),
|
||||||
constructor_valid_flag: Cell::new(true),
|
constructor_valid_flag: Cell::new(true),
|
||||||
context_alpha_flag: alpha,
|
context_alpha_flag: alpha,
|
||||||
|
input_arguments_len: input_arguments_len,
|
||||||
context: JS::from_ref(context),
|
context: JS::from_ref(context),
|
||||||
});
|
});
|
||||||
result.class_constructor.set(class_constructor.get());
|
result.class_constructor.set(class_constructor.get());
|
||||||
|
|
|
@ -822,7 +822,8 @@ pub trait Painter: Sync + Send {
|
||||||
fn draw_a_paint_image(&self,
|
fn draw_a_paint_image(&self,
|
||||||
size: TypedSize2D<f32, CSSPixel>,
|
size: TypedSize2D<f32, CSSPixel>,
|
||||||
zoom: ScaleFactor<f32, CSSPixel, DevicePixel>,
|
zoom: ScaleFactor<f32, CSSPixel, DevicePixel>,
|
||||||
properties: Vec<(Atom, String)>)
|
properties: Vec<(Atom, String)>,
|
||||||
|
arguments: Vec<String>)
|
||||||
-> DrawAPaintImageResult;
|
-> DrawAPaintImageResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
use cssparser::serialize_identifier;
|
use cssparser::serialize_identifier;
|
||||||
|
use custom_properties::SpecifiedValue;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use style_traits::{HasViewportPercentage, ToCss};
|
use style_traits::{HasViewportPercentage, ToCss};
|
||||||
use values::computed::ComputedValueAsSpecified;
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
@ -136,17 +137,26 @@ pub struct ColorStop<Color, LengthOrPercentage> {
|
||||||
|
|
||||||
/// Specified values for a paint worklet.
|
/// Specified values for a paint worklet.
|
||||||
/// https://drafts.css-houdini.org/css-paint-api/
|
/// https://drafts.css-houdini.org/css-paint-api/
|
||||||
#[derive(Clone, Debug, PartialEq, ToComputedValue)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct PaintWorklet {
|
pub struct PaintWorklet {
|
||||||
/// The name the worklet was registered with.
|
/// The name the worklet was registered with.
|
||||||
pub name: Atom,
|
pub name: Atom,
|
||||||
|
/// The arguments for the worklet.
|
||||||
|
/// TODO: store a parsed representation of the arguments.
|
||||||
|
pub arguments: Vec<SpecifiedValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ComputedValueAsSpecified for PaintWorklet {}
|
||||||
|
|
||||||
impl ToCss for PaintWorklet {
|
impl ToCss for PaintWorklet {
|
||||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
dest.write_str("paint(")?;
|
dest.write_str("paint(")?;
|
||||||
serialize_identifier(&*self.name.to_string(), dest)?;
|
serialize_identifier(&*self.name.to_string(), dest)?;
|
||||||
|
for argument in &self.arguments {
|
||||||
|
dest.write_str(", ")?;
|
||||||
|
argument.to_css(dest)?;
|
||||||
|
}
|
||||||
dest.write_str(")")
|
dest.write_str(")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
use cssparser::{Parser, Token, BasicParseError};
|
use cssparser::{Parser, Token, BasicParseError};
|
||||||
|
use custom_properties::SpecifiedValue;
|
||||||
use parser::{Parse, ParserContext};
|
use parser::{Parse, ParserContext};
|
||||||
use selectors::parser::SelectorParseError;
|
use selectors::parser::SelectorParseError;
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
|
@ -874,12 +875,17 @@ impl Parse for ColorStop {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parse for PaintWorklet {
|
impl Parse for PaintWorklet {
|
||||||
fn parse<'i, 't>(_context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||||
input.expect_function_matching("paint")?;
|
input.expect_function_matching("paint")?;
|
||||||
input.parse_nested_block(|i| {
|
input.parse_nested_block(|input| {
|
||||||
let name = i.expect_ident()?;
|
let name = Atom::from(&**input.expect_ident()?);
|
||||||
|
let arguments = input.try(|input| {
|
||||||
|
input.expect_comma()?;
|
||||||
|
input.parse_comma_separated(|input| Ok(*SpecifiedValue::parse(context, input)?))
|
||||||
|
}).unwrap_or(vec![]);
|
||||||
Ok(PaintWorklet {
|
Ok(PaintWorklet {
|
||||||
name: Atom::from(name.as_ref()),
|
name: name,
|
||||||
|
arguments: arguments,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
[paint-arguments.html]
|
|
||||||
type: reftest
|
|
||||||
expected: FAIL
|
|
||||||
bug: https://github.com/servo/servo/issues/17435
|
|
|
@ -1,4 +0,0 @@
|
||||||
[paint-function-arguments.html]
|
|
||||||
type: reftest
|
|
||||||
expected: FAIL
|
|
||||||
bug: https://github.com/servo/servo/issues/17435
|
|
Loading…
Add table
Add a link
Reference in a new issue