Index: trunk/extensions/CategoryTree/CategoryTree.php
===================================================================
--- trunk/extensions/CategoryTree/CategoryTree.php (revision 36863)
+++ trunk/extensions/CategoryTree/CategoryTree.php (revision 36864)
@@ -67,7 +67,7 @@
$wgCategoryTreeDefaultOptions['mode'] = NULL; # will be set to $wgCategoryTreeDefaultMode in efCategoryTree(); compatibility quirk
$wgCategoryTreeDefaultOptions['hideprefix'] = NULL; # will be set to $wgCategoryTreeDefaultMode in efCategoryTree(); compatibility quirk
$wgCategoryTreeDefaultOptions['showcount'] = false;
-#TODO: hideprefix: always, never, catonly, catonly_if_onlycat
+$wgCategoryTreeDefaultOptions['namespaces'] = false; # false means "no filter"
$wgCategoryTreeCategoryPageMode = CT_MODE_CATEGORIES;
$wgCategoryTreeCategoryPageOptions = array(); #Options to be used for category pages
@@ -115,7 +115,6 @@
$wgHooks['ArticleFromTitle'][] = 'efCategoryTreeArticleFromTitle';
$wgHooks['LanguageGetMagic'][] = 'efCategoryTreeGetMagic';
-
/**
* register Ajax function
*/
Index: trunk/extensions/CategoryTree/CategoryTree.js
===================================================================
--- trunk/extensions/CategoryTree/CategoryTree.js (revision 36863)
+++ trunk/extensions/CategoryTree/CategoryTree.js (revision 36864)
@@ -34,7 +34,7 @@
lnk.title= categoryTreeCollapseMsg;
lnk.onclick= function() { categoryTreeCollapseNode(cat, options, lnk) }
- if (lnk.className != "CategoryTreeLoaded") {
+ if (!lnk.className.match(/(^| )CategoryTreeLoaded($| )/)) {
categoryTreeLoadNode(cat, options, lnk, div);
}
}
@@ -58,40 +58,52 @@
categoryTreeLoadChildren(cat, options, div)
}
- function categoryTreeEncodeOptions(options) {
- var opt = "";
+ function categoryTreeEncodeValue(value) {
+ switch (typeof value) {
+ case 'function':
+ throw new Error("categoryTreeEncodeValue encountered a function");
+ break;
- for (k in options) {
- v = options[k];
-
- switch (typeof v) {
case 'string':
- v = '"' + v.replace(/([\\"'])/g, "\\$1") + '"';
+ s = '"' + value.replace(/([\\"'])/g, "\\$1") + '"';
break;
case 'number':
case 'boolean':
case 'null':
- v = String(v);
+ s = String(value);
break;
case 'object':
- if ( !v ) v = 'null';
- else throw new Error("categoryTreeLoadChildren can not encode complex types");
+ if ( !value ) {
+ s = 'null';
+ }
+ else if (typeof value.length === 'number' && !(value.propertyIsEnumerable('length'))) {
+ s = '';
+ for (i = 0; i<value.length; i++) {
+ v = value[i];
+ if ( s!='' ) s += ', ';
+ s += categoryTreeEncodeValue( v );
+ }
+ s = '[' + s + ']';
+ }
+ else {
+ s = '';
+ for (k in value) {
+ v = value[k];
+ if ( s!='' ) s += ', ';
+ s += categoryTreeEncodeValue( k );
+ s += ': ';
+ s += categoryTreeEncodeValue( v );
+ }
+ s = '{' + s + '}';
+ }
break;
-
default:
- throw new Error("categoryTreeLoadChildren encountered strange variable type " + (typeof v));
+ throw new Error("categoryTreeEncodeValue encountered strange variable type " + (typeof value));
}
- if ( opt != "" ) opt += ", ";
- opt += k;
- opt += ":";
- opt += v;
- }
-
- opt = "{"+opt+"}";
- return opt;
+ return s;
}
function categoryTreeLoadChildren(cat, options, div) {
@@ -130,6 +142,6 @@
div.innerHTML= result;
}
- var opt = categoryTreeEncodeOptions(options);
+ var opt = categoryTreeEncodeValue(options);
sajax_do_call( "efCategoryTreeAjaxWrapper", [cat, opt, 'json'] , f );
}
Index: trunk/extensions/CategoryTree/CategoryTreeFunctions.php
===================================================================
--- trunk/extensions/CategoryTree/CategoryTreeFunctions.php (revision 36863)
+++ trunk/extensions/CategoryTree/CategoryTreeFunctions.php (revision 36864)
@@ -33,12 +33,60 @@
$this->mOptions['mode'] = self::decodeMode( $this->mOptions['mode'] );
$this->mOptions['hideprefix'] = self::decodeHidePrefix( $this->mOptions['hideprefix'] );
$this->mOptions['showcount'] = self::decodeBoolean( $this->mOptions['showcount'] );
+ $this->mOptions['namespaces'] = self::decodeNamespaces( $this->mOptions['namespaces'] );
+
+ if ( $this->mOptions['namespaces'] ) {
+ # automatically adjust mode to match namespace filter
+ if ( sizeof( $this->mOptions['namespaces'] ) === 1
+ && $this->mOptions['namespaces'][0] == NS_CATEGORY ) {
+ $this->mOptions['mode'] = CT_MODE_CATEGORIES;
+ } else if ( !in_array( NS_IMAGE, $this->mOptions['namespaces'] ) ) {
+ $this->mOptions['mode'] = CT_MODE_PAGES;
+ } else {
+ $this->mOptions['mode'] = CT_MODE_ALL;
+ }
+ }
}
function getOption( $name ) {
return $this->mOptions[$name];
}
+ static function decodeNamespaces( $nn ) {
+ global $wgContLang;
+
+ if ( !$nn )
+ return false;
+
+ if ( !is_array($nn) )
+ $nn = preg_split( '![\s#:|]+!', $nn );
+
+ $namespaces = array();
+
+ foreach ( $nn as $n ) {
+ if ( is_int( $n ) ) {
+ $ns = $n;
+ }
+ else {
+ $n = trim( $n );
+ if ( $n === '' ) continue;
+
+ $lower = strtolower( $n );
+
+ if ( is_numeric($n) ) $ns = (int)$n;
+ elseif ( $n == '-' || $n == '_' || $n == '*' || $lower == 'main' ) $ns = NS_MAIN;
+ else $ns = $wgContLang->getNsIndex( $n );
+ }
+
+ if ( is_int( $ns ) ) {
+ $namespaces[] = $ns;
+ }
+ }
+
+ sort( $namespaces ); # get elements into canonical order
+ return $namespaces;
+ }
+
static function decodeMode( $mode ) {
global $wgCategoryTreeDefaultOptions;
@@ -199,6 +247,7 @@
$key = "";
foreach ( $this->mOptions as $k => $v ) {
+ if ( is_array( $v ) ) $v = implode( '|', $v );
$key .= $k . ':' . $v . ';';
}
@@ -341,11 +390,19 @@
$mode = $this->getOption('mode');
+ $namespaces = $this->getOption('namespaces');
- #namespace filter. Should be configurable
- if ( $mode == CT_MODE_ALL ) $nsmatch = '';
- else if ( $mode == CT_MODE_PAGES ) $nsmatch = ' AND cat.page_namespace != ' . NS_IMAGE;
- else $nsmatch = ' AND cat.page_namespace = ' . NS_CATEGORY;
+ #namespace filter.
+ if ( $namespaces ) {
+ #NOTE: we assume that the $namespaces array contains only integers!
+ if ( sizeof( $namespaces ) === 1 ) $nsmatch = ' AND cat.page_namespace = ' . $namespaces[0] . ' ';
+ else $nsmatch = ' AND cat.page_namespace IN ( ' . implode( ', ', $namespaces ) . ') ';
+ }
+ else {
+ if ( $mode == CT_MODE_ALL ) $nsmatch = '';
+ else if ( $mode == CT_MODE_PAGES ) $nsmatch = ' AND cat.page_namespace != ' . NS_IMAGE;
+ else $nsmatch = ' AND cat.page_namespace = ' . NS_CATEGORY;
+ }
#additional stuff to be used if "transaltion" by interwiki-links is desired
$transFields = '';
@@ -551,13 +608,15 @@
$linkattr[ 'class' ] = "CategoryTreeToggle";
- if ( $count === 0 ) {
+ /*if ( $count === 0 ) {
$tag = 'span';
$txt = wfMsgNoTrans( 'categorytree-empty-bullet' );
}
- else if ( $children == 0 || $loadchildren ) {
+ else*/
+ if ( $children == 0 || $loadchildren ) {
$tag = 'a';
- $txt = wfMsgNoTrans( 'categorytree-expand-bullet' );
+ if ( $count === 0 ) $txt = wfMsgNoTrans( 'categorytree-empty-bullet' );
+ else $txt = wfMsgNoTrans( 'categorytree-expand-bullet' );
$linkattr[ 'onclick' ] = "this.href='javascript:void(0)'; categoryTreeExpandNode('".Xml::escapeJsString($key)."',".$this->getOptionsAsJsStructure().",this);";
# Don't load this message for ajax requests, so that we don't have to initialise $wgLang
$linkattr[ 'title' ] = $this->mIsAjaxRequest ? '##LOAD##' : wfMsgNoTrans('categorytree-expand');
@@ -593,7 +652,19 @@
$s .= "\n\t\t";
$s .= Xml::openElement( 'div', array( 'class' => 'CategoryTreeChildren', 'style' => $children > 0 ? "display:block" : "display:none" ) );
- if ( $children > 0 && !$loadchildren) $s .= $this->renderChildren( $title, $children );
+ if ( $ns == NS_CATEGORY && $children > 0 && !$loadchildren) {
+ $children = $this->renderChildren( $title, $children );
+ if ( $children == '' ) {
+ $s .= Xml::openElement( 'i', array( 'class' => 'CategoryTreeNotice' ) );
+ if ( $mode == CT_MODE_CATEGORIES ) $s .= wfMsgExt( 'categorytree-no-subcategories', 'parsemag');
+ else if ( $mode == CT_MODE_PAGES ) $s .= wfMsgExt( 'categorytree-no-pages', 'parsemag');
+ else $s .= wfMsgExt( 'categorytree-nothing-found', 'parsemag');
+ $s .= Xml::closeElement( 'i' );
+ } else {
+ $s .= $children;
+ }
+ }
+
$s .= Xml::closeElement( 'div' );
$s .= Xml::closeElement( 'div' );