15f891b7eSNickeau<?php 25f891b7eSNickeau 35f891b7eSNickeau// implementation of 45f891b7eSNickeau// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite 55f891b7eSNickeau 65f891b7eSNickeau// must be run within Dokuwiki 75f891b7eSNickeauuse ComboStrap\LogUtility; 85f891b7eSNickeauuse ComboStrap\PluginUtility; 95f891b7eSNickeauuse ComboStrap\Tag; 10*32b85071SNickeauuse ComboStrap\TitleUtility; 115f891b7eSNickeau 125f891b7eSNickeaurequire_once(__DIR__ . '/../class/HeaderUtility.php'); 135f891b7eSNickeau 145f891b7eSNickeauif (!defined('DOKU_INC')) die(); 155f891b7eSNickeau 165f891b7eSNickeau 175f891b7eSNickeauclass syntax_plugin_combo_label extends DokuWiki_Syntax_Plugin 185f891b7eSNickeau{ 195f891b7eSNickeau 205f891b7eSNickeau 215f891b7eSNickeau const TAG = "label"; 225f891b7eSNickeau 235f891b7eSNickeau /** 245f891b7eSNickeau * The id of the heading element for a accordion label 255f891b7eSNickeau */ 265f891b7eSNickeau const HEADING_ID = "headingId"; 275f891b7eSNickeau /** 285f891b7eSNickeau * The id of the collapsable target 295f891b7eSNickeau */ 305f891b7eSNickeau const TARGET_ID = "targetId"; 315f891b7eSNickeau 325f891b7eSNickeau /** 335f891b7eSNickeau * An indicator attribute that tells if the accordion is collpased or not 345f891b7eSNickeau */ 355f891b7eSNickeau const COLLAPSED = "collapsed"; 365f891b7eSNickeau 375f891b7eSNickeau function getType() 385f891b7eSNickeau { 395f891b7eSNickeau return 'formatting'; 405f891b7eSNickeau } 415f891b7eSNickeau 425f891b7eSNickeau /** 435f891b7eSNickeau * How Dokuwiki will add P element 445f891b7eSNickeau * 455f891b7eSNickeau * * 'normal' - The plugin can be used inside paragraphs (inline) 465f891b7eSNickeau * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 475f891b7eSNickeau * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 485f891b7eSNickeau * 495f891b7eSNickeau * @see DokuWiki_Syntax_Plugin::getPType() 505f891b7eSNickeau */ 515f891b7eSNickeau function getPType() 525f891b7eSNickeau { 535f891b7eSNickeau return 'normal'; 545f891b7eSNickeau } 555f891b7eSNickeau 565f891b7eSNickeau function getAllowedTypes() 575f891b7eSNickeau { 585f891b7eSNickeau return array('substition', 'formatting', 'disabled'); 595f891b7eSNickeau } 605f891b7eSNickeau 615f891b7eSNickeau function getSort() 625f891b7eSNickeau { 635f891b7eSNickeau return 201; 645f891b7eSNickeau } 655f891b7eSNickeau 665f891b7eSNickeau 675f891b7eSNickeau function connectTo($mode) 685f891b7eSNickeau { 695f891b7eSNickeau 705f891b7eSNickeau $this->Lexer->addEntryPattern(PluginUtility::getContainerTagPattern(self::TAG), $mode, PluginUtility::getModeForComponent($this->getPluginComponent())); 715f891b7eSNickeau } 725f891b7eSNickeau 735f891b7eSNickeau public function postConnect() 745f891b7eSNickeau { 755f891b7eSNickeau $this->Lexer->addExitPattern('</' . self::TAG . '>', PluginUtility::getModeForComponent($this->getPluginComponent())); 765f891b7eSNickeau } 775f891b7eSNickeau 785f891b7eSNickeau function handle($match, $state, $pos, Doku_Handler $handler) 795f891b7eSNickeau { 805f891b7eSNickeau 815f891b7eSNickeau switch ($state) { 825f891b7eSNickeau 835f891b7eSNickeau case DOKU_LEXER_ENTER: 845f891b7eSNickeau $tagAttributes = PluginUtility::getTagAttributes($match); 855f891b7eSNickeau 865f891b7eSNickeau $tag = new Tag(self::TAG, $tagAttributes, $state, $handler); 875f891b7eSNickeau $parentTag = $tag->getParent(); 885f891b7eSNickeau $context = null; 895f891b7eSNickeau if ($parentTag != null) { 905f891b7eSNickeau $grandfather = $parentTag->getParent(); 915f891b7eSNickeau if ($grandfather != null) { 925f891b7eSNickeau $grandFatherName = $grandfather->getName(); 935f891b7eSNickeau switch ($grandFatherName) { 945f891b7eSNickeau case syntax_plugin_combo_accordion::TAG: 955f891b7eSNickeau $id = $parentTag->getAttribute("id"); 965f891b7eSNickeau $tagAttributes["id"] = $id; 975f891b7eSNickeau $tagAttributes[self::HEADING_ID] = "heading" . ucfirst($id); 985f891b7eSNickeau $tagAttributes[self::TARGET_ID] = "collapse" . ucfirst($id); 995f891b7eSNickeau $parentAttribute = $parentTag->getAttributes(); 1005f891b7eSNickeau if (!key_exists(self::COLLAPSED, $parentAttribute)) { 1015f891b7eSNickeau // Accordion are collapsed by default 1025f891b7eSNickeau $tagAttributes[self::COLLAPSED] = "true"; 1035f891b7eSNickeau } else { 1045f891b7eSNickeau $tagAttributes[self::COLLAPSED] = $parentAttribute[self::COLLAPSED]; 1055f891b7eSNickeau } 1065f891b7eSNickeau $context = syntax_plugin_combo_accordion::TAG; 1075f891b7eSNickeau break; 1085f891b7eSNickeau case syntax_plugin_combo_tabs::TAG: 1095f891b7eSNickeau $context = syntax_plugin_combo_tabs::TAG; 1105f891b7eSNickeau $tagAttributes = $parentTag->getAttributes(); 1115f891b7eSNickeau break; 1125f891b7eSNickeau default: 1135f891b7eSNickeau LogUtility::log2FrontEnd("The label is included in the $grandFatherName component and this is unexpected", LogUtility::LVL_MSG_WARNING, self::TAG); 1145f891b7eSNickeau } 1155f891b7eSNickeau } 1165f891b7eSNickeau } 1175f891b7eSNickeau 1185f891b7eSNickeau return array( 1195f891b7eSNickeau PluginUtility::STATE => $state, 1205f891b7eSNickeau PluginUtility::ATTRIBUTES => $tagAttributes, 1215f891b7eSNickeau PluginUtility::CONTEXT => $context 1225f891b7eSNickeau ); 1235f891b7eSNickeau 1245f891b7eSNickeau case DOKU_LEXER_UNMATCHED : 125*32b85071SNickeau return PluginUtility::handleAndReturnUnmatchedData(self::TAG,$match,$handler); 1265f891b7eSNickeau 1275f891b7eSNickeau case DOKU_LEXER_EXIT : 1285f891b7eSNickeau $tag = new Tag(self::TAG, array(), $state, $handler); 1295f891b7eSNickeau $openingTag = $tag->getOpeningTag(); 1305f891b7eSNickeau $context = $openingTag->getContext(); 1315f891b7eSNickeau return array( 1325f891b7eSNickeau PluginUtility::STATE => $state, 1335f891b7eSNickeau PluginUtility::CONTEXT => $context, 1345f891b7eSNickeau PluginUtility::ATTRIBUTES => $openingTag->getAttributes() 1355f891b7eSNickeau ); 1365f891b7eSNickeau 1375f891b7eSNickeau 1385f891b7eSNickeau } 1395f891b7eSNickeau return array(); 1405f891b7eSNickeau 1415f891b7eSNickeau } 1425f891b7eSNickeau 1435f891b7eSNickeau /** 1445f891b7eSNickeau * Render the output 1455f891b7eSNickeau * @param string $format 1465f891b7eSNickeau * @param Doku_Renderer $renderer 1475f891b7eSNickeau * @param array $data - what the function handle() return'ed 1485f891b7eSNickeau * @return boolean - rendered correctly? (however, returned value is not used at the moment) 1495f891b7eSNickeau * @see DokuWiki_Syntax_Plugin::render() 1505f891b7eSNickeau * 1515f891b7eSNickeau * 1525f891b7eSNickeau */ 1535f891b7eSNickeau function render($format, Doku_Renderer $renderer, $data) 1545f891b7eSNickeau { 1555f891b7eSNickeau 1565f891b7eSNickeau if ($format == 'xhtml') { 1575f891b7eSNickeau 1585f891b7eSNickeau /** @var Doku_Renderer_xhtml $renderer */ 1595f891b7eSNickeau $state = $data[PluginUtility::STATE]; 1605f891b7eSNickeau switch ($state) { 1615f891b7eSNickeau 1625f891b7eSNickeau case DOKU_LEXER_ENTER: 1635f891b7eSNickeau 1645f891b7eSNickeau $context = $data[PluginUtility::CONTEXT]; 1655f891b7eSNickeau switch ($context) { 1665f891b7eSNickeau case syntax_plugin_combo_accordion::TAG: 1675f891b7eSNickeau $attribute = $data[PluginUtility::ATTRIBUTES]; 1685f891b7eSNickeau $headingId = $attribute[self::HEADING_ID]; 1695f891b7eSNickeau $collapseId = $attribute[self::TARGET_ID]; 1705f891b7eSNickeau $collapsed = $attribute[self::COLLAPSED]; 1715f891b7eSNickeau if ($collapsed == "false") { 1725f891b7eSNickeau $collapsedClass = "collapsed"; 1735f891b7eSNickeau } else { 1745f891b7eSNickeau $collapsedClass = ""; 1755f891b7eSNickeau } 1765f891b7eSNickeau $renderer->doc .= "<div class=\"card-header\" id=\"$headingId\">" . DOKU_LF; 1775f891b7eSNickeau $renderer->doc .= "<h2 class=\"mb-0\">"; 1785f891b7eSNickeau $renderer->doc .= "<button class=\"btn btn-link btn-block text-left $collapsedClass\" type=\"button\" data-toggle=\"collapse\" data-target=\"#$collapseId\" aria-expanded=\"true\" aria-controls=\"$collapseId\">"; 1795f891b7eSNickeau break; 1805f891b7eSNickeau case syntax_plugin_combo_tabs::TAG: 1815f891b7eSNickeau $attributes = $data[PluginUtility::ATTRIBUTES]; 1825f891b7eSNickeau $renderer->doc .= syntax_plugin_combo_tabs::openNavigationalTabElement($attributes); 1835f891b7eSNickeau break; 1845f891b7eSNickeau default: 1855f891b7eSNickeau LogUtility::log2FrontEnd("The context ($context) of the label is unknown in exit", LogUtility::LVL_MSG_WARNING, self::TAG); 1865f891b7eSNickeau } 1875f891b7eSNickeau break; 1885f891b7eSNickeau 1895f891b7eSNickeau case DOKU_LEXER_UNMATCHED : 190*32b85071SNickeau $renderer->doc .= PluginUtility::renderUnmatched($data); 1915f891b7eSNickeau break; 1925f891b7eSNickeau 1935f891b7eSNickeau case DOKU_LEXER_EXIT: 1945f891b7eSNickeau $context = $data[PluginUtility::CONTEXT]; 1955f891b7eSNickeau switch ($context) { 1965f891b7eSNickeau case syntax_plugin_combo_accordion::TAG: 1975f891b7eSNickeau $attribute = $data[PluginUtility::ATTRIBUTES]; 1985f891b7eSNickeau $collapseId = $attribute[self::TARGET_ID]; 1995f891b7eSNickeau $headingId = $attribute[self::HEADING_ID]; 2005f891b7eSNickeau $collapsed = $attribute[self::COLLAPSED]; 2015f891b7eSNickeau if ($collapsed == "false") { 2025f891b7eSNickeau $showClass = "show"; 2035f891b7eSNickeau } else { 2045f891b7eSNickeau $showClass = ""; 2055f891b7eSNickeau } 2065f891b7eSNickeau $renderer->doc .= "</button></h2></div>"; 2075f891b7eSNickeau $renderer->doc .= "<div id=\"$collapseId\" class=\"collapse $showClass\" aria-labelledby=\"$headingId\" data-parent=\"#$headingId\">"; 2085f891b7eSNickeau $renderer->doc .= "<div class=\"card-body\">" . DOKU_LF; 2095f891b7eSNickeau break; 2105f891b7eSNickeau case syntax_plugin_combo_tabs::TAG: 2115f891b7eSNickeau $renderer->doc .= syntax_plugin_combo_tabs::closeNavigationalTabElement(); 2125f891b7eSNickeau break; 2135f891b7eSNickeau default: 2145f891b7eSNickeau LogUtility::log2FrontEnd("The context ($context) of the label is unknown in exit", LogUtility::LVL_MSG_WARNING, self::TAG); 2155f891b7eSNickeau 2165f891b7eSNickeau } 2175f891b7eSNickeau break; 2185f891b7eSNickeau 2195f891b7eSNickeau 2205f891b7eSNickeau } 2215f891b7eSNickeau } 2225f891b7eSNickeau // unsupported $mode 2235f891b7eSNickeau return false; 2245f891b7eSNickeau } 2255f891b7eSNickeau 2265f891b7eSNickeau 2275f891b7eSNickeau} 2285f891b7eSNickeau 229