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}