restore section folding
authorErik Moeller <erik@users.mediawiki.org>
Thu, 13 May 2004 12:20:59 +0000 (12:20 +0000)
committerErik Moeller <erik@users.mediawiki.org>
Thu, 13 May 2004 12:20:59 +0000 (12:20 +0000)
includes/Article.php
includes/EditPage.php
includes/OutputPage.php
includes/Parser.php
includes/Skin.php
includes/SkinPHPTal.php
includes/SpecialPreferences.php
includes/Title.php
includes/WebRequest.php
languages/Language.php

index 0ac58b9..71ffb69 100644 (file)
@@ -64,14 +64,16 @@ class Article {
        # Return the text of this revision
        function getContent( $noredir )
        {
-               global $wgRequest;
+               global $wgRequest,$wgUser,$wgOut;
+
+               $fname =  "Article::getContent";
+               wfProfileIn( $fname );
 
                # Get variables from query string :P
                $action = $wgRequest->getText( 'action', 'view' );
                $section = $wgRequest->getText( 'section' );
-
-               $fname =  "Article::getContent";
-               wfProfileIn( $fname );
+               $sectiontitle = $wgRequest->getText( 'sectiontitle' );  
+               $oid = $wgRequest->getInt( 'oldid' );   
 
                if ( 0 == $this->getID() ) {
                        if ( "edit" == $action ) {
@@ -80,60 +82,126 @@ class Article {
                        }
                        wfProfileOut( $fname );
                        return wfMsg( "noarticletext" );
-               } else {
+               } else {                        
                        $this->loadContent( $noredir );
-
-                       if(
-                               # check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
-                               ( $this->mTitle->getNamespace() == Namespace::getTalk( Namespace::getUser()) ) &&
-                                 preg_match("/^\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3}$/",$this->mTitle->getText()) &&
-                                 $action=="view"
-                               )
-                               {
-                               wfProfileOut( $fname );
-                               return $this->mContent . "\n" .wfMsg("anontalkpagetext"); }
-                       else {
-                               if($action=="edit") {
-                                       if($section!="") {
-                                               if($section=="new") {
-                                                       wfProfileOut( $fname );
-                                                       return "";
-                                               }
-
-                                               # strip NOWIKI etc. to avoid confusion (true-parameter causes HTML
-                                               # comments to be stripped as well)
-                                               $striparray=array();
-                                               $parser=new Parser();
-                                               $parser->mOutputType=OT_WIKI;
-                                               $striptext=$parser->strip($this->mContent, $striparray, true);
-
-                                               # now that we can be sure that no pseudo-sections are in the source,
-                                               # split it up by section
-                                               $secs =
-                                                 preg_split(
-                                                 "/(^=+.*?=+|^<h[1-6].*?" . ">.*?<\/h[1-6].*?" . ">)/mi",
-                                                 $striptext, -1,
-                                                 PREG_SPLIT_DELIM_CAPTURE);
-
-                                               if($section==0) {
-                                                       $rv=$secs[0];
-                                               } else {
-                                                       $rv=$secs[$section*2-1] . $secs[$section*2];
-                                               }
-
-                                               # reinsert stripped tags
-                                               $rv=$parser->unstrip($rv,$striparray);
-                                               $rv=trim($rv);
-                                               wfProfileOut( $fname );
-                                               return $rv;
-                                       }
+                       
+                       # size threshold at which pages are automatically collapsed
+                       $collapsethreshold=$wgUser->getOption( "collapsethreshold" );
+                       if($collapsethreshold && strlen($this->mContent)>=$collapsethreshold) {
+                               $collapse=true;                 
+                       } else {
+                               $collapse=false;
+                       }
+                       #override user pref is expansion is explicitly requested
+                       if($wgRequest->getBool('collapse')) { $collapse=true; }
+                       if( $wgRequest->getText( 'collapse' ) == 'false') {                     
+                               $collapse=false;
+                       }
+                       if($oid) { $collapse=false; }
+                       $wgOut->setCollapse($collapse);
+                       
+                       # check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page
+                       # if so, a "This is an anonymous talk page .." message must be appended to the 
+                       # displayed page (but not during editing!).
+                       $anontalk=false;
+                       if( ( $this->mTitle->getNamespace() == Namespace::getTalk( Namespace::getUser()) ) &&      
+                           preg_match("/^\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3}$/",$this->mTitle->getText()) &&
+                           $action=="view" 
+                       ) {  $anontalk=true; }                          
+                       
+                       # When a page is viewed in collapsed mode, only the intro section and, for
+                       # pages with multiple sections, a table of contents are shown.                  
+                       if($collapse && $action=="view" && $section=="") {
+                               $rv=$this->getSection($this->mContent,0,$sectiontitle);                         
+                               $wgOut->setToc(Parser::getTocFromSource($this->mContent));                              
+                               if($anontalk) { $rv = $rv . "\n" . wfMsg("anontalkpage"); }
+                               wfProfileOut( $fname ); 
+                               return $rv;
+                       }
+                       # $section contains a section number and is used for section viewing and editing.
+                       if($section!="") {
+                               if($section=="new" && $action=="edit") {
+                                       wfProfileOut( $fname );
+                                       return "";
                                }
-                               wfProfileOut( $fname );
-                               return $this->mContent;
+                               $rv=$this->getSection($this->mContent,$section,$sectiontitle);
+                               if($anontalk) { $rv = $rv . "\n" . wfMsg("anontalkpage"); }
+                               wfProfileOut( $fname ); 
+                               return $rv;
                        }
                }
+                                       
+               if($anontalk) { return $this->mContent . "\n" . wfMsg("anontalkpage"); }
+               wfProfileOut( $fname );                         
+               return $this->mContent;
+       
        }
 
+       # This function returns the text of a section, specified by a number ($section)
+       # and a section title ($sectiontitle). A section is text under a heading like
+       # == Heading == or <h1>Heading</h1>, or the first section before any such
+       # heading (section 0).
+       #
+       # If a section contains subsections, these are also returned.
+       #
+       function getSection($text,$section,$sectiontitle)  {
+               
+               # strip NOWIKI etc. to avoid confusion (true-parameter causes HTML
+               # comments to be stripped as well)
+               $striparray=array();
+               $parser=new Parser();
+               $parser->mOutputType=OT_WIKI;
+               $striptext=$parser->strip($text, $striparray, true);
+
+               # now that we can be sure that no pseudo-sections are in the source,
+               # split it up by section
+               $secs =
+                 preg_split(
+                 "/(^=+.*?=+|^<h[1-6].*?" . ">.*?<\/h[1-6].*?" . ">)/mi",
+                 $striptext, -1,
+                 PREG_SPLIT_DELIM_CAPTURE);
+               if($section==0) {
+                       $rv=$secs[0];
+               } else {
+                       $headline=$secs[$section*2-1];
+                       preg_match( "/^(=+).*?=+|^<h([1-6]).*?>.*?<\/h[1-6].*?>/mi",$headline,$matches);
+                       $hlevel=$matches[1];
+                       
+                       # translate wiki heading into level
+                       if(strpos($hlevel,"=")!==false) {
+                               $hlevel=strlen($hlevel);                        
+                       }
+                       
+                       $rv=$headline. $secs[$section*2];
+                       $count=$section+1;
+                       
+                       $break=false;
+                       while(!empty($secs[$count*2-1]) && !$break) {
+                       
+                               $subheadline=$secs[$count*2-1];
+                               preg_match( "/^(=+).*?=+|^<h([1-6]).*?>.*?<\/h[1-6].*?>/mi",$subheadline,$matches);
+                               $subhlevel=$matches[1];
+                               if(strpos($subhlevel,"=")!==false) {
+                                       $subhlevel=strlen($subhlevel);                                          
+                               }
+                               if($subhlevel > $hlevel) {
+                                       $rv.=$subheadline.$secs[$count*2];
+                               }
+                               if($subhlevel <= $hlevel) {
+                                       $break=true;
+                               }
+                               $count++;
+                                               
+                       }
+               }
+               # reinsert stripped tags
+               $rv=$parser->unstrip($rv,$striparray);
+               $rv=trim($rv);
+               return $rv;
+
+       }
+       
+       
        # Load the revision (including cur_text) into this object
        function loadContent( $noredir = false )
        {
@@ -472,7 +540,7 @@ class Article {
                # If we got diff and oldid in the query, we want to see a
                # diff page instead of the article.
 
-               if ( !is_null( $diff ) ) {
+               if ( !is_null( $diff ) ) {                      
                        $wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
                        $de = new DifferenceEngine( intval($oldid), intval($diff) );
                        $de->showDiffPage();
@@ -604,7 +672,7 @@ class Article {
        /* Side effects: loads last edit */
        function getTextOfLastEditWithSectionReplacedOrAdded($section, $text, $summary = ""){
                $this->loadLastEdit();
-               $oldtext = $this->getContent( true );
+               $oldtext = $this->getContent( true );           
                if ($section != "") {
                        if($section=="new") {
                                if($summary) $subject="== {$summary} ==\n\n";
@@ -620,15 +688,58 @@ class Article {
 
                                # now that we can be sure that no pseudo-sections are in the source,
                                # split it up
+                               # Unfortunately we can't simply do a preg_replace because that might
+                               # replace the wrong section, so we have to use the section counter instead
                                $secs=preg_split("/(^=+.*?=+|^<h[1-6].*?" . ">.*?<\/h[1-6].*?" . ">)/mi",
                                  $oldtext,-1,PREG_SPLIT_DELIM_CAPTURE);
                                $secs[$section*2]=$text."\n\n"; // replace with edited
-                               if($section) { $secs[$section*2-1]=""; } // erase old headline
+                               
+                               # section 0 is top (intro) section
+                               if($section!=0) { 
+                                       
+                                       # headline of old section - we need to go through this section
+                                       # to determine if there are any subsections that now need to
+                                       # be erased, as the mother section has been replaced with
+                                       # the text of all subsections.
+                                       $headline=$secs[$section*2-1];
+                                       preg_match( "/^(=+).*?=+|^<h([1-6]).*?>.*?<\/h[1-6].*?>/mi",$headline,$matches);
+                                       $hlevel=$matches[1];
+                                       
+                                       # determine headline level for wikimarkup headings
+                                       if(strpos($hlevel,"=")!==false) {
+                                               $hlevel=strlen($hlevel);                        
+                                       }
+                                       
+                                       $secs[$section*2-1]=""; // erase old headline
+                                       $count=$section+1;
+                                       $break=false;
+                                       while(!empty($secs[$count*2-1]) && !$break) {
+                       
+                                               $subheadline=$secs[$count*2-1];
+                                               preg_match(
+                                                "/^(=+).*?=+|^<h([1-6]).*?>.*?<\/h[1-6].*?>/mi",$subheadline,$matches);
+                                               $subhlevel=$matches[1];
+                                               if(strpos($subhlevel,"=")!==false) {
+                                                       $subhlevel=strlen($subhlevel);          
+                                               }
+                                               if($subhlevel > $hlevel) {
+                                                       // erase old subsections
+                                                       $secs[$count*2-1]="";
+                                                       $secs[$count*2]="";
+                                               }
+                                               if($subhlevel <= $hlevel) {
+                                                       $break=true;
+                                               }
+                                               $count++;
+                                               
+                                       }
+                                       
+                               }
                                $text=join("",$secs);
-
                                # reinsert the stuff that we stripped out earlier
-                               $text=$parser->unstrip($text,$striparray,true);
+                               $text=$parser->unstrip($text,$striparray);      
                        }
+                                                               
                }
                return $text;
        }
index 2c04c1f..3151ea0 100644 (file)
@@ -196,7 +196,7 @@ class EditPage {
                                        return;
                                else
                                        $isConflict = true;
-                       }
+                       }                       
                }
                # First time through: get contents, set time for conflict
                # checking, etc.
@@ -335,7 +335,7 @@ class EditPage {
                                $previewhead.="<h2>" . wfMsg( "previewconflict" ) .
                                  "</h2>\n";
                        }
-                       $previewtext = wfUnescapeHTML( $this->textbox1 );
+                       $previewtext = $this->textbox1;
 
                        $parserOptions = ParserOptions::newFromUser( $wgUser );
                        $parserOptions->setUseCategoryMagic( false );
index e859ed2..5f553a3 100644 (file)
@@ -18,6 +18,8 @@ class OutputPage {
        var $mParserOptions;
        var $mShowFeedLinks = false;
        var $mEnableClientCache = true;
+       var $mToc;              # Table of contents for collapsed pages (in HTML)
+       var $mCollapse = false; # Collapse output? (Set in Article.php)
        
        function OutputPage()
        {
@@ -35,6 +37,7 @@ class OutputPage {
                $this->mContainsOldMagic = $this->mContainsNewMagic = 0;
                $this->mParserOptions = ParserOptions::newFromUser( $temp = NULL );
                $this->mSquidMaxage = 0;
+               $this->mToc='';
        }
 
        function addHeader( $name, $val ) { array_push( $this->mHeaders, "$name: $val" ) ; }
@@ -713,5 +716,29 @@ class OutputPage {
                # $ret .= "<!--[if gte IE 5.5000]><script type='text/javascript' src='$fix'></script><![endif]-->";
                return $ret;
        }
+       
+       function setToc($toc) {
+       
+               $this->mToc=$toc;
+       
+       }
+
+       function getToc() {
+       
+               return $this->mToc;
+       
+       }       
+
+       function setCollapse($collapse) {
+       
+               $this->mCollapse=$collapse;
+       
+       }
+
+       function getCollapse() {
+       
+               return $this->mCollapse;
+       
+       }       
 }
 ?>
index e488b50..dfba14d 100644 (file)
@@ -547,7 +547,9 @@ class Parser
                return $t ;
        }
 
-       function internalParse( $text, $linestart, $args = array() )
+       // set isMain=false if you call from a template etc. and don't want to do stuff
+       // like TOC insertion for that content
+       function internalParse( $text, $linestart, $args = array(), $isMain=true )
        {
                $fname = "Parser::internalParse";
                wfProfileIn( $fname );
@@ -565,7 +567,7 @@ class Parser
                $text = $this->replaceExternalLinks( $text );
                $text = $this->doTokenizedParser ( $text );
                $text = $this->doTableStuff ( $text ) ;
-               $text = $this->formatHeadings( $text );
+               $text = $this->formatHeadings( $text, $isMain );
                $sk =& $this->mOptions->getSkin();
                $text = $sk->transformContent( $text );
 
@@ -729,7 +731,7 @@ class Parser
                } elseif ( $state["strong"] !== false ) {
                        $s .= "</strong><em>";
                        $state["strong"] = FALSE;
-                       $state["em"] = @$token["pos"];
+                       $state["em"] = $token["pos"];
                } else { # not $em and not $strong
                        $s .= "<strong><em>";
                        $state["strong"] = $state["em"] = isset($token["pos"]) ? $token["pos"] : true;
@@ -1507,7 +1509,8 @@ class Parser
 
                        # Run full parser on the included text
                        $text = $this->strip( $text, $this->mStripState );
-                       $text = $this->internalParse( $text, (bool)$newline, $assocArgs );
+                       $text = $this->internalParse( $text, (bool)$newline, $assocArgs, false );
+                       if(!empty($newline)) $text = "\n".$text;
 
                        # Add the result to the strip state for re-inclusion after
                        # the rest of the processing
@@ -1672,10 +1675,12 @@ class Parser
  *
  */
 
-       /* private */ function formatHeadings( $text )
+       /* private */ function formatHeadings( $text, $isMain=true )
        {
-               global $wgInputEncoding;
+               global $wgInputEncoding,$wgRequest,$wgOut;
                
+               $startsection=$wgRequest->getVal('section');    
+               if($startsection) { $startsection--;}
                $doNumberHeadings = $this->mOptions->getNumberHeadings();
                $doShowToc = $this->mOptions->getShowToc();
                if( !$this->mTitle->userCanEdit() ) {
@@ -1807,12 +1812,12 @@ class Parser
                                if ( empty( $head[$headlineCount] ) ) {
                                        $head[$headlineCount] = "";
                                }
-                               $head[$headlineCount] .= $sk->editSectionLink($headlineCount+1);
+                               $head[$headlineCount] .= $sk->editSectionLink($startsection+$headlineCount+1);
                        }
 
                        # Add the edit section span
                        if( $rightClickHack ) {
-                               $headline = $sk->editSectionScript($headlineCount+1,$headline);
+                               $headline = $sk->editSectionScript($startsection+$headlineCount+1,$headline);
                        }
 
                        # give headline the correct <h#> tag
@@ -1846,6 +1851,14 @@ class Parser
                        # Top anchor now in skin
                                $full = $full.$toc;
                        }
+                       
+                       # If a page is viewed in collapsed mode, a TOC generated
+                       # from the wikisource is stored in the title object.
+                       # This TOC is now fetched and inserted here if it exists.
+                       $collapsedtoc=$wgOut->getToc();
+                       if ($collapsedtoc && !$i && $isMain) {
+                               $full = $full.$collapsedtoc;            
+                       }                       
 
                        if( !empty( $head[$i] ) ) {
                                $full .= $head[$i];
@@ -1856,6 +1869,115 @@ class Parser
                return $full;
        }
 
+       /* Generates a HTML-formatted table of contents which links to individual sections 
+          from the wikisource. Used for collapsing long pages.
+        */        
+       /* static */ function getTocFromSource( $text ) {               
+               
+               global $wgUser,$wgInputEncoding,$wgTitle,$wgOut,$wgParser;              
+               $sk = $wgUser->getSkin();               
+               
+               $striparray=array();
+               $oldtype=$wgParser->mOutputType;
+               $wgParser->mOutputType=OT_WIKI;
+               $text=$wgParser->strip($text, $striparray, true);
+               $wgParser->mOutputType=$oldtype;        
+               
+               $numMatches = preg_match_all( "/^(=+)(.*?)=+|^<h([1-6]).*?>(.*?)<\/h[1-6].*?>/mi",$text,$matches);
+               
+               # no headings: text cannot be collapsed
+               if( $numMatches == 0 ) {
+                       return "";
+               }
+               
+               # We combine the headlines into a bundle and convert them to HTML
+               # in order to make stripping out the wikicrap easier.
+               $combined=implode("!@@@!",$matches[2]);
+               $myout=$wgParser->parse($combined,$wgTitle,$wgOut->mParserOptions);                     
+               $combined_html=$myout->getText();               
+               $headlines=array();
+               $headlines=explode("!@@@!",$combined_html);
+               
+               # headline counter
+               $headlineCount = 0;             
+               $toclevel = 0;
+               $toc = "";
+               $full = "";
+               $head = array();
+               $sublevelCount = array();
+               $level = 0;
+               $prevlevel = 0;
+               foreach( $headlines as $headline ) {                    
+                       $headline=trim($headline);
+                       $numbering = "";
+                       if( $level ) {
+                               $prevlevel = $level;
+                       }
+                       $level = $matches[1][$headlineCount];
+                       
+                       # wikisource headings need to be converted into numbers
+                       # =foo= equals <h1>foo</h1>, ==foo== equals <h2>foo</h2> etc.
+                       if(strpos($level,"=")!==false) {
+                               $level=strlen($level);                  
+                       }
+                       
+                       if(  $prevlevel && $level > $prevlevel ) {
+                               # reset when we enter a new level
+                               $sublevelCount[$level] = 0;
+                               $toc .= $sk->tocIndent( $level - $prevlevel );
+                               $toclevel += $level - $prevlevel;
+                       }
+                       if( $level < $prevlevel ) {
+                               # reset when we step back a level
+                               $sublevelCount[$level+1]=0;
+                               $toc .= $sk->tocUnindent( $prevlevel - $level );
+                               $toclevel -= $prevlevel - $level;
+                       }
+                       # count number of headlines for each level
+                       @$sublevelCount[$level]++;                      
+                       $dot = 0;
+                       for( $i = 1; $i <= $level; $i++ ) {
+                               if( !empty( $sublevelCount[$i] ) ) {
+                                       if( $dot ) {
+                                               $numbering .= ".";
+                                       }
+                                       $numbering .= $sublevelCount[$i];
+                                       $dot = 1;
+                               }
+                       }
+                       
+
+                       # The canonized header is a version of the header text safe to use for links
+                       # Avoid insertion of weird stuff like <math> by expanding the relevant sections
+                       $state=array();
+                       $canonized_headline = Parser::unstrip( $headline, $state);                      
+                       
+                       # strip out HTML
+                       $canonized_headline = preg_replace( "/<.*?" . ">/","",$canonized_headline );
+                       $tocline = trim( $canonized_headline );
+                       $canonized_headline = preg_replace("/[ \\?&\\/<>\\(\\)\\[\\]=,+']+/", '_', urlencode( do_html_entity_decode( $tocline, ENT_COMPAT, $wgInputEncoding ) ) );
+                       $refer[$headlineCount] = $canonized_headline;
+
+                       # count how many in assoc. array so we can track dupes in anchors
+                       @$refers[$canonized_headline]++;
+                       $refcount[$headlineCount]=$refers[$canonized_headline];
+                       $tocline = $numbering . " " . $tocline;
+
+                       # Create the anchor for linking from the TOC to the section
+                       $anchor = trim($canonized_headline);
+                       
+                       if($refcount[$headlineCount] > 1 ) {
+                               $anchor .= "_" . $refcount[$headlineCount];
+                       }                       
+                       $headlineCount++;
+                       $toc .= $sk->tocLine($anchor,$tocline,$toclevel,$headlineCount);
+               }
+               $toclines = $headlineCount;
+               $toc .= $sk->tocUnindent( $toclevel );
+               $toc = $sk->tocTable( $toc );
+               return $toc;
+       
+       }
        /* private */ function doMagicISBN( &$tokenizer )
        {
                global $wgLang;
index 7b53b6e..c74dabd 100644 (file)
@@ -195,26 +195,17 @@ class Skin {
        {
                global $wgUser, $wgTitle, $wgNamespaceBackgrounds, $wgOut, $wgRequest;
                
-               extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff' ) );
+               extract( $wgRequest->getValues( 'oldid', 'redirect', 'diff', 'section','sectiontitle') );
+               $collapse=$wgOut->getCollapse();
 
                if ( 0 != $wgTitle->getNamespace() ) {
                        $a = array( "bgcolor" => "#ffffec" );
                }
                else $a = array( "bgcolor" => "#FFFFFF" );
-               if($wgOut->isArticle() && $wgUser->getOption("editondblclick") && 
-                 (!$wgTitle->isProtected() || $wgUser->isSysop()) ) {
-                       $t = wfMsg( "editthispage" );
-                       $oid = $red = "";
-                       if ( !empty($redirect) ) { 
-                               $red = "&redirect={$redirect}"; 
-                       }
-                       if ( !empty($oldid) && ! isset( $diff ) ) {
-                               $oid = "&oldid={$oldid}";
-                       }
-                       $s = $wgTitle->getFullURL( "action=edit{$oid}{$red}" );
+               if($wgOut->isArticle() && $wgUser->getOption("editondblclick")) {
+                       $s = $this->editThisPage(false);
                        $s = "document.location = \"" .$s ."\";";
                        $a += array ("ondblclick" => $s);
-
                }
                $a['onload'] = $wgOut->getOnloadHandler();
                return $a;
@@ -524,9 +515,17 @@ class Skin {
 
        function pageTitle()
        {
-               global $wgOut, $wgTitle, $wgUser;
-
-               $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";
+               global $wgOut, $wgTitle, $wgUser, $wgRequest;
+               $section=$wgRequest->getVal('section');
+               $action=$wgRequest->getVal('action');
+                               
+               if ($section && $action=="view") {      
+                       $link= $this->makeLink( $wgTitle->getPrefixedText(), htmlspecialchars($wgOut->getPageTitle()) );
+                       $s = "<h1 class='pagetitle'>" . $link . " " . wfMsg("sectionedit")."</h1>";                     
+               } else {
+               
+                       $s = "<h1 class='pagetitle'>" . htmlspecialchars( $wgOut->getPageTitle() ) . "</h1>";   
+               }
                if($wgUser->getOption("editsectiononrightclick") && $wgTitle->userCanEdit()) { $s=$this->editSectionScript(0,$s);}
                return $s;
        }
@@ -1105,15 +1104,19 @@ class Skin {
                return $s;
        }
 
-       function editThisPage()
+       # if makeLink is false, just return the edit URL
+       function editThisPage($makeLink=true)
        {
                global $wgOut, $wgTitle, $wgRequest;
                
                $oldid = $wgRequest->getVal( 'oldid' );
                $diff = $wgRequest->getVal( 'diff' );
                $redirect = $wgRequest->getVal( 'redirect' );
+               $section = $wgRequest->getVal('section');
+               $sectiontitle = $wgRequest->getVal('sectiontitle');
+               $collapse = $wgOut->getCollapse();
                
-               if ( ! $wgOut->isArticleRelated() ) {
+               if ( ! $wgOut->isArticleRelated() && $makeLink) {
                        $s = wfMsg( "protectedpage" );
                } else {
                        $n = $wgTitle->getPrefixedText();
@@ -1123,13 +1126,27 @@ class Skin {
                                #$t = wfMsg( "protectedpage" );
                                $t = wfMsg( "viewsource" );
                        }
-                       $oid = $red = "";
+                       $oid = $red = $sid = $stl = "";
 
                        if ( !is_null( $redirect ) ) { $red = "&redirect={$redirect}"; }
                        if ( $oldid && ! isset( $diff ) ) {
                                $oid = "&oldid={$oldid}";
                        }
-                       $s = $this->makeKnownLink( $n, $t, "action=edit{$oid}{$red}" );
+                       if ( !empty($section) ) {
+                               $sid = "&section={$section}";
+                       }
+                       if ( !empty($sectiontitle) ) {
+                               $stl = "&sectiontitle={$sectiontitle}";
+                       }
+                       if ($collapse && !$section) {
+                               $sid = "&section=0";
+                       }
+                       $action="action=edit{$oid}{$red}{$sid}{$stl}";
+                       if($makeLink) {
+                               $s = $this->makeKnownLink( $n, $t, $action );
+                       } else {
+                               $s = $wgTitle->getFullUrl($action);
+                       }
                }
                return $s;
        }
@@ -2481,8 +2498,11 @@ class Skin {
        }
 
        # parameter level defines if we are on an indentation level
-       function tocLine( $anchor, $tocline, $level ) {
-               $link = "<a href=\"#$anchor\">$tocline</a><br />";
+       function tocLine( $anchor, $tocline, $level,$section=0 ) {
+               global $wgTitle;                
+               $url = $section ?  $wgTitle->getLocalURL( "action=view&section={$section}&sectiontitle={$anchor}" ) 
+                      : "#$anchor";            
+               $link = "<a href=\"$url\" class='internal'>$tocline</a><br />";
                if($level) {
                        return "$link\n";
                } else {
@@ -2494,13 +2514,31 @@ class Skin {
        function tocTable($toc) {
                # note to CSS fanatics: putting this in a div does not work -- div won't auto-expand
                # try min-width & co when somebody gets a chance
+               global $wgRequest,$wgTitle,$wgOut;
+               $collapse=$wgOut->getCollapse();
+               $section=$wgRequest->getVal('section');
+               $collapseexpand="";
+               if(!$section) {
+                       if($collapse) {
+                               $url=$wgTitle->getLocalURL("action=view&collapse=false");
+                               $collapseexpand="<a href=\"$url\" class=\"internal\">".wfMsg("expandpage")."</A>";
+                       } else {
+                               $url=$wgTitle->getLocalURL("action=view&collapse=true");
+                               $collapseexpand="<a href=\"$url\" class=\"internal\">".wfMsg("collapsepage")."</A>";
+                       }
+               }
                $hideline = " <script type='text/javascript'>showTocToggle(\"" . addslashes( wfMsg("showtoc") ) . "\",\"" . addslashes( wfMsg("hidetoc") ) . "\")</script>";
-               return
+               $rv=
                "<table border=\"0\" id=\"toc\"><tr><td align=\"center\">\n".
                "<b>".wfMsg("toc")."</b>" .
                $hideline .
                "</td></tr><tr id='tocinside'><td>\n".
-               $toc."</td></tr></table>\n";
+               $toc."</td></tr>";
+               if($collapseexpand) {
+                       $rv.="<tr><td align=\"center\"><I>$collapseexpand</I></td></tr>";
+               }
+               $rv.="</table>\n";
+               return $rv;
        }
 
        # These two do not check for permissions: check $wgTitle->userCanEdit before calling them
index fa0dcbf..40feac6 100644 (file)
 
                        $this->titletxt = $wgTitle->getPrefixedText();
                        
-                       $tpl->set( "title", $wgOut->getPageTitle() );
+                       $title=$wgOut->getPageTitle();                  
+                       $section=$wgRequest->getVal('section');                 
+                       if ($section && $action=="view") {      
+                               $title .= " " . wfMsg("sectionedit");
+                       }
+                       $tpl->set( "title", $title );
                        $tpl->set( "pagetitle", $wgOut->getHTMLTitle() );
                        
                        $tpl->setRef( "thispage", &$this->thispage );
                
                # an array of edit links by default used for the tabs
                function buildContentActionUrls () {
-                       global $wgTitle, $wgUser, $wgRequest;
+                       global $wgTitle, $wgUser, $wgRequest,$wgOut;
                        $action = $wgRequest->getText( 'action' );
                        $section = $wgRequest->getText( 'section' );
                        $oldid = $wgRequest->getVal( 'oldid' );
+                       $section = $wgRequest->getVal( 'section' );
+                       $sectiontitle = $wgRequest->getVal( 'sectiontitle' );
+                       $collapse = $wgOut->getCollapse();
                        $diff = $wgRequest->getVal( 'diff' );
                        $content_actions = array();
                        
 
                                if ( $wgTitle->userCanEdit() ) {
                                        $oid = ( $oldid && ! isset( $diff ) ) ? "&oldid={$oldid}" : false;
+                                       
+                                       $sid = $section ? "&section={$section}" : false;
+                                       $stl = $sectiontitle ? "&sectiontitle={$sectiontitle}" : false;
+                                       if($collapse && !$sid) { $sid="&section=0";}
                                        $istalk = ( Namespace::isTalk( $wgTitle->getNamespace()) );
                                        $istalkclass = $istalk?' istalk':'';
                                        $content_actions['edit'] = array(
                                                'class' => ((($action == 'edit' or $action == 'submit') and $section != 'new') ? 'selected' : '').$istalkclass,
                                                'text' => wfMsg('edit'),
-                                               'href' => $this->makeUrl($this->thispage, 'action=edit'.$oid),
+                                               'href' => $this->makeUrl($this->thispage, 'action=edit'.$oid.$sid.$stl),
                                                'ttip' => wfMsg('tooltip-edit'),
                                                'akey' => wfMsg('accesskey-edit')
                                        );
                                        }
                                } else {
                                        $oid = ( $oldid && ! isset( $diff ) ) ? "&oldid={$oldid}" : '';
+                                       $sid = $section ? "&section={$section}" : false;
+                                       $stl = $sectiontitle ? "&sectiontitle={$sectiontitle}" : false;                 
+                                       if($collapse && !$sid) { $sid="&section=0";}
                                        $content_actions['edit'] = array('class' => ($action == 'edit') ? 'selected' : false,
                                        'text' => wfMsg('viewsource'),
-                                       'href' => $this->makeUrl($this->thispage, 'action=edit'.$oid),
+                                       'href' => $this->makeUrl($this->thispage, 'action=edit'.$oid.$sid.$stl),
                                        'ttip' => wfMsg('tooltip-viewsource'),
                                        'akey' => wfMsg('accesskey-viewsource'));
                                }
index ba649ea..ea495dc 100644 (file)
@@ -22,6 +22,7 @@ class PreferencesForm {
                $this->mNewpass = $request->getVal( 'wpNewpass' );
                $this->mRetypePass =$request->getVal( 'wpRetypePass' );
                $this->mStubs = $request->getVal( 'wpStubs' );
+               $this->mCollapse = $request->getVal( 'wpCollapse' );
                $this->mRows = $request->getVal( 'wpRows' );
                $this->mCols = $request->getVal( 'wpCols' );
                $this->mSkin = $request->getVal( 'wpSkin' );
@@ -158,6 +159,7 @@ class PreferencesForm {
                $wgUser->setOption( "rows", $this->validateInt( $this->mRows, 4, 1000 ) );
                $wgUser->setOption( "cols", $this->validateInt( $this->mCols, 4, 1000 ) );
                $wgUser->setOption( "stubthreshold", $this->validateIntOrNull( $this->mStubs ) );
+               $wgUser->setOption( "collapsethreshold", $this->validateIntOrNull( $this->mCollapse ) );
                $wgUser->setOption( "timecorrection", $this->validateTimeZone( $this->mHourDiff, -12, 14 ) );
 
                # Set search namespace options
@@ -197,6 +199,7 @@ class PreferencesForm {
                $this->mRows = $wgUser->getOption( "rows" );
                $this->mCols = $wgUser->getOption( "cols" );
                $this->mStubs = $wgUser->getOption( "stubthreshold" );
+               $this->mCollapse = $wgUser->getOption( "collapsethreshold" );
                $this->mHourDiff = $wgUser->getOption( "timecorrection" );
                $this->mSearch = $wgUser->getOption( "searchlimit" );
                $this->mSearchLines = $wgUser->getOption( "contextlines" );
@@ -311,6 +314,7 @@ class PreferencesForm {
                $emf = wfMsg( "emailflag" );
                $ynn = wfMsg( "yournick" );
                $stt = wfMsg ( "stubthreshold" ) ;
+               $coltr = wfMsg("collapsethreshold");
                $srh = wfMsg( "searchresultshead" );
                $rpp = wfMsg( "resultsperpage" );
                $scl = wfMsg( "contextlines" );
@@ -439,6 +443,7 @@ class PreferencesForm {
                " . $this->getToggle( "hideminor" ) .
                $this->getToggle( "usenewrc" ) . "
                <div><label>$stt: <input type='text' name=\"wpStubs\" value=\"$this->mStubs\" size='6' /></label></div>
+               <div><label>$coltr: <input type='text' name=\"wpCollapse\" value=\"$this->mCollapse\" size='6' /></label></div>
        </fieldset>
        
        <fieldset>
index 255cc15..55248c6 100644 (file)
@@ -38,7 +38,7 @@ class Title {
                $this->mNamespace = 0;
                $this->mRestrictionsLoaded = false;
                $this->mRestrictions = array();
-        $this->mDefaultNamespace = 0;
+               $this->mDefaultNamespace = 0;           
        }
 
        # From a prefixed DB key
@@ -1139,6 +1139,6 @@ class Title {
                Article::onArticleCreate( $this );
                return true;
        }
-       
+
 }
 ?>
index bcec3c0..593ca78 100644 (file)
@@ -101,7 +101,9 @@ class WebRequest {
        }
        
        function getBool( $name, $default = false ) {
-               return $this->getVal( $name, $default ) ? true : false;
+               $val=$this->getVal( $name, $default );
+               if($val=="false") { $val=false; }
+               return $val ? true : false;
        }
        
        function getCheck( $name ) {
index ca50244..4aa2336 100644 (file)
@@ -49,7 +49,7 @@ if($wgMetaNamespace === FALSE)
        "cols" => 80, "rows" => 25, "searchlimit" => 20,
        "contextlines" => 5, "contextchars" => 50,
        "skin" => $wgDefaultSkin, "math" => 1, "rcdays" => 7, "rclimit" => 50,
-       "highlightbroken" => 1, "stubthreshold" => 0,
+       "highlightbroken" => 1, "stubthreshold" => 0, "collapsethreshold" => 30000,
        "previewontop" => 1, "editsection"=>1,"editsectiononrightclick"=>0, "showtoc"=>1,
        "showtoolbar" =>1,
        "date" => 0
@@ -569,6 +569,8 @@ performed by sysops with  \"bureaucrat\" status.",
 "toc" => "Table of contents",
 "showtoc" => "show",
 "hidetoc" => "hide",
+"collapsepage" => "Collapse page",
+"expandpage" => "Expand page",
 "thisisdeleted" => "View or restore $1?",
 "restorelink" => "$1 deleted edits",
 'feedlinks' => 'Feed:',
@@ -942,7 +944,8 @@ See [[{{ns:4}}:User preferences help]] for help deciphering the options.",
 "resultsperpage" => "Hits to show per page",
 "contextlines" => "Lines to show per hit",
 "contextchars" => "Characters of context per line",
-"stubthreshold" => "Threshold for stub display",
+"stubthreshold" => "Threshold (in bytes) for marking links as stubs",
+"collapsethreshold" => "Threshold (in bytes) for auto-collapsing pages",
 "recentchangescount" => "Number of titles in recent changes",
 "savedprefs"   => "Your preferences have been saved.",
 "timezonetext" => "Enter number of hours your local time differs