1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeaunamespace ComboStrap; 4*04fd306cSNickeau 5*04fd306cSNickeau 6*04fd306cSNickeauuse syntax_plugin_combo_fragment; 7*04fd306cSNickeau 8*04fd306cSNickeau/** 9*04fd306cSNickeau * Carrousel 10*04fd306cSNickeau * 11*04fd306cSNickeau * We loved 12*04fd306cSNickeau * https://github.com/OwlCarousel2/OwlCarousel2 13*04fd306cSNickeau * but it's deprecated and 14*04fd306cSNickeau * send us to 15*04fd306cSNickeau * https://github.com/ganlanyuan/tiny-slider 16*04fd306cSNickeau * But it used as gutter the padding not the margin (http://ganlanyuan.github.io/tiny-slider/demo/#gutter_wrapper) 17*04fd306cSNickeau * Then we found 18*04fd306cSNickeau * https://glidejs.com/ 19*04fd306cSNickeau * 20*04fd306cSNickeau * If we need another, 21*04fd306cSNickeau * * https://swiperjs.com/ - <a href="https://themes.getbootstrap.com/preview/?theme_id=5348">purpose template</a> 22*04fd306cSNickeau * * https://github.com/ganlanyuan/tiny-slider - https://themes.getbootstrap.com/preview/?theme_id=92520 - blogzine 23*04fd306cSNickeau * 24*04fd306cSNickeau * 25*04fd306cSNickeau */ 26*04fd306cSNickeauclass CarrouselTag 27*04fd306cSNickeau{ 28*04fd306cSNickeau public const ELEMENT_WIDTH_ATTRIBUTE = "element-width"; 29*04fd306cSNickeau /** 30*04fd306cSNickeau * To center the image inside a link in a carrousel 31*04fd306cSNickeau */ 32*04fd306cSNickeau public const MEDIA_CENTER_LINK_CLASS = "justify-content-center align-items-center d-flex"; 33*04fd306cSNickeau public const CONTROL_ATTRIBUTE = "control"; 34*04fd306cSNickeau public const CANONICAL = CarrouselTag::TAG; 35*04fd306cSNickeau public const ELEMENTS_MIN_ATTRIBUTE = "elements-min"; 36*04fd306cSNickeau public const ELEMENTS_MIN_DEFAULT = 3; 37*04fd306cSNickeau public const GLIDE_SLIDE_CLASS = "glide__slide"; 38*04fd306cSNickeau public const TAG = 'carrousel'; 39*04fd306cSNickeau 40*04fd306cSNickeau 41*04fd306cSNickeau /** 42*04fd306cSNickeau * Glide copy the HTML element and lozad does not see element that are not visible 43*04fd306cSNickeau * The element non-visible are not processed by lozad 44*04fd306cSNickeau * We set lazy loading to HTML loading attribute 45*04fd306cSNickeau */ 46*04fd306cSNickeau public static function setLazyLoadToHtmlOnImageTagUntilTheEndOfTheStack(CallStack $callStack) 47*04fd306cSNickeau { 48*04fd306cSNickeau while ($actualCall = $callStack->next()) { 49*04fd306cSNickeau if ($actualCall->getState() === DOKU_LEXER_SPECIAL && in_array($actualCall->getTagName(), Call::IMAGE_TAGS)) { 50*04fd306cSNickeau $actualCall->addAttribute( 51*04fd306cSNickeau LazyLoad::LAZY_LOAD_METHOD, 52*04fd306cSNickeau LazyLoad::LAZY_LOAD_METHOD_HTML_VALUE 53*04fd306cSNickeau ); 54*04fd306cSNickeau } 55*04fd306cSNickeau } 56*04fd306cSNickeau } 57*04fd306cSNickeau 58*04fd306cSNickeau public static function handleEnter(\Doku_Handler $handler): array 59*04fd306cSNickeau { 60*04fd306cSNickeau $callStack = CallStack::createFromHandler($handler); 61*04fd306cSNickeau $parent = $callStack->moveToParent(); 62*04fd306cSNickeau $context = null; 63*04fd306cSNickeau if ($parent !== false) { 64*04fd306cSNickeau $context = $parent->getTagName(); 65*04fd306cSNickeau } 66*04fd306cSNickeau return array(PluginUtility::CONTEXT => $context); 67*04fd306cSNickeau } 68*04fd306cSNickeau 69*04fd306cSNickeau public static function handleExit(\Doku_Handler $handler): array 70*04fd306cSNickeau { 71*04fd306cSNickeau $callStack = CallStack::createFromHandler($handler); 72*04fd306cSNickeau $openingCall = $callStack->moveToPreviousCorrespondingOpeningCall(); 73*04fd306cSNickeau $actualCall = $callStack->moveToFirstChildTag(); 74*04fd306cSNickeau if ($actualCall !== false) { 75*04fd306cSNickeau if ($actualCall->getTagName() === FragmentTag::FRAGMENT_TAG) { 76*04fd306cSNickeau $templateEndCall = $callStack->moveToNextCorrespondingExitTag(); 77*04fd306cSNickeau $templateCallStackInstructions = $templateEndCall->getPluginData(FragmentTag::CALLSTACK); 78*04fd306cSNickeau if ($templateCallStackInstructions !== null) { 79*04fd306cSNickeau $templateCallStack = CallStack::createFromInstructions($templateCallStackInstructions); 80*04fd306cSNickeau // Lazy load 81*04fd306cSNickeau $templateCallStack->moveToStart(); 82*04fd306cSNickeau CarrouselTag::setLazyLoadToHtmlOnImageTagUntilTheEndOfTheStack($templateCallStack); 83*04fd306cSNickeau $templateEndCall->setPluginData(FragmentTag::CALLSTACK, $templateCallStack->getStack()); 84*04fd306cSNickeau } 85*04fd306cSNickeau } else { 86*04fd306cSNickeau // Lazy load 87*04fd306cSNickeau $callStack->moveToEnd(); 88*04fd306cSNickeau $callStack->moveToPreviousCorrespondingOpeningCall(); 89*04fd306cSNickeau CarrouselTag::setLazyLoadToHtmlOnImageTagUntilTheEndOfTheStack($callStack); 90*04fd306cSNickeau } 91*04fd306cSNickeau } 92*04fd306cSNickeau return array(PluginUtility::ATTRIBUTES => $openingCall->getAttributes()); 93*04fd306cSNickeau } 94*04fd306cSNickeau 95*04fd306cSNickeau public static function renderEnterXhtml(TagAttributes $tagAttributes, array $data): string 96*04fd306cSNickeau { 97*04fd306cSNickeau /** 98*04fd306cSNickeau * Control 99*04fd306cSNickeau */ 100*04fd306cSNickeau $control = $tagAttributes->getValueAndRemoveIfPresent(CarrouselTag::CONTROL_ATTRIBUTE); 101*04fd306cSNickeau if ($control !== null) { 102*04fd306cSNickeau $tagAttributes->addOutputAttributeValue("data-" . CarrouselTag::CONTROL_ATTRIBUTE, $control); 103*04fd306cSNickeau } 104*04fd306cSNickeau 105*04fd306cSNickeau /** 106*04fd306cSNickeau * Element Min 107*04fd306cSNickeau */ 108*04fd306cSNickeau $elementsMin = $tagAttributes->getValueAndRemoveIfPresent(CarrouselTag::ELEMENTS_MIN_ATTRIBUTE, CarrouselTag::ELEMENTS_MIN_DEFAULT); 109*04fd306cSNickeau $tagAttributes->addOutputAttributeValue("data-" . CarrouselTag::ELEMENTS_MIN_ATTRIBUTE, $elementsMin); 110*04fd306cSNickeau 111*04fd306cSNickeau /** 112*04fd306cSNickeau * Minimal Width 113*04fd306cSNickeau */ 114*04fd306cSNickeau $slideMinimalWidth = $tagAttributes->getValueAndRemoveIfPresent(CarrouselTag::ELEMENT_WIDTH_ATTRIBUTE); 115*04fd306cSNickeau if ($slideMinimalWidth !== null) { 116*04fd306cSNickeau try { 117*04fd306cSNickeau $slideMinimalWidth = ConditionalLength::createFromString($slideMinimalWidth)->toPixelNumber(); 118*04fd306cSNickeau $tagAttributes->addOutputAttributeValue("data-" . CarrouselTag::ELEMENT_WIDTH_ATTRIBUTE, $slideMinimalWidth); 119*04fd306cSNickeau } catch (ExceptionCompile $e) { 120*04fd306cSNickeau LogUtility::msg("The minimal width value ($slideMinimalWidth) is not a valid value. Error: {$e->getMessage()}"); 121*04fd306cSNickeau } 122*04fd306cSNickeau } 123*04fd306cSNickeau 124*04fd306cSNickeau 125*04fd306cSNickeau /** 126*04fd306cSNickeau * Snippets 127*04fd306cSNickeau */ 128*04fd306cSNickeau $snippetSystem = ExecutionContext::getActualOrCreateFromEnv() 129*04fd306cSNickeau ->getSnippetSystem(); 130*04fd306cSNickeau 131*04fd306cSNickeau 132*04fd306cSNickeau $snippetId = CarrouselTag::TAG; 133*04fd306cSNickeau 134*04fd306cSNickeau // Theme customized from the below official theme 135*04fd306cSNickeau // https://cdn.jsdelivr.net/npm/@glidejs/glide@3.5.2/dist/css/glide.theme.css 136*04fd306cSNickeau $snippetSystem->attachCssInternalStyleSheet($snippetId)->setCritical(false); 137*04fd306cSNickeau 138*04fd306cSNickeau /** 139*04fd306cSNickeau * The dependency first 140*04fd306cSNickeau */ 141*04fd306cSNickeau $snippetSystem->attachJavascriptFromComponentId("combo-loader"); 142*04fd306cSNickeau $snippetSystem->attachJavascriptFromComponentId($snippetId); 143*04fd306cSNickeau 144*04fd306cSNickeau /** 145*04fd306cSNickeau * Return 146*04fd306cSNickeau */ 147*04fd306cSNickeau return $tagAttributes->toHtmlEnterTag("div"); 148*04fd306cSNickeau } 149*04fd306cSNickeau 150*04fd306cSNickeau public static function renderExitXhtml(): string 151*04fd306cSNickeau { 152*04fd306cSNickeau return '</div>'; 153*04fd306cSNickeau } 154*04fd306cSNickeau} 155*04fd306cSNickeau 156