1<?php
2
3namespace ComboStrap;
4
5
6use Doku_Handler;
7use Doku_Renderer;
8
9
10/**
11 *
12 * TODO: when level 3 of grid
13 *   https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Masonry_Layout
14 *
15 */
16class MasonryTag
17{
18    public const TEASER_COLUMNS_TAG = 'teaser-columns';
19    /**
20     * The Tag constant should be the exact same last name of the class
21     * This is how we recognize a tag in the {@link \ComboStrap\CallStack}
22     */
23    public const MASONRY_TAG = "masonry";
24    public const LOGICAL_TAG = "masonry";
25    /**
26     * The syntax tags
27     */
28    public const CARD_COLUMNS_TAG = "card-columns";
29    /**
30     * Same as commercial
31     * https://isotope.metafizzy.co/
32     *
33     */
34    public const MASONRY_SCRIPT_ID = "masonry";
35
36
37    /**
38     * In Bootstrap5, to support card-columns, we need masonry javascript and
39     * a column
40     * We close it as seen here:
41     * https://getbootstrap.com/docs/5.0/examples/masonry/
42     *
43     * The column is open with the function {@link MasonryTag::addColIfBootstrap5AndCardColumns()}
44     * @param Doku_Renderer $renderer
45     * @param $context
46     */
47    public static function endColIfBootstrap5AnCardColumns(Doku_Renderer $renderer, $context)
48    {
49
50        /**
51         * Bootstrap five does not include masonry
52         * directly, we need to add a column
53         * and we close it here
54         */
55        $bootstrapVersion = Bootstrap::getBootStrapMajorVersion();
56        if ($bootstrapVersion == Bootstrap::BootStrapFiveMajorVersion) {
57            $renderer->doc .= '</div>';
58        }
59
60    }
61
62    public static function getSyntaxTags(): array
63    {
64        return array(self::MASONRY_TAG, self::CARD_COLUMNS_TAG, self::TEASER_COLUMNS_TAG);
65    }
66
67    /**
68     * @param $renderer
69     * @param $context Doku_Renderer
70     *
71     * Bootstrap five does not include masonry
72     * directly, we need to add a column around the children {@link syntax_plugin_combo_card} and
73     * {@link BlockquoteTag}
74     * https://getbootstrap.com/docs/5.0/examples/masonry/
75     *
76     * The column is open with the function {@link syntax_plugin_combo_masonry::endColIfBootstrap5AndCardColumns()}
77     *
78     * TODO: do it programmatically by adding call with {@link \ComboStrap\CallStack}
79     */
80    public static function addColIfBootstrap5AndCardColumns(&$renderer, $context)
81    {
82        $bootstrapVersion = Bootstrap::getBootStrapMajorVersion();
83        if ($bootstrapVersion == Bootstrap::BootStrapFiveMajorVersion && $context == MasonryTag::MASONRY_TAG) {
84            $renderer->doc .= '<div class="col-sm-6 col-lg-4 mb-4">';
85        }
86    }
87
88    public static function handleExit(Doku_Handler $handler)
89    {
90        /**
91         * When the masonry is used in an iterator, the direct
92         * context is lost
93         */
94        $callStack = CallStack::createFromHandler($handler);
95        $callStack->moveToPreviousCorrespondingOpeningCall();
96        while ($actualCall = $callStack->next()) {
97            if (
98                in_array($actualCall->getTagName(), [CardTag::CARD_TAG, BlockquoteTag::TAG])
99                && in_array($actualCall->getState(), [DOKU_LEXER_ENTER, DOKU_LEXER_EXIT])
100            ) {
101                $actualCall->setContext(MasonryTag::MASONRY_TAG);
102            }
103        }
104
105    }
106
107    public static function renderEnterTag(): string
108    {
109        $bootstrapVersion = Bootstrap::getBootStrapMajorVersion();
110        switch ($bootstrapVersion) {
111            case 5:
112                // No support for 5, we use Bs with their example
113                // https://getbootstrap.com/docs/5.0/examples/masonry/
114                // https://masonry.desandro.com/layout.html#responsive-layouts
115                // https://masonry.desandro.com/extras.html#bootstrap
116                // https://masonry.desandro.com/#initialize-with-vanilla-javascript
117                PluginUtility::getSnippetManager()->attachRemoteJavascriptLibrary(
118                    MasonryTag::MASONRY_SCRIPT_ID,
119                    "https://cdn.jsdelivr.net/npm/masonry-layout@4.2.2/dist/masonry.pkgd.min.js",
120                    "sha384-GNFwBvfVxBkLMJpYMOABq3c+d3KnQxudP/mGPkzpZSTYykLBNsZEnG2D9G/X/+7D"
121                );
122                PluginUtility::getSnippetManager()->attachJavascriptFromComponentId(MasonryTag::MASONRY_SCRIPT_ID);
123                $masonryClass = MasonryTag::MASONRY_SCRIPT_ID;
124                return "<div class=\"row $masonryClass\">";
125            default:
126                return '<div class="card-columns">' ;
127        }
128    }
129
130    public static function renderExitHtml(): string
131    {
132        return '</div>';
133    }
134}
135
136