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