diff options
Diffstat (limited to 'vendor/github.com/microcosm-cc/bluemonday/css/handlers.go')
-rw-r--r-- | vendor/github.com/microcosm-cc/bluemonday/css/handlers.go | 2086 |
1 files changed, 2086 insertions, 0 deletions
diff --git a/vendor/github.com/microcosm-cc/bluemonday/css/handlers.go b/vendor/github.com/microcosm-cc/bluemonday/css/handlers.go new file mode 100644 index 0000000000..200a6729a2 --- /dev/null +++ b/vendor/github.com/microcosm-cc/bluemonday/css/handlers.go @@ -0,0 +1,2086 @@ +// Copyright (c) 2019, David Kitchen <david@buro9.com> +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the organisation (Microcosm) nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +package css + +import ( + "regexp" + "strings" +) + +var ( + defaultStyleHandlers = map[string]func(string) bool{ + "align-content": AlignContentHandler, + "align-items": AlignItemsHandler, + "align-self": AlignSelfHandler, + "all": AllHandler, + "animation": AnimationHandler, + "animation-delay": AnimationDelayHandler, + "animation-direction": AnimationDirectionHandler, + "animation-duration": AnimationDurationHandler, + "animation-fill-mode": AnimationFillModeHandler, + "animation-iteration-count": AnimationIterationCountHandler, + "animation-name": AnimationNameHandler, + "animation-play-state": AnimationPlayStateHandler, + "animation-timing-function": TimingFunctionHandler, + "backface-visibility": BackfaceVisibilityHandler, + "background": BackgroundHandler, + "background-attachment": BackgroundAttachmentHandler, + "background-blend-mode": BackgroundBlendModeHandler, + "background-clip": BackgroundClipHandler, + "background-color": ColorHandler, + "background-image": ImageHandler, + "background-origin": BackgroundOriginHandler, + "background-position": BackgroundPositionHandler, + "background-repeat": BackgroundRepeatHandler, + "background-size": BackgroundSizeHandler, + "border": BorderHandler, + "border-bottom": BorderSideHandler, + "border-bottom-color": ColorHandler, + "border-bottom-left-radius": BorderSideRadiusHandler, + "border-bottom-right-radius": BorderSideRadiusHandler, + "border-bottom-style": BorderSideStyleHandler, + "border-bottom-width": BorderSideWidthHandler, + "border-collapse": BorderCollapseHandler, + "border-color": ColorHandler, + "border-image": BorderImageHandler, + "border-image-outset": BorderImageOutsetHandler, + "border-image-repeat": BorderImageRepeatHandler, + "border-image-slice": BorderImageSliceHandler, + "border-image-source": ImageHandler, + "border-image-width": BorderImageWidthHandler, + "border-left": BorderSideHandler, + "border-left-color": ColorHandler, + "border-left-style": BorderSideStyleHandler, + "border-left-width": BorderSideWidthHandler, + "border-radius": BorderRadiusHandler, + "border-right": BorderSideHandler, + "border-right-color": ColorHandler, + "border-right-style": BorderSideStyleHandler, + "border-right-width": BorderSideWidthHandler, + "border-spacing": BorderSpacingHandler, + "border-style": BorderStyleHandler, + "border-top": BorderSideHandler, + "border-top-color": ColorHandler, + "border-top-left-radius": BorderSideRadiusHandler, + "border-top-right-radius": BorderSideRadiusHandler, + "border-top-style": BorderSideStyleHandler, + "border-top-width": BorderSideWidthHandler, + "border-width": BorderWidthHandler, + "bottom": SideHandler, + "box-decoration-break": BoxDecorationBreakHandler, + "box-shadow": BoxShadowHandler, + "box-sizing": BoxSizingHandler, + "break-after": BreakBeforeAfterHandler, + "break-before": BreakBeforeAfterHandler, + "break-inside": BreakInsideHandler, + "caption-side": CaptionSideHandler, + "caret-color": CaretColorHandler, + "clear": ClearHandler, + "clip": ClipHandler, + "color": ColorHandler, + "column-count": ColumnCountHandler, + "column-fill": ColumnFillHandler, + "column-gap": ColumnGapHandler, + "column-rule": ColumnRuleHandler, + "column-rule-color": ColorHandler, + "column-rule-style": BorderSideStyleHandler, + "column-rule-width": ColumnRuleWidthHandler, + "column-span": ColumnSpanHandler, + "column-width": ColumnWidthHandler, + "columns": ColumnsHandler, + "cursor": CursorHandler, + "direction": DirectionHandler, + "display": DisplayHandler, + "empty-cells": EmptyCellsHandler, + "filter": FilterHandler, + "flex": FlexHandler, + "flex-basis": FlexBasisHandler, + "flex-direction": FlexDirectionHandler, + "flex-flow": FlexFlowHandler, + "flex-grow": FlexGrowHandler, + "flex-shrink": FlexGrowHandler, + "flex-wrap": FlexWrapHandler, + "float": FloatHandler, + "font": FontHandler, + "font-family": FontFamilyHandler, + "font-kerning": FontKerningHandler, + "font-language-override": FontLanguageOverrideHandler, + "font-size": FontSizeHandler, + "font-size-adjust": FontSizeAdjustHandler, + "font-stretch": FontStretchHandler, + "font-style": FontStyleHandler, + "font-synthesis": FontSynthesisHandler, + "font-variant": FontVariantHandler, + "font-variant-caps": FontVariantCapsHandler, + "font-variant-position": FontVariantPositionHandler, + "font-weight": FontWeightHandler, + "grid": GridHandler, + "grid-area": GridAreaHandler, + "grid-auto-columns": GridAutoColumnsHandler, + "grid-auto-flow": GridAutoFlowHandler, + "grid-auto-rows": GridAutoColumnsHandler, + "grid-column": GridColumnHandler, + "grid-column-end": GridAxisStartEndHandler, + "grid-column-gap": LengthHandler, + "grid-column-start": GridAxisStartEndHandler, + "grid-gap": GridGapHandler, + "grid-row": GridRowHandler, + "grid-row-end": GridAxisStartEndHandler, + "grid-row-gap": LengthHandler, + "grid-row-start": GridAxisStartEndHandler, + "grid-template": GridTemplateHandler, + "grid-template-areas": GridTemplateAreasHandler, + "grid-template-columns": GridTemplateColumnsHandler, + "grid-template-rows": GridTemplateRowsHandler, + "hanging-punctuation": HangingPunctuationHandler, + "height": HeightHandler, + "hyphens": HyphensHandler, + "image-rendering": ImageRenderingHandler, + "isolation": IsolationHandler, + "justify-content": JustifyContentHandler, + "left": SideHandler, + "letter-spacing": LetterSpacingHandler, + "line-break": LineBreakHandler, + "line-height": LineHeightHandler, + "list-style": ListStyleHandler, + "list-style-image": ImageHandler, + "list-style-position": ListStylePositionHandler, + "list-style-type": ListStyleTypeHandler, + "margin": MarginHandler, + "margin-bottom": MarginSideHandler, + "margin-left": MarginSideHandler, + "margin-right": MarginSideHandler, + "margin-top": MarginSideHandler, + "max-height": MaxHeightWidthHandler, + "max-width": MaxHeightWidthHandler, + "min-height": MinHeightWidthHandler, + "min-width": MinHeightWidthHandler, + "mix-blend-mode": MixBlendModeHandler, + "object-fit": ObjectFitHandler, + "object-position": ObjectPositionHandler, + "opacity": OpacityHandler, + "order": OrderHandler, + "orphans": OrphansHandler, + "outline": OutlineHandler, + "outline-color": ColorHandler, + "outline-offset": OutlineOffsetHandler, + "outline-style": OutlineStyleHandler, + "outline-width": OutlineWidthHandler, + "overflow": OverflowHandler, + "overflow-wrap": OverflowWrapHandler, + "overflow-x": OverflowXYHandler, + "overflow-y": OverflowXYHandler, + "padding": PaddingHandler, + "padding-bottom": PaddingSideHandler, + "padding-left": PaddingSideHandler, + "padding-right": PaddingSideHandler, + "padding-top": PaddingSideHandler, + "page-break-after": PageBreakBeforeAfterHandler, + "page-break-before": PageBreakBeforeAfterHandler, + "page-break-inside": PageBreakInsideHandler, + "perspective": PerspectiveHandler, + "perspective-origin": PerspectiveOriginHandler, + "pointer-events": PointerEventsHandler, + "position": PositionHandler, + "quotes": QuotesHandler, + "resize": ResizeHandler, + "right": SideHandler, + "scroll-behavior": ScrollBehaviorHandler, + "tab-size": TabSizeHandler, + "table-layout": TableLayoutHandler, + "text-align": TextAlignHandler, + "text-align-last": TextAlignLastHandler, + "text-combine-upright": TextCombineUprightHandler, + "text-decoration": TextDecorationHandler, + "text-decoration-color": ColorHandler, + "text-decoration-line": TextDecorationLineHandler, + "text-decoration-style": TextDecorationStyleHandler, + "text-indent": TextIndentHandler, + "text-justify": TextJustifyHandler, + "text-orientation": TextOrientationHandler, + "text-overflow": TextOverflowHandler, + "text-shadow": TextShadowHandler, + "text-transform": TextTransformHandler, + "top": SideHandler, + "transform": TransformHandler, + "transform-origin": TransformOriginHandler, + "transform-style": TransformStyleHandler, + "transition": TransitionHandler, + "transition-delay": TransitionDelayHandler, + "transition-duration": TransitionDurationHandler, + "transition-property": TransitionPropertyHandler, + "transition-timing-function": TimingFunctionHandler, + "unicode-bidi": UnicodeBidiHandler, + "user-select": UserSelectHandler, + "vertical-align": VerticalAlignHandler, + "visibility": VisiblityHandler, + "white-space": WhiteSpaceHandler, + "widows": OrphansHandler, + "width": WidthHandler, + "word-break": WordBreakHandler, + "word-spacing": WordSpacingHandler, + "word-wrap": WordWrapHandler, + "writing-mode": WritingModeHandler, + "z-index": ZIndexHandler, + } + colorValues = []string{"initial", "inherit", "aliceblue", "antiquewhite", + "aqua", "aquamarine", "azure", "beige", "bisque", "black", + "blanchedalmond", "blue", "blueviolet", "brown", "burlywood", + "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", + "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", + "darkgray", "darkgrey", "darkgreen", "darkkhaki", "darkmagenta", + "darkolivegreen", "darkorange", "darkorchid", "darkred", "darksalmon", + "darkseagreen", "darkslateblue", "darkslategrey", "darkslategray", + "darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", + "dimgrey", "dodgerblue", "firebrick", "floralwhite", "forestgreen", + "fuchsia", "gainsboro", "ghostwhite", "gold", "goldenrod", "gray", + "grey", "green", "greenyellow", "honeydew", "hotpink", "indianred", + "indigo", "ivory", "khaki", "lavender", "lavenderblush", + "lemonchiffon", "lightblue", "lightcoral", "lightcyan", + "lightgoldenrodyellow", "lightgray", "lightgrey", "lightgreen", + "lightpink", "lightsalmon", "lightseagreen", "lightskyblue", + "lightslategray", "lightslategrey", "lightsteeelblue", "lightyellow", + "lime", "limegreen", "linen", "magenta", "maroon", "mediumaquamarine", + "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen", + "mediumslateblue", "mediumspringgreen", "mediumturquoise", + "mediumvioletred", "midnightblue", "mintcream", "mistyrose", + "moccasin", "navajowhite", "navy", "oldlace", "olive", "olivedrab", + "orange", "orangered", "orchid", "palegoldenrod", "palegreen", + "paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", + "pink", "plum", "powderblue", "purple", "rebeccapurple", "red", + "rosybrown", "royalblue", "saddlebrown", "salmon", "sandybrown", + "seagreen", "seashell", "sienna", "silver", "skyblue", "slateblue", + "slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", + "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", + "whitesmoke", "yellow", "yellowgreen"} +) + +func multiSplit(value string, seps ...string) []string { + curArray := []string{value} + for _, i := range seps { + newArray := []string{} + for _, j := range curArray { + newArray = append(newArray, strings.Split(j, i)...) + } + curArray = newArray + } + return curArray +} + +func recursiveCheck(value []string, funcs []func(string) bool) bool { + for i := 0; i < len(value); i++ { + tempVal := strings.Join(value[:i+1], " ") + for _, j := range funcs { + if j(tempVal) && (len(value[i+1:]) == 0 || recursiveCheck(value[i+1:], funcs)) { + return true + } + } + } + return false +} + +func in(value []string, arr []string) bool { + for _, i := range value { + foundString := false + for _, j := range arr { + if j == i { + foundString = true + } + } + if !foundString { + return false + } + } + return true +} + +func splitValues(value string) []string { + values := strings.Split(value, ",") + for _, strippedValue := range values { + strippedValue = strings.ToLower(strings.TrimSpace(strippedValue)) + } + return values +} + +func GetDefaultHandler(attr string) func(string) bool { + + if defaultStyleHandlers[attr] != nil { + return defaultStyleHandlers[attr] + } + return BaseHandler +} + +func BaseHandler(value string) bool { + return false +} + +func AlignContentHandler(value string) bool { + values := []string{"stretch", "center", "flex-start", + "flex-end", "space-between", "space-around", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AlignItemsHandler(value string) bool { + values := []string{"stretch", "center", "flex-start", + "flex-end", "baseline", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AlignSelfHandler(value string) bool { + values := []string{"auto", "stretch", "center", "flex-start", + "flex-end", "baseline", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AllHandler(value string) bool { + values := []string{"initial", "inherit", "unset"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AnimationHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + AnimationNameHandler, + AnimationDurationHandler, + TimingFunctionHandler, + AnimationDelayHandler, + AnimationIterationCountHandler, + AnimationDirectionHandler, + AnimationFillModeHandler, + AnimationPlayStateHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func AnimationDelayHandler(value string) bool { + reg := regexp.MustCompile(`[\-]?[0-9]+[\.]?[0-9]*[s|ms]?`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AnimationDirectionHandler(value string) bool { + values := []string{"normal", "reverse", "alternate", "alternate-reverse", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AnimationDurationHandler(value string) bool { + reg := regexp.MustCompile(`[0-9]+[\.]?[0-9]*[s|ms]?`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AnimationFillModeHandler(value string) bool { + values := []string{"none", "forwards", "backwards", "both", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AnimationIterationCountHandler(value string) bool { + reg := regexp.MustCompile(`[0-9]+[\.]?[0-9]*`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"infinite", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func AnimationNameHandler(value string) bool { + reg := regexp.MustCompile(`[a-z]+`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func AnimationPlayStateHandler(value string) bool { + values := []string{"paused", "running", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TimingFunctionHandler(value string) bool { + values := []string{"linear", "ease", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end", "initial", "inherit"} + splitVals := splitValues(value) + if in(splitVals, values) { + return true + } + reg := regexp.MustCompile(`cubic-bezier\(([ ]*(0(.[0-9]+)?|1(.0)?),){3}[ ]*(0(.[0-9]+)?|1)\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`steps\([ ]*[0-9]+([ ]*,[ ]*(start|end)?)\)`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func BackfaceVisibilityHandler(value string) bool { + values := []string{"visible", "hidden", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BackgroundHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + newSplitVals := []string{} + for _, i := range splitVals { + if len(strings.Split(i, "/")) == 2 { + newSplitVals = append(newSplitVals, strings.Split(i, "/")...) + } else { + newSplitVals = append(newSplitVals, i) + } + } + usedFunctions := []func(string) bool{ + ColorHandler, + ImageHandler, + BackgroundPositionHandler, + BackgroundSizeHandler, + BackgroundRepeatHandler, + BackgroundOriginHandler, + BackgroundClipHandler, + BackgroundAttachmentHandler, + } + return recursiveCheck(newSplitVals, usedFunctions) +} + +func BackgroundAttachmentHandler(value string) bool { + values := []string{"scroll", "fixed", "local", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BackgroundClipHandler(value string) bool { + values := []string{"border-box", "padding-box", "content-box", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BackgroundBlendModeHandler(value string) bool { + values := []string{"normal", "multiply", "screen", "overlay", "darken", + "lighten", "color-dodge", "saturation", "color", "luminosity"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ImageHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + splitVals := splitValues(value) + if in(splitVals, values) { + return true + } + reg := regexp.MustCompile(`url\([\"\']?((https|http)[a-z0-9\.\\/_:]+[\"\']?)\)`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func BackgroundOriginHandler(value string) bool { + values := []string{"padding-box", "border-box", "content-box", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BackgroundPositionHandler(value string) bool { + splitVals := strings.Split(value, ";") + 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"} + if in(splitVals, values) { + return true + } + reg := regexp.MustCompile(`[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]* [[\-]*[0-9]+[cm|mm|in|px|pt|pc\%]*]*`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + return false +} + +func BackgroundRepeatHandler(value string) bool { + values := []string{"repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BackgroundSizeHandler(value string) bool { + splitVals := strings.Split(value, " ") + values := []string{"auto", "cover", "contain", "initial", "inherit"} + if in(splitVals, values) { + return true + } + if len(splitVals) > 0 && LengthHandler(splitVals[0]) { + if len(splitVals) < 2 || (len(splitVals) == 2 && LengthHandler(splitVals[1])) { + return true + } + } + return false +} + +func BorderHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := multiSplit(value, " ", "/") + usedFunctions := []func(string) bool{ + BorderWidthHandler, + BorderStyleHandler, + ColorHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func BorderSideHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + BorderSideWidthHandler, + BorderSideStyleHandler, + ColorHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func BorderSideRadiusHandler(value string) bool { + splitVals := strings.Split(value, " ") + valid := true + for _, i := range splitVals { + if !LengthHandler(i) { + valid = false + break + } + } + if valid { + return true + } + splitVals = splitValues(value) + values := []string{"initial", "inherit"} + return in(splitVals, values) +} + +func BorderSideStyleHandler(value string) bool { + values := []string{"none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BorderSideWidthHandler(value string) bool { + if LengthHandler(value) { + return true + } + splitVals := strings.Split(value, ";") + values := []string{"medium", "thin", "thick", "initial", "inherit"} + return in(splitVals, values) +} + +func BorderCollapseHandler(value string) bool { + values := []string{"separate", "collapse", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BorderImageHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := multiSplit(value, " ", " / ") + usedFunctions := []func(string) bool{ + ImageHandler, + BorderImageSliceHandler, + BorderImageWidthHandler, + BorderImageOutsetHandler, + BorderImageRepeatHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func BorderImageOutsetHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BorderImageRepeatHandler(value string) bool { + values := []string{"stretch", "repeat", "round", "space", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BorderImageSliceHandler(value string) bool { + values := []string{"fill", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + if len(splitVals) > 4 { + return false + } + usedFunctions := []func(string) bool{ + LengthHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func BorderImageWidthHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BorderRadiusHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + if len(splitVals) > 4 { + return false + } + usedFunctions := []func(string) bool{ + LengthHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func BorderSpacingHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + if len(splitVals) > 2 { + return false + } + usedFunctions := []func(string) bool{ + LengthHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func BorderStyleHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + if len(splitVals) > 4 { + return false + } + usedFunctions := []func(string) bool{ + BorderSideStyleHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func BorderWidthHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + if len(splitVals) > 4 { + return false + } + usedFunctions := []func(string) bool{ + BorderSideWidthHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func SideHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"auto", "inherit", "unset"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BoxDecorationBreakHandler(value string) bool { + values := []string{"slice", "clone", "initial", "initial", "inherit", "unset"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BoxShadowHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + commaSplitVals := strings.Split(value, ",") + for _, val := range commaSplitVals { + splitVals := strings.Split(val, " ") + if len(splitVals) > 6 || len(splitVals) < 2 { + return false + } + if !LengthHandler(splitVals[0]) { + return false + } + if !LengthHandler(splitVals[1]) { + return false + } + usedFunctions := []func(string) bool{ + LengthHandler, + ColorHandler, + } + if len(splitVals) > 2 && !recursiveCheck(splitVals[2:], usedFunctions) { + return false + } + } + return true +} + +func BoxSizingHandler(value string) bool { + values := []string{"slicontent-box", "border-box", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BreakBeforeAfterHandler(value string) bool { + values := []string{"auto", "avoid", "always", "all", "avoid-page", "page", "left", "right", "recto", "verso", "avoid-column", "column", "avoid-region", "region"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func BreakInsideHandler(value string) bool { + values := []string{"auto", "avoid", "avoid-page", "avoid-column", "avoid-region"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func CaptionSideHandler(value string) bool { + values := []string{"top", "bottom", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func CaretColorHandler(value string) bool { + splitVals := splitValues(value) + if in(splitVals, colorValues) { + return true + } + reg := regexp.MustCompile(`#[0-9abcdef]{6}`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = 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]))))\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = 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]+))\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)`) + if reg.FindString(value) == value && value != "" { + return true + } + reg = 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]+))\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + return false +} + +func ClearHandler(value string) bool { + values := []string{"none", "left", "right", "both", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ClipHandler(value string) bool { + reg := regexp.MustCompile(`rect\([0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px,[ ]*[0-9]+px\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ColorHandler(value string) bool { + splitVals := splitValues(value) + if in(splitVals, colorValues) { + return true + } + reg := regexp.MustCompile(`#[0-9abcdef]{6}`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = 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]))))\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = 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]+))\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = 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]+))\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + return false +} + +func ColumnCountHandler(value string) bool { + reg := regexp.MustCompile(`[0-9]+`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ColumnFillHandler(value string) bool { + values := []string{"balance", "auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ColumnGapHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"normal", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ColumnRuleHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + ColumnRuleWidthHandler, + BorderSideStyleHandler, + ColorHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func ColumnRuleWidthHandler(value string) bool { + if LengthHandler(value) { + return true + } + splitVals := strings.Split(value, ";") + values := []string{"medium", "thin", "thick", "initial", "inherit"} + return in(splitVals, values) +} + +func ColumnSpanHandler(value string) bool { + values := []string{"none", "all", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ColumnWidthHandler(value string) bool { + if LengthHandler(value) { + return true + } + splitVals := strings.Split(value, ";") + values := []string{"auto", "initial", "inherit"} + return in(splitVals, values) +} + +func ColumnsHandler(value string) bool { + values := []string{"auto", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + ColumnWidthHandler, + ColumnCountHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func CursorHandler(value string) bool { + 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"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func DirectionHandler(value string) bool { + values := []string{"ltr", "rtl", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func DisplayHandler(value string) bool { + 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"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func EmptyCellsHandler(value string) bool { + values := []string{"show", "hide", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FilterHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + splitVals := splitValues(value) + if in(splitVals, values) { + return true + } + reg := regexp.MustCompile(`blur\([0-9]+px\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`(brightness|contrast)\([0-9]+\%\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`drop-shadow\(([-]?[0-9]+px) ([-]?[0-9]+px)( [-]?[0-9]+px)?( ([-]?[0-9]+px))?`) + reg.Longest() + colorValue := strings.TrimSuffix(string(reg.ReplaceAll([]byte(value), []byte{})), ")") + if ColorHandler(colorValue) { + return true + } + reg = regexp.MustCompile(`grayscale\(([0-9]{1,2}|100)%\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`hue-rotate\(([12]?[0-9]{1,2}|3[0-5][0-9]|360)?\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`invert\(([0-9]{1,2}|100)%\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`opacity\(([0-9]{1,2}|100)%\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`saturate\([0-9]+%\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`sepia\(([0-9]{1,2}|100)%\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + //Not allowing URLs + return false +} + +func FlexHandler(value string) bool { + values := []string{"auto", "initial", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + FlexGrowHandler, + FlexBasisHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func FlexBasisHandler(value string) bool { + if LengthHandler(value) { + return true + } + splitVals := strings.Split(value, ";") + values := []string{"auto", "initial", "inherit"} + return in(splitVals, values) +} + +func FlexDirectionHandler(value string) bool { + values := []string{"row", "row-reverse", "column", "column-reverse", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FlexFlowHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + FlexDirectionHandler, + FlexWrapHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func FlexGrowHandler(value string) bool { + reg := regexp.MustCompile(`[0-9\.]+`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + splitVals := strings.Split(value, ";") + values := []string{"initial", "inherit"} + return in(splitVals, values) +} + +func FlexWrapHandler(value string) bool { + values := []string{"nowrap", "wrap", "wrap-reverse", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FloatHandler(value string) bool { + values := []string{"none", "left", "right", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontHandler(value string) bool { + values := []string{"caption", "icon", "menu", "message-box", "small-caption", "status-bar", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + newSplitVals := []string{} + for _, i := range splitVals { + if len(strings.Split(i, "/")) == 2 { + newSplitVals = append(newSplitVals, strings.Split(i, "/")...) + } else { + newSplitVals = append(newSplitVals, i) + } + } + usedFunctions := []func(string) bool{ + FontStyleHandler, + FontVariantHandler, + FontWeightHandler, + FontSizeHandler, + FontFamilyHandler, + } + return recursiveCheck(newSplitVals, usedFunctions) +} + +func FontFamilyHandler(value string) bool { + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + if in(splitVals, values) { + return true + } + reg := regexp.MustCompile(`('[a-z \-]+'|[a-z \-]+)`) + reg.Longest() + for _, i := range splitVals { + i = strings.TrimSpace(i) + if reg.FindString(i) != i { + return false + } + } + return true +} + +func FontKerningHandler(value string) bool { + values := []string{"auto", "normal", "none"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontLanguageOverrideHandler(value string) bool { + reg := regexp.MustCompile(`[a-z]+`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func FontSizeHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"medium", "xx-small", "x-small", "small", "large", "x-large", "xx-large", "smaller", "larger", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontSizeAdjustHandler(value string) bool { + reg := regexp.MustCompile(`[0-9]+[\.]?[0-9]*`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontStretchHandler(value string) bool { + values := []string{"ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontStyleHandler(value string) bool { + values := []string{"normal", "italic", "oblique", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontSynthesisHandler(value string) bool { + values := []string{"none", "style", "weight"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontVariantCapsHandler(value string) bool { + values := []string{"normal", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "unicase", "titling-caps"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontVariantHandler(value string) bool { + values := []string{"normal", "small-caps", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontVariantPositionHandler(value string) bool { + values := []string{"normal", "sub", "super"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func FontWeightHandler(value string) bool { + values := []string{"normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func GridHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + newSplitVals := []string{} + for _, i := range splitVals { + if i != "/" { + newSplitVals = append(newSplitVals, i) + } + } + usedFunctions := []func(string) bool{ + GridTemplateRowsHandler, + GridTemplateColumnsHandler, + GridTemplateAreasHandler, + GridAutoColumnsHandler, + GridAutoFlowHandler, + } + return recursiveCheck(newSplitVals, usedFunctions) +} + +func GridAreaHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " / ") + usedFunctions := []func(string) bool{ + GridAxisStartEndHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func GridAutoColumnsHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"auto", "max-content", "min-content", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func GridAutoFlowHandler(value string) bool { + values := []string{"row", "column", "dense", "row dense", "column dense"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func GridColumnHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " / ") + if len(splitVals) > 2 { + return false + } + usedFunctions := []func(string) bool{ + GridAxisStartEndHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func GridColumnGapHandler(value string) bool { + return LengthHandler(value) +} + +func LengthHandler(value string) bool { + reg := regexp.MustCompile(`[\-]?[0-9]+[\.]?[0-9]*(%|cm|mm|in|px|pt|pc|em|ex|ch|rem|vw|vh|vmin|vmax|deg|rad|turn)?`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func LineBreakHandler(value string) bool { + values := []string{"auto", "loose", "normal", "strict"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func GridAxisStartEndHandler(value string) bool { + reg := regexp.MustCompile(`[0-9]+`) + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`span [0-9]+`) + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"auto"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func GridGapHandler(value string) bool { + splitVals := strings.Split(value, " ") + if len(splitVals) > 2 { + return false + } + usedFunctions := []func(string) bool{ + GridColumnGapHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func GridRowHandler(value string) bool { + splitVals := strings.Split(value, " / ") + if len(splitVals) > 2 { + return false + } + usedFunctions := []func(string) bool{ + GridAxisStartEndHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func GridTemplateHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " / ") + if len(splitVals) > 2 { + return false + } + usedFunctions := []func(string) bool{ + GridTemplateColumnsHandler, + GridTemplateRowsHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func GridTemplateAreasHandler(value string) bool { + values := []string{"none"} + if in([]string{value}, values) { + return true + } + reg := regexp.MustCompile(`['"]?[a-z ]+['"]?`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func GridTemplateColumnsHandler(value string) bool { + splitVals := strings.Split(value, " ") + values := []string{"none", "auto", "max-content", "min-content", "initial", "inherit"} + for _, val := range splitVals { + if LengthHandler(val) { + continue + } + valArr := []string{val} + if !in(valArr, values) { + return false + } + } + return true +} + +func GridTemplateRowsHandler(value string) bool { + splitVals := strings.Split(value, " ") + values := []string{"none", "auto", "max-content", "min-content"} + for _, val := range splitVals { + if LengthHandler(val) { + continue + } + valArr := []string{val} + if !in(valArr, values) { + return false + } + } + return true +} + +func HangingPunctuationHandler(value string) bool { + values := []string{"none", "first", "last", "allow-end", "force-end", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func HeightHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func HyphensHandler(value string) bool { + values := []string{"none", "manual", "auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ImageRenderingHandler(value string) bool { + values := []string{"auto", "smooth", "high-quality", "crisp-edges", "pixelated"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func IsolationHandler(value string) bool { + values := []string{"auto", "isolate", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func JustifyContentHandler(value string) bool { + values := []string{"flex-start", "flex-end", "center", "space-between", "space-around", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func LetterSpacingHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"normal", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func LineHeightHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"normal", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ListStyleHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + ListStyleTypeHandler, + ListStylePositionHandler, + ImageHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func ListStylePositionHandler(value string) bool { + values := []string{"inside", "outside", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ListStyleTypeHandler(value string) bool { + 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"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func MarginHandler(value string) bool { + values := []string{"auto", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + MarginSideHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func MarginSideHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func MaxHeightWidthHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"none", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func MinHeightWidthHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func MixBlendModeHandler(value string) bool { + values := []string{"normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "difference", "exclusion", "hue", "saturation", "color", "luminosity"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ObjectFitHandler(value string) bool { + values := []string{"fill", "contain", "cover", "none", "scale-down", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ObjectPositionHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + if len(splitVals) > 2 { + return false + } + usedFunctions := []func(string) bool{ + LengthHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func OpacityHandler(value string) bool { + reg := regexp.MustCompile("(0[.]?[0-9]*)|(1.0)") + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func OrderHandler(value string) bool { + reg := regexp.MustCompile("[0-9]+") + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func OutlineHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + ColorHandler, + OutlineWidthHandler, + OutlineStyleHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func OutlineOffsetHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func OutlineStyleHandler(value string) bool { + values := []string{"none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func OutlineWidthHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"medium", "thin", "thick", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func OverflowHandler(value string) bool { + values := []string{"visible", "hidden", "scroll", "auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func OverflowXYHandler(value string) bool { + values := []string{"visible", "hidden", "scroll", "auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func OverflowWrapHandler(value string) bool { + values := []string{"normal", "break-word", "anywhere"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func OrphansHandler(value string) bool { + reg := regexp.MustCompile(`[0-9]+`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func PaddingHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + if len(splitVals) > 4 { + return false + } + usedFunctions := []func(string) bool{ + PaddingSideHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func PaddingSideHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func PageBreakBeforeAfterHandler(value string) bool { + values := []string{"auto", "always", "avoid", "left", "right", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func PageBreakInsideHandler(value string) bool { + values := []string{"auto", "avoid", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func PerspectiveHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"none", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func PerspectiveOriginHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + xValues := []string{"left", "center", "right"} + yValues := []string{"top", "center", "bottom"} + if len(splitVals) > 1 { + if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) { + return false + } + return in([]string{splitVals[1]}, yValues) || LengthHandler(splitVals[1]) + } else if len(splitVals) == 1 { + return in(splitVals, xValues) || in(splitVals, yValues) || LengthHandler(splitVals[0]) + } + return false +} + +func PointerEventsHandler(value string) bool { + values := []string{"auto", "none", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func PositionHandler(value string) bool { + values := []string{"static", "absolute", "fixed", "relative", "sticky", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func QuotesHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + splitVals := splitValues(value) + if in(splitVals, values) { + return true + } + reg := 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}]["'])+`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func ResizeHandler(value string) bool { + values := []string{"none", "both", "horizontal", "vertical", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ScrollBehaviorHandler(value string) bool { + values := []string{"auto", "smooth", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TabSizeHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TableLayoutHandler(value string) bool { + values := []string{"auto", "fixed", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TextAlignHandler(value string) bool { + values := []string{"left", "right", "center", "justify", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TextAlignLastHandler(value string) bool { + values := []string{"auto", "left", "right", "center", "justify", "start", "end", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TextCombineUprightHandler(value string) bool { + values := []string{"none", "all"} + splitVals := splitValues(value) + if in(splitVals, values) { + return true + } + reg := regexp.MustCompile(`digits [2-4]`) + reg.Longest() + return reg.FindString(value) == value && value != "" +} + +func TextDecorationHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + TextDecorationStyleHandler, + ColorHandler, + TextDecorationLineHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func TextDecorationLineHandler(value string) bool { + values := []string{"none", "underline", "overline", "line-through", "initial", "inherit"} + splitVals := strings.Split(value, " ") + return in(splitVals, values) +} + +func TextDecorationStyleHandler(value string) bool { + values := []string{"solid", "double", "dotted", "dashed", "wavy", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TextIndentHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TextJustifyHandler(value string) bool { + values := []string{"auto", "inter-word", "inter-character", "none", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TextOverflowHandler(value string) bool { + reg := regexp.MustCompile("[\"'][a-z]+[\"']") + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"clip", "ellipsis", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TextOrientationHandler(value string) bool { + values := []string{"mixed", "upright", "sideways", "sideways-right"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TextShadowHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + commaSplitVals := strings.Split(value, ",") + for _, val := range commaSplitVals { + splitVals := strings.Split(val, " ") + if len(splitVals) > 6 || len(splitVals) < 2 { + return false + } + if !LengthHandler(splitVals[0]) { + return false + } + if !LengthHandler(splitVals[1]) { + return false + } + usedFunctions := []func(string) bool{ + LengthHandler, + ColorHandler, + } + if len(splitVals) > 2 && !recursiveCheck(splitVals[2:], usedFunctions) { + return false + } + } + return true +} + +func TextTransformHandler(value string) bool { + values := []string{"none", "capitalize", "uppercase", "lowercase", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TransformHandler(value string) bool { + values := []string{"none", "initial", "inherit"} + if in([]string{value}, values) { + return true + } + reg := regexp.MustCompile(`matrix\(([ ]*[0-9]+[\.]?[0-9]*,){5}([ ]*[0-9]+[\.]?[0-9]*)\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`matrix3d\(([ ]*[0-9]+[\.]?[0-9]*,){15}([ ]*[0-9]+[\.]?[0-9]*)\)`) + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`(translate|translate3d|translatex|translatey|translatez|scale|scale3d|scalex|scaley|scalez)\(`) + reg.Longest() + subValue := string(reg.ReplaceAll([]byte(value), []byte{})) + trimValue := strings.Split(strings.TrimSuffix(subValue, ")"), ",") + valid := true + for _, i := range trimValue { + if !LengthHandler(strings.TrimSpace(i)) { + valid = false + break + } + } + if valid && trimValue != nil { + return true + } + reg = regexp.MustCompile(`rotate(x|y|z)?\(([12]?|3[0-5][0-9]|360)\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`rotate3d\(([ ]?(1(\.0)?|0\.[0-9]+),){3}([12]?|3[0-5][0-9]|360)\)`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + reg = regexp.MustCompile(`skew(x|y)?\(`) + reg.Longest() + subValue = string(reg.ReplaceAll([]byte(value), []byte{})) + subValue = strings.TrimSuffix(subValue, ")") + trimValue = strings.Split(subValue, ",") + valid = true + for _, i := range trimValue { + if !LengthHandler(strings.TrimSpace(i)) { + valid = false + break + } + } + if valid { + return true + } + reg = regexp.MustCompile(`perspective\(`) + reg.Longest() + subValue = string(reg.ReplaceAll([]byte(value), []byte{})) + subValue = strings.TrimSuffix(subValue, ")") + return LengthHandler(subValue) +} + +func TransformOriginHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + xValues := []string{"left", "center", "right"} + yValues := []string{"top", "center", "bottom"} + if len(splitVals) > 2 { + if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) { + return false + } + if !in([]string{splitVals[1]}, yValues) && !LengthHandler(splitVals[1]) { + return false + } + return LengthHandler(splitVals[2]) + } else if len(splitVals) > 1 { + if !in([]string{splitVals[0]}, xValues) && !LengthHandler(splitVals[0]) { + return false + } + return in([]string{splitVals[1]}, yValues) || LengthHandler(splitVals[1]) + } else if len(splitVals) == 1 { + return in(splitVals, xValues) || in(splitVals, yValues) || LengthHandler(splitVals[0]) + } + return false +} + +func TransformStyleHandler(value string) bool { + values := []string{"flat", "preserve-3d", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TransitionHandler(value string) bool { + values := []string{"initial", "inherit"} + if in([]string{value}, values) { + return true + } + splitVals := strings.Split(value, " ") + usedFunctions := []func(string) bool{ + TransitionPropertyHandler, + TransitionDurationHandler, + TimingFunctionHandler, + TransitionDelayHandler, + ColorHandler, + } + return recursiveCheck(splitVals, usedFunctions) +} + +func TransitionDelayHandler(value string) bool { + reg := regexp.MustCompile("[0-9]+[.]?[0-9]*(s|ms)?") + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TransitionDurationHandler(value string) bool { + reg := regexp.MustCompile("[0-9]+[.]?[0-9]*(s|ms)?") + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func TransitionPropertyHandler(value string) bool { + reg := regexp.MustCompile("([a-zA-Z]+,[ ]?)*[a-zA-Z]+") + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"none", "all", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func UnicodeBidiHandler(value string) bool { + values := []string{"normal", "embed", "bidi-override", "isolate", "isolate-override", "plaintext", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func UserSelectHandler(value string) bool { + values := []string{"auto", "none", "text", "all"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func VerticalAlignHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"baseline", "sub", "super", "top", "text-top", "middle", "bottom", "text-bottom", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func VisiblityHandler(value string) bool { + values := []string{"visible", "hidden", "collapse", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func WhiteSpaceHandler(value string) bool { + values := []string{"normal", "nowrap", "pre", "pre-line", "pre-wrap", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func WidthHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func WordSpacingHandler(value string) bool { + if LengthHandler(value) { + return true + } + values := []string{"normal", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func WordBreakHandler(value string) bool { + values := []string{"normal", "break-all", "keep-all", "break-word", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func WordWrapHandler(value string) bool { + values := []string{"normal", "break-word", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func WritingModeHandler(value string) bool { + values := []string{"horizontal-tb", "vertical-rl", "vertical-lr"} + splitVals := splitValues(value) + return in(splitVals, values) +} + +func ZIndexHandler(value string) bool { + reg := regexp.MustCompile(`[\-]?[0-9]+`) + reg.Longest() + if reg.FindString(value) == value && value != "" { + return true + } + values := []string{"auto", "initial", "inherit"} + splitVals := splitValues(value) + return in(splitVals, values) +} |