handlers.go

   1// Copyright (c) 2019, David Kitchen <david@buro9.com>
   2//
   3// All rights reserved.
   4//
   5// Redistribution and use in source and binary forms, with or without
   6// modification, are permitted provided that the following conditions are met:
   7//
   8// * Redistributions of source code must retain the above copyright notice, this
   9//   list of conditions and the following disclaimer.
  10//
  11// * Redistributions in binary form must reproduce the above copyright notice,
  12//   this list of conditions and the following disclaimer in the documentation
  13//   and/or other materials provided with the distribution.
  14//
  15// * Neither the name of the organisation (Microcosm) nor the names of its
  16//   contributors may be used to endorse or promote products derived from
  17//   this software without specific prior written permission.
  18//
  19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  20// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  23// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  25// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  26// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  27// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29
  30package css
  31
  32import (
  33	"regexp"
  34	"strings"
  35)
  36
  37var (
  38	defaultStyleHandlers = map[string]func(string) bool{
  39		"align-content":              AlignContentHandler,
  40		"align-items":                AlignItemsHandler,
  41		"align-self":                 AlignSelfHandler,
  42		"all":                        AllHandler,
  43		"animation":                  AnimationHandler,
  44		"animation-delay":            AnimationDelayHandler,
  45		"animation-direction":        AnimationDirectionHandler,
  46		"animation-duration":         AnimationDurationHandler,
  47		"animation-fill-mode":        AnimationFillModeHandler,
  48		"animation-iteration-count":  AnimationIterationCountHandler,
  49		"animation-name":             AnimationNameHandler,
  50		"animation-play-state":       AnimationPlayStateHandler,
  51		"animation-timing-function":  TimingFunctionHandler,
  52		"backface-visibility":        BackfaceVisibilityHandler,
  53		"background":                 BackgroundHandler,
  54		"background-attachment":      BackgroundAttachmentHandler,
  55		"background-blend-mode":      BackgroundBlendModeHandler,
  56		"background-clip":            BackgroundClipHandler,
  57		"background-color":           ColorHandler,
  58		"background-image":           ImageHandler,
  59		"background-origin":          BackgroundOriginHandler,
  60		"background-position":        BackgroundPositionHandler,
  61		"background-repeat":          BackgroundRepeatHandler,
  62		"background-size":            BackgroundSizeHandler,
  63		"border":                     BorderHandler,
  64		"border-bottom":              BorderSideHandler,
  65		"border-bottom-color":        ColorHandler,
  66		"border-bottom-left-radius":  BorderSideRadiusHandler,
  67		"border-bottom-right-radius": BorderSideRadiusHandler,
  68		"border-bottom-style":        BorderSideStyleHandler,
  69		"border-bottom-width":        BorderSideWidthHandler,
  70		"border-collapse":            BorderCollapseHandler,
  71		"border-color":               ColorHandler,
  72		"border-image":               BorderImageHandler,
  73		"border-image-outset":        BorderImageOutsetHandler,
  74		"border-image-repeat":        BorderImageRepeatHandler,
  75		"border-image-slice":         BorderImageSliceHandler,
  76		"border-image-source":        ImageHandler,
  77		"border-image-width":         BorderImageWidthHandler,
  78		"border-left":                BorderSideHandler,
  79		"border-left-color":          ColorHandler,
  80		"border-left-style":          BorderSideStyleHandler,
  81		"border-left-width":          BorderSideWidthHandler,
  82		"border-radius":              BorderRadiusHandler,
  83		"border-right":               BorderSideHandler,
  84		"border-right-color":         ColorHandler,
  85		"border-right-style":         BorderSideStyleHandler,
  86		"border-right-width":         BorderSideWidthHandler,
  87		"border-spacing":             BorderSpacingHandler,
  88		"border-style":               BorderStyleHandler,
  89		"border-top":                 BorderSideHandler,
  90		"border-top-color":           ColorHandler,
  91		"border-top-left-radius":     BorderSideRadiusHandler,
  92		"border-top-right-radius":    BorderSideRadiusHandler,
  93		"border-top-style":           BorderSideStyleHandler,
  94		"border-top-width":           BorderSideWidthHandler,
  95		"border-width":               BorderWidthHandler,
  96		"bottom":                     SideHandler,
  97		"box-decoration-break":       BoxDecorationBreakHandler,
  98		"box-shadow":                 BoxShadowHandler,
  99		"box-sizing":                 BoxSizingHandler,
 100		"break-after":                BreakBeforeAfterHandler,
 101		"break-before":               BreakBeforeAfterHandler,
 102		"break-inside":               BreakInsideHandler,
 103		"caption-side":               CaptionSideHandler,
 104		"caret-color":                CaretColorHandler,
 105		"clear":                      ClearHandler,
 106		"clip":                       ClipHandler,
 107		"color":                      ColorHandler,
 108		"column-count":               ColumnCountHandler,
 109		"column-fill":                ColumnFillHandler,
 110		"column-gap":                 ColumnGapHandler,
 111		"column-rule":                ColumnRuleHandler,
 112		"column-rule-color":          ColorHandler,
 113		"column-rule-style":          BorderSideStyleHandler,
 114		"column-rule-width":          ColumnRuleWidthHandler,
 115		"column-span":                ColumnSpanHandler,
 116		"column-width":               ColumnWidthHandler,
 117		"columns":                    ColumnsHandler,
 118		"cursor":                     CursorHandler,
 119		"direction":                  DirectionHandler,
 120		"display":                    DisplayHandler,
 121		"empty-cells":                EmptyCellsHandler,
 122		"filter":                     FilterHandler,
 123		"flex":                       FlexHandler,
 124		"flex-basis":                 FlexBasisHandler,
 125		"flex-direction":             FlexDirectionHandler,
 126		"flex-flow":                  FlexFlowHandler,
 127		"flex-grow":                  FlexGrowHandler,
 128		"flex-shrink":                FlexGrowHandler,
 129		"flex-wrap":                  FlexWrapHandler,
 130		"float":                      FloatHandler,
 131		"font":                       FontHandler,
 132		"font-family":                FontFamilyHandler,
 133		"font-kerning":               FontKerningHandler,
 134		"font-language-override":     FontLanguageOverrideHandler,
 135		"font-size":                  FontSizeHandler,
 136		"font-size-adjust":           FontSizeAdjustHandler,
 137		"font-stretch":               FontStretchHandler,
 138		"font-style":                 FontStyleHandler,
 139		"font-synthesis":             FontSynthesisHandler,
 140		"font-variant":               FontVariantHandler,
 141		"font-variant-caps":          FontVariantCapsHandler,
 142		"font-variant-position":      FontVariantPositionHandler,
 143		"font-weight":                FontWeightHandler,
 144		"grid":                       GridHandler,
 145		"grid-area":                  GridAreaHandler,
 146		"grid-auto-columns":          GridAutoColumnsHandler,
 147		"grid-auto-flow":             GridAutoFlowHandler,
 148		"grid-auto-rows":             GridAutoColumnsHandler,
 149		"grid-column":                GridColumnHandler,
 150		"grid-column-end":            GridAxisStartEndHandler,
 151		"grid-column-gap":            LengthHandler,
 152		"grid-column-start":          GridAxisStartEndHandler,
 153		"grid-gap":                   GridGapHandler,
 154		"grid-row":                   GridRowHandler,
 155		"grid-row-end":               GridAxisStartEndHandler,
 156		"grid-row-gap":               LengthHandler,
 157		"grid-row-start":             GridAxisStartEndHandler,
 158		"grid-template":              GridTemplateHandler,
 159		"grid-template-areas":        GridTemplateAreasHandler,
 160		"grid-template-columns":      GridTemplateColumnsHandler,
 161		"grid-template-rows":         GridTemplateRowsHandler,
 162		"hanging-punctuation":        HangingPunctuationHandler,
 163		"height":                     HeightHandler,
 164		"hyphens":                    HyphensHandler,
 165		"image-rendering":            ImageRenderingHandler,
 166		"isolation":                  IsolationHandler,
 167		"justify-content":            JustifyContentHandler,
 168		"left":                       SideHandler,
 169		"letter-spacing":             LetterSpacingHandler,
 170		"line-break":                 LineBreakHandler,
 171		"line-height":                LineHeightHandler,
 172		"list-style":                 ListStyleHandler,
 173		"list-style-image":           ImageHandler,
 174		"list-style-position":        ListStylePositionHandler,
 175		"list-style-type":            ListStyleTypeHandler,
 176		"margin":                     MarginHandler,
 177		"margin-bottom":              MarginSideHandler,
 178		"margin-left":                MarginSideHandler,
 179		"margin-right":               MarginSideHandler,
 180		"margin-top":                 MarginSideHandler,
 181		"max-height":                 MaxHeightWidthHandler,
 182		"max-width":                  MaxHeightWidthHandler,
 183		"min-height":                 MinHeightWidthHandler,
 184		"min-width":                  MinHeightWidthHandler,
 185		"mix-blend-mode":             MixBlendModeHandler,
 186		"object-fit":                 ObjectFitHandler,
 187		"object-position":            ObjectPositionHandler,
 188		"opacity":                    OpacityHandler,
 189		"order":                      OrderHandler,
 190		"orphans":                    OrphansHandler,
 191		"outline":                    OutlineHandler,
 192		"outline-color":              ColorHandler,
 193		"outline-offset":             OutlineOffsetHandler,
 194		"outline-style":              OutlineStyleHandler,
 195		"outline-width":              OutlineWidthHandler,
 196		"overflow":                   OverflowHandler,
 197		"overflow-wrap":              OverflowWrapHandler,
 198		"overflow-x":                 OverflowXYHandler,
 199		"overflow-y":                 OverflowXYHandler,
 200		"padding":                    PaddingHandler,
 201		"padding-bottom":             PaddingSideHandler,
 202		"padding-left":               PaddingSideHandler,
 203		"padding-right":              PaddingSideHandler,
 204		"padding-top":                PaddingSideHandler,
 205		"page-break-after":           PageBreakBeforeAfterHandler,
 206		"page-break-before":          PageBreakBeforeAfterHandler,
 207		"page-break-inside":          PageBreakInsideHandler,
 208		"perspective":                PerspectiveHandler,
 209		"perspective-origin":         PerspectiveOriginHandler,
 210		"pointer-events":             PointerEventsHandler,
 211		"position":                   PositionHandler,
 212		"quotes":                     QuotesHandler,
 213		"resize":                     ResizeHandler,
 214		"right":                      SideHandler,
 215		"scroll-behavior":            ScrollBehaviorHandler,
 216		"tab-size":                   TabSizeHandler,
 217		"table-layout":               TableLayoutHandler,
 218		"text-align":                 TextAlignHandler,
 219		"text-align-last":            TextAlignLastHandler,
 220		"text-combine-upright":       TextCombineUprightHandler,
 221		"text-decoration":            TextDecorationHandler,
 222		"text-decoration-color":      ColorHandler,
 223		"text-decoration-line":       TextDecorationLineHandler,
 224		"text-decoration-style":      TextDecorationStyleHandler,
 225		"text-indent":                TextIndentHandler,
 226		"text-justify":               TextJustifyHandler,
 227		"text-orientation":           TextOrientationHandler,
 228		"text-overflow":              TextOverflowHandler,
 229		"text-shadow":                TextShadowHandler,
 230		"text-transform":             TextTransformHandler,
 231		"top":                        SideHandler,
 232		"transform":                  TransformHandler,
 233		"transform-origin":           TransformOriginHandler,
 234		"transform-style":            TransformStyleHandler,
 235		"transition":                 TransitionHandler,
 236		"transition-delay":           TransitionDelayHandler,
 237		"transition-duration":        TransitionDurationHandler,
 238		"transition-property":        TransitionPropertyHandler,
 239		"transition-timing-function": TimingFunctionHandler,
 240		"unicode-bidi":               UnicodeBidiHandler,
 241		"user-select":                UserSelectHandler,
 242		"vertical-align":             VerticalAlignHandler,
 243		"visibility":                 VisiblityHandler,
 244		"white-space":                WhiteSpaceHandler,
 245		"widows":                     OrphansHandler,
 246		"width":                      WidthHandler,
 247		"word-break":                 WordBreakHandler,
 248		"word-spacing":               WordSpacingHandler,
 249		"word-wrap":                  WordWrapHandler,
 250		"writing-mode":               WritingModeHandler,
 251		"z-index":                    ZIndexHandler,
 252	}
 253	colorValues = []string{"initial", "inherit", "aliceblue", "antiquewhite",
 254		"aqua", "aquamarine", "azure", "beige", "bisque", "black",
 255		"blanchedalmond", "blue", "blueviolet", "brown", "burlywood",
 256		"cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue",
 257		"cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod",
 258		"darkgray", "darkgrey", "darkgreen", "darkkhaki", "darkmagenta",
 259		"darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon",
 260		"darkseagreen", "darkslateblue", "darkslategrey", "darkslategray",
 261		"darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray",
 262		"dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen",
 263		"fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray",
 264		"grey", "green", "greenyellow", "honeydew", "hotpink", "indianred",
 265		"indigo", "ivory", "khaki", "lavender", "lavenderblush",
 266		"lemonchiffon", "lightblue", "lightcoral", "lightcyan",
 267		"lightgoldenrodyellow", "lightgray", "lightgrey", "lightgreen",
 268		"lightpink", "lightsalmon", "lightseagreen", "lightskyblue",
 269		"lightslategray", "lightslategrey", "lightsteeelblue", "lightyellow",
 270		"lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine",
 271		"mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
 272		"mediumslateblue", "mediumspringgreen", "mediumturquoise",
 273		"mediumvioletred", "midnightblue", "mintcream", "mistyrose",
 274		"moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab",
 275		"orange", "orangered", "orchid", "palegoldenrod", "palegreen",
 276		"paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru",
 277		"pink", "plum", "powderblue", "purple", "rebeccapurple", "red",
 278		"rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown",
 279		"seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue",
 280		"slategray", "slategrey", "snow", "springgreen", "steelblue", "tan",
 281		"teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white",
 282		"whitesmoke", "yellow", "yellowgreen"}
 283
 284	Alpha             = regexp.MustCompile(`^[a-z]+$`)
 285	Blur              = regexp.MustCompile(`^blur\([0-9]+px\)$`)
 286	BrightnessCont    = regexp.MustCompile(`^(brightness|contrast)\([0-9]+\%\)$`)
 287	Count             = regexp.MustCompile(`^[0-9]+[\.]?[0-9]*$`)
 288	CubicBezier       = regexp.MustCompile(`^cubic-bezier\(([ ]*(0(.[0-9]+)?|1(.0)?),){3}[ ]*(0(.[0-9]+)?|1)\)$`)
 289	Digits            = regexp.MustCompile(`^digits [2-4]$`)
 290	DropShadow        = regexp.MustCompile(`drop-shadow\(([-]?[0-9]+px) ([-]?[0-9]+px)( [-]?[0-9]+px)?( ([-]?[0-9]+px))?`)
 291	Font              = regexp.MustCompile(`^('[a-z \-]+'|[a-z \-]+)$`)
 292	Grayscale         = regexp.MustCompile(`^grayscale\(([0-9]{1,2}|100)%\)$`)
 293	GridTemplateAreas = regexp.MustCompile(`^['"]?[a-z ]+['"]?$`)
 294	HexRGB            = regexp.MustCompile(`^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$`)
 295	HSL               = regexp.MustCompile(`^hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)$`)
 296	HSLA              = regexp.MustCompile(`^hsla\(([ ]*[012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%,[ ]*(1|1\.0|0|(0\.[0-9]+))\)$`)
 297	HueRotate         = regexp.MustCompile(`^hue-rotate\(([12]?[0-9]{1,2}|3[0-5][0-9]|360)?\)$`)
 298	Invert            = regexp.MustCompile(`^invert\(([0-9]{1,2}|100)%\)$`)
 299	Length            = regexp.MustCompile(`^[\-]?([0-9]+|[0-9]*[\.][0-9]+)(%|cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|deg|rad|turn)?$`)
 300	Matrix            = regexp.MustCompile(`^matrix\(([ ]*[0-9]+[\.]?[0-9]*,){5}([ ]*[0-9]+[\.]?[0-9]*)\)$`)
 301	Matrix3D          = regexp.MustCompile(`^matrix3d\(([ ]*[0-9]+[\.]?[0-9]*,){15}([ ]*[0-9]+[\.]?[0-9]*)\)$`)
 302	NegTime           = regexp.MustCompile(`^[\-]?[0-9]+[\.]?[0-9]*(s|ms)?$`)
 303	Numeric           = regexp.MustCompile(`^[0-9]+$`)
 304	NumericDecimal    = regexp.MustCompile(`^[0-9\.]+$`)
 305	Opactiy           = regexp.MustCompile(`^opacity\(([0-9]{1,2}|100)%\)$`)
 306	Perspective       = regexp.MustCompile(`perspective\(`)
 307	Position          = regexp.MustCompile(`^[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]* [[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]*]*$`)
 308	Opacity           = regexp.MustCompile(`^(0[.]?[0-9]*)|(1.0)$`)
 309	QuotedAlpha       = regexp.MustCompile(`^["'][a-z]+["']$`)
 310	Quotes            = regexp.MustCompile(`^([ ]*["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'] ["'][\x{0022}\x{0027}\x{2039}\x{2039}\x{203A}\x{00AB}\x{00BB}\x{2018}\x{2019}\x{201C}-\x{201E}]["'])+$`)
 311	Rect              = regexp.MustCompile(`^rect\([0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px\)$`)
 312	RGB               = regexp.MustCompile(`^rgb\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){2}([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))))\)$`)
 313	RGBA              = regexp.MustCompile(`^rgba\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){3}[ ]*(1(\.0)?|0|(0\.[0-9]+))\)$`)
 314	Rotate            = regexp.MustCompile(`^rotate(x|y|z)?\(([12]?|3[0-5][0-9]|360)\)$`)
 315	Rotate3D          = regexp.MustCompile(`^rotate3d\(([ ]?(1(\.0)?|0\.[0-9]+),){3}([12]?|3[0-5][0-9]|360)\)$`)
 316	Saturate          = regexp.MustCompile(`^saturate\([0-9]+%\)$`)
 317	Sepia             = regexp.MustCompile(`^sepia\(([0-9]{1,2}|100)%\)$`)
 318	Skew              = regexp.MustCompile(`skew(x|y)?\(`)
 319	Span              = regexp.MustCompile(`^span [0-9]+$`)
 320	Steps             = regexp.MustCompile(`^steps\([ ]*[0-9]+([ ]*,[ ]*(start|end)?)\)$`)
 321	Time              = regexp.MustCompile(`^[0-9]+[\.]?[0-9]*(s|ms)?$`)
 322	TransitionProp    = regexp.MustCompile(`^([a-zA-Z]+,[ ]?)*[a-zA-Z]+$`)
 323	TranslateScale    = regexp.MustCompile(`(translate|translate3d|translatex|translatey|translatez|scale|scale3d|scalex|scaley|scalez)\(`)
 324	URL               = regexp.MustCompile(`^url\([\"\']?((https|http)[a-z0-9\.\\/_:]+[\"\']?)\)$`)
 325	ZIndex            = regexp.MustCompile(`^[\-]?[0-9]+$`)
 326)
 327
 328func multiSplit(value string, seps ...string) []string {
 329	curArray := []string{value}
 330	for _, i := range seps {
 331		newArray := []string{}
 332		for _, j := range curArray {
 333			newArray = append(newArray, strings.Split(j, i)...)
 334		}
 335		curArray = newArray
 336	}
 337	return curArray
 338}
 339
 340func recursiveCheck(value []string, funcs []func(string) bool) bool {
 341	for i := 0; i < len(value); i++ {
 342		tempVal := strings.Join(value[:i+1], " ")
 343		for _, j := range funcs {
 344			if j(tempVal) && (len(value[i+1:]) == 0 || recursiveCheck(value[i+1:], funcs)) {
 345				return true
 346			}
 347		}
 348	}
 349	return false
 350}
 351
 352func in(value []string, arr []string) bool {
 353	for _, i := range value {
 354		foundString := false
 355		for _, j := range arr {
 356			if j == i {
 357				foundString = true
 358			}
 359		}
 360		if !foundString {
 361			return false
 362		}
 363	}
 364	return true
 365}
 366
 367func splitValues(value string) []string {
 368	values := strings.Split(value, ",")
 369	newValues := []string{}
 370	for _, strippedValue := range values {
 371		newValues = append(newValues, strings.ToLower(strings.TrimSpace(strippedValue)))
 372	}
 373	return newValues
 374}
 375
 376func GetDefaultHandler(attr string) func(string) bool {
 377
 378	if defaultStyleHandlers[attr] != nil {
 379		return defaultStyleHandlers[attr]
 380	}
 381	return BaseHandler
 382}
 383
 384func BaseHandler(value string) bool {
 385	return false
 386}
 387
 388func AlignContentHandler(value string) bool {
 389	values := []string{"stretch", "center", "flex-start",
 390		"flex-end", "space-between", "space-around", "initial", "inherit"}
 391	splitVals := splitValues(value)
 392	return in(splitVals, values)
 393}
 394
 395func AlignItemsHandler(value string) bool {
 396	values := []string{"stretch", "center", "flex-start",
 397		"flex-end", "baseline", "initial", "inherit"}
 398	splitVals := splitValues(value)
 399	return in(splitVals, values)
 400}
 401
 402func AlignSelfHandler(value string) bool {
 403	values := []string{"auto", "stretch", "center", "flex-start",
 404		"flex-end", "baseline", "initial", "inherit"}
 405	splitVals := splitValues(value)
 406	return in(splitVals, values)
 407}
 408
 409func AllHandler(value string) bool {
 410	values := []string{"initial", "inherit", "unset"}
 411	splitVals := splitValues(value)
 412	return in(splitVals, values)
 413}
 414
 415func AnimationHandler(value string) bool {
 416	values := []string{"initial", "inherit"}
 417	if in([]string{value}, values) {
 418		return true
 419	}
 420	splitVals := strings.Split(value, " ")
 421	usedFunctions := []func(string) bool{
 422		AnimationNameHandler,
 423		AnimationDurationHandler,
 424		TimingFunctionHandler,
 425		AnimationDelayHandler,
 426		AnimationIterationCountHandler,
 427		AnimationDirectionHandler,
 428		AnimationFillModeHandler,
 429		AnimationPlayStateHandler,
 430	}
 431	return recursiveCheck(splitVals, usedFunctions)
 432}
 433
 434func AnimationDelayHandler(value string) bool {
 435	if NegTime.MatchString(value) {
 436		return true
 437	}
 438	values := []string{"initial", "inherit"}
 439	splitVals := splitValues(value)
 440	return in(splitVals, values)
 441}
 442
 443func AnimationDirectionHandler(value string) bool {
 444	values := []string{"normal", "reverse", "alternate", "alternate-reverse", "initial", "inherit"}
 445	splitVals := splitValues(value)
 446	return in(splitVals, values)
 447}
 448
 449func AnimationDurationHandler(value string) bool {
 450	if Time.MatchString(value) {
 451		return true
 452	}
 453	values := []string{"initial", "inherit"}
 454	splitVals := splitValues(value)
 455	return in(splitVals, values)
 456}
 457
 458func AnimationFillModeHandler(value string) bool {
 459	values := []string{"none", "forwards", "backwards", "both", "initial", "inherit"}
 460	splitVals := splitValues(value)
 461	return in(splitVals, values)
 462}
 463
 464func AnimationIterationCountHandler(value string) bool {
 465	if Count.MatchString(value) {
 466		return true
 467	}
 468	values := []string{"infinite", "initial", "inherit"}
 469	splitVals := splitValues(value)
 470	return in(splitVals, values)
 471}
 472
 473func AnimationNameHandler(value string) bool {
 474	return Alpha.MatchString(value)
 475}
 476
 477func AnimationPlayStateHandler(value string) bool {
 478	values := []string{"paused", "running", "initial", "inherit"}
 479	splitVals := splitValues(value)
 480	return in(splitVals, values)
 481}
 482
 483func TimingFunctionHandler(value string) bool {
 484	values := []string{"linear", "ease", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "initial", "inherit"}
 485	splitVals := splitValues(value)
 486	if in(splitVals, values) {
 487		return true
 488	}
 489	if CubicBezier.MatchString(value) {
 490		return true
 491	}
 492	return Steps.MatchString(value)
 493}
 494
 495func BackfaceVisibilityHandler(value string) bool {
 496	values := []string{"visible", "hidden", "initial", "inherit"}
 497	splitVals := splitValues(value)
 498	return in(splitVals, values)
 499}
 500
 501func BackgroundHandler(value string) bool {
 502	values := []string{"initial", "inherit"}
 503	if in([]string{value}, values) {
 504		return true
 505	}
 506	splitVals := strings.Split(value, " ")
 507	newSplitVals := []string{}
 508	for _, i := range splitVals {
 509		if len(strings.Split(i, "/")) == 2 {
 510			newSplitVals = append(newSplitVals, strings.Split(i, "/")...)
 511		} else {
 512			newSplitVals = append(newSplitVals, i)
 513		}
 514	}
 515	usedFunctions := []func(string) bool{
 516		ColorHandler,
 517		ImageHandler,
 518		BackgroundPositionHandler,
 519		BackgroundSizeHandler,
 520		BackgroundRepeatHandler,
 521		BackgroundOriginHandler,
 522		BackgroundClipHandler,
 523		BackgroundAttachmentHandler,
 524	}
 525	return recursiveCheck(newSplitVals, usedFunctions)
 526}
 527
 528func BackgroundAttachmentHandler(value string) bool {
 529	values := []string{"scroll", "fixed", "local", "initial", "inherit"}
 530	splitVals := splitValues(value)
 531	return in(splitVals, values)
 532}
 533
 534func BackgroundClipHandler(value string) bool {
 535	values := []string{"border-box", "padding-box", "content-box", "initial", "inherit"}
 536	splitVals := splitValues(value)
 537	return in(splitVals, values)
 538}
 539
 540func BackgroundBlendModeHandler(value string) bool {
 541	values := []string{"normal", "multiply", "screen", "overlay", "darken",
 542		"lighten", "color-dodge", "saturation", "color", "luminosity"}
 543	splitVals := splitValues(value)
 544	return in(splitVals, values)
 545}
 546
 547func ImageHandler(value string) bool {
 548	values := []string{"none", "initial", "inherit"}
 549	splitVals := splitValues(value)
 550	if in(splitVals, values) {
 551		return true
 552	}
 553	return URL.MatchString(value)
 554}
 555
 556func BackgroundOriginHandler(value string) bool {
 557	values := []string{"padding-box", "border-box", "content-box", "initial", "inherit"}
 558	splitVals := splitValues(value)
 559	return in(splitVals, values)
 560}
 561
 562func BackgroundPositionHandler(value string) bool {
 563	splitVals := strings.Split(value, ";")
 564	values := []string{"left", "left top", "left bottom", "right", "right top", "right bottom", "right center", "center top", "center center", "center bottom", "center", "top", "bottom", "initial", "inherit"}
 565	if in(splitVals, values) {
 566		return true
 567	}
 568	return Position.MatchString(value)
 569}
 570
 571func BackgroundRepeatHandler(value string) bool {
 572	values := []string{"repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round", "initial", "inherit"}
 573	splitVals := splitValues(value)
 574	return in(splitVals, values)
 575}
 576
 577func BackgroundSizeHandler(value string) bool {
 578	splitVals := strings.Split(value, " ")
 579	values := []string{"auto", "cover", "contain", "initial", "inherit"}
 580	if in(splitVals, values) {
 581		return true
 582	}
 583	if len(splitVals) > 0 && LengthHandler(splitVals[0]) {
 584		if len(splitVals) < 2 || (len(splitVals) == 2 && LengthHandler(splitVals[1])) {
 585			return true
 586		}
 587	}
 588	return false
 589}
 590
 591func BorderHandler(value string) bool {
 592	values := []string{"initial", "inherit"}
 593	if in([]string{value}, values) {
 594		return true
 595	}
 596	splitVals := multiSplit(value, " ", "/")
 597	usedFunctions := []func(string) bool{
 598		BorderWidthHandler,
 599		BorderStyleHandler,
 600		ColorHandler,
 601	}
 602	return recursiveCheck(splitVals, usedFunctions)
 603}
 604
 605func BorderSideHandler(value string) bool {
 606	values := []string{"initial", "inherit"}
 607	if in([]string{value}, values) {
 608		return true
 609	}
 610	splitVals := strings.Split(value, " ")
 611	usedFunctions := []func(string) bool{
 612		BorderSideWidthHandler,
 613		BorderSideStyleHandler,
 614		ColorHandler,
 615	}
 616	return recursiveCheck(splitVals, usedFunctions)
 617}
 618
 619func BorderSideRadiusHandler(value string) bool {
 620	splitVals := strings.Split(value, " ")
 621	valid := true
 622	for _, i := range splitVals {
 623		if !LengthHandler(i) {
 624			valid = false
 625			break
 626		}
 627	}
 628	if valid {
 629		return true
 630	}
 631	splitVals = splitValues(value)
 632	values := []string{"initial", "inherit"}
 633	return in(splitVals, values)
 634}
 635
 636func BorderSideStyleHandler(value string) bool {
 637	values := []string{"none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "initial", "inherit"}
 638	splitVals := splitValues(value)
 639	return in(splitVals, values)
 640}
 641
 642func BorderSideWidthHandler(value string) bool {
 643	if LengthHandler(value) {
 644		return true
 645	}
 646	splitVals := strings.Split(value, ";")
 647	values := []string{"medium", "thin", "thick", "initial", "inherit"}
 648	return in(splitVals, values)
 649}
 650
 651func BorderCollapseHandler(value string) bool {
 652	values := []string{"separate", "collapse", "initial", "inherit"}
 653	splitVals := splitValues(value)
 654	return in(splitVals, values)
 655}
 656
 657func BorderImageHandler(value string) bool {
 658	values := []string{"initial", "inherit"}
 659	if in([]string{value}, values) {
 660		return true
 661	}
 662	splitVals := multiSplit(value, " ", " / ")
 663	usedFunctions := []func(string) bool{
 664		ImageHandler,
 665		BorderImageSliceHandler,
 666		BorderImageWidthHandler,
 667		BorderImageOutsetHandler,
 668		BorderImageRepeatHandler,
 669	}
 670	return recursiveCheck(splitVals, usedFunctions)
 671}
 672
 673func BorderImageOutsetHandler(value string) bool {
 674	if LengthHandler(value) {
 675		return true
 676	}
 677	values := []string{"initial", "inherit"}
 678	splitVals := splitValues(value)
 679	return in(splitVals, values)
 680}
 681
 682func BorderImageRepeatHandler(value string) bool {
 683	values := []string{"stretch", "repeat", "round", "space", "initial", "inherit"}
 684	splitVals := splitValues(value)
 685	return in(splitVals, values)
 686}
 687
 688func BorderImageSliceHandler(value string) bool {
 689	values := []string{"fill", "initial", "inherit"}
 690	if in([]string{value}, values) {
 691		return true
 692	}
 693	splitVals := strings.Split(value, " ")
 694	if len(splitVals) > 4 {
 695		return false
 696	}
 697	usedFunctions := []func(string) bool{
 698		LengthHandler,
 699	}
 700	return recursiveCheck(splitVals, usedFunctions)
 701}
 702
 703func BorderImageWidthHandler(value string) bool {
 704	if LengthHandler(value) {
 705		return true
 706	}
 707	values := []string{"auto", "initial", "inherit"}
 708	splitVals := splitValues(value)
 709	return in(splitVals, values)
 710}
 711
 712func BorderRadiusHandler(value string) bool {
 713	values := []string{"initial", "inherit"}
 714	if in([]string{value}, values) {
 715		return true
 716	}
 717	splitVals := strings.Split(value, " ")
 718	if len(splitVals) > 4 {
 719		return false
 720	}
 721	usedFunctions := []func(string) bool{
 722		LengthHandler,
 723	}
 724	return recursiveCheck(splitVals, usedFunctions)
 725}
 726
 727func BorderSpacingHandler(value string) bool {
 728	values := []string{"initial", "inherit"}
 729	if in([]string{value}, values) {
 730		return true
 731	}
 732	splitVals := strings.Split(value, " ")
 733	if len(splitVals) > 2 {
 734		return false
 735	}
 736	usedFunctions := []func(string) bool{
 737		LengthHandler,
 738	}
 739	return recursiveCheck(splitVals, usedFunctions)
 740}
 741
 742func BorderStyleHandler(value string) bool {
 743	values := []string{"initial", "inherit"}
 744	if in([]string{value}, values) {
 745		return true
 746	}
 747	splitVals := strings.Split(value, " ")
 748	if len(splitVals) > 4 {
 749		return false
 750	}
 751	usedFunctions := []func(string) bool{
 752		BorderSideStyleHandler,
 753	}
 754	return recursiveCheck(splitVals, usedFunctions)
 755}
 756
 757func BorderWidthHandler(value string) bool {
 758	values := []string{"initial", "inherit"}
 759	if in([]string{value}, values) {
 760		return true
 761	}
 762	splitVals := strings.Split(value, " ")
 763	if len(splitVals) > 4 {
 764		return false
 765	}
 766	usedFunctions := []func(string) bool{
 767		BorderSideWidthHandler,
 768	}
 769	return recursiveCheck(splitVals, usedFunctions)
 770}
 771
 772func SideHandler(value string) bool {
 773	if LengthHandler(value) {
 774		return true
 775	}
 776	values := []string{"auto", "inherit", "unset"}
 777	splitVals := splitValues(value)
 778	return in(splitVals, values)
 779}
 780
 781func BoxDecorationBreakHandler(value string) bool {
 782	values := []string{"slice", "clone", "initial", "initial", "inherit", "unset"}
 783	splitVals := splitValues(value)
 784	return in(splitVals, values)
 785}
 786
 787func BoxShadowHandler(value string) bool {
 788	values := []string{"none", "initial", "inherit"}
 789	if in([]string{value}, values) {
 790		return true
 791	}
 792	commaSplitVals := strings.Split(value, ",")
 793	for _, val := range commaSplitVals {
 794		splitVals := strings.Split(val, " ")
 795		if len(splitVals) > 6 || len(splitVals) < 2 {
 796			return false
 797		}
 798		if !LengthHandler(splitVals[0]) {
 799			return false
 800		}
 801		if !LengthHandler(splitVals[1]) {
 802			return false
 803		}
 804		usedFunctions := []func(string) bool{
 805			LengthHandler,
 806			ColorHandler,
 807		}
 808		if len(splitVals) > 2 && !recursiveCheck(splitVals[2:], usedFunctions) {
 809			return false
 810		}
 811	}
 812	return true
 813}
 814
 815func BoxSizingHandler(value string) bool {
 816	values := []string{"slicontent-box", "border-box", "initial", "inherit"}
 817	splitVals := splitValues(value)
 818	return in(splitVals, values)
 819}
 820
 821func BreakBeforeAfterHandler(value string) bool {
 822	values := []string{"auto", "avoid", "always", "all", "avoid-page", "page", "left", "right", "recto", "verso", "avoid-column", "column", "avoid-region", "region"}
 823	splitVals := splitValues(value)
 824	return in(splitVals, values)
 825}
 826
 827func BreakInsideHandler(value string) bool {
 828	values := []string{"auto", "avoid", "avoid-page", "avoid-column", "avoid-region"}
 829	splitVals := splitValues(value)
 830	return in(splitVals, values)
 831}
 832
 833func CaptionSideHandler(value string) bool {
 834	values := []string{"top", "bottom", "initial", "inherit"}
 835	splitVals := splitValues(value)
 836	return in(splitVals, values)
 837}
 838
 839func CaretColorHandler(value string) bool {
 840	splitVals := splitValues(value)
 841	if in(splitVals, colorValues) {
 842		return true
 843	}
 844	if HexRGB.MatchString(value) {
 845		return true
 846	}
 847	if RGB.MatchString(value) {
 848		return true
 849	}
 850	if RGBA.MatchString(value) {
 851		return true
 852	}
 853	if HSL.MatchString(value) {
 854		return true
 855	}
 856	return HSLA.MatchString(value)
 857}
 858
 859func ClearHandler(value string) bool {
 860	values := []string{"none", "left", "right", "both", "initial", "inherit"}
 861	splitVals := splitValues(value)
 862	return in(splitVals, values)
 863}
 864
 865func ClipHandler(value string) bool {
 866	if Rect.MatchString(value) {
 867		return true
 868	}
 869	values := []string{"auto", "initial", "inherit"}
 870	splitVals := splitValues(value)
 871	return in(splitVals, values)
 872}
 873
 874func ColorHandler(value string) bool {
 875	splitVals := splitValues(value)
 876	if in(splitVals, colorValues) {
 877		return true
 878	}
 879	if HexRGB.MatchString(value) {
 880		return true
 881	}
 882	if RGB.MatchString(value) {
 883		return true
 884	}
 885	if RGBA.MatchString(value) {
 886		return true
 887	}
 888	if HSL.MatchString(value) {
 889		return true
 890	}
 891	return HSLA.MatchString(value)
 892}
 893
 894func ColumnCountHandler(value string) bool {
 895	if Numeric.MatchString(value) {
 896		return true
 897	}
 898	values := []string{"auto", "initial", "inherit"}
 899	splitVals := splitValues(value)
 900	return in(splitVals, values)
 901}
 902
 903func ColumnFillHandler(value string) bool {
 904	values := []string{"balance", "auto", "initial", "inherit"}
 905	splitVals := splitValues(value)
 906	return in(splitVals, values)
 907}
 908
 909func ColumnGapHandler(value string) bool {
 910	if LengthHandler(value) {
 911		return true
 912	}
 913	values := []string{"normal", "initial", "inherit"}
 914	splitVals := splitValues(value)
 915	return in(splitVals, values)
 916}
 917
 918func ColumnRuleHandler(value string) bool {
 919	values := []string{"initial", "inherit"}
 920	if in([]string{value}, values) {
 921		return true
 922	}
 923	splitVals := strings.Split(value, " ")
 924	usedFunctions := []func(string) bool{
 925		ColumnRuleWidthHandler,
 926		BorderSideStyleHandler,
 927		ColorHandler,
 928	}
 929	return recursiveCheck(splitVals, usedFunctions)
 930}
 931
 932func ColumnRuleWidthHandler(value string) bool {
 933	if LengthHandler(value) {
 934		return true
 935	}
 936	splitVals := strings.Split(value, ";")
 937	values := []string{"medium", "thin", "thick", "initial", "inherit"}
 938	return in(splitVals, values)
 939}
 940
 941func ColumnSpanHandler(value string) bool {
 942	values := []string{"none", "all", "initial", "inherit"}
 943	splitVals := splitValues(value)
 944	return in(splitVals, values)
 945}
 946
 947func ColumnWidthHandler(value string) bool {
 948	if LengthHandler(value) {
 949		return true
 950	}
 951	splitVals := strings.Split(value, ";")
 952	values := []string{"auto", "initial", "inherit"}
 953	return in(splitVals, values)
 954}
 955
 956func ColumnsHandler(value string) bool {
 957	values := []string{"auto", "initial", "inherit"}
 958	if in([]string{value}, values) {
 959		return true
 960	}
 961	splitVals := strings.Split(value, " ")
 962	usedFunctions := []func(string) bool{
 963		ColumnWidthHandler,
 964		ColumnCountHandler,
 965	}
 966	return recursiveCheck(splitVals, usedFunctions)
 967}
 968
 969func CursorHandler(value string) bool {
 970	values := []string{"alias", "all-scroll", "auto", "cell", "context-menu", "col-resize", "copy", "crosshair", "default", "e-resize", "ew-resize", "grab", "grabbing", "help", "move", "n-resize", "ne-resize", "nesw-resize", "ns-resize", "nw-resize", "nwse-resize", "no-drop", "none", "not-allowed", "pointer", "progress", "row-resize", "s-resize", "se-resize", "sw-resize", "text", "vertical-text", "w-resize", "wait", "zoom-in", "zoom-out", "initial", "inherit"}
 971	splitVals := splitValues(value)
 972	return in(splitVals, values)
 973}
 974
 975func DirectionHandler(value string) bool {
 976	values := []string{"ltr", "rtl", "initial", "inherit"}
 977	splitVals := splitValues(value)
 978	return in(splitVals, values)
 979}
 980
 981func DisplayHandler(value string) bool {
 982	values := []string{"inline", "block", "contents", "flex", "grid", "inline-block", "inline-flex", "inline-grid", "inline-table", "list-item", "run-in", "table", "table-caption", "table-column-group", "table-header-group", "table-footer-group", "table-row-group", "table-cell", "table-column", "table-row", "none", "initial", "inherit"}
 983	splitVals := splitValues(value)
 984	return in(splitVals, values)
 985}
 986
 987func EmptyCellsHandler(value string) bool {
 988	values := []string{"show", "hide", "initial", "inherit"}
 989	splitVals := splitValues(value)
 990	return in(splitVals, values)
 991}
 992
 993func FilterHandler(value string) bool {
 994	values := []string{"none", "initial", "inherit"}
 995	splitVals := splitValues(value)
 996	if in(splitVals, values) {
 997		return true
 998	}
 999	if Blur.MatchString(value) {
1000		return true
1001	}
1002	if BrightnessCont.MatchString(value) {
1003		return true
1004	}
1005	if DropShadow.MatchString(value) {
1006		return true
1007	}
1008	colorValue := strings.TrimSuffix(string(DropShadow.ReplaceAll([]byte(value), []byte{})), ")")
1009	if ColorHandler(colorValue) {
1010		return true
1011	}
1012	if Grayscale.MatchString(value) {
1013		return true
1014	}
1015	if HueRotate.MatchString(value) {
1016		return true
1017	}
1018	if Invert.MatchString(value) {
1019		return true
1020	}
1021	if Opacity.MatchString(value) {
1022		return true
1023	}
1024	if Saturate.MatchString(value) {
1025		return true
1026	}
1027	return Sepia.MatchString(value)
1028}
1029
1030func FlexHandler(value string) bool {
1031	values := []string{"auto", "initial", "initial", "inherit"}
1032	if in([]string{value}, values) {
1033		return true
1034	}
1035	splitVals := strings.Split(value, " ")
1036	usedFunctions := []func(string) bool{
1037		FlexGrowHandler,
1038		FlexBasisHandler,
1039	}
1040	return recursiveCheck(splitVals, usedFunctions)
1041}
1042
1043func FlexBasisHandler(value string) bool {
1044	if LengthHandler(value) {
1045		return true
1046	}
1047	splitVals := strings.Split(value, ";")
1048	values := []string{"auto", "initial", "inherit"}
1049	return in(splitVals, values)
1050}
1051
1052func FlexDirectionHandler(value string) bool {
1053	values := []string{"row", "row-reverse", "column", "column-reverse", "initial", "inherit"}
1054	splitVals := splitValues(value)
1055	return in(splitVals, values)
1056}
1057
1058func FlexFlowHandler(value string) bool {
1059	values := []string{"initial", "inherit"}
1060	if in([]string{value}, values) {
1061		return true
1062	}
1063	splitVals := strings.Split(value, " ")
1064	usedFunctions := []func(string) bool{
1065		FlexDirectionHandler,
1066		FlexWrapHandler,
1067	}
1068	return recursiveCheck(splitVals, usedFunctions)
1069}
1070
1071func FlexGrowHandler(value string) bool {
1072	if NumericDecimal.MatchString(value) {
1073		return true
1074	}
1075	splitVals := strings.Split(value, ";")
1076	values := []string{"initial", "inherit"}
1077	return in(splitVals, values)
1078}
1079
1080func FlexWrapHandler(value string) bool {
1081	values := []string{"nowrap", "wrap", "wrap-reverse", "initial", "inherit"}
1082	splitVals := splitValues(value)
1083	return in(splitVals, values)
1084}
1085
1086func FloatHandler(value string) bool {
1087	values := []string{"none", "left", "right", "initial", "inherit"}
1088	splitVals := splitValues(value)
1089	return in(splitVals, values)
1090}
1091
1092func FontHandler(value string) bool {
1093	values := []string{"caption", "icon", "menu", "message-box", "small-caption", "status-bar", "initial", "inherit"}
1094	if in([]string{value}, values) {
1095		return true
1096	}
1097	splitVals := strings.Split(value, " ")
1098	newSplitVals := []string{}
1099	for _, i := range splitVals {
1100		if len(strings.Split(i, "/")) == 2 {
1101			newSplitVals = append(newSplitVals, strings.Split(i, "/")...)
1102		} else {
1103			newSplitVals = append(newSplitVals, i)
1104		}
1105	}
1106	usedFunctions := []func(string) bool{
1107		FontStyleHandler,
1108		FontVariantHandler,
1109		FontWeightHandler,
1110		FontSizeHandler,
1111		FontFamilyHandler,
1112	}
1113	return recursiveCheck(newSplitVals, usedFunctions)
1114}
1115
1116func FontFamilyHandler(value string) bool {
1117	values := []string{"initial", "inherit"}
1118	splitVals := splitValues(value)
1119	if in(splitVals, values) {
1120		return true
1121	}
1122	for _, i := range splitVals {
1123		i = strings.TrimSpace(i)
1124		if Font.FindString(i) != i {
1125			return false
1126		}
1127	}
1128	return true
1129}
1130
1131func FontKerningHandler(value string) bool {
1132	values := []string{"auto", "normal", "none"}
1133	splitVals := splitValues(value)
1134	return in(splitVals, values)
1135}
1136
1137func FontLanguageOverrideHandler(value string) bool {
1138	return Alpha.MatchString(value)
1139}
1140
1141func FontSizeHandler(value string) bool {
1142	if LengthHandler(value) {
1143		return true
1144	}
1145	values := []string{"medium", "xx-small", "x-small", "small", "large", "x-large", "xx-large", "smaller", "larger", "initial", "inherit"}
1146	splitVals := splitValues(value)
1147	return in(splitVals, values)
1148}
1149
1150func FontSizeAdjustHandler(value string) bool {
1151	if Count.MatchString(value) {
1152		return true
1153	}
1154	values := []string{"auto", "initial", "inherit"}
1155	splitVals := splitValues(value)
1156	return in(splitVals, values)
1157}
1158
1159func FontStretchHandler(value string) bool {
1160	values := []string{"ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", "initial", "inherit"}
1161	splitVals := splitValues(value)
1162	return in(splitVals, values)
1163}
1164
1165func FontStyleHandler(value string) bool {
1166	values := []string{"normal", "italic", "oblique", "initial", "inherit"}
1167	splitVals := splitValues(value)
1168	return in(splitVals, values)
1169}
1170
1171func FontSynthesisHandler(value string) bool {
1172	values := []string{"none", "style", "weight"}
1173	splitVals := splitValues(value)
1174	return in(splitVals, values)
1175}
1176
1177func FontVariantCapsHandler(value string) bool {
1178	values := []string{"normal", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps"}
1179	splitVals := splitValues(value)
1180	return in(splitVals, values)
1181}
1182
1183func FontVariantHandler(value string) bool {
1184	values := []string{"normal", "small-caps", "initial", "inherit"}
1185	splitVals := splitValues(value)
1186	return in(splitVals, values)
1187}
1188
1189func FontVariantPositionHandler(value string) bool {
1190	values := []string{"normal", "sub", "super"}
1191	splitVals := splitValues(value)
1192	return in(splitVals, values)
1193}
1194
1195func FontWeightHandler(value string) bool {
1196	values := []string{"normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "initial", "inherit"}
1197	splitVals := splitValues(value)
1198	return in(splitVals, values)
1199}
1200
1201func GridHandler(value string) bool {
1202	values := []string{"none", "initial", "inherit"}
1203	if in([]string{value}, values) {
1204		return true
1205	}
1206	splitVals := strings.Split(value, " ")
1207	newSplitVals := []string{}
1208	for _, i := range splitVals {
1209		if i != "/" {
1210			newSplitVals = append(newSplitVals, i)
1211		}
1212	}
1213	usedFunctions := []func(string) bool{
1214		GridTemplateRowsHandler,
1215		GridTemplateColumnsHandler,
1216		GridTemplateAreasHandler,
1217		GridAutoColumnsHandler,
1218		GridAutoFlowHandler,
1219	}
1220	return recursiveCheck(newSplitVals, usedFunctions)
1221}
1222
1223func GridAreaHandler(value string) bool {
1224	values := []string{"none", "initial", "inherit"}
1225	if in([]string{value}, values) {
1226		return true
1227	}
1228	splitVals := strings.Split(value, " / ")
1229	usedFunctions := []func(string) bool{
1230		GridAxisStartEndHandler,
1231	}
1232	return recursiveCheck(splitVals, usedFunctions)
1233}
1234
1235func GridAutoColumnsHandler(value string) bool {
1236	if LengthHandler(value) {
1237		return true
1238	}
1239	values := []string{"auto", "max-content", "min-content", "initial", "inherit"}
1240	splitVals := splitValues(value)
1241	return in(splitVals, values)
1242}
1243
1244func GridAutoFlowHandler(value string) bool {
1245	values := []string{"row", "column", "dense", "row dense", "column dense"}
1246	splitVals := splitValues(value)
1247	return in(splitVals, values)
1248}
1249
1250func GridColumnHandler(value string) bool {
1251	values := []string{"none", "initial", "inherit"}
1252	if in([]string{value}, values) {
1253		return true
1254	}
1255	splitVals := strings.Split(value, " / ")
1256	if len(splitVals) > 2 {
1257		return false
1258	}
1259	usedFunctions := []func(string) bool{
1260		GridAxisStartEndHandler,
1261	}
1262	return recursiveCheck(splitVals, usedFunctions)
1263}
1264
1265func GridColumnGapHandler(value string) bool {
1266	return LengthHandler(value)
1267}
1268
1269func LengthHandler(value string) bool {
1270	return Length.MatchString(value)
1271}
1272
1273func LineBreakHandler(value string) bool {
1274	values := []string{"auto", "loose", "normal", "strict"}
1275	splitVals := splitValues(value)
1276	return in(splitVals, values)
1277}
1278
1279func GridAxisStartEndHandler(value string) bool {
1280	if Numeric.MatchString(value) {
1281		return true
1282	}
1283	if Span.MatchString(value) {
1284		return true
1285	}
1286	values := []string{"auto"}
1287	splitVals := splitValues(value)
1288	return in(splitVals, values)
1289}
1290
1291func GridGapHandler(value string) bool {
1292	splitVals := strings.Split(value, " ")
1293	if len(splitVals) > 2 {
1294		return false
1295	}
1296	usedFunctions := []func(string) bool{
1297		GridColumnGapHandler,
1298	}
1299	return recursiveCheck(splitVals, usedFunctions)
1300}
1301
1302func GridRowHandler(value string) bool {
1303	splitVals := strings.Split(value, " / ")
1304	if len(splitVals) > 2 {
1305		return false
1306	}
1307	usedFunctions := []func(string) bool{
1308		GridAxisStartEndHandler,
1309	}
1310	return recursiveCheck(splitVals, usedFunctions)
1311}
1312
1313func GridTemplateHandler(value string) bool {
1314	values := []string{"none", "initial", "inherit"}
1315	if in([]string{value}, values) {
1316		return true
1317	}
1318	splitVals := strings.Split(value, " / ")
1319	if len(splitVals) > 2 {
1320		return false
1321	}
1322	usedFunctions := []func(string) bool{
1323		GridTemplateColumnsHandler,
1324		GridTemplateRowsHandler,
1325	}
1326	return recursiveCheck(splitVals, usedFunctions)
1327}
1328
1329func GridTemplateAreasHandler(value string) bool {
1330	values := []string{"none"}
1331	if in([]string{value}, values) {
1332		return true
1333	}
1334	return GridTemplateAreas.MatchString(value)
1335}
1336
1337func GridTemplateColumnsHandler(value string) bool {
1338	splitVals := strings.Split(value, " ")
1339	values := []string{"none", "auto", "max-content", "min-content", "initial", "inherit"}
1340	for _, val := range splitVals {
1341		if LengthHandler(val) {
1342			continue
1343		}
1344		valArr := []string{val}
1345		if !in(valArr, values) {
1346			return false
1347		}
1348	}
1349	return true
1350}
1351
1352func GridTemplateRowsHandler(value string) bool {
1353	splitVals := strings.Split(value, " ")
1354	values := []string{"none", "auto", "max-content", "min-content"}
1355	for _, val := range splitVals {
1356		if LengthHandler(val) {
1357			continue
1358		}
1359		valArr := []string{val}
1360		if !in(valArr, values) {
1361			return false
1362		}
1363	}
1364	return true
1365}
1366
1367func HangingPunctuationHandler(value string) bool {
1368	values := []string{"none", "first", "last", "allow-end", "force-end", "initial", "inherit"}
1369	splitVals := splitValues(value)
1370	return in(splitVals, values)
1371}
1372
1373func HeightHandler(value string) bool {
1374	if LengthHandler(value) {
1375		return true
1376	}
1377	values := []string{"auto", "initial", "inherit"}
1378	splitVals := splitValues(value)
1379	return in(splitVals, values)
1380}
1381
1382func HyphensHandler(value string) bool {
1383	values := []string{"none", "manual", "auto", "initial", "inherit"}
1384	splitVals := splitValues(value)
1385	return in(splitVals, values)
1386}
1387
1388func ImageRenderingHandler(value string) bool {
1389	values := []string{"auto", "smooth", "high-quality", "crisp-edges", "pixelated"}
1390	splitVals := splitValues(value)
1391	return in(splitVals, values)
1392}
1393
1394func IsolationHandler(value string) bool {
1395	values := []string{"auto", "isolate", "initial", "inherit"}
1396	splitVals := splitValues(value)
1397	return in(splitVals, values)
1398}
1399
1400func JustifyContentHandler(value string) bool {
1401	values := []string{"flex-start", "flex-end", "center", "space-between", "space-around", "initial", "inherit"}
1402	splitVals := splitValues(value)
1403	return in(splitVals, values)
1404}
1405
1406func LetterSpacingHandler(value string) bool {
1407	if LengthHandler(value) {
1408		return true
1409	}
1410	values := []string{"normal", "initial", "inherit"}
1411	splitVals := splitValues(value)
1412	return in(splitVals, values)
1413}
1414
1415func LineHeightHandler(value string) bool {
1416	if LengthHandler(value) {
1417		return true
1418	}
1419	values := []string{"normal", "initial", "inherit"}
1420	splitVals := splitValues(value)
1421	return in(splitVals, values)
1422}
1423
1424func ListStyleHandler(value string) bool {
1425	values := []string{"initial", "inherit"}
1426	if in([]string{value}, values) {
1427		return true
1428	}
1429	splitVals := strings.Split(value, " ")
1430	usedFunctions := []func(string) bool{
1431		ListStyleTypeHandler,
1432		ListStylePositionHandler,
1433		ImageHandler,
1434	}
1435	return recursiveCheck(splitVals, usedFunctions)
1436}
1437
1438func ListStylePositionHandler(value string) bool {
1439	values := []string{"inside", "outside", "initial", "inherit"}
1440	splitVals := splitValues(value)
1441	return in(splitVals, values)
1442}
1443
1444func ListStyleTypeHandler(value string) bool {
1445	values := []string{"disc", "armenian", "circle", "cjk-ideographic", "decimal", "decimal-leading-zero", "georgian", "hebrew", "hiragana", "hiragana-iroha", "katakana", "katakana-iroha", "lower-alpha", "lower-greek", "lower-latin", "lower-roman", "none", "square", "upper-alpha", "upper-greek", "upper-latin", "upper-roman", "initial", "inherit"}
1446	splitVals := splitValues(value)
1447	return in(splitVals, values)
1448}
1449
1450func MarginHandler(value string) bool {
1451	values := []string{"auto", "initial", "inherit"}
1452	if in([]string{value}, values) {
1453		return true
1454	}
1455	splitVals := strings.Split(value, " ")
1456	usedFunctions := []func(string) bool{
1457		MarginSideHandler,
1458	}
1459	return recursiveCheck(splitVals, usedFunctions)
1460}
1461
1462func MarginSideHandler(value string) bool {
1463	if LengthHandler(value) {
1464		return true
1465	}
1466	values := []string{"auto", "initial", "inherit"}
1467	splitVals := splitValues(value)
1468	return in(splitVals, values)
1469}
1470
1471func MaxHeightWidthHandler(value string) bool {
1472	if LengthHandler(value) {
1473		return true
1474	}
1475	values := []string{"none", "initial", "inherit"}
1476	splitVals := splitValues(value)
1477	return in(splitVals, values)
1478}
1479
1480func MinHeightWidthHandler(value string) bool {
1481	if LengthHandler(value) {
1482		return true
1483	}
1484	values := []string{"initial", "inherit"}
1485	splitVals := splitValues(value)
1486	return in(splitVals, values)
1487}
1488
1489func MixBlendModeHandler(value string) bool {
1490	values := []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}
1491	splitVals := splitValues(value)
1492	return in(splitVals, values)
1493}
1494
1495func ObjectFitHandler(value string) bool {
1496	values := []string{"fill", "contain", "cover", "none", "scale-down", "initial", "inherit"}
1497	splitVals := splitValues(value)
1498	return in(splitVals, values)
1499}
1500
1501func ObjectPositionHandler(value string) bool {
1502	values := []string{"initial", "inherit"}
1503	if in([]string{value}, values) {
1504		return true
1505	}
1506	splitVals := strings.Split(value, " ")
1507	if len(splitVals) > 2 {
1508		return false
1509	}
1510	usedFunctions := []func(string) bool{
1511		LengthHandler,
1512	}
1513	return recursiveCheck(splitVals, usedFunctions)
1514}
1515
1516func OpacityHandler(value string) bool {
1517	if Opacity.MatchString(value) {
1518		return true
1519	}
1520	values := []string{"initial", "inherit"}
1521	splitVals := splitValues(value)
1522	return in(splitVals, values)
1523}
1524
1525func OrderHandler(value string) bool {
1526	if Numeric.MatchString(value) {
1527		return true
1528	}
1529	values := []string{"initial", "inherit"}
1530	splitVals := splitValues(value)
1531	return in(splitVals, values)
1532}
1533
1534func OutlineHandler(value string) bool {
1535	values := []string{"initial", "inherit"}
1536	if in([]string{value}, values) {
1537		return true
1538	}
1539	splitVals := strings.Split(value, " ")
1540	usedFunctions := []func(string) bool{
1541		ColorHandler,
1542		OutlineWidthHandler,
1543		OutlineStyleHandler,
1544	}
1545	return recursiveCheck(splitVals, usedFunctions)
1546}
1547
1548func OutlineOffsetHandler(value string) bool {
1549	if LengthHandler(value) {
1550		return true
1551	}
1552	values := []string{"initial", "inherit"}
1553	splitVals := splitValues(value)
1554	return in(splitVals, values)
1555}
1556
1557func OutlineStyleHandler(value string) bool {
1558	values := []string{"none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "initial", "inherit"}
1559	splitVals := splitValues(value)
1560	return in(splitVals, values)
1561}
1562
1563func OutlineWidthHandler(value string) bool {
1564	if LengthHandler(value) {
1565		return true
1566	}
1567	values := []string{"medium", "thin", "thick", "initial", "inherit"}
1568	splitVals := splitValues(value)
1569	return in(splitVals, values)
1570}
1571
1572func OverflowHandler(value string) bool {
1573	values := []string{"visible", "hidden", "scroll", "auto", "initial", "inherit"}
1574	splitVals := splitValues(value)
1575	return in(splitVals, values)
1576}
1577
1578func OverflowXYHandler(value string) bool {
1579	values := []string{"visible", "hidden", "scroll", "auto", "initial", "inherit"}
1580	splitVals := splitValues(value)
1581	return in(splitVals, values)
1582}
1583
1584func OverflowWrapHandler(value string) bool {
1585	values := []string{"normal", "break-word", "anywhere"}
1586	splitVals := splitValues(value)
1587	return in(splitVals, values)
1588}
1589
1590func OrphansHandler(value string) bool {
1591	return Numeric.MatchString(value)
1592}
1593
1594func PaddingHandler(value string) bool {
1595	values := []string{"initial", "inherit"}
1596	if in([]string{value}, values) {
1597		return true
1598	}
1599	splitVals := strings.Split(value, " ")
1600	if len(splitVals) > 4 {
1601		return false
1602	}
1603	usedFunctions := []func(string) bool{
1604		PaddingSideHandler,
1605	}
1606	return recursiveCheck(splitVals, usedFunctions)
1607}
1608
1609func PaddingSideHandler(value string) bool {
1610	if LengthHandler(value) {
1611		return true
1612	}
1613	values := []string{"initial", "inherit"}
1614	splitVals := splitValues(value)
1615	return in(splitVals, values)
1616}
1617
1618func PageBreakBeforeAfterHandler(value string) bool {
1619	values := []string{"auto", "always", "avoid", "left", "right", "initial", "inherit"}
1620	splitVals := splitValues(value)
1621	return in(splitVals, values)
1622}
1623
1624func PageBreakInsideHandler(value string) bool {
1625	values := []string{"auto", "avoid", "initial", "inherit"}
1626	splitVals := splitValues(value)
1627	return in(splitVals, values)
1628}
1629
1630func PerspectiveHandler(value string) bool {
1631	if LengthHandler(value) {
1632		return true
1633	}
1634	values := []string{"none", "initial", "inherit"}
1635	splitVals := splitValues(value)
1636	return in(splitVals, values)
1637}
1638
1639func PerspectiveOriginHandler(value string) bool {
1640	values := []string{"initial", "inherit"}
1641	if in([]string{value}, values) {
1642		return true
1643	}
1644	splitVals := strings.Split(value, " ")
1645	xValues := []string{"left", "center", "right"}
1646	yValues := []string{"top", "center", "bottom"}
1647	if len(splitVals) > 1 {
1648		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
1649			return false
1650		}
1651		return in([]string{splitVals[1]}, yValues) || LengthHandler(splitVals[1])
1652	} else if len(splitVals) == 1 {
1653		return in(splitVals, xValues) || in(splitVals, yValues) || LengthHandler(splitVals[0])
1654	}
1655	return false
1656}
1657
1658func PointerEventsHandler(value string) bool {
1659	values := []string{"auto", "none", "initial", "inherit"}
1660	splitVals := splitValues(value)
1661	return in(splitVals, values)
1662}
1663
1664func PositionHandler(value string) bool {
1665	values := []string{"static", "absolute", "fixed", "relative", "sticky", "initial", "inherit"}
1666	splitVals := splitValues(value)
1667	return in(splitVals, values)
1668}
1669
1670func QuotesHandler(value string) bool {
1671	values := []string{"none", "initial", "inherit"}
1672	splitVals := splitValues(value)
1673	if in(splitVals, values) {
1674		return true
1675	}
1676	return Quotes.MatchString(value)
1677}
1678
1679func ResizeHandler(value string) bool {
1680	values := []string{"none", "both", "horizontal", "vertical", "initial", "inherit"}
1681	splitVals := splitValues(value)
1682	return in(splitVals, values)
1683}
1684
1685func ScrollBehaviorHandler(value string) bool {
1686	values := []string{"auto", "smooth", "initial", "inherit"}
1687	splitVals := splitValues(value)
1688	return in(splitVals, values)
1689}
1690
1691func TabSizeHandler(value string) bool {
1692	if LengthHandler(value) {
1693		return true
1694	}
1695	values := []string{"initial", "inherit"}
1696	splitVals := splitValues(value)
1697	return in(splitVals, values)
1698}
1699
1700func TableLayoutHandler(value string) bool {
1701	values := []string{"auto", "fixed", "initial", "inherit"}
1702	splitVals := splitValues(value)
1703	return in(splitVals, values)
1704}
1705
1706func TextAlignHandler(value string) bool {
1707	values := []string{"left", "right", "center", "justify", "initial", "inherit"}
1708	splitVals := splitValues(value)
1709	return in(splitVals, values)
1710}
1711
1712func TextAlignLastHandler(value string) bool {
1713	values := []string{"auto", "left", "right", "center", "justify", "start", "end", "initial", "inherit"}
1714	splitVals := splitValues(value)
1715	return in(splitVals, values)
1716}
1717
1718func TextCombineUprightHandler(value string) bool {
1719	values := []string{"none", "all"}
1720	splitVals := splitValues(value)
1721	if in(splitVals, values) {
1722		return true
1723	}
1724	return Digits.MatchString(value)
1725}
1726
1727func TextDecorationHandler(value string) bool {
1728	values := []string{"initial", "inherit"}
1729	if in([]string{value}, values) {
1730		return true
1731	}
1732	splitVals := strings.Split(value, " ")
1733	usedFunctions := []func(string) bool{
1734		TextDecorationStyleHandler,
1735		ColorHandler,
1736		TextDecorationLineHandler,
1737	}
1738	return recursiveCheck(splitVals, usedFunctions)
1739}
1740
1741func TextDecorationLineHandler(value string) bool {
1742	values := []string{"none", "underline", "overline", "line-through", "initial", "inherit"}
1743	splitVals := strings.Split(value, " ")
1744	return in(splitVals, values)
1745}
1746
1747func TextDecorationStyleHandler(value string) bool {
1748	values := []string{"solid", "double", "dotted", "dashed", "wavy", "initial", "inherit"}
1749	splitVals := splitValues(value)
1750	return in(splitVals, values)
1751}
1752
1753func TextIndentHandler(value string) bool {
1754	if LengthHandler(value) {
1755		return true
1756	}
1757	values := []string{"initial", "inherit"}
1758	splitVals := splitValues(value)
1759	return in(splitVals, values)
1760}
1761
1762func TextJustifyHandler(value string) bool {
1763	values := []string{"auto", "inter-word", "inter-character", "none", "initial", "inherit"}
1764	splitVals := splitValues(value)
1765	return in(splitVals, values)
1766}
1767
1768func TextOverflowHandler(value string) bool {
1769	if QuotedAlpha.MatchString(value) {
1770		return true
1771	}
1772	values := []string{"clip", "ellipsis", "initial", "inherit"}
1773	splitVals := splitValues(value)
1774	return in(splitVals, values)
1775}
1776
1777func TextOrientationHandler(value string) bool {
1778	values := []string{"mixed", "upright", "sideways", "sideways-right"}
1779	splitVals := splitValues(value)
1780	return in(splitVals, values)
1781}
1782
1783func TextShadowHandler(value string) bool {
1784	values := []string{"none", "initial", "inherit"}
1785	if in([]string{value}, values) {
1786		return true
1787	}
1788	commaSplitVals := strings.Split(value, ",")
1789	for _, val := range commaSplitVals {
1790		splitVals := strings.Split(val, " ")
1791		if len(splitVals) > 6 || len(splitVals) < 2 {
1792			return false
1793		}
1794		if !LengthHandler(splitVals[0]) {
1795			return false
1796		}
1797		if !LengthHandler(splitVals[1]) {
1798			return false
1799		}
1800		usedFunctions := []func(string) bool{
1801			LengthHandler,
1802			ColorHandler,
1803		}
1804		if len(splitVals) > 2 && !recursiveCheck(splitVals[2:], usedFunctions) {
1805			return false
1806		}
1807	}
1808	return true
1809}
1810
1811func TextTransformHandler(value string) bool {
1812	values := []string{"none", "capitalize", "uppercase", "lowercase", "initial", "inherit"}
1813	splitVals := splitValues(value)
1814	return in(splitVals, values)
1815}
1816
1817func TransformHandler(value string) bool {
1818	values := []string{"none", "initial", "inherit"}
1819	if in([]string{value}, values) {
1820		return true
1821	}
1822	if Matrix.MatchString(value) {
1823		return true
1824	}
1825	if Matrix3D.MatchString(value) {
1826		return true
1827	}
1828	subValue := string(TranslateScale.ReplaceAll([]byte(value), []byte{}))
1829	trimValue := strings.Split(strings.TrimSuffix(subValue, ")"), ",")
1830	valid := true
1831	for _, i := range trimValue {
1832		if !LengthHandler(strings.TrimSpace(i)) {
1833			valid = false
1834			break
1835		}
1836	}
1837	if valid && trimValue != nil {
1838		return true
1839	}
1840	if Rotate.MatchString(value) {
1841		return true
1842	}
1843	if Rotate3D.MatchString(value) {
1844		return true
1845	}
1846	subValue = string(Skew.ReplaceAll([]byte(value), []byte{}))
1847	subValue = strings.TrimSuffix(subValue, ")")
1848	trimValue = strings.Split(subValue, ",")
1849	valid = true
1850	for _, i := range trimValue {
1851		if !LengthHandler(strings.TrimSpace(i)) {
1852			valid = false
1853			break
1854		}
1855	}
1856	if valid {
1857		return true
1858	}
1859	subValue = string(Perspective.ReplaceAll([]byte(value), []byte{}))
1860	subValue = strings.TrimSuffix(subValue, ")")
1861	return LengthHandler(subValue)
1862}
1863
1864func TransformOriginHandler(value string) bool {
1865	values := []string{"initial", "inherit"}
1866	if in([]string{value}, values) {
1867		return true
1868	}
1869	splitVals := strings.Split(value, " ")
1870	xValues := []string{"left", "center", "right"}
1871	yValues := []string{"top", "center", "bottom"}
1872	if len(splitVals) > 2 {
1873		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
1874			return false
1875		}
1876		if !in([]string{splitVals[1]}, yValues) && !LengthHandler(splitVals[1]) {
1877			return false
1878		}
1879		return LengthHandler(splitVals[2])
1880	} else if len(splitVals) > 1 {
1881		if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) {
1882			return false
1883		}
1884		return in([]string{splitVals[1]}, yValues) || LengthHandler(splitVals[1])
1885	} else if len(splitVals) == 1 {
1886		return in(splitVals, xValues) || in(splitVals, yValues) || LengthHandler(splitVals[0])
1887	}
1888	return false
1889}
1890
1891func TransformStyleHandler(value string) bool {
1892	values := []string{"flat", "preserve-3d", "initial", "inherit"}
1893	splitVals := splitValues(value)
1894	return in(splitVals, values)
1895}
1896
1897func TransitionHandler(value string) bool {
1898	values := []string{"initial", "inherit"}
1899	if in([]string{value}, values) {
1900		return true
1901	}
1902	splitVals := strings.Split(value, " ")
1903	usedFunctions := []func(string) bool{
1904		TransitionPropertyHandler,
1905		TransitionDurationHandler,
1906		TimingFunctionHandler,
1907		TransitionDelayHandler,
1908		ColorHandler,
1909	}
1910	return recursiveCheck(splitVals, usedFunctions)
1911}
1912
1913func TransitionDelayHandler(value string) bool {
1914	if Time.MatchString(value) {
1915		return true
1916	}
1917	values := []string{"initial", "inherit"}
1918	splitVals := splitValues(value)
1919	return in(splitVals, values)
1920}
1921
1922func TransitionDurationHandler(value string) bool {
1923	if Time.MatchString(value) {
1924		return true
1925	}
1926	values := []string{"initial", "inherit"}
1927	splitVals := splitValues(value)
1928	return in(splitVals, values)
1929}
1930
1931func TransitionPropertyHandler(value string) bool {
1932	if TransitionProp.MatchString(value) {
1933		return true
1934	}
1935	values := []string{"none", "all", "initial", "inherit"}
1936	splitVals := splitValues(value)
1937	return in(splitVals, values)
1938}
1939
1940func UnicodeBidiHandler(value string) bool {
1941	values := []string{"normal", "embed", "bidi-override", "isolate", "isolate-override", "plaintext", "initial", "inherit"}
1942	splitVals := splitValues(value)
1943	return in(splitVals, values)
1944}
1945
1946func UserSelectHandler(value string) bool {
1947	values := []string{"auto", "none", "text", "all"}
1948	splitVals := splitValues(value)
1949	return in(splitVals, values)
1950}
1951
1952func VerticalAlignHandler(value string) bool {
1953	if LengthHandler(value) {
1954		return true
1955	}
1956	values := []string{"baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "initial", "inherit"}
1957	splitVals := splitValues(value)
1958	return in(splitVals, values)
1959}
1960
1961func VisiblityHandler(value string) bool {
1962	values := []string{"visible", "hidden", "collapse", "initial", "inherit"}
1963	splitVals := splitValues(value)
1964	return in(splitVals, values)
1965}
1966
1967func WhiteSpaceHandler(value string) bool {
1968	values := []string{"normal", "nowrap", "pre", "pre-line", "pre-wrap", "initial", "inherit"}
1969	splitVals := splitValues(value)
1970	return in(splitVals, values)
1971}
1972
1973func WidthHandler(value string) bool {
1974	if LengthHandler(value) {
1975		return true
1976	}
1977	values := []string{"auto", "initial", "inherit"}
1978	splitVals := splitValues(value)
1979	return in(splitVals, values)
1980}
1981
1982func WordSpacingHandler(value string) bool {
1983	if LengthHandler(value) {
1984		return true
1985	}
1986	values := []string{"normal", "initial", "inherit"}
1987	splitVals := splitValues(value)
1988	return in(splitVals, values)
1989}
1990
1991func WordBreakHandler(value string) bool {
1992	values := []string{"normal", "break-all", "keep-all", "break-word", "initial", "inherit"}
1993	splitVals := splitValues(value)
1994	return in(splitVals, values)
1995}
1996
1997func WordWrapHandler(value string) bool {
1998	values := []string{"normal", "break-word", "initial", "inherit"}
1999	splitVals := splitValues(value)
2000	return in(splitVals, values)
2001}
2002
2003func WritingModeHandler(value string) bool {
2004	values := []string{"horizontal-tb", "vertical-rl", "vertical-lr"}
2005	splitVals := splitValues(value)
2006	return in(splitVals, values)
2007}
2008
2009func ZIndexHandler(value string) bool {
2010	if ZIndex.MatchString(value) {
2011		return true
2012	}
2013	values := []string{"auto", "initial", "inherit"}
2014	splitVals := splitValues(value)
2015	return in(splitVals, values)
2016}