From 201af52713806c7c850ad7c7c9a6cb35535a09d5 Mon Sep 17 00:00:00 2001 From: Erik Moeller Date: Thu, 13 May 2004 12:20:59 +0000 Subject: [PATCH] restore section folding --- includes/Article.php | 225 ++++++++++++++++++++++++-------- includes/EditPage.php | 4 +- includes/OutputPage.php | 27 ++++ includes/Parser.php | 138 ++++++++++++++++++-- includes/Skin.php | 86 ++++++++---- includes/SkinPHPTal.php | 23 +++- includes/SpecialPreferences.php | 5 + includes/Title.php | 4 +- includes/WebRequest.php | 4 +- languages/Language.php | 7 +- 10 files changed, 423 insertions(+), 100 deletions(-) diff --git a/includes/Article.php b/includes/Article.php index 0ac58b9eef..71ffb693ab 100644 --- a/includes/Article.php +++ b/includes/Article.php @@ -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].*?" . ">)/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

Heading

, 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].*?" . ">)/mi", + $striptext, -1, + PREG_SPLIT_DELIM_CAPTURE); + if($section==0) { + $rv=$secs[0]; + } else { + $headline=$secs[$section*2-1]; + preg_match( "/^(=+).*?=+|^.*?<\/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].*?>/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].*?" . ">)/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].*?>/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].*?>/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; } diff --git a/includes/EditPage.php b/includes/EditPage.php index 2c04c1fdbd..3151ea06de 100644 --- a/includes/EditPage.php +++ b/includes/EditPage.php @@ -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.="

" . wfMsg( "previewconflict" ) . "

\n"; } - $previewtext = wfUnescapeHTML( $this->textbox1 ); + $previewtext = $this->textbox1; $parserOptions = ParserOptions::newFromUser( $wgUser ); $parserOptions->setUseCategoryMagic( false ); diff --git a/includes/OutputPage.php b/includes/OutputPage.php index e859ed2229..5f553a328d 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -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 .= ""; return $ret; } + + function setToc($toc) { + + $this->mToc=$toc; + + } + + function getToc() { + + return $this->mToc; + + } + + function setCollapse($collapse) { + + $this->mCollapse=$collapse; + + } + + function getCollapse() { + + return $this->mCollapse; + + } } ?> diff --git a/includes/Parser.php b/includes/Parser.php index e488b50abd..dfba14d2b9 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -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 .= ""; $state["strong"] = FALSE; - $state["em"] = @$token["pos"]; + $state["em"] = $token["pos"]; } else { # not $em and not $strong $s .= ""; $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 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].*?>/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

foo

, ==foo== equals

foo

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 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; diff --git a/includes/Skin.php b/includes/Skin.php index 7b53b6ee3e..c74dabdf33 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -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 = "

" . htmlspecialchars( $wgOut->getPageTitle() ) . "

"; + 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 = "

" . $link . " " . wfMsg("sectionedit")."

"; + } else { + + $s = "

" . htmlspecialchars( $wgOut->getPageTitle() ) . "

"; + } 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 = "§ion={$section}"; + } + if ( !empty($sectiontitle) ) { + $stl = "§iontitle={$sectiontitle}"; + } + if ($collapse && !$section) { + $sid = "§ion=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 = "$tocline
"; + function tocLine( $anchor, $tocline, $level,$section=0 ) { + global $wgTitle; + $url = $section ? $wgTitle->getLocalURL( "action=view§ion={$section}§iontitle={$anchor}" ) + : "#$anchor"; + $link = "$tocline
"; 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="".wfMsg("expandpage").""; + } else { + $url=$wgTitle->getLocalURL("action=view&collapse=true"); + $collapseexpand="".wfMsg("collapsepage").""; + } + } $hideline = " "; - return + $rv= "
\n". "".wfMsg("toc")."" . $hideline . "
\n". - $toc."
\n"; + $toc.""; + if($collapseexpand) { + $rv.="$collapseexpand"; + } + $rv.="\n"; + return $rv; } # These two do not check for permissions: check $wgTitle->userCanEdit before calling them diff --git a/includes/SkinPHPTal.php b/includes/SkinPHPTal.php index fa0dcbfa5e..40feac6c41 100644 --- a/includes/SkinPHPTal.php +++ b/includes/SkinPHPTal.php @@ -87,7 +87,12 @@ $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 ); @@ -287,10 +292,13 @@ # 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(); @@ -327,12 +335,16 @@ if ( $wgTitle->userCanEdit() ) { $oid = ( $oldid && ! isset( $diff ) ) ? "&oldid={$oldid}" : false; + + $sid = $section ? "§ion={$section}" : false; + $stl = $sectiontitle ? "§iontitle={$sectiontitle}" : false; + if($collapse && !$sid) { $sid="§ion=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') ); @@ -347,9 +359,12 @@ } } else { $oid = ( $oldid && ! isset( $diff ) ) ? "&oldid={$oldid}" : ''; + $sid = $section ? "§ion={$section}" : false; + $stl = $sectiontitle ? "§iontitle={$sectiontitle}" : false; + if($collapse && !$sid) { $sid="§ion=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')); } diff --git a/includes/SpecialPreferences.php b/includes/SpecialPreferences.php index ba649eaa49..ea495dc9b2 100644 --- a/includes/SpecialPreferences.php +++ b/includes/SpecialPreferences.php @@ -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" ) . "
+
diff --git a/includes/Title.php b/includes/Title.php index 255cc157bc..55248c6eff 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -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; } - + } ?> diff --git a/includes/WebRequest.php b/includes/WebRequest.php index bcec3c05fc..593ca78f1c 100644 --- a/includes/WebRequest.php +++ b/includes/WebRequest.php @@ -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 ) { diff --git a/languages/Language.php b/languages/Language.php index ca5024436f..4aa2336391 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -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 -- 2.20.1