1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeaunamespace ComboStrap; 4*04fd306cSNickeau 5*04fd306cSNickeauuse Doku_Handler; 6*04fd306cSNickeauuse Doku_Renderer_metadata; 7*04fd306cSNickeauuse Exception; 8*04fd306cSNickeauuse syntax_plugin_combo_link; 9*04fd306cSNickeauuse syntax_plugin_combo_media; 10*04fd306cSNickeauuse syntax_plugin_combo_note; 11*04fd306cSNickeauuse syntax_plugin_combo_tooltip; 12*04fd306cSNickeau 13*04fd306cSNickeauclass IconTag 14*04fd306cSNickeau{ 15*04fd306cSNickeau 16*04fd306cSNickeau const CANONICAL = "icon"; 17*04fd306cSNickeau public const TAG = "icon"; 18*04fd306cSNickeau 19*04fd306cSNickeau public static function handleSpecial(TagAttributes $tagAttributes, Doku_Handler $handler): array 20*04fd306cSNickeau { 21*04fd306cSNickeau // Get the parameters 22*04fd306cSNickeau $callStack = CallStack::createFromHandler($handler); 23*04fd306cSNickeau $parent = $callStack->moveToParent(); 24*04fd306cSNickeau $context = ""; 25*04fd306cSNickeau if ($parent !== false) { 26*04fd306cSNickeau $context = $parent->getTagName(); 27*04fd306cSNickeau if ($context === syntax_plugin_combo_link::TAG) { 28*04fd306cSNickeau $context = $parent->getTagName(); 29*04fd306cSNickeau } 30*04fd306cSNickeau } 31*04fd306cSNickeau /** 32*04fd306cSNickeau * Color setting should know the color of its parent 33*04fd306cSNickeau * For now, we don't set any color if the parent is a button, note, link 34*04fd306cSNickeau * As a header is not a parent, we may say that if the icon is contained, the default 35*04fd306cSNickeau * branding color is not set ? 36*04fd306cSNickeau */ 37*04fd306cSNickeau $requestedColor = $tagAttributes->getValue(ColorRgb::COLOR); 38*04fd306cSNickeau if ( 39*04fd306cSNickeau $requestedColor === null && 40*04fd306cSNickeau Site::isBrandingColorInheritanceEnabled() && 41*04fd306cSNickeau !in_array($context, [ 42*04fd306cSNickeau ButtonTag::MARKUP_LONG, 43*04fd306cSNickeau syntax_plugin_combo_note::TAG, 44*04fd306cSNickeau syntax_plugin_combo_link::TAG 45*04fd306cSNickeau ]) 46*04fd306cSNickeau ) { 47*04fd306cSNickeau 48*04fd306cSNickeau $requestedWidth = $tagAttributes->getValue(Dimension::WIDTH_KEY, FetcherSvg::DEFAULT_ICON_LENGTH); 49*04fd306cSNickeau 50*04fd306cSNickeau // By default, a character icon 51*04fd306cSNickeau $color = Site::getSecondaryColor(); 52*04fd306cSNickeau try { 53*04fd306cSNickeau $requestedWidthInPx = ConditionalLength::createFromString($requestedWidth)->toPixelNumber(); 54*04fd306cSNickeau if ($requestedWidthInPx > 36) { 55*04fd306cSNickeau // Illustrative icon 56*04fd306cSNickeau $color = Site::getPrimaryColor(); 57*04fd306cSNickeau } 58*04fd306cSNickeau } catch (ExceptionBadArgument $e) { 59*04fd306cSNickeau LogUtility::error("The requested icon width ($requestedWidth) is not a conform width. Error: " . $e->getMessage(), self::CANONICAL, $e); 60*04fd306cSNickeau } 61*04fd306cSNickeau 62*04fd306cSNickeau if ($color !== null) { 63*04fd306cSNickeau $tagAttributes->setComponentAttributeValue(ColorRgb::COLOR, $color); 64*04fd306cSNickeau } 65*04fd306cSNickeau } 66*04fd306cSNickeau return array(PluginUtility::CONTEXT => $context); 67*04fd306cSNickeau } 68*04fd306cSNickeau 69*04fd306cSNickeau public static function exceptionHandling(Exception $e, $tagAttribute): string 70*04fd306cSNickeau { 71*04fd306cSNickeau $errorClass = syntax_plugin_combo_media::SVG_RENDERING_ERROR_CLASS; 72*04fd306cSNickeau $message = "Icon ({$tagAttribute->getValue("name")}). Error while rendering: {$e->getMessage()}"; 73*04fd306cSNickeau $html = "<span class=\"text-danger $errorClass\">" . hsc(trim($message)) . "</span>"; 74*04fd306cSNickeau LogUtility::warning($message, self::CANONICAL, $e); 75*04fd306cSNickeau return $html; 76*04fd306cSNickeau } 77*04fd306cSNickeau 78*04fd306cSNickeau /** 79*04fd306cSNickeau * @param TagAttributes $tagAttributes 80*04fd306cSNickeau * @return string 81*04fd306cSNickeau */ 82*04fd306cSNickeau public static function renderEmptyTag(TagAttributes $tagAttributes): string 83*04fd306cSNickeau { 84*04fd306cSNickeau 85*04fd306cSNickeau try { 86*04fd306cSNickeau return Icon::createFromTagAttributes($tagAttributes) 87*04fd306cSNickeau ->toHtml(); 88*04fd306cSNickeau } catch (\Exception $e) { 89*04fd306cSNickeau // catch all 90*04fd306cSNickeau return IconTag::exceptionHandling($e, $tagAttributes); 91*04fd306cSNickeau } 92*04fd306cSNickeau 93*04fd306cSNickeau } 94*04fd306cSNickeau 95*04fd306cSNickeau /** 96*04fd306cSNickeau * @param Doku_Renderer_metadata $renderer 97*04fd306cSNickeau * @param $tagAttribute 98*04fd306cSNickeau * @return void 99*04fd306cSNickeau */ 100*04fd306cSNickeau public static function metadata(Doku_Renderer_metadata $renderer, $tagAttribute) 101*04fd306cSNickeau { 102*04fd306cSNickeau 103*04fd306cSNickeau try { 104*04fd306cSNickeau $mediaPath = Icon::createFromTagAttributes($tagAttribute)->getFetchSvg()->getSourcePath(); 105*04fd306cSNickeau } catch (ExceptionCompile $e) { 106*04fd306cSNickeau // error is already fired in the renderer 107*04fd306cSNickeau return; 108*04fd306cSNickeau } 109*04fd306cSNickeau if (FileSystems::exists($mediaPath)) { 110*04fd306cSNickeau syntax_plugin_combo_media::registerFirstImage($renderer, $mediaPath); 111*04fd306cSNickeau } 112*04fd306cSNickeau } 113*04fd306cSNickeau 114*04fd306cSNickeau public static function handleEnter(TagAttributes $tagAttributes, Doku_Handler $handler): array 115*04fd306cSNickeau { 116*04fd306cSNickeau return self::handleSpecial($tagAttributes, $handler); 117*04fd306cSNickeau } 118*04fd306cSNickeau 119*04fd306cSNickeau public static function handleExit(Doku_Handler $handler): array 120*04fd306cSNickeau { 121*04fd306cSNickeau $callStack = CallStack::createFromHandler($handler); 122*04fd306cSNickeau $openingCall = $callStack->moveToPreviousCorrespondingOpeningCall(); 123*04fd306cSNickeau return array( 124*04fd306cSNickeau PluginUtility::ATTRIBUTES => $openingCall->getAttributes(), 125*04fd306cSNickeau PluginUtility::CONTEXT => $openingCall->getContext() 126*04fd306cSNickeau ); 127*04fd306cSNickeau } 128*04fd306cSNickeau 129*04fd306cSNickeau public static function renderEnterTag(TagAttributes $tagAttributes): string 130*04fd306cSNickeau { 131*04fd306cSNickeau $tooltip = $tagAttributes->getValueAndRemoveIfPresent(Tooltip::TOOLTIP_ATTRIBUTE); 132*04fd306cSNickeau $html = ""; 133*04fd306cSNickeau if ($tooltip !== null) { 134*04fd306cSNickeau /** 135*04fd306cSNickeau * If there is a tooltip, we need 136*04fd306cSNickeau * to start with a span to wrap the svg with it 137*04fd306cSNickeau */ 138*04fd306cSNickeau 139*04fd306cSNickeau 140*04fd306cSNickeau $tooltipTag = TagAttributes::createFromCallStackArray([Tooltip::TOOLTIP_ATTRIBUTE => $tooltip]) 141*04fd306cSNickeau ->addClassName(syntax_plugin_combo_tooltip::TOOLTIP_CLASS_INLINE_BLOCK); 142*04fd306cSNickeau $html .= $tooltipTag->toHtmlEnterTag("span"); 143*04fd306cSNickeau } 144*04fd306cSNickeau /** 145*04fd306cSNickeau * Print the icon 146*04fd306cSNickeau */ 147*04fd306cSNickeau $html .= IconTag::renderEmptyTag($tagAttributes); 148*04fd306cSNickeau /** 149*04fd306cSNickeau * Close the span if we are in a tooltip context 150*04fd306cSNickeau */ 151*04fd306cSNickeau if ($tooltip !== null) { 152*04fd306cSNickeau $html .= "</span>"; 153*04fd306cSNickeau } 154*04fd306cSNickeau return $html; 155*04fd306cSNickeau } 156*04fd306cSNickeau} 157