MediaWiki:Spoiler

From Vanishing Point Wiki
Jump to: navigation, search

Contents

Overview

Several people have asked me about the spoiler extension, so I figured I might as well release it to the public. The JavaScript and CSS are based around the Perplex City Card Catalog invisiclues I did earlier in the year. The MediaWiki plugin code is based on the Extending Wiki Markup article at MediaWiki.

Here is an example of the script in action:

Show text


Bugs

Keep in mind that only limited testing has been done on this extension. There is certainly an issue in the rare case that a browser supports CSS but not JavaScript: the spoilerized block starts out with the CSS "visibility:hidden" attribute with no way to switch it to visible.

If you find any bugs (or if you have fixes for bugs you've found--which is what I would much prefer), drop me a line at brian@{this domain name}.

TODO

  • Spoilerized text should probably start out as being visible, with on-load JavaScript to hide it immediately. This would help in the case where a browser supports CSS but not JavaScript (e.g. the NoScript Firefox extension)
  • There should probably be "media=print" CSS styles defined so that spoilerized text will be visible on printouts.

Installation

To install, simply copy spoiler.php (the code is below) to your mediawiki /extensions/ folder and add the following line to your LocalSettings.php:

require_once("$IP/extensions/spoiler.php");

This is the content of the spoiler.php file:

<?php
# WikiMedia spoiler extension
# <spoiler> some text </spoiler>
# the function registered by the extension hides the text between the
# tags behind a JavaScript spoiler block.
#
# (C) Copyright 2006, Brian Enigma <brian@netninja.com>
# This work is licensed under a Creative Commons Attribution-Noncommercial-Share 
# Alike 2.5 License.  Some rights reserved.
# http://creativecommons.org/licenses/by-nc-sa/2.5/

$wgExtensionFunctions[] = "wfSpoilerExtension";
# $wgHooks['ParserBeforeTidy'][] = 'spoilerParserHook' ;
$wgHooks['OutputPageBeforeHTML'][] = 'spoilerParserHook' ;

function wfSpoilerExtension() {
    global $wgParser;
    # register the extension with the WikiText parser
    # the first parameter is the name of the new tag.
    # In this case it defines the tag <example> ... </example>
    # the second parameter is the callback function for
    # processing the text between the tags
    $wgParser->setHook( "spoiler", "renderSpoiler" );
}

function wfSpoilerJavaScript() {
return  "<script language=\"JavaScript\">\n" .
        "\n" . 
        "function getStyleObject(objectId) {\n" .
        "    // checkW3C DOM, then MSIE 4, then NN 4.\n" .
        "    //\n" .
        "    if(document.getElementById) {\n" .
        "      if (document.getElementById(objectId)) {\n" .
        "	     return document.getElementById(objectId).style;\n" .
        "      }\n" . 
        "    } else if (document.all) {\n" .
        "      if (document.all(objectId)) {\n" .
        "	     return document.all(objectId).style;\n" .
        "      }\n" . 
        "    } else if (document.layers) { \n" . 
        "      if (document.layers[objectId]) { \n" .
        "	     return document.layers[objectId];\n" .
        "      }\n" . 
        "    } else {\n" .
        "	   return false;\n" .
        "    }\n" .
        "}\n" .
        "\n" .
        "function toggleObjectVisibility(objectId) {\n" .
        "    // first get the object's stylesheet\n" .
        "    var styleObject = getStyleObject(objectId);\n" .
        "\n" .
        "    // then if we find a stylesheet, set its visibility\n" .
        "    // as requested\n" .
        "    //\n" .
        "    if (styleObject) {\n" .
        "        if (styleObject.visibility == 'hidden') {\n" .
        "            styleObject.visibility = 'visible';\n" .
        "            styleObject.position = 'relative';\n" .
        "        } else {\n" .
        "            styleObject.visibility = 'hidden';\n" .
        "            styleObject.position = 'absolute';\n" .
        "        }\n" .
        "        return true;\n" .
        "    } else {\n" .
        "        return false;\n" .
        "    }\n" .
        "}\n" .
        "</script>\n" .
        "<style type=\"text/css\"><!--\n" .
        "div.spoiler {border: dashed red 3px; background-color: #ffdddd; padding:3px;}\n" .
        "span.spoilerHeader {font-size:135%; color:#ff0000;}\n" . 
        "a.spoilerLink {background-color:#ff0000; color:#ffff00; font-weight:bold; padding:4px 4px 2px 4px; border:solid black 1px;}\n" . 
        "--></style>\n";
}

function spoilerParserHook( &$parser , &$text ) { 
    $text = wfSpoilerJavaScript() . $text;
    return true;
}

function wfMakeSpoilerId() {
    $result = "";
    for ($i=0; $i<20; $i++)
        $result .= chr(rand(ord('A'), ord('Z')));
    return $result;
}

# The callback function for converting the input text to HTML output
function renderSpoiler( $input, $argv, &$parser ) {
    # $argv is an array containing any arguments passed to the
    # extension like <example argument="foo" bar>..
    # Put this on the sandbox page:  (works in MediaWiki 1.5.5)
    #   <example argument="foo" argument2="bar">Testing text **example** in between the new tags</example>
    $localParser = new Parser();
    $outputObj = $localParser->parse($input, $parser->mTitle, $parser->mOptions);
    $spoilerId = wfMakeSpoilerId();
    $output  = "<a href=\"#\"onclick=\"toggleObjectVisibility('" . $spoilerId . "'); return false;\" class=\"spoilerLink\">";
    $output .= "Click to reveal Spoiler</a>\n";
    $output .= "<div id=\"" . $spoilerId . "\" class=\"spoiler\" style=\"visibility: hidden; position:absolute;\">\n";
    $output .= "<span class=\"spoilerHeader\">SPOILER</span><br />\n";
    $output .= $outputObj->getText() . "\n";
    #$output .= $input . "\n";
    $output .= "</div>\n";
    # $output .= "Text passed into example extension: <br/>$input";
    # $output .= " <br/> and the value for the arg 'argument' is " . $argv["argument"];
    # $output .= " <br/> and the value for the arg 'argument2' is: " . $argv["argument2"];
    return $output;
}
?>
Personal tools