Difference between revisions of "Extension:Treeview4.php"

From Organic Design wiki
(4.0.9 - minor bug fix)
(5.0.2 - $id not $uid for per-tree id's ($uid is used by voodoo only))
Line 1: Line 1:
 
<?php
 
<?php
# MediaWiki Treeview Extension{{php}}{{Category:Extensions|Treeview4}}{{Category:Code that uses voodoo|Treeview4}}
+
/**
# - See http://www.mediawiki.org/wiki/Extension:Tree_view for installation and usage details
+
* MediaWiki Treeview Extension{{php}}{{Category:Extensions|Treeview5}}{{Category:Code that uses voodoo|Treeview5}}
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
+
* - See http://www.mediawiki.org/wiki/Extension:Tree_view for installation and usage details
# - Author:  http://www.organicdesign.co.nz/nad
+
* - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
# - Started: (Version4) 2007-09-06
+
* - Author:  http://www.organicdesign.co.nz/nad
+
* - Started: (Version5) 2007-10-24{{Category:Extensions in progress|Treeview5}}
 +
*/
 +
 
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
+
 
define('TREEVIEW4_VERSION','4.0.9, 2007-12-29');
+
define('TREEVIEW5_VERSION','5.0.2, 2008-02-27');
+
 
 
# Set any unset images to default titles
 
# Set any unset images to default titles
 
if (!isset($wgTreeViewImages) || !is_array($wgTreeViewImages)) $wgTreeViewImages = array();
 
if (!isset($wgTreeViewImages) || !is_array($wgTreeViewImages)) $wgTreeViewImages = array();
if (!isset($wgTreeViewImages['plus']))  $wgTreeViewImages['plus']  = 'Plus.gif';
 
if (!isset($wgTreeViewImages['minus']))  $wgTreeViewImages['minus']  = 'Minus.gif';
 
if (!isset($wgTreeViewImages['opened'])) $wgTreeViewImages['opened'] = 'Folder_opn_sml_yel.gif';
 
if (!isset($wgTreeViewImages['closed'])) $wgTreeViewImages['closed'] = 'Folder_sml_yel.gif';
 
if (!isset($wgTreeViewImages['doc']))    $wgTreeViewImages['doc']    = 'Doc-icon.gif';
 
if (!isset($wgTreeViewImages['spacer'])) $wgTreeViewImages['spacer'] = 'Blank.gif';
 
  
# These images are needed if you have $wgTreeViewShowLines set
 
if (!isset($wgTreeViewImages['vert'])) $wgTreeViewImages['vert'] = 'Vertline.gif';
 
if (!isset($wgTreeViewImages['node'])) $wgTreeViewImages['node'] = 'Node.gif';
 
if (!isset($wgTreeViewImages['last'])) $wgTreeViewImages['last'] = 'Lastnode.gif';
 
 
 
# Keep track of JavaScript added to page to avoid doubleups
 
# Keep track of JavaScript added to page to avoid doubleups
 
if (!isset($wgJS)) $wgJS = array();
 
if (!isset($wgJS)) $wgJS = array();
+
 
$wgTreeView4Magic             = "tree"; # the parser-function name for trees
+
$wgTreeView5Magic             = "tree"; # the parser-function name for trees
$wgTreeViewIndent              = 0;      # the number of pixels each level indents by (0 means doc-icon width)
 
 
$wgTreeViewShowLines          = false;  # whether to render the dotted lines joining nodes
 
$wgTreeViewShowLines          = false;  # whether to render the dotted lines joining nodes
$wgExtensionFunctions[]        = 'wfSetupTreeView4';
+
$wgExtensionFunctions[]        = 'wfSetupTreeView5';
$wgHooks['LanguageGetMagic'][] = 'wfTreeView4LanguageGetMagic';
+
$wgHooks['LanguageGetMagic'][] = 'wfTreeView5LanguageGetMagic';
+
 
 
$wgExtensionCredits['parserhook'][] = array(
 
$wgExtensionCredits['parserhook'][] = array(
'name'        => 'Treeview4',
+
'name'        => 'Treeview5',
'author'      => '[http://www.organicdesign.co.nz/nad User:Nad]',
+
'author'      => '[http://www.organicdesign.co.nz/nad Nad], [http://www.organicdesign.co.nz/User:Sven Sven]',
 
'url'        => 'http://www.mediawiki.org/wiki/Extension:Treeview',
 
'url'        => 'http://www.mediawiki.org/wiki/Extension:Treeview',
'description' => 'Allows dynamic tree-views to be made with bullet-list syntax',
+
'description' => 'Extends the wiki parser to allow bullet and numbered lists to work with recursion and optionally
'version'    => TREEVIEW4_VERSION
+
allows these to be rendered as collapsible trees using the free
 +
[http://www.destroydrop.com/javascripts/tree dTree] JavaScript tree menu.',
 +
'version'    => TREEVIEW5_VERSION
 
);
 
);
+
 
class TreeView4 {
+
class TreeView5 {
+
 
var $version  = TREEVIEW4_VERSION;
+
var $version  = TREEVIEW5_VERSION;
var $width    = 16;
+
var $uid;
var $uniq    = array();
+
var $baseDir;
var $uid      = '';
+
var $baseUrl;
var $js      = 0;
+
var $useLines;
+
 
# Constructor
+
/**
function TreeView4() {
+
* Constructor
global $wgParser,$wgHooks,$wgTreeView4Magic,$wgTreeViewIconMagic,$wgTreeViewImages,$wgTreeViewIndent;
+
*/
 +
function TreeView5() {
 +
global $wgParser,$wgScriptPath,$wgTreeView5Magic,$wgTreeViewImages,$wgTreeViewShowLines;
  
 
# Convert image titles to file paths and obtain pixel width of items
 
# Convert image titles to file paths and obtain pixel width of items
if ($wgTreeViewIndent) $this->width = $wgTreeViewIndent;
 
 
foreach ($wgTreeViewImages as $k => $v) {
 
foreach ($wgTreeViewImages as $k => $v) {
 
$title = Title::newFromText($v,NS_IMAGE);
 
$title = Title::newFromText($v,NS_IMAGE);
 
$image = Image::newFromTitle($title);
 
$image = Image::newFromTitle($title);
if ($image && $image->exists()) {
+
if ($image && $image->exists()) $wgTreeViewImages[$k] = $image->getURL();
$wgTreeViewImages[$k] = $image->getURL();
 
if ($wgTreeViewIndent < 1 && $k == 'doc') $this->width = $image->getWidth();
 
}
 
 
}
 
}
  
 +
$wgParser->setFunctionHook($wgTreeView5Magic,array($this,'Tree'));
 +
 
$this->uid = uniqid('TVUNIQ');
 
$this->uid = uniqid('TVUNIQ');
$wgParser->setFunctionHook($wgTreeView4Magic,array($this,'Tree'));
+
$this->baseDir = dirname(__FILE__);
}
+
$this->baseUrl = preg_replace('|^.+(?=/extensions)|',$wgScriptPath,$this->baseDir);
+
$this->useLines = $wgTreeViewShowLines ? 'true' : 'false';
# Restructure recursive trees into a single bullet list surrounded by internal treeview4 tags
+
}
 +
 
 +
/**
 +
* Restructure recursive trees into a single bullet list surrounded by internal treeview5 tags
 +
*/
 
function Tree(&$parser) {
 
function Tree(&$parser) {
 
global $wgParser;
 
global $wgParser;
$id   = uniqid();
+
$id = uniqid('');
 
$args = "id='$id'";
 
$args = "id='$id'";
 
foreach (func_get_args() as $arg) if (!is_object($arg)) {
 
foreach (func_get_args() as $arg) if (!is_object($arg)) {
Line 79: Line 75:
 
# Black magic
 
# Black magic
 
$text = $this->uniq[$id] = preg_replace(
 
$text = $this->uniq[$id] = preg_replace(
'/^\\*(\\**)\\s*(\\x07UNIQ.+?-treeview4(.+?)-.+?-QINU\\x07?)/me',
+
'/^\\*(\\**)\\s*(\\x07UNIQ.+?-treeview5(.+?)-.+?-QINU\\x07?)/me',
 
'$this->uniq["$3"] ? preg_replace("/^(\\*+)/m","$1\$1",$this->uniq["$3"]) : "$1$2"',
 
'$this->uniq["$3"] ? preg_replace("/^(\\*+)/m","$1\$1",$this->uniq["$3"]) : "$1$2"',
 
$text
 
$text
Line 85: Line 81:
  
 
# And a little more voodoo here
 
# And a little more voodoo here
$wgParser->setHook("treeview4$id",array($this,'treeview'));
+
$wgParser->setHook("treeview5$id",array($this,'treeview'));
return "<treeview4$id $args>$text</treeview4$id>";
+
return "<treeview5$id $args>$text</treeview5$id>";
 
}
 
}
  
# Convert a bullet list into a treeview
+
/**
 +
* Convert a bullet list into a treeview
 +
*/
 
function treeview($text,$argv,&$parser) {
 
function treeview($text,$argv,&$parser) {
global $wgTreeViewImages;
+
global $wgTreeViewImages,$wgJsMimeType;
+
 
$id     = $argv['id'];
+
$id   = 'tv'.$argv['id']; // id of this tree (must be valid JS variable identifier)
$uid     = $this->uid;
+
$uid = $this->uid;       // used by voodoo
$ver    = $this->version;
+
$root = isset($argv['root']) ? $argv['root'] : '';
$width  = $this->width;
+
 
$plus    = $wgTreeViewImages['plus'];
 
$minus  = $wgTreeViewImages['minus'];
 
$opened  = $wgTreeViewImages['opened'];
 
$closed  = $wgTreeViewImages['closed'];
 
$spacer  = $wgTreeViewImages['spacer'];
 
$doc    = $wgTreeViewImages['doc'];
 
$vert    = $wgTreeViewImages['vert'];
 
$node    = $wgTreeViewImages['node'];
 
$last    = $wgTreeViewImages['last'];
 
$default = isset($argv['openlevels']) ? $argv['openlevels']+1 : 1;
 
$rows    = array();
 
$lasts  = array();
 
$cols    = 0;
 
$next    = 0;
 
$tree    = '';
 
 
 
# Protect the asterisk structure and wiki-parse the bullet tree
 
# Protect the asterisk structure and wiki-parse the bullet tree
 
$text = preg_replace("/(?<=\\*)\\s*\\[\\[Image:(.+?)\\]\\]/","{$uid}3$1{$uid}4",$text);
 
$text = preg_replace("/(?<=\\*)\\s*\\[\\[Image:(.+?)\\]\\]/","{$uid}3$1{$uid}4",$text);
Line 121: Line 103:
 
# Extract the valid rows and process if any
 
# Extract the valid rows and process if any
 
if (preg_match_all("/1{$uid}([0-9]+)-({$uid}3(.+?){$uid}4)?(.+?){$uid}2/",$text,$matches,PREG_SET_ORDER)) {
 
if (preg_match_all("/1{$uid}([0-9]+)-({$uid}3(.+?){$uid}4)?(.+?){$uid}2/",$text,$matches,PREG_SET_ORDER)) {
 +
 +
# Convert the custom images in $wgTreeViewImages into JS statements
 +
$images = '';
 +
foreach ($wgTreeViewImages as $k => $v) $images .= "$id.icon['$k'] = '$v';";
 +
 +
# Build the dTree instantiation code
 +
$dtree = "// TreeView{$this->version}
 +
$id = new dTree('$id');
 +
for (i in $id.icon) $id.icon[i] = '{$this->baseUrl}/'+$id.icon[i];
 +
{$images}
 +
$id.config.useLines = {$this->useLines};
 +
$id.add(0, -1, '$rootname');
 +
";
  
# Parse 1
+
# Add the content to the dTree object
 +
$counter  = 1;
 +
$parent    = 0;
 +
$currdepth = 0;
 
foreach ($matches as $row) {
 
foreach ($matches as $row) {
 
list(,$depth,,$icon,$item) = $row;
 
list(,$depth,,$icon,$item) = $row;
 
if ($depth > $cols) $lasts[$cols = $depth] = true;
 
if ($depth > $cols) $lasts[$cols = $depth] = true;
$rows[] = array($depth,$icon,$item);
+
$parent    = $currdepth < $depth-1 ? $counter-1 : $depth-1;
}
+
$item      = str_replace("'","\\'",$item);
 
+
$dtree    .= "${id}.add($counter,$parent,'$item');\n";
# Parse 2
+
$currdepth = $depth-1;
for ($row = count($rows)-1; $row >= 0; $row--) {
+
$counter++;
list($depth,$i,$item) = $rows[$row];
 
$diff = $depth - $next;
 
$show = $depth > $default ? " style='display:none'" : "";
 
$span = $cols+2-$depth;
 
$span = $span == 1 ? "" : " colspan='$span'";
 
$td  = "";
 
$ibg  = "";
 
 
 
# Determine the open/close link and the folder/doc icon
 
if ($depth >= $default) { $open = $plus; $icon = $closed; }
 
else { $open = $minus; $icon = $opened; $ibg = " style='background: url($vert) 0 10px no-repeat'"; }
 
if ($depth >= $next) { $open = "<img src='$spacer' width='$width'/>"; $icon = $doc; $ibg = ''; }
 
else $open = "<a href='javascript:toggleTreeviewItem(\"$id\",$row)'><img id='tvi$id$row' src='$open'/></a>";
 
 
 
# Handle custom image
 
if ($i) {
 
$i = Image::newFromTitle(Title::newFromText($i,NS_IMAGE));
 
if ($i && $i->exists()) $icon = $i->getURL();
 
}
 
 
 
# Construct the dotted joining lines and position the open/close link in the last one
 
if ($diff > 0) $lasts[$depth] = true;
 
for ($col = $depth+1; $col < $cols; $col++) $lasts[$col] = true;
 
for ($col = 1; $col <= $depth; $col++) {
 
if ($diff > 1 && $col > $next && $col < $depth-1) $lasts[$col] = true;
 
if ($col == $depth) { $fg = $open; $bg = $lasts[$col] ? $last : $node; }
 
else { $fg = ""; $bg = $lasts[$col] ? $spacer : $vert; }
 
$td .= "<td style='background: url($bg) no-repeat'>$fg</td>";
 
}
 
$lasts[$depth] = false;
 
 
 
# Add the icon and the item content and append a table row to the tree definition
 
$td .= "<td class='tree-icon'><img id='tvf$id$row' src='$icon'/></td>";
 
$td .= "<td class='tree-text'$span>$item</td>";
 
$tree = "<tr$show depth='$depth' id='tvr$id$row'>$td</tr>\n$tree";
 
$next = $depth;
 
}
 
 
}
 
}
  
# This invisible row at the start fixes a bug making some text items not maximum width
+
# Output the dTree
$td = '';
+
$dtree .= "document.write($uid);\n";
for ($col = 1; $col <= $cols+1; $col++) $td .= "<td width=0/>";
+
}
$tree = "<tr>$td<td width=100%/></tr>\n$tree";
 
  
return "<table cellpadding=0 cellspacing=0 class='tree-view' id='tv$id' title='Extension:Treeview (ver $ver)'>\n$tree</table>";
+
return("<script type=\"$wgJsMimeType\">\n<!--\n$dtree-->\n</script>");
}
+
}
  
# Protect asterisk bullet structure from wiki parser
+
/**
 +
* Protect asterisk bullet structure from wiki parser
 +
*/
 
function protectTree($m) {
 
function protectTree($m) {
 
return "1{$this->uid}".strlen($m[1])."-$m[2]{$this->uid}2\n";
 
return "1{$this->uid}".strlen($m[1])."-$m[2]{$this->uid}2\n";
 
}
 
}
 
   
 
   
# Add the javascript to the output object if not added yet and there is at least one tree
+
/**
 +
* Add the javascript to the output object if not added yet and there is at least one tree
 +
*/
 
function addJS() {
 
function addJS() {
global $wgOut,$wgTreeViewImages,$wgJS,$wgJsMimeType;
+
global $wgOut,$wgJS,$wgJsMimeType;
if (isset($wgJS['TreeView4'])) return;
+
if (isset($wgJS['TreeView5'])) return;
$wgJS['TreeView4'] = true;
+
$wgJS['TreeView5'] = true;
$plus    = $wgTreeViewImages['plus'];
+
$wgOut->addScript("<script type=\"$wgJsMimeType\" src=\"{$this->baseUrl}/dtree.js\" />\n");
$minus  = $wgTreeViewImages['minus'];
 
$opened  = $wgTreeViewImages['opened'];
 
$closed  = $wgTreeViewImages['closed'];
 
$spacer  = $wgTreeViewImages['spacer'];
 
$doc    = $wgTreeViewImages['doc'];
 
$vert    = $wgTreeViewImages['vert'];
 
$wgOut->addScript('<script type="'.$wgJsMimeType.'">
 
function toggleTreeviewItem(id,row) {
 
var plus  = "'.$plus.'";
 
var minus  = "'.$minus.'";
 
var opened = "'.$opened.'";
 
var closed = "'.$closed.'";
 
var doc    = "'.$doc.'";
 
var item  = document.getElementById("tvr"+id+row);
 
var next  = document.getElementById("tvr"+id+(row+1));
 
var depth  = 0+item.getAttribute("depth");
 
var close  = next.style.display != "none";
 
var img    = document.getElementById("tvi"+id+row);
 
var fld    = document.getElementById("tvf"+id+row);
 
var src   = fld.getAttribute("src");
 
if (src == opened) fld.setAttribute("src",closed);
 
if (src == closed) fld.setAttribute("src",opened);
 
fld.setAttribute("style",close ? "" : "background:url('.$vert.') repeat-y");
 
img.setAttribute("src",close ? plus : minus);
 
while ((item = document.getElementById("tvr"+id+(++row))) && (0+item.getAttribute("depth") > depth)) {
 
if (close) item.style.display = "none";
 
else if (depth == item.getAttribute("depth")-1) {
 
item.style.display = "";
 
if (img = document.getElementById("tvi"+id+row)) img.setAttribute("src",plus);
 
if (fld = document.getElementById("tvf"+id+row))
 
if (fld.getAttribute("src") == opened) {
 
fld.setAttribute("src",closed);
 
fld.serAttribute("style","");
 
}
 
}
 
}
 
}</script>');
 
}
 
 
}
 
}
 +
}
 
   
 
   
# Called from $wgExtensionFunctions array when initialising extensions
+
/**
function wfSetupTreeView4() {
+
* Called from $wgExtensionFunctions array when initialising extensions
global $wgTreeView4;
+
*/
$wgTreeView4 = new TreeView4();
+
function wfSetupTreeView5() {
$wgTreeView4->addJS(); # Make code unconditional for now due to parser caching
+
global $wgTreeView5;
 +
$wgTreeView5 = new TreeView5();
 +
$wgTreeView5->addJS(); # Make code unconditional for now due to parser caching  
 
}
 
}
 
   
 
   
# Needed in MediaWiki >1.8.0 for magic word hooks to work properly
+
/**
function wfTreeView4LanguageGetMagic(&$magicWords,$langCode = 0) {
+
* Needed in MediaWiki >1.8.0 for magic word hooks to work properly
global $wgTreeView4,$wgTreeView4Magic;
+
*/
$magicWords[$wgTreeView4Magic] = array(0,$wgTreeView4Magic);
+
function wfTreeView5LanguageGetMagic(&$magicWords,$langCode = 0) {
 +
global $wgTreeView5,$wgTreeView5Magic;
 +
$magicWords[$wgTreeView5Magic] = array(0,$wgTreeView5Magic);
 
return true;
 
return true;
 
}
 
}
?>
 

Revision as of 05:28, 27 February 2008

<?php /**

Info.svg These are the MediaWiki extensions we're using and/or developing. Please refer to the information on the mediawiki.org wiki for installation and usage details. Extensions here which have no corresponding mediawiki article are either not ready for use or have been superseded. You can also browse our extension code in our local Subversion repository or our GitHub mirror.
Voodoo.svg

In computer programming, "Voodoo", or "Magic" refers to techniques that are secret or not widely known, and may be deliberately kept secret. The Jargon File makes a distinction between "deep magic", which refers to code based on esoteric theoretical knowledge; "black magic" (voodoo), which refers to code based on techniques that appear to work but which lack a theoretical explanation; and "heavy wizardry", which refers to code based on obscure or undocumented intricacies of particular hardware or software.

At Organic Design the most common of these is extending an instance's class at runtime after it has been instantiated, a technique that can be used to provide additional hooks into existing code without requiring modification of code-base files. Another is reading in a class file, declaring it under a different name, then sub-classing that with a new class of the original name - that way the environment uses the new extended class thinking it's the original one.

See also

if (!defined('MEDIAWIKI')) die('Not an entry point.');

define('TREEVIEW5_VERSION','5.0.2, 2008-02-27');

  1. Set any unset images to default titles

if (!isset($wgTreeViewImages) || !is_array($wgTreeViewImages)) $wgTreeViewImages = array();

  1. Keep track of JavaScript added to page to avoid doubleups

if (!isset($wgJS)) $wgJS = array();

$wgTreeView5Magic = "tree"; # the parser-function name for trees $wgTreeViewShowLines = false; # whether to render the dotted lines joining nodes $wgExtensionFunctions[] = 'wfSetupTreeView5'; $wgHooks['LanguageGetMagic'][] = 'wfTreeView5LanguageGetMagic';

$wgExtensionCredits['parserhook'][] = array( 'name' => 'Treeview5', 'author' => 'Nad, Sven', 'url' => 'http://www.mediawiki.org/wiki/Extension:Treeview', 'description' => 'Extends the wiki parser to allow bullet and numbered lists to work with recursion and optionally allows these to be rendered as collapsible trees using the free dTree JavaScript tree menu.', 'version' => TREEVIEW5_VERSION );

class TreeView5 {

var $version = TREEVIEW5_VERSION; var $uid; var $baseDir; var $baseUrl; var $useLines;

/** * Constructor */ function TreeView5() { global $wgParser,$wgScriptPath,$wgTreeView5Magic,$wgTreeViewImages,$wgTreeViewShowLines;

# Convert image titles to file paths and obtain pixel width of items foreach ($wgTreeViewImages as $k => $v) { $title = Title::newFromText($v,NS_IMAGE); $image = Image::newFromTitle($title); if ($image && $image->exists()) $wgTreeViewImages[$k] = $image->getURL(); }

$wgParser->setFunctionHook($wgTreeView5Magic,array($this,'Tree'));

$this->uid = uniqid('TVUNIQ'); $this->baseDir = dirname(__FILE__); $this->baseUrl = preg_replace('|^.+(?=/extensions)|',$wgScriptPath,$this->baseDir); $this->useLines = $wgTreeViewShowLines ? 'true' : 'false'; }

/** * Restructure recursive trees into a single bullet list surrounded by internal treeview5 tags */ function Tree(&$parser) { global $wgParser; $id = uniqid(); $args = "id='$id'"; foreach (func_get_args() as $arg) if (!is_object($arg)) { if (preg_match('/^(.+?=.+)$/',$arg,$m)) $args .= " $arg"; else $text = $arg; }

# Black magic $text = $this->uniq[$id] = preg_replace( '/^\\*(\\**)\\s*(\\x07UNIQ.+?-treeview5(.+?)-.+?-QINU\\x07?)/me', '$this->uniq["$3"] ? preg_replace("/^(\\*+)/m","$1\$1",$this->uniq["$3"]) : "$1$2"', $text );

# And a little more voodoo here $wgParser->setHook("treeview5$id",array($this,'treeview')); return "<treeview5$id $args>$text</treeview5$id>"; }

/** * Convert a bullet list into a treeview */ function treeview($text,$argv,&$parser) { global $wgTreeViewImages,$wgJsMimeType;

$id = 'tv'.$argv['id']; // id of this tree (must be valid JS variable identifier) $uid = $this->uid; // used by voodoo $root = isset($argv['root']) ? $argv['root'] : ;

# Protect the asterisk structure and wiki-parse the bullet tree $text = preg_replace("/(?<=\\*)\\s*\\[\\[Image:(.+?)\\]\\]/","{$uid}3$1{$uid}4",$text); $text = preg_replace_callback("/^(\\*+)(.*?)$/m",array($this,'protectTree'),$text); $out = $parser->parse($text,$parser->mTitle,$parser->mOptions,false,false); $text = $out->getText();

# Extract the valid rows and process if any if (preg_match_all("/1{$uid}([0-9]+)-({$uid}3(.+?){$uid}4)?(.+?){$uid}2/",$text,$matches,PREG_SET_ORDER)) {

# Convert the custom images in $wgTreeViewImages into JS statements $images = ; foreach ($wgTreeViewImages as $k => $v) $images .= "$id.icon['$k'] = '$v';";

# Build the dTree instantiation code $dtree = "// TreeView{$this->version} $id = new dTree('$id'); for (i in $id.icon) $id.icon[i] = '{$this->baseUrl}/'+$id.icon[i]; {$images} $id.config.useLines = {$this->useLines}; $id.add(0, -1, '$rootname'); ";

# Add the content to the dTree object $counter = 1; $parent = 0; $currdepth = 0; foreach ($matches as $row) { list(,$depth,,$icon,$item) = $row; if ($depth > $cols) $lasts[$cols = $depth] = true; $parent = $currdepth < $depth-1 ? $counter-1 : $depth-1; $item = str_replace("'","\\'",$item); $dtree .= "${id}.add($counter,$parent,'$item');\n"; $currdepth = $depth-1; $counter++; }

# Output the dTree $dtree .= "document.write($uid);\n"; }

return("<script type=\"$wgJsMimeType\">\n\n</script>"); }

/** * Protect asterisk bullet structure from wiki parser */ function protectTree($m) { return "1{$this->uid}".strlen($m[1])."-$m[2]{$this->uid}2\n"; }

/** * Add the javascript to the output object if not added yet and there is at least one tree */ function addJS() { global $wgOut,$wgJS,$wgJsMimeType; if (isset($wgJS['TreeView5'])) return; $wgJS['TreeView5'] = true; $wgOut->addScript("<script type=\"$wgJsMimeType\" src=\"{$this->baseUrl}/dtree.js\" />\n"); } }

/**

* Called from $wgExtensionFunctions array when initialising extensions
*/

function wfSetupTreeView5() { global $wgTreeView5; $wgTreeView5 = new TreeView5(); $wgTreeView5->addJS(); # Make code unconditional for now due to parser caching }

/**

* Needed in MediaWiki >1.8.0 for magic word hooks to work properly
*/

function wfTreeView5LanguageGetMagic(&$magicWords,$langCode = 0) { global $wgTreeView5,$wgTreeView5Magic; $magicWords[$wgTreeView5Magic] = array(0,$wgTreeView5Magic); return true; }