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