Extension:NavContent
From MediaWiki.org
|
NavContent Release status: beta |
|
|---|---|
| Implementation | Parser function, Variable, Ajax |
| Description | Navigation tool to toggle showing of content |
| Author(s) | Tommy Ekola |
| Version | 0.9 |
| MediaWiki | tested with 1.11.0 |
| License | GPL |
| Download | Here |
| Hooks used |
LanguageGetMagic |
NavContent is an extension that implements a type of navigational frame, i.e. a mechanism for users to expand (and collapse) certain page content by clicking on a link. This extension goes a bit beyond the simplest form of navigational frame and the main features of this implementation are
- show and hide content,
- dynamic loading of content,
- toggle between content, and
- step through content.
Contents |
[edit] Example
[edit] Show and hide content
Insert the following line of code in your wiki text
{{#NAVCONTENT: Answer|Answer to exercise 1.1}}
This will create a simple navigational bar.
If you click on the "Answer" link the content associated with this link will be revealed. In this case it will just be a link to a non-existent page "Answer to exercise 1.1".
One more click on the "Answer" link will hide the content again.
[edit] Dynamic loading of content
Continuing with the example above, you should now create a new page "Answer to exercise 1.1" in the wiki with the following content:
The answer is 42.
If you now click on the "Answer" link, on the page containing the navigation bar, you will this time first see a flash of a loading message
and then the content of your newly created page is inserted instead of the red-link you saw before.
[edit] Toggle between content
You should now expand the NavContent code to:
{{#NAVCONTENT: Answer|Answer to exercise 1.1|Solution|Solution to exercise 1.1}}
This time the navigation bar contains two links "Answer" and "Solution".
These links will individually show/hide the content associated with them. If, for example, you click on "Solution" a link to the non-existent page "Solution to exercise 1.1" will be folded out.
Now, clicking on "Answer" will replace the current content with the content associated with the "Answer" link, i.e. the "Answer" and "Solution" links toggle each other.
(You can, of course, have any number of links in the navigational bar and they all toggle each other.)
[edit] Step through content
To complete this example you should now create a page "Solution to exercise 1.1" in the wiki with the following content:
{{NAVCONTENT_START}}
If you add 1 to 40 you get 41,
{{NAVCONTENT_STEP}}
and if you add 1 to 41 you get the answer 42.
{{NAVCONTENT_STOP}}
On the page containing the #NAVCONTENT function the text from the page "Solution to exercise 1.1" is, as expected, injected as the content under the "Solution" link. However, if you click on "Solution" only the text up to the first {{NAVCONTENT_STEP}} is displayed and a second navigational bar is displayed at the bottom.
You can use this so-called progress bar to reveal or hide parts of the page with the links "Show more", "Show less", "Show all" and "Hide all". For example, clicking on "Show more" will show the second part of the solution.
(As you might have guessed: inserting more {{NAVCONTENT_STEP}} lines will subdivide the included material into more parts for the user to step through.)
[edit] Show full content on printable version
If you click on the "Printable version" link in the toolbox (located in the sidebar of the page), then the resulting printable page will contain all loaded material in an expanded view.
[edit] Installation
[edit] Install jQuery
Install the javascript library jQuery.
[edit] Save the code
Create the directory $IP/extensions/NavContent and save the code in the files NavContent.php, NavContent.i18n.php, NavContent.js, NavContent.css and NavContentPrint.css, respectively, in that directory. You should also download the image file Loading.gif and save it in the same directory. (Optionally, download a suitable image from www.ajaxload.info.) This is the image that is shown while content is being loaded.
[edit] Configure the extension
Add the following lines at the end of the file $IP/LocalSettings.php
$wgJQueryRoot = "/jquery/"; $wgNavContentRoot = "/wiki/extensions/NavContent/"; include_once( $IP . "/extensions/NavContent/NavContent.php" );
where
- $wgJQueryRoot is the path to the javascript file jquery.js,
- $wgNavContentRoot is the path to this extension.
Further configuration:
- If you want some javascript functions to run on included content then you need to add these functions to the array $wgNavContentSubpagesJsCode before NavContent.php is included. These functions will be fed a DOM-pointer to the included material as an argument. For example, if you use the JsMath extension and want jsMath to be run on included content you write
which will result in jsMath.Process(...) being run after a page is loaded. (If you do this, make sure you set autoload = 0 in the jsMath configuration file easy/load.js.)
$wgNavContentSubpagesJsCode = array( 'jsMath.Process' );
- If you do not want all content to be expanded when the user is viewing a printable version of the page then you should write
$wgNavContentDisablePrint = 1;
before NavContent.php is included.
- You should consider changing the two style sheet files NavContent.css and NavContentPrint.css. At present they are merely useful for very simplistic needs.
[edit] The code
[edit] NavContent.php
<?php /* * @author Tommy Ekola * @copyright © 2008 by Tommy Ekola (tek@kth.se) * @licence GNU General Public Licence 2 or later */ if (! defined( 'MEDIAWIKI' ) ) { echo( "This is an extension to the MediaWiki package and cannot be run standalone.\n" ); die( -1 ); } // Extension information $wgExtensionCredits['other'][] = array( 'name' => 'NavContent', 'description' => 'Navigation bar that toggles showing of content', 'version' => '0.9', 'author' => 'Tommy Ekola'); // Configuration if(! isset($wgJQueryRoot) ) { echo( "The root directory of jquery.js is not specified. Make sure \$wgJQueryRoot is set in $IP/LocalSettings.php" ); die( -1 ); } if(! isset($wgNavContentRoot) ) { echo( "The root directory of NavContent is not specified. Make sure \$wgNavContentRoot is set in $IP/LocalSettings.php" ); die( -1 ); } // Define {{#NAVCONTENT: ...}} $wgExtensionFunctions[] = 'wfNavContent_Setup'; function wfNavContent_Setup() { global $wgParser, $wgRequest, $wgOut, $wgJsMimeType, $wgNavContentDisablePrint, $wgNavContentRoot, $wgNavContentSubpagesJsCode, $wgJQueryRoot; $wgOut->addScript( '<script type="' . $wgJsMimeType . '" src="' . $wgJQueryRoot . '/jquery.js"></script>' ); $printable = ($wgRequest->getVal('printable') == 'yes'); $printable = $printable && (isset($wgNavContentDisablePrint) || !$wgNavContentDisablePrint); wfNavContentMessages(); $wgParser->setFunctionHook( 'navcontent', 'wfNavContent_Render' ); if( $printable ) { $wgOut->addScript( '<link rel="stylesheet" type="text/css" ' . 'href="' . $wgNavContentRoot . '/NavContentPrint.css" />' ); } else { $wgOut->addScript( '<link rel="stylesheet" type="text/css" ' . 'href="' . $wgNavContentRoot . '/NavContent.css" />' ); } $wgOut->addScript( '<script type="' . $wgJsMimeType . '" src="' . $wgNavContentRoot . '/NavContent.js"></script>' ); if( isset($wgNavContentSubpagesJsCode) ) { foreach($wgNavContentSubpagesJsCode as $jsfunct) { $wgOut->addInlineScript( "addOnloadSubpagesHook(" . $jsfunct . ");" ); } } if( $printable ) { $wgOut->addInlineScript( "addOnloadHook(NavContentLoadContent);" ); } else { $wgOut->addInlineScript( "addOnloadHook(NavContentCreate);" ); } } function wfNavContent_Render( &$parser ) { global $wgNavContentRoot; $arguments = array_slice( func_get_args(), 1 ); $n = count( $arguments ); $output = array(); $output['noparse'] = true; $output['isHTML'] = true; // Check arguments if ( fmod( $n, 2 ) != 0 ) { $output[0] = "<div class=\"mw-warning\">Uneven number of arguments to #NAVCONTENT</div>"; return $output; } foreach( $arguments as $i => $pageref ) { if( fmod($i,2) == 1 ) { if(! Title::newFromText( $pageref ) ) { $output[0] = "<div class=\"mw-warning\">Argument \"" . htmlspecialchars($pageref) . "\" in #NAVCONTENT is referring to a non-valid page</div>"; return $output; } } } // Add navigation bar $output[0] = "<div class=\"NavContentFrame\">\n" . "<div class=\"NavContentBar\" style=\"display: none;\">\n"; for( $i=0; $i < $n; $i += 2) { $output[0] .= "<a class=\"NavContentBarLink\" style=\"cursor: pointer;\">" . htmlspecialchars($arguments[$i]) . "</a>\n"; } $output[0] .= "</div>\n"; for( $i=0; $i<$n; $i+=2 ) { $output[0] .= "<div class=\"NavContentPart\">\n"; // Add content $title = Title::newFromText( $arguments[$i+1] ); $output[0] .= "<div class=\"NavContentHeader\">\n" . htmlspecialchars($arguments[$i]) . "</div>\n" . "<div class=\"NavContentContent load-on-demand\">\n" . "<div class=\"NavContentContentPart\">\n" . "<a "; if(! $title->exists() ) $output[0] .= "class=\"new\" " . "href=\"" . $title->escapeFullURL('action=edit') . "\">"; else $output[0] .= "href=\"" . $title->escapeFullURL() . "\">"; $output[0] .= htmlspecialchars($arguments[$i+1]) . "</a>" . "<div class=\"NavContentLoading\" style=\"display:none;\">" . "<img align=\"middle\" style=\"display: inline;\" " . "src=\"" . $wgNavContentRoot . "/Loading.gif\"/>" . " " . wfMsg('navcontentloading') . "</div>\n" . "</div>\n" . "</div>\n"; // Add progress bar $output[0] .= "<div class=\"NavContentProgressBar\" style=\"display:none;\">\n" . "<span class=\"NavContentShowLess\">" . wfMsg('navcontentshowless') . "</span>\n" . "<span class=\"NavContentShowMore\">" . wfMsg('navcontentshowmore') . "</span>\n" . "<span class=\"NavContentShowNone\">" . wfMsg('navcontentshownone') . "</span>\n" . "<span class=\"NavContentShowAll\">" . wfMsg('navcontentshowall') . "</span>\n" . "</div>\n" . "</div>\n"; } $output[0] .= "</div>"; return $output; } $wgHooks['LanguageGetMagic'][] = 'wfNavContent_Magic'; function wfNavContent_Magic( &$MagicWords, &$langCode ) { $MagicWords['navcontent'] = array( 0, 'navcontent' ); return true; } // Insert links to referenced pages on the edit page $wgHooks['EditPage::showEditForm:initial'][] = 'wfNavContentRefPages'; function wfNavContentRefPages(&$editpage) { global $wgUser, $wgParser; if(! $editpage->mTitle->exists() ) return true; // Parse the edit page (and turn #navcontent into _#navcontent) $wgParser->setFunctionHook( 'navcontent', 'wfNavContent_FakeRender' ); $text = $editpage->textbox1; $popts = new ParserOptions; $popts->setTidy(true); $parsedOutput = $wgParser->parse( $text, $editpage->mTitle, $popts ); $text = $parsedOutput->getText(); $wgParser->setFunctionHook( 'navcontent', 'wfNavContent_Render' ); // Extract pages referenced by _#navcontent $t = explode( '{{', $text ); $navcontentlinks = array(); foreach( $t as $key => $x ) { $y = explode( '}}', $x ); if ( count( $y ) >= 2 ) { $z = $y[0]; $z = explode( ':', $z ); if ( in_array( strtolower($z[0]), array('_#navcontent') ) ) { array_shift( $z ); $z = implode( ':', $z ); $z = explode( '|', $z ); foreach( $z as $i => $page ) { if( fmod($i,2)==1 ) { $navcontentlinks[] = Title::newFromText( trim($page) ); } } } } } if( count($navcontentlinks) == 0 ) return true; $sk = $wgUser->getSkin(); // Do a batch existence check $batch = new LinkBatch; foreach( $navcontentlinks as $titleObj ) { $batch->addObj( $titleObj ); } $batch->execute(); // Add links to referenced pages $outText .= "\n<div class=\"templatesUsed\">\n<div class=\"mw-templatesUsedExplanation\"><p>"; if( $editpage->preview ) { $outText .= wfMsg( 'navcontentpagesusedpreview' ); } elseif( $editpage->section != '' ) { $outText .= wfMsg( 'navcontentpagesusedsection' ); } else { $outText .= wfMsg( 'navcontentpagesused' ); } $outText .= "</p></div>\n<ul>\n"; foreach( $navcontentlinks as $titleObj ) { if( $titleObj ) { $r = $titleObj->getRestrictions( 'edit' ); if( in_array( 'sysop', $r ) ) { $protected = wfMsg( 'navcontent-protected' ); } elseif ( in_array( 'autoconfirmed', $r ) ) { $protected = wfMsg( 'navcontent-semiprotected' ); } else { $protected = ''; } $outText .= "<li>" . $sk->makeLinkObj( $titleObj ) . " " . $protected . "</li>\n"; } } $outText .= "</ul>\n</div>"; $editpage->editFormTextAfterTools .= $outText; return true; } function wfNavContent_FakeRender( &$parser ) { $arguments = array_slice( func_get_args(), 1 ); $n = count( $arguments ); $output = array(); $output['noparse'] = true; $output['isHTML'] = true; $output[0] = "{{_#navcontent:"; foreach( $arguments as $arg ) { $output[0] .= $arg . "|"; } $output[0] = substr($output[0],0,strlen($output[0])-1); $output[0] .= "}}"; return $output; } // Ajax-loading of referenced pages $wgAjaxExportList[] = "wfAjaxLoadContent"; function wfAjaxLoadContent( $term ) { global $wgContLang, $wgOut, $wgParser; $t = Title::newFromText( $term ); $r = new Article($t); if($r->getID()==0) { $text = "[[" . $t . "]]"; } else { $text = $r->getContent(); } $popts = new ParserOptions; $popts->setTidy(true); $parsedOutput = $wgParser->parse( $text, $t, $popts ); $html = $parsedOutput->getText(); $response = new AjaxResponse( $html ); $response->setCacheDuration( 30*60 ); return $response; } // Define {{NAVCONTENT_START}}, {{NAVCONTENT_STEP}} and {{NAVCONTENT_STOP}} define( 'NAVCONTENT_START', 'navcontent_start' ); define( 'NAVCONTENT_STEP', 'navcontent_step' ); define( 'NAVCONTENT_STOP', 'navcontent_stop' ); $wgHooks['LanguageGetMagic'][] = 'wfNavContentStepping_Magic'; function wfNavContentStepping_Magic( &$MagicWords, &$langCode ) { $MagicWords['navcontent_start'] = array( 0, 'navcontent_start' ); $MagicWords['navcontent_step'] = array( 0, 'navcontent_step' ); $MagicWords['navcontent_stop'] = array( 0, 'navcontent_stop' ); return true; } $wgHooks['ParserGetVariableValueSwitch'][] = 'wfNavContentVarAssign'; function wfNavContentVarAssign(&$parser, &$cache, &$magicWordId, &$ret) { switch( $magicWordId ) { case NAVCONTENT_START: $ret='<div class="NavContentContentPart">'; return true; case NAVCONTENT_STEP: $ret='</div><div class="NavContentContentPart">'; return true; case NAVCONTENT_STOP: $ret='</div>'; return true; } return true; } $wgHooks['MagicWordwgVariableIDs'][] = 'wfNavContentDeclareVarIds'; function wfNavContentDeclareVarIds(&$aCustomVariableIds) { $aCustomVariableIds[] = NAVCONTENT_START; $aCustomVariableIds[] = NAVCONTENT_STEP; $aCustomVariableIds[] = NAVCONTENT_STOP; return true; } // Internationalization function wfNavContentMessages() { static $messagesLoaded = false; global $wgMessageCache; if (! $messagesLoaded ) { $messagesLoaded = true; require( dirname( __FILE__ ) . '/NavContent.i18n.php' ); foreach( $messages as $lang => $langMessages ) { $wgMessageCache->addMessages( $langMessages, $lang ); } } return true; }
[edit] NavContent.i18n.php
<?php /* * @author Tommy Ekola * @copyright © 2008 by Tommy Ekola (tek@kth.se) * @licence GNU General Public Licence 2 or later */ $messages = array( 'en' => array('navcontentloading' => 'Loading...', 'navcontentshowless' => 'Show less', 'navcontentshowmore' => 'Show more', 'navcontentshownone' => 'Hide all', 'navcontentshowall' => 'Show all', 'navcontentpagesusedpreview' => 'Pages that #NAVCONTENT is referring to in this preview:', 'navcontentpagesusedsection' => 'Pages that #NAVCONTENT is referring to in this section:', 'navcontentpagesused' => 'Pages that #NAVCONTENT is referring to on this page:', 'navcontent-protected' => '(protected)', 'navcontent-semiprotected' => '(semiprotected)'), 'sv' => array('navcontentloading' => 'Hämtar...', 'navcontentshowless' => 'Visa mindre', 'navcontentshowmore' => 'Visa mer', 'navcontentshownone' => 'Dölj allt', 'navcontentshowall' => 'Visa allt', 'navcontentpagesusedpreview' => 'Sidor som #NAVCONTENT hänvisar till i förhandsgranskningen:', 'navcontentpagesusedsection' => 'Sidor som #NAVCONTENT hänvisar till i detta avsnitt:', 'navcontentpagesused' => 'Sidor som #NAVCONTENT hänvisar till på denna sida:', 'navcontent-protected' => '(skyddad)', 'navcontent-semiprotected' => '(delvis skyddad)') );
[edit] NavContent.js
// Hook setup if(!window.onloadSubpagesFuncts) { var onloadSubpagesFuncts = []; } function addOnloadSubpagesHook(hookFunct) { onloadSubpagesFuncts[onloadSubpagesFuncts.length] = hookFunct; } function runOnloadSubpagesHook(el) { if(!(document.getElementById && document.getElementsByTagName)) { return; } for(var i=0; i<onloadSubpagesFuncts.length; i++) { onloadSubpagesFuncts[i](el); } } // Navigation bar function NavContentCreate(el) { if(!el) el=document; // Hide all parts $("div.NavContentFrame div.NavContentPart",el).hide(); // Hide the header inside each part $("div.NavContentFrame div.NavContentPart div.NavContentHeader",el).hide(); // Add some space and a vertical bar between the bar links $("div.NavContentFrame div.NavContentBar",el) .each(function(){ $("a.NavContentBarLink",this).not(":last").after(" | "); }) .show(); // Add navigation links to each progress bar $("div.NavContentFrame div.NavContentPart div.NavContentProgressBar",el) .each(function(){ $("span",this) .each(function(){ $(this).after("<a></a>"); }); }); $("div.NavContentFrame div.NavContentPart div.NavContentProgressBar a",el) .each(function(){ $(this) .addClass($(this).prev("span").attr("class")) .css({cursor: "pointer"}) .text($(this).prev("span").text()); }) // Hide all non-clickable links $("div.NavContentFrame div.NavContentPart div.NavContentProgressBar span",el) .hide(); // Add some space and a vertical bar between the progress bar links $("div.NavContentFrame div.NavContentPart div.NavContentProgressBar",el) .each(function(){ $("a",this).not(":last").after(" | "); }); // Replace link with message on load-on-demand div's $("div.NavContentFrame div.NavContentPart div.NavContentContent.load-on-demand",el) .find("div.NavContentContentPart a:not(.new)") .hide() .siblings().show(); // Add actions to each link in bar $("div.NavContentFrame div.NavContentBar",el) .each(function(i){ $("a.NavContentBarLink",this) .each(function(j){ $(this).click( function(){ // Make all other links normal face $(this).parent() .find("a.NavContentBarLink") .not(":eq(" + j + ")") .css("fontWeight","normal"); // Toggle this link (normal/bold) if($(this).css("fontWeight")=="bold") $(this).css("fontWeight","normal"); else $(this).css("fontWeight","bold"); // Make all other parts hidden $(this).parents("div.NavContentFrame") .find("div.NavContentPart") .not(":eq(" + j + ")") .hide(); // Load contents if needed var contents = $(this).parents("div.NavContentFrame") .find("div.NavContentPart").eq(j) .find("div.NavContentContent"); if (contents.hasClass("load-on-demand")) { if(!contents.find("a").hasClass("new")) { addr = $("a",contents).attr("href"); addrs = addr.match(/\/[^\/]+/g); host = addr.split(/\/index.php/g)[0]; addr = addrs[addrs.length-1].slice(1); if (/[\?\&]title\=/.test(addr)) { addr = addr.match(/[\?\&]title\=[^\?\&]+/); addr = addr[0].match(/([\?\&]title\=)([^\?\&]+)/); addr = addr[2]; } $(contents).load(host + "/index.php?action=ajax&rs=wfAjaxLoadContent&rsargs=" + addr, {}, function(){ runOnloadSubpagesHook(this); $(this).removeClass("load-on-demand"); $("div.NavContentContentPart:first",this).slideDown("normal"); $("div.NavContentContentPart:gt(0)",this).hide(); if($("div.NavContentContentPart",this).size()>1) $(this).parent().find("div.NavContentProgressBar").show(); }); } } // Toggle the visibility of this part if($(this).css("fontWeight")=="bold") $(this).parents("div.NavContentFrame") .find("div.NavContentPart").eq(j) .slideDown("normal"); else $(this).parents("div.NavContentFrame") .find("div.NavContentPart").eq(j) .slideUp("normal"); }); }); }); // Hide all but the first content in each part $("div.NavContentFrame div.NavContentPart div.NavContentContent",el) .each(function(){ $("div.NavContentContentPart:first",this).show(); }); $("div.NavContentFrame div.NavContentPart div.NavContentContent",el) .each(function(){ $("div.NavContentContentPart:gt(0)",this).hide(); }); // If there is zero or one content in a part then the progress bar is hidden $("div.NavContentFrame div.NavContentPart",el) .each(function(){ if($("div.NavContentContentPart",this).size()<2) { $("div.NavContentProgressBar",this).hide(); } else { $("div.NavContentProgressBar",this).show(); } }); // Actions to perform when a progress bar link is clicked $("div.NavContentFrame",el) .each(function(i){ $("div.NavContentPart div.NavContentProgressBar",this) .each(function(j){ $("a.NavContentShowLess",this).click( function(){ // Make this link invisible if needed if($(this).parents("div.NavContentPart") .find("div.NavContentContentPart:visible") .size() < 2) { $(this).hide() .parent() .find("span.NavContentShowLess") .show() .end() .find("a.NavContentShowNone") .hide() .end() .find("span.NavContentShowNone") .show(); } // Hide the last visible content $(this).parents("div.NavContentPart") .find("div.NavContentContentPart:visible:last") .slideUp("normal"); // Make other links visible $(this).parent() .find("span.NavContentShowMore").hide() .end() .find("a.NavContentShowMore").show() .end() .find("span.NavContentShowAll").hide() .end() .find("a.NavContentShowAll").show(); }); $("a.NavContentShowMore",this).click( function(){ // Make other links invisible if needed if($(this).parents("div.NavContentPart") .find("div.NavContentContentPart:hidden") .size() < 2) { $(this).hide() .parent() .find("span.NavContentShowMore").show() .end() .find("a.NavContentShowAll").hide() .end() .find("span.NavContentShowAll").show(); } // Show the first invisible content $(this).parents("div.NavContentPart") .find("div.NavContentContent").show() .end() .find("div.NavContentContentPart:hidden:first").slideDown("normal"); // Make less/none links visible $(this).parent() .find("span.NavContentShowLess").hide() .end() .find("a.NavContentShowLess").show() .end() .find("span.NavContentShowNone").hide() .end() .find("a.NavContentShowNone").show(); }); $("a.NavContentShowAll",this).click( function(){ // Show all invisible content $(this).parents("div.NavContentPart") .find("div.NavContentContent").show() .find("div.NavContentContentPart:hidden:first") .slideDown("normal", function(){ $(this).parents("div.NavContentContent") .find("div.NavContentContentPart:hidden") .show(); }); // Make less/none links visible $(this).parent() .find("span.NavContentShowLess").hide() .end() .find("a.NavContentShowLess").show() .end() .find("span.NavContentShowNone").hide() .end() .find("a.NavContentShowNone").show(); // Make more/all links invisible $(this).hide().parent() .find("span.NavContentShowAll").show() .end() .find("a.NavContentShowMore").hide() .end() .find("span.NavContentShowMore").show(); }); $("a.NavContentShowNone",this).click( function(){ // Hide all visible content $(this).parents("div.NavContentPart") .find("div.NavContentContent").show() .find("div.NavContentContentPart:visible:last") .slideUp("normal", function(){ $(this).parents("div.NavContentContent") .find("div.NavContentContentPart:visible") .hide(); }); // Make more/all links visible $(this).parent() .find("span.NavContentShowMore").hide() .end() .find("a.NavContentShowMore").show() .end() .find("span.NavContentShowAll").hide() .end() .find("a.NavContentShowAll").show(); // Make less/none links invisible $(this).hide().parent() .find("span.NavContentShowNone").show() .end() .find("a.NavContentShowLess").hide() .end() .find("span.NavContentShowLess").show(); }); }); }); } function NavContentLoadContent(el) { if(!el) el=document; // Replace link with message on load-on-demand div's $("div.NavContentFrame div.NavContentPart div.NavContentContent.load-on-demand",el) .find("div.NavContentContentPart a:not(.new)") .hide() .siblings().show(); // Load content $("div.load-on-demand",el).each(function(){ if(!$("a",this).hasClass("new")) { addr = $("a",this).attr("href"); addrs = addr.match(/\/[^\/]+/g); host = addr.split(/\/index.php/g)[0]; addr = addrs[addrs.length-1].slice(1); if (/[\?\&]title\=/.test(addr)) { addr = addr.match(/[\?\&]title\=[^\?\&]+/); addr = addr[0].match(/([\?\&]title\=)([^\?\&]+)/); addr = addr[2]; } $(this).load(host + "/index.php?action=ajax&rs=wfAjaxLoadContent&rsargs=" + addr, {}, function(){ runOnloadSubpagesHook(this); $(this).removeClass("load-on-demand"); }); } }); }
[edit] NavContent.css
div.NavContentFrame { margin:1em 0em 1em 0em; padding:0.5em 1.5em .2em 1.5em; border:1px solid #CFCFCF; width:580px; } div.NavContentBar { font-size: 70%; } a.NavContentBarLink, a.NavContentShowLess, a.NavContentShowMore, a.NavContentShowNone, a.NavContentShowAll { Cursor: pointer; } div.NavContentHeader + div.NavContentContent { margin-top: 2em; } div.NavContentProgressBar { margin-top: 2em; font-size: 70%; } div.NavContentLoading { width: 100%; margin: 1em 0em 1em 0em; text-align: center; }
[edit] NavContentPrint.css
div.NavContentFrame { margin: 0; padding: 0; border: 0; width: auto; } div.NavContentPart { margin:1.5em 0em 1em 0em; padding:0.5em 1.5em .5em 1.5em; border:1px solid black; width:580px; } div.NavContentHeader { position: relative; float: left; margin-top: -1em; margin-bottom: 1em; padding-left: 1em; padding-right: 1em; background-color: white; } div.NavContentContent, div.NavContentContentPart {







