1<?php
2/**
3 * Copyright (c) 2020. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4 *
5 * This source code is licensed under the GPL license found in the
6 * COPYING  file in the root directory of this source tree.
7 *
8 * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9 * @author   ComboStrap <support@combostrap.com>
10 *
11 */
12
13namespace ComboStrap\TagAttribute;
14
15
16use ComboStrap\ExceptionNotEquals;
17use ComboStrap\StringUtility;
18use ComboStrap\TagAttributes;
19
20/**
21 * This class gots static function about the HTML style attribute
22 *
23 * The style attribute is not allowed due to security concern
24 * in Combostrap (Click Hijacking, ...)
25 */
26class StyleAttribute
27{
28
29    const COMBOSTRAP_FIX = "cs";
30    public const STYLE_ATTRIBUTE = "style";
31
32    public static function getRule(array $styles, $selector): string
33    {
34        $rule = $selector . " {" . DOKU_LF;
35        foreach ($styles as $key => $value) {
36            $rule .= "    $key:$value;" . DOKU_LF;
37        }
38        StringUtility::rtrim($rule, ";");
39        return $rule . DOKU_LF . "}" . DOKU_LF;
40
41    }
42
43    /**
44     * @param array $array of property as key and value
45     * @return string a html inline style property
46     */
47    public static function createInlineValue(array $array)
48    {
49        $inline = "";
50        foreach ($array as $property => $value) {
51            if ($inline != "") {
52                $inline .= ";$property:$value";
53            } else {
54                $inline = "$property:$value";
55            }
56        }
57        return $inline;
58
59    }
60
61    /**
62     * Add class for user styling
63     * See
64     * https://combostrap.com/styling/userstyle#class
65     * @param TagAttributes $tagAttributes
66     */
67    public static function addStylingClass(TagAttributes &$tagAttributes)
68    {
69        $logicalTag = $tagAttributes->getLogicalTag();
70        if ($logicalTag !== null && $tagAttributes->getDefaultStyleClassShouldBeAdded() === true) {
71
72            $tagAttributes->addClassName(self::addComboStrapSuffix($logicalTag));
73            if (!empty($tagAttributes->getType())) {
74                $tagAttributes->addClassName($logicalTag . "-" . $tagAttributes->getType() . "-" . self::COMBOSTRAP_FIX);
75            }
76        }
77    }
78
79    public static function addComboStrapSuffix($name): string
80    {
81        return $name . "-" . self::COMBOSTRAP_FIX;
82    }
83
84    public static function HtmlStyleValueToArray(string $htmlStyleValue): array
85    {
86        $stylingDeclarationsAsString = explode(";", $htmlStyleValue);
87        $stylingDeclarationAsArray = [];
88        foreach ($stylingDeclarationsAsString as $stylingDeclaration) {
89            if (empty($stylingDeclaration)) {
90                // case with a trailing comma. ie `width:18rem;`
91                continue;
92            }
93            [$key, $value] = preg_split("/:/", $stylingDeclaration, 2);
94            $stylingDeclarationAsArray[$key] = $value;
95        }
96        return $stylingDeclarationAsArray;
97
98    }
99
100    /**
101     * @throws ExceptionNotEquals
102     */
103    public static function arrayEquals(array $expectedQuery, array $actualQuery)
104    {
105        foreach ($actualQuery as $key => $value) {
106            $expectedValue = $expectedQuery[$key];
107            if ($expectedValue === null) {
108                throw new ExceptionNotEquals("The expected style does not have the $key property");
109            }
110            if ($expectedValue !== $value) {
111                throw new ExceptionNotEquals("The style $key property does not have the same value ($value vs $expectedValue)");
112            }
113            unset($expectedQuery[$key]);
114        }
115        foreach ($expectedQuery as $key => $value) {
116            throw new ExceptionNotEquals("The expected styles has an extra property ($key=$value)");
117        }
118    }
119
120    /**
121     * @throws ExceptionNotEquals
122     */
123    public static function stringEquals($leftStyles, $rightStyles)
124    {
125        $leftStylesArray = StyleAttribute::HtmlStyleValueToArray($leftStyles);
126        $rightStylesArray = StyleAttribute::HtmlStyleValueToArray($rightStyles);
127        self::arrayEquals($leftStylesArray,$rightStylesArray);
128    }
129}
130