import { Keyword , Percentage , Token } from "@siteimprove/alfa-css" ; import { Parser } from "@siteimprove/alfa-parser" ; import { Result , Err } from "@siteimprove/alfa-result" ; import { Slice } from "@siteimprove/alfa-slice" ; import { Property } from "../property" ; import { List } from "./value/list" ; import { Tuple } from "./value/tuple" ; import * as Attachment from "./background-attachment" ; import * as Clip from "./background-clip" ; import * as Color from "./background-color" ; import * as Image from "./background-image" ; import * as Origin from "./background-origin" ; import * as Position from "./background-position" ; import * as PositionX from "./background-position-x" ; import * as PositionY from "./background-position-y" ; import * as Repeat from "./background-repeat" ; import * as RepeatX from "./background-repeat-x" ; import * as RepeatY from "./background-repeat-y" ; import * as Size from "./background-size" ; const { map , filter , delimited , option , right , separatedList } = Parser ; declare module "../property" { interface Shorthands { background : Property . Shorthand < "background-color" | "background-image" | "background-position-x" | "background-position-y" | "background-size" | "background-repeat-x" | "background-repeat-y" | "background-attachment" | "background-origin" | "background-clip" > ; } } internal export const parse = ( input ) => { let color ; let image ; let positionX ; let positionY ; let size ; let repeatX ; let repeatY ; let attachment ; let origin ; let clip ; while ( true ) { for ( const [ remainder ] of Token . parseWhitespace ( input ) ) { input = remainder ; } if ( color === undefined ) { const result = Color . parse ( input ) ; if ( result . isOk ( ) ) { [ input , color ] = result . get ( ) ; continue ; } } if ( image === undefined ) { const result = Image . parse ( input ) ; if ( result . isOk ( ) ) { [ input , image ] = result . get ( ) ; continue ; } } if ( positionX === undefined || positionY === undefined ) { const result = Position . parse ( input ) ; if ( result . isOk ( ) ) { [ input , { horizontal : positionX , vertical : positionY } ] = result . get ( ) ; { const result = delimited ( option ( Token . parseWhitespace ) , right ( delimited ( option ( Token . parseWhitespace ) , Token . parseDelim ( "/" ) ) , Size . parse ) ) ( input ) ; if ( result . isOk ( ) ) { [ input , size ] = result . get ( ) ; } } continue ; } } if ( repeatX === undefined || repeatY === undefined ) { const result = Repeat . parse ( input ) ; if ( result . isOk ( ) ) { [ input , [ repeatX , repeatY ] ] = result . get ( ) ; continue ; } } if ( attachment === undefined ) { const result = Attachment . parse ( input ) ; if ( result . isOk ( ) ) { [ input , attachment ] = result . get ( ) ; continue ; } } if ( origin === undefined ) { const result = Origin . parse ( input ) ; if ( result . isOk ( ) ) { [ input , origin ] = result . get ( ) ; { const result = delimited ( option ( Token . parseWhitespace ) , Clip . parse ) ( input ) ; if ( result . isOk ( ) ) { [ input , clip ] = result . get ( ) ; } } continue ; } } break ; } if ( [ color , image , positionX , positionY , repeatX , repeatY , attachment , origin , clip , ] . every ( ( property ) => property === undefined ) ) { return Err . of ( `Expected one of color, image, position, repeat, attachment, origin, or clip` ) ; } return Result . of ( [ input , [ color , image , positionX , positionY , size , repeatX , repeatY , attachment , origin , clip ?? origin , ] , ] ) ; } ; internal export const parseList = map ( filter ( separatedList ( parse , delimited ( option ( Token . parseWhitespace ) , Token . parseComma ) ) , ( layers ) => [ ... layers ] . slice ( 0 , - 1 ) . every ( ( [ color ] ) => color === undefined ) , ( ) => "Only the last layer may contain a color" ) , ( layers ) => List . of ( layers , ", " ) ) ; /**
 *  https internal export default Property . registerShorthand ( "background" , Property . shorthand ( [ "background-color" , "background-image" , "background-position-x" , "background-position-y" , "background-size" , "background-repeat-x" , "background-repeat-y" , "background-attachment" , "background-origin" , "background-clip" , ] , map ( parseList , ( layers ) => { let color ; let image = [ ] ; let positionX = [ ] ; let positionY = [ ] ; let size = [ ] ; let repeatX = [ ] ; let repeatY = [ ] ; let attachment = [ ] ; let origin = [ ] ; let clip = [ ] ; for ( const layer of layers ) { color = layer [ 0 ] ; image . push ( layer [ 1 ] ?? Keyword . of ( "none" ) ) ; positionX . push ( layer [ 2 ] ?? Percentage . of ( 0 ) ) ; positionY . push ( layer [ 3 ] ?? Percentage . of ( 0 ) ) ; size . push ( layer [ 4 ] ?? Tuple . of ( Keyword . of ( "auto" ) , Keyword . of ( "auto" ) ) ) ; repeatX . push ( layer [ 5 ] ?? Keyword . of ( "repeat" ) ) ; repeatY . push ( layer [ 6 ] ?? Keyword . of ( "repeat" ) ) ; attachment . push ( layer [ 7 ] ?? Keyword . of ( "scroll" ) ) ; origin . push ( layer [ 8 ] ?? Keyword . of ( "padding-box" ) ) ; clip . push ( layer [ 9 ] ?? Keyword . of ( "border-box" ) ) ; } return [ [ "background-color" , color ?? Keyword . of ( "initial" ) ] , [ "background-image" , List . of ( image , ", " ) ] , [ "background-position-x" , List . of ( positionX , ", " ) ] , [ "background-position-y" , List . of ( positionY , ", " ) ] , [ "background-size" , List . of ( size , ", " ) ] , [ "background-repeat-x" , List . of ( repeatX , ", " ) ] , [ "background-repeat-y" , List . of ( repeatY , ", " ) ] , [ "background-attachment" , List . of ( attachment , ", " ) ] , [ "background-origin" , List . of ( origin , ", " ) ] , [ "background-clip" , List . of ( clip , ", " ) ] , ] ; } ) ) ) ;