handlers.go 62 KB

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