1<?php 2 3namespace ComboStrap\Tag; 4 5use action_plugin_combo_instructionspostprocessing; 6use ComboStrap\CallStack; 7use ComboStrap\ContainerTag; 8use ComboStrap\DataType; 9use ComboStrap\EditButton; 10use ComboStrap\ExceptionBadArgument; 11use ComboStrap\ExceptionNotFound; 12use ComboStrap\ExecutionContext; 13use ComboStrap\TagAttribute\Hero; 14use ComboStrap\LogUtility; 15use ComboStrap\PluginUtility; 16use ComboStrap\SiteConfig; 17use ComboStrap\TagAttributes; 18 19/** 20 * Separator: See: https://getwaves.io/ 21 * 22 * * horizontal block are known as section in mjml 23 */ 24class BarTag 25{ 26 27 28 public const SIZE_ATTRIBUTE = "size"; 29 public const HTML_TAG_ATTRIBUTES = "html_tag"; 30 public const CANONICAL = BarTag::SLIDE_TAG; 31 public const CONF_ENABLE_BAR_EDITING = "enableBarEditing"; 32 public const SLIDE_TAG = "slide"; 33 public const BAR_TAG = "bar"; 34 public const HTML_SECTION_TAG = "section"; 35 const LOGICAL_TAG = self::BAR_TAG; 36 public static $tags = [BarTag::BAR_TAG, BarTag::SLIDE_TAG]; 37 38 public static function getHtmlTag(): string 39 { 40 $tag = "div"; 41 try { 42 $isFragmentExecution = ExecutionContext::getActualOrCreateFromEnv() 43 ->getExecutingMarkupHandler() 44 ->isFragment(); 45 if (!$isFragmentExecution) { 46 $tag = self::HTML_SECTION_TAG; 47 } 48 return $tag; 49 } catch (ExceptionNotFound $e) { 50 return $tag; 51 } 52 } 53 54 public static function handleEnter(TagAttributes $tagAttributes): array 55 { 56 57 $htmlTag = BarTag::getHtmlTag(); 58 59 /** 60 * Deprecation 61 */ 62 $size = $tagAttributes->getValueAndRemoveIfPresent(BarTag::SIZE_ATTRIBUTE); 63 if ($size !== null) { 64 LogUtility::warning("The size attribute on bar/slide has been deprecated for the hero attribute"); 65 $tagAttributes->setComponentAttributeValue(Hero::ATTRIBUTE, $size); 66 } 67 68 return array(BarTag::HTML_TAG_ATTRIBUTES => $htmlTag); 69 } 70 71 public static function handleExit(\Doku_Handler $handler, int $pos, string $match): array 72 { 73 $callStack = CallStack::createFromHandler($handler); 74 $openingTag = $callStack->moveToPreviousCorrespondingOpeningCall(); 75 76 /** 77 * Section heading control 78 */ 79 $htmlTag = $openingTag->getPluginData(BarTag::HTML_TAG_ATTRIBUTES); 80 $message = null; 81 if ($htmlTag === BarTag::HTML_SECTION_TAG) { 82 $headingFound = false; 83 while ($actualCall = $callStack->next()) { 84 if (in_array($actualCall->getTagName(), action_plugin_combo_instructionspostprocessing::HEADING_TAGS)) { 85 $headingFound = true; 86 break; 87 } 88 } 89 if (!$headingFound) { 90 $id = $openingTag->getIdOrDefault(); 91 $message = "No heading was found in the section bar ($id). An heading is mandatory for navigation within device."; 92 } 93 } 94 95 if (SiteConfig::getConfValue(BarTag::CONF_ENABLE_BAR_EDITING, 1)) { 96 97 $position = $openingTag->getFirstMatchedCharacterPosition(); 98 try { 99 $startPosition = DataType::toInteger($position); 100 } catch (ExceptionBadArgument $e) { 101 LogUtility::error("The position of the slide is not an integer", BarTag::CANONICAL); 102 $startPosition = null; 103 } 104 $id = $openingTag->getIdOrDefault(); 105 // +1 to go at the line 106 $endPosition = $pos + strlen($match) + 1; 107 $tag = BarTag::BAR_TAG; 108 $editButtonCall = EditButton::create("Edit $tag $id") 109 ->setStartPosition($startPosition) 110 ->setEndPosition($endPosition) 111 ->toComboCallComboFormat(); 112 $callStack->moveToEnd(); 113 $callStack->insertBefore($editButtonCall); 114 } 115 116 117 return array( 118 BarTag::HTML_TAG_ATTRIBUTES => $htmlTag, 119 PluginUtility::EXIT_MESSAGE => $message 120 ); 121 } 122 123 public static function renderEnterXhtml(TagAttributes $attributes, array $data): string 124 { 125 $barTag = BarTag::BAR_TAG; 126 $attributes->addClassName($barTag); 127 128 PluginUtility::getSnippetManager()->attachCssInternalStyleSheet($barTag); 129 130 $htmlTag = $data[BarTag::HTML_TAG_ATTRIBUTES]; 131 $html = $attributes->toHtmlEnterTag($htmlTag); 132 133 $layoutContainer = SiteConfig::getConfValue(ContainerTag::DEFAULT_LAYOUT_CONTAINER_CONF, ContainerTag::DEFAULT_LAYOUT_CONTAINER_DEFAULT_VALUE); 134 $containerClass = ContainerTag::getClassName($layoutContainer); 135 136 $html .= "<div class=\"$barTag-body position-relative $containerClass\">"; 137 return $html; 138 } 139 140 public static function renderExitXhtml(array $data): string 141 { 142 /** 143 * End body 144 */ 145 $html = '</div>'; 146 147 /** 148 * End component 149 */ 150 $htmlTag = $data[BarTag::HTML_TAG_ATTRIBUTES]; 151 $html .= "</$htmlTag>"; 152 return $html; 153 } 154} 155