1use crate::parser::{Parse, ParserContext};
8use crate::stylesheets::CorsMode;
9use cssparser::Parser;
10use style_traits::ParseError;
11
12#[cfg(feature = "gecko")]
13pub mod gecko;
14#[cfg(feature = "gecko")]
15pub use gecko::{ComputedUrl, CssUrl, SpecifiedUrl};
16#[cfg(feature = "servo")]
17pub mod servo;
18#[cfg(feature = "servo")]
19pub use servo::{ComputedUrl, CssUrl, SpecifiedUrl};
20
21impl CssUrl {
22 pub fn parse_with_cors_mode(
24 context: &ParserContext,
25 input: &mut Parser,
26 cors_mode: CorsMode,
27 ) -> Result<Self, ParseError> {
28 let start = input.position().byte_index();
29 let url = input.expect_url()?;
30 let end = input.position().byte_index();
31 Self::parse_from_string(url.as_ref().to_owned(), start, end, context, cors_mode)
32 }
33
34 pub fn parse_from_string(
38 url: String,
39 url_start: usize,
40 url_end: usize,
41 context: &ParserContext,
42 cors_mode: CorsMode,
43 ) -> Result<Self, ParseError> {
44 use crate::custom_properties::AttrTaintedRange;
45 use style_traits::StyleParseErrorKind;
46 let range = AttrTaintedRange::new(url_start, url_end);
47 if context.disallow_urls_in_range(&range) {
48 return Err(ParseError::custom(StyleParseErrorKind::UnspecifiedError));
49 }
50 Ok(Self::new_from_string(url, context, cors_mode))
51 }
52
53 pub fn new_from_untainted_string(
58 url: String,
59 context: &ParserContext,
60 cors_mode: CorsMode,
61 ) -> Self {
62 debug_assert!(context.attr_tainted_regions.is_empty());
63 Self::new_from_string(url, context, cors_mode)
64 }
65}
66
67impl Parse for CssUrl {
68 fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ParseError> {
69 Self::parse_with_cors_mode(context, input, CorsMode::None)
70 }
71}