xref: /plugin/combo/ComboStrap/Tag/BoxTag.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1*04fd306cSNickeau<?php
2*04fd306cSNickeau
3*04fd306cSNickeaunamespace ComboStrap\Tag;
4*04fd306cSNickeau
5*04fd306cSNickeau
6*04fd306cSNickeauuse ComboStrap\Call;
7*04fd306cSNickeauuse ComboStrap\CallStack;
8*04fd306cSNickeauuse ComboStrap\Dimension;
9*04fd306cSNickeauuse ComboStrap\LogUtility;
10*04fd306cSNickeauuse ComboStrap\PluginUtility;
11*04fd306cSNickeauuse ComboStrap\TagAttribute\Align;
12*04fd306cSNickeauuse ComboStrap\TagAttributes;
13*04fd306cSNickeauuse Doku_Handler;
14*04fd306cSNickeau
15*04fd306cSNickeau/**
16*04fd306cSNickeau * Class syntax_plugin_combo_box
17*04fd306cSNickeau * Implementation of a div
18*04fd306cSNickeau * It permits also to dynamically add html element from other component
19*04fd306cSNickeau * via the {@link Call::createComboCall()}
20*04fd306cSNickeau *
21*04fd306cSNickeau */
22*04fd306cSNickeauclass BoxTag
23*04fd306cSNickeau{
24*04fd306cSNickeau
25*04fd306cSNickeau    const TAG = "box";
26*04fd306cSNickeau
27*04fd306cSNickeau
28*04fd306cSNickeau    // the logical tag applied (class)
29*04fd306cSNickeau    const LOGICAL_TAG_ATTRIBUTE = "logical-tag";
30*04fd306cSNickeau    const LOGICAL_TAG_DEFAUT = self::TAG;
31*04fd306cSNickeau    // the html tag
32*04fd306cSNickeau    const HTML_TAG_ATTRIBUTE = "html-tag";
33*04fd306cSNickeau    const DEFAULT_HTML_TAG = "div";
34*04fd306cSNickeau    // Tag that may make external http requests are not authorized
35*04fd306cSNickeau    const NON_AUTHORIZED_HTML_TAG = ["script", "style", "img", "video"];
36*04fd306cSNickeau
37*04fd306cSNickeau    public static function handleEnter(TagAttributes $attributes)
38*04fd306cSNickeau    {
39*04fd306cSNickeau        $tag = $attributes->getValue(self::HTML_TAG_ATTRIBUTE);
40*04fd306cSNickeau        if (in_array($tag, self::NON_AUTHORIZED_HTML_TAG)) {
41*04fd306cSNickeau            LogUtility::error("The html tag ($tag) is not authorized.");
42*04fd306cSNickeau            $attributes->setComponentAttributeValue(self::HTML_TAG_ATTRIBUTE, self::DEFAULT_HTML_TAG);
43*04fd306cSNickeau        }
44*04fd306cSNickeau    }
45*04fd306cSNickeau
46*04fd306cSNickeau
47*04fd306cSNickeau    static function handleExit(Doku_Handler $handler): array
48*04fd306cSNickeau    {
49*04fd306cSNickeau
50*04fd306cSNickeau        $callStack = CallStack::createFromHandler($handler);
51*04fd306cSNickeau
52*04fd306cSNickeau        /**
53*04fd306cSNickeau         * Check children align
54*04fd306cSNickeau         */
55*04fd306cSNickeau        $openingTag = $callStack->moveToPreviousCorrespondingOpeningCall();
56*04fd306cSNickeau        $align = $openingTag->getAttribute(Align::ALIGN_ATTRIBUTE);
57*04fd306cSNickeau        if ($align !== null && strpos($align, "children") !== false) {
58*04fd306cSNickeau
59*04fd306cSNickeau            /**
60*04fd306cSNickeau             * Scan to see the type of content
61*04fd306cSNickeau             * children can be use against one inline element or more block element
62*04fd306cSNickeau             * Not against more than one inline children element
63*04fd306cSNickeau             *
64*04fd306cSNickeau             * Retrieve the number of inline element
65*04fd306cSNickeau             * ie enter, special and box unmatched
66*04fd306cSNickeau             */
67*04fd306cSNickeau            $inlineTagFounds = [];
68*04fd306cSNickeau            while ($actual = $callStack->next()) {
69*04fd306cSNickeau
70*04fd306cSNickeau                switch ($actual->getState()) {
71*04fd306cSNickeau                    case DOKU_LEXER_EXIT:
72*04fd306cSNickeau                        continue 2;
73*04fd306cSNickeau                    case DOKU_LEXER_UNMATCHED:
74*04fd306cSNickeau                        if ($actual->getTagName() !== self::TAG) {
75*04fd306cSNickeau                            continue 2;
76*04fd306cSNickeau                        } else {
77*04fd306cSNickeau                            // Not a problem is the text are only space
78*04fd306cSNickeau                            if (trim($actual->getCapturedContent()) === "") {
79*04fd306cSNickeau                                continue 2;
80*04fd306cSNickeau                            }
81*04fd306cSNickeau                        }
82*04fd306cSNickeau                }
83*04fd306cSNickeau                if ($actual->getDisplay() == Call::INLINE_DISPLAY) {
84*04fd306cSNickeau                    $tagName = $actual->getTagName();
85*04fd306cSNickeau                    if ($actual->getTagName() === self::TAG && $actual->getState() === DOKU_LEXER_UNMATCHED) {
86*04fd306cSNickeau                        $tagName = "$tagName text";
87*04fd306cSNickeau                    }
88*04fd306cSNickeau                    $inlineTagFounds[] = $tagName;
89*04fd306cSNickeau                }
90*04fd306cSNickeau            }
91*04fd306cSNickeau            if (count($inlineTagFounds) > 1) {
92*04fd306cSNickeau                // You can't use children align value against inline
93*04fd306cSNickeau                LogUtility::warning("The `children` align attribute ($align) on the box component was apply against more than one inline elements (ie " . implode(", ", $inlineTagFounds) . "). If you don't get what you want use a text align value such as `text-center`");
94*04fd306cSNickeau            }
95*04fd306cSNickeau        }
96*04fd306cSNickeau
97*04fd306cSNickeau        /**
98*04fd306cSNickeau         * Add a scroll toggle if the
99*04fd306cSNickeau         * box is constrained by height
100*04fd306cSNickeau         */
101*04fd306cSNickeau        Dimension::addScrollToggleOnClickIfNoControl($callStack);
102*04fd306cSNickeau
103*04fd306cSNickeau        /**
104*04fd306cSNickeau         *
105*04fd306cSNickeau         */
106*04fd306cSNickeau        return array(
107*04fd306cSNickeau            PluginUtility::ATTRIBUTES => $openingTag->getAttributes()
108*04fd306cSNickeau        );
109*04fd306cSNickeau
110*04fd306cSNickeau
111*04fd306cSNickeau    }
112*04fd306cSNickeau
113*04fd306cSNickeau    static public function renderEnterXhtml(TagAttributes $tagAttributes): string
114*04fd306cSNickeau    {
115*04fd306cSNickeau        $htmlTagName = $tagAttributes->getValueAndRemove(self::HTML_TAG_ATTRIBUTE, self::DEFAULT_HTML_TAG);
116*04fd306cSNickeau        $logicalTag = $tagAttributes->getValueAndRemove(self::LOGICAL_TAG_ATTRIBUTE);
117*04fd306cSNickeau        if ($logicalTag !== null) {
118*04fd306cSNickeau            $tagAttributes->setLogicalTag($logicalTag);
119*04fd306cSNickeau        }
120*04fd306cSNickeau        return $tagAttributes->toHtmlEnterTag($htmlTagName);
121*04fd306cSNickeau    }
122*04fd306cSNickeau
123*04fd306cSNickeau
124*04fd306cSNickeau    static function renderExitXhtml(TagAttributes $tagAttributes): string
125*04fd306cSNickeau    {
126*04fd306cSNickeau        $tagName = $tagAttributes->getValueAndRemove(self::HTML_TAG_ATTRIBUTE, self::DEFAULT_HTML_TAG);
127*04fd306cSNickeau        return "</$tagName>";
128*04fd306cSNickeau    }
129*04fd306cSNickeau
130*04fd306cSNickeau
131*04fd306cSNickeau}
132*04fd306cSNickeau
133