spoiler plugin by Heikki Hokkanen
Adds initially hidden sections
Last updated on 2007-07-19. Provides Syntax.
Compatible with DokuWiki 2007-06-26.
Similar to wrap.
Spoiler tag for DokuWiki. Allows sections that are initially hidden, and are shown when a “Show” button is clicked. The spoiler can be hidden again by pressing the button. An optional title can be given, otherwise a “Spoiler:” text is shown before the button.
See http://wiki.fealdia.org/projects/dokuwiki/spoiler for images, playground, and download.
I'd like to see it work within a list:
* <spoiler>
* Foo
* Bar
</spoiler>
This would be a very helpfull bonus to this already very helpful plugin.
Patch to provide control over all 'spoiler' items in a page
Usage:
%%~~SPOILER:open|Label Text~~%% %%~~SPOILER:close|Label Text~~%% %%~~SPOILER:hide|Label Text~~%% %%~~SPOILER~~%%
Default behaviour is open, which is to un-hide all spoiler items, this is opposite of using <spoiler> without ~~SPOILER~~.
Permitted modes are:
open : All spoiler tags are expanded and visible when the page is renderedclose: All spoiler tags are collapsed (closed) and visible when the page is renderedhide : All spoiler tags are not visible and the button to open/close them is not rendered
The Label Text works similar to <spoiler>.
Here are the code changes to style.css and syntax.php:
*** ./style.css Wed Jul 18 14:14:43 2007
--- ./new_style.css Tue Nov 17 15:43:41 2009
***************
*** 24,26 ****
--- 24,47 ----
margin-top: 0.5em;
}
+ .spoilerctrl {
+ margin-top: 0.5em;
+ margin-bottom: 1em;
+ }
+
+ .spoilerctrl .title {
+ /* font-size: 110%; */
+ font-size: 90%;
+ font-weight: bold;
+ display: block;
+ float: left;
+ }
+
+ .spoilerctrl .title:after {
+ content: ': ';
+ }
+
+
+ .spoilerctrl input {
+ font-size: 70%;
+ }
*** ./syntax.php Thu Jul 19 15:32:57 2007
--- ./new_syntax.php Tue Nov 17 15:43:41 2009
***************
*** 56,61 ****
--- 56,62 ----
function connectTo($mode) {
// Lookahead assertion: check that there is an end tag.
$this->Lexer->addEntryPattern('<spoiler[^>\r\n]*?>(?=.*?</spoiler>)', $mode, 'plugin_spoiler');
+ $this->Lexer->addSpecialPattern('~~SPOILER[^~\r\n]*?~~', $mode, 'plugin_spoiler');
}
function postConnect() {
***************
*** 73,88 ****
$title = substr($options, strpos($options, '|') + 1);
}
! return array($state, $title);
break;
case DOKU_LEXER_MATCHED :
break;
case DOKU_LEXER_UNMATCHED :
! return array($state, $match);
break;
case DOKU_LEXER_EXIT :
break;
case DOKU_LEXER_SPECIAL :
break;
}
return array($state);
--- 74,108 ----
$title = substr($options, strpos($options, '|') + 1);
}
! return array($state, $title, '');
break;
case DOKU_LEXER_MATCHED :
break;
case DOKU_LEXER_UNMATCHED :
! return array($state, $match, '');
break;
case DOKU_LEXER_EXIT :
break;
case DOKU_LEXER_SPECIAL :
+ // "~~SPOILER" options "~~"
+ $options = substr($match, 8, -2);
+
+ $endPos = strlen($options) + 1;
+ if (strpos($options, '|') !== False) {
+ $endPos = strpos($options,'|');
+ $title = substr($options, $endPos + 1);
+ }
+
+ $switch = 'show';
+ $options = substr($options,1,$endPos - 1);
+ if (strpos($options, ':') !== False) {
+ $startPos = strpos($options,':');
+ $switch = substr($options, $startPos + 1, $endPos - ($startPos + 1));
+ }
+
+ if ($title == '') $title = 'Spoiler Control';
+
+ return array($state, $title, $switch);
break;
}
return array($state);
***************
*** 90,96 ****
function render($mode, &$renderer, $data) {
if($mode == 'xhtml'){
! list($state, $payload) = $data;
switch ($state) {
case DOKU_LEXER_ENTER :
--- 110,116 ----
function render($mode, &$renderer, $data) {
if($mode == 'xhtml'){
! list($state, $payload, $switch) = $data;
switch ($state) {
case DOKU_LEXER_ENTER :
***************
*** 100,105 ****
--- 120,139 ----
break;
case DOKU_LEXER_MATCHED :
break;
+ case DOKU_LEXER_SPECIAL :
+ $script = "if (this.value == 'Show All') { spoilerControl(1); this.value = 'Hide All' } else { spoilerControl(0); this.value = 'Show All' }";
+ switch($switch){
+ case 'close':
+ $renderer->doc .= '<div class="spoilerctrl"><div class="title">'. $payload .'</div><input type="button" value="Show All" onClick="'. $script .'" /></div><script type="text/javascript">spoilerControl(0);</script>';
+ break;
+ case 'hide':
+ $renderer->doc .= '<script type="text/javascript">spoilerControl(0);</script>';
+ break;
+ default:
+ $renderer->doc .= '<div class="spoilerctrl"><div class="title">'. $payload .'</div><input type="button" value="Hide All" onClick="'. $script .'" /></div>';
+ break;
+ }
+ break;
case DOKU_LEXER_UNMATCHED :
$renderer->doc .= $renderer->_xmlEntities($payload);
break;
Also, add the file script.js:
function spoilerControl(state) {
var el = document.getElementsByTagName('DIV');
for(var j=0; j < el.length; j++) {
var className = el[j].className;
if (className == "spoiler") {
if (state == 1) {
el[j].style.display = '';
}else {
el[j].style.display = 'none';
}
}
}
}
This extra file hides away any 'spoiler' items when printing (call it print.css):
div.dokuwiki .spoiler {
visibility: hidden;
display: none;
}
div.dokuwiki .spoilerctrl {
visibility: hidden;
display: none;
}
– Chris Usher 2009-11-17