mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1695402 - Support image-set() on the cursor property. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D106745
This commit is contained in:
parent
03be7ebe5a
commit
dee15c3162
@ -3944,8 +3944,10 @@ static CursorImage ComputeCustomCursor(nsPresContext* aPresContext,
|
||||
// consumer know.
|
||||
bool loading = false;
|
||||
for (const auto& image : style.StyleUI()->mCursor.images.AsSpan()) {
|
||||
MOZ_ASSERT(image.image.IsImageRequestType(),
|
||||
"Cursor image should only parse url() type");
|
||||
uint32_t status;
|
||||
imgRequestProxy* req = image.url.GetImage();
|
||||
imgRequestProxy* req = image.image.GetImageRequest();
|
||||
if (!req || NS_FAILED(req->GetImageStatus(&status))) {
|
||||
continue;
|
||||
}
|
||||
|
@ -659,7 +659,7 @@ static void CollectImageURLsForProperty(nsCSSPropertyID aProp,
|
||||
switch (aProp) {
|
||||
case eCSSProperty_cursor:
|
||||
for (auto& image : aStyle.StyleUI()->mCursor.images.AsSpan()) {
|
||||
AddImageURL(image.url, aURLs);
|
||||
AddImageURL(image.image, aURLs);
|
||||
}
|
||||
break;
|
||||
case eCSSProperty_background_image:
|
||||
|
@ -3055,13 +3055,10 @@ void nsStyleUI::TriggerImageLoads(Document& aDocument,
|
||||
: Span<const StyleCursorImage>();
|
||||
for (size_t i = 0; i < cursorImages.Length(); ++i) {
|
||||
auto& cursor = cursorImages[i];
|
||||
|
||||
if (!cursor.url.IsImageResolved()) {
|
||||
const auto* oldCursor =
|
||||
oldCursorImages.Length() > i ? &oldCursorImages[i] : nullptr;
|
||||
const_cast<StyleComputedImageUrl&>(cursor.url)
|
||||
.ResolveImage(aDocument, oldCursor ? &oldCursor->url : nullptr);
|
||||
}
|
||||
const auto* oldCursorImage =
|
||||
oldCursorImages.Length() > i ? &oldCursorImages[i].image : nullptr;
|
||||
const_cast<StyleCursorImage&>(cursor).image.ResolveImage(aDocument,
|
||||
oldCursorImage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5628,8 +5628,15 @@ var gCSSProperties = {
|
||||
"url(foo.png), url(bar.png) 7 2, wait",
|
||||
"url(foo.png) 3 2, url(bar.png) 7 9, pointer",
|
||||
"url(foo.png) calc(1 + 2) calc(3), pointer",
|
||||
"image-set(url(foo.png)), auto",
|
||||
],
|
||||
invalid_values: [
|
||||
"url(foo.png)",
|
||||
"url(foo.png) 5 5",
|
||||
"image-set(linear-gradient(red, blue)), auto",
|
||||
// Gradients are supported per spec, but we don't have support for it yet
|
||||
"linear-gradient(red, blue), auto",
|
||||
],
|
||||
invalid_values: ["url(foo.png)", "url(foo.png) 5 5"],
|
||||
},
|
||||
direction: {
|
||||
domProp: "direction",
|
||||
|
@ -5,7 +5,7 @@
|
||||
//! Computed values for UI properties
|
||||
|
||||
use crate::values::computed::color::Color;
|
||||
use crate::values::computed::url::ComputedImageUrl;
|
||||
use crate::values::computed::image::Image;
|
||||
use crate::values::computed::Number;
|
||||
use crate::values::generics::ui as generics;
|
||||
|
||||
@ -16,7 +16,7 @@ pub use crate::values::specified::ui::{MozForceBrokenImageIcon, UserSelect};
|
||||
pub type Cursor = generics::GenericCursor<CursorImage>;
|
||||
|
||||
/// A computed value for item of `image cursors`.
|
||||
pub type CursorImage = generics::GenericCursorImage<ComputedImageUrl, Number>;
|
||||
pub type CursorImage = generics::GenericCursorImage<Image, Number>;
|
||||
|
||||
/// A computed value for `scrollbar-color` property.
|
||||
pub type ScrollbarColor = generics::GenericScrollbarColor<Color>;
|
||||
|
@ -61,15 +61,14 @@ impl<Image: ToCss> ToCss for Cursor<Image> {
|
||||
Debug,
|
||||
MallocSizeOf,
|
||||
PartialEq,
|
||||
SpecifiedValueInfo,
|
||||
ToComputedValue,
|
||||
ToResolvedValue,
|
||||
ToShmem,
|
||||
)]
|
||||
#[repr(C)]
|
||||
pub struct GenericCursorImage<ImageUrl, Number> {
|
||||
pub struct GenericCursorImage<Image, Number> {
|
||||
/// The url to parse images from.
|
||||
pub url: ImageUrl,
|
||||
pub image: Image,
|
||||
/// Whether the image has a hotspot or not.
|
||||
pub has_hotspot: bool,
|
||||
/// The x coordinate.
|
||||
@ -80,12 +79,12 @@ pub struct GenericCursorImage<ImageUrl, Number> {
|
||||
|
||||
pub use self::GenericCursorImage as CursorImage;
|
||||
|
||||
impl<ImageUrl: ToCss, Number: ToCss> ToCss for CursorImage<ImageUrl, Number> {
|
||||
impl<Image: ToCss, Number: ToCss> ToCss for CursorImage<Image, Number> {
|
||||
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
|
||||
where
|
||||
W: Write,
|
||||
{
|
||||
self.url.to_css(dest)?;
|
||||
self.image.to_css(dest)?;
|
||||
if self.has_hotspot {
|
||||
dest.write_str(" ")?;
|
||||
self.hotspot_x.to_css(dest)?;
|
||||
|
@ -181,7 +181,7 @@ impl Parse for Image {
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Image, ParseError<'i>> {
|
||||
Image::parse_with_cors_mode(context, input, CorsMode::None, /* allow_none = */ true)
|
||||
Image::parse_with_cors_mode(context, input, CorsMode::None, /* allow_none = */ true, /* only_url = */ false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,23 +191,32 @@ impl Image {
|
||||
input: &mut Parser<'i, 't>,
|
||||
cors_mode: CorsMode,
|
||||
allow_none: bool,
|
||||
only_url: bool,
|
||||
) -> Result<Image, ParseError<'i>> {
|
||||
if allow_none && input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||
return Ok(generic::Image::None);
|
||||
}
|
||||
|
||||
if let Ok(url) = input
|
||||
.try_parse(|input| SpecifiedImageUrl::parse_with_cors_mode(context, input, cors_mode))
|
||||
{
|
||||
return Ok(generic::Image::Url(url));
|
||||
}
|
||||
if let Ok(gradient) = input.try_parse(|i| Gradient::parse(context, i)) {
|
||||
return Ok(generic::Image::Gradient(Box::new(gradient)));
|
||||
}
|
||||
|
||||
if image_set_enabled() {
|
||||
if let Ok(is) = input.try_parse(|input| ImageSet::parse(context, input, cors_mode)) {
|
||||
if let Ok(is) = input.try_parse(|input| ImageSet::parse(context, input, cors_mode, only_url)) {
|
||||
return Ok(generic::Image::ImageSet(Box::new(is)));
|
||||
}
|
||||
}
|
||||
|
||||
if only_url {
|
||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||
}
|
||||
|
||||
if let Ok(gradient) = input.try_parse(|i| Gradient::parse(context, i)) {
|
||||
return Ok(generic::Image::Gradient(Box::new(gradient)));
|
||||
}
|
||||
|
||||
if cross_fade_enabled() {
|
||||
if let Ok(cf) = input.try_parse(|input| CrossFade::parse(context, input, cors_mode)) {
|
||||
return Ok(generic::Image::CrossFade(Box::new(cf)));
|
||||
@ -264,6 +273,21 @@ impl Image {
|
||||
input,
|
||||
CorsMode::Anonymous,
|
||||
/* allow_none = */ true,
|
||||
/* only_url = */ false,
|
||||
)
|
||||
}
|
||||
|
||||
/// Provides an alternate method for parsing, but only for urls.
|
||||
pub fn parse_only_url<'i, 't>(
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
) -> Result<Image, ParseError<'i>> {
|
||||
Self::parse_with_cors_mode(
|
||||
context,
|
||||
input,
|
||||
CorsMode::None,
|
||||
/* allow_none = */ false,
|
||||
/* only_url = */ true,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -310,7 +334,7 @@ impl CrossFadeImage {
|
||||
cors_mode: CorsMode,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
if let Ok(image) = input.try_parse(|input| {
|
||||
Image::parse_with_cors_mode(context, input, cors_mode, /* allow_none = */ false)
|
||||
Image::parse_with_cors_mode(context, input, cors_mode, /* allow_none = */ false, /* only_url = */ false)
|
||||
}) {
|
||||
return Ok(Self::Image(image));
|
||||
}
|
||||
@ -339,10 +363,11 @@ impl ImageSet {
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
cors_mode: CorsMode,
|
||||
only_url: bool,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
input.expect_function_matching("image-set")?;
|
||||
let items = input.parse_nested_block(|input| {
|
||||
input.parse_comma_separated(|input| ImageSetItem::parse(context, input, cors_mode))
|
||||
input.parse_comma_separated(|input| ImageSetItem::parse(context, input, cors_mode, only_url))
|
||||
})?;
|
||||
Ok(Self {
|
||||
selected_index: 0,
|
||||
@ -356,6 +381,7 @@ impl ImageSetItem {
|
||||
context: &ParserContext,
|
||||
input: &mut Parser<'i, 't>,
|
||||
cors_mode: CorsMode,
|
||||
only_url: bool,
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
let image = match input.try_parse(|i| i.expect_url_or_string()) {
|
||||
Ok(url) => Image::Url(SpecifiedImageUrl::parse_from_string(
|
||||
@ -364,7 +390,7 @@ impl ImageSetItem {
|
||||
cors_mode,
|
||||
)),
|
||||
Err(..) => Image::parse_with_cors_mode(
|
||||
context, input, cors_mode, /* allow_none = */ false,
|
||||
context, input, cors_mode, /* allow_none = */ false, /* only_url = */ only_url
|
||||
)?,
|
||||
};
|
||||
let resolution = input
|
||||
|
@ -7,17 +7,17 @@
|
||||
use crate::parser::{Parse, ParserContext};
|
||||
use crate::values::generics::ui as generics;
|
||||
use crate::values::specified::color::Color;
|
||||
use crate::values::specified::url::SpecifiedImageUrl;
|
||||
use crate::values::specified::image::Image;
|
||||
use crate::values::specified::Number;
|
||||
use cssparser::Parser;
|
||||
use std::fmt::{self, Write};
|
||||
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
|
||||
use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss};
|
||||
|
||||
/// A specified value for the `cursor` property.
|
||||
pub type Cursor = generics::GenericCursor<CursorImage>;
|
||||
|
||||
/// A specified value for item of `image cursors`.
|
||||
pub type CursorImage = generics::GenericCursorImage<SpecifiedImageUrl, Number>;
|
||||
pub type CursorImage = generics::GenericCursorImage<Image, Number>;
|
||||
|
||||
impl Parse for Cursor {
|
||||
/// cursor: [<url> [<number> <number>]?]# [auto | default | ...]
|
||||
@ -47,7 +47,7 @@ impl Parse for CursorImage {
|
||||
) -> Result<Self, ParseError<'i>> {
|
||||
use crate::Zero;
|
||||
|
||||
let url = SpecifiedImageUrl::parse(context, input)?;
|
||||
let image = Image::parse_only_url(context, input)?;
|
||||
let mut has_hotspot = false;
|
||||
let mut hotspot_x = Number::zero();
|
||||
let mut hotspot_y = Number::zero();
|
||||
@ -59,7 +59,7 @@ impl Parse for CursorImage {
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
url,
|
||||
image,
|
||||
has_hotspot,
|
||||
hotspot_x,
|
||||
hotspot_y,
|
||||
@ -67,6 +67,10 @@ impl Parse for CursorImage {
|
||||
}
|
||||
}
|
||||
|
||||
// This trait is manually implemented because we don't support the whole <image>
|
||||
// syntax for cursors
|
||||
impl SpecifiedValueInfo for CursorImage {}
|
||||
|
||||
/// Specified value of `-moz-force-broken-image-icon`
|
||||
#[derive(
|
||||
Clone,
|
||||
|
Loading…
Reference in New Issue
Block a user