From 221156150edbf9fdace17d13a5a27af15d580a7f Mon Sep 17 00:00:00 2001 From: Tom Gilder Date: Sat, 15 Jan 2005 23:21:52 +0000 Subject: [PATCH] Complete TOC recode: proper HTML list; CSS for layout; JS recode; hidden TOC stays hidden across different pages; never show TOC if no headings; more opportunity to style TOC --- includes/Linker.php | 48 ++++++++++---------- includes/Parser.php | 97 ++++++++++++++++++++++++++-------------- skins/amethyst/main.css | 52 ++++++++++++++++----- skins/chick/main.css | 4 +- skins/common/common.css | 56 ++++++++++++++++++----- skins/common/wikibits.js | 66 ++++++++++++++++++--------- skins/monobook/main.css | 64 +++++++++++++++++++++----- skins/monobook/rtl.css | 12 +++++ 8 files changed, 283 insertions(+), 116 deletions(-) diff --git a/includes/Linker.php b/includes/Linker.php index dc4bf14d35..7a725c496b 100644 --- a/includes/Linker.php +++ b/includes/Linker.php @@ -735,37 +735,39 @@ class Linker { return $comment; } - function tocIndent($level) { - return str_repeat( '
'."\n", $level>0 ? $level : 0 ); + function tocIndent() { + return "\n
\n", $level>0 ? $level : 0 ); + return "\n" . str_repeat( "\n\n", $level>0 ? $level : 0 ); } /** * parameter level defines if we are on an indentation level */ - function tocLine( $anchor, $tocline, $level ) { - $link = ''.$tocline.'
'; - if($level) { - return $link."\n"; - } else { - return '
'.$link."
\n"; - } - - } - - 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 - $hideline = ' '; - return - '
'."\n". - ''.wfMsgForContent('toc').'' . - $hideline . - '
'."\n". - $toc."
\n"; + function tocLine( $anchor, $tocline, $tocnumber, $level ) { + return "\n
  • ' . $tocnumber . ' ' . $tocline . ''; + } + + function tocLineEnd() + { + return "
  • \n"; + } + + function tocList($toc) { + return "
    \n" + . "

    " . wfMsg('toc') . "

    \n" + . $toc + . "\n
    \n" + . '' + . "
    \n"; } /** diff --git a/includes/Parser.php b/includes/Parser.php index a0f5a1f477..e2407e7d33 100644 --- a/includes/Parser.php +++ b/includes/Parser.php @@ -2424,8 +2424,9 @@ class Parser # if the string __TOC__ (not case-sensitive) occurs in the HTML, # override above conditions and always show TOC at that place + $mw =& MagicWord::get( MAG_TOC ); - if ($mw->match( $text ) ) { + if($mw->match( $text ) ) { $doShowToc = 1; $forceTocHere = true; } else { @@ -2437,7 +2438,10 @@ class Parser } } - + # Never ever show TOC if no headers + if( $numMatches < 1 ) { + $doShowToc = 0; + } # We need this to perform operations on the HTML $sk =& $this->mOptions->getSkin(); @@ -2448,17 +2452,22 @@ class Parser # Ugh .. the TOC should have neat indentation levels which can be # passed to the skin functions. These are determined here - $toclevel = 0; $toc = ''; $full = ''; $head = array(); $sublevelCount = array(); + $levelCount = array(); + $toclevel = 0; $level = 0; $prevlevel = 0; + $toclevel = 0; + $prevtoclevel = 0; + foreach( $matches[3] as $headline ) { $istemplate = 0; - $templatetitle = ""; + $templatetitle = ''; $templatesection = 0; + $numbering = ''; if (preg_match("//", $headline, $mat)) { $istemplate = 1; @@ -2467,28 +2476,54 @@ class Parser $headline = preg_replace("//", "", $headline); } - $numbering = ''; - if( $level ) { + if( $toclevel ) { $prevlevel = $level; + $prevtoclevel = $toclevel; } $level = $matches[1][$headlineCount]; - if( ( $doNumberHeadings || $doShowToc ) && $prevlevel && $level > $prevlevel ) { - # reset when we enter a new level - $sublevelCount[$level] = 0; - $toc .= $sk->tocIndent( $level - $prevlevel ); - $toclevel += $level - $prevlevel; - } - if( ( $doNumberHeadings || $doShowToc ) && $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]++; + if( $doNumberHeadings || $doShowToc ) { + + if ( $level > $prevlevel ) { + # Increase TOC level + $toclevel++; + $sublevelCount[$toclevel] = 0; + $toc .= $sk->tocIndent(); + } + elseif ( $level < $prevlevel && $toclevel > 1 ) { + # Decrease TOC level, find level to jump to + + if ( $toclevel == 2 && $level <= $levelCount[1] ) { + # Can only go down to level 1 + $toclevel = 1; + } else { + for ($i = $toclevel; $i > 0; $i--) { + if ( $levelCount[$i] == $level ) { + # Found last matching level + $toclevel = $i; + break; + } + elseif ( $levelCount[$i] < $level ) { + # Found first matching level below current level + $toclevel = $i + 1; + break; + } + } + } + + $toc .= $sk->tocUnindent( $prevtoclevel - $toclevel ); + } + else { + # No change in level, end TOC line + $toc .= $sk->tocLineEnd(); + } + + $levelCount[$toclevel] = $level; + + # count number of headlines for each level + @$sublevelCount[$toclevel]++; $dot = 0; - for( $i = 1; $i <= $level; $i++ ) { + for( $i = 1; $i <= $toclevel; $i++ ) { if( !empty( $sublevelCount[$i] ) ) { if( $dot ) { $numbering .= '.'; @@ -2527,16 +2562,10 @@ class Parser @$refers[$canonized_headline]++; $refcount[$headlineCount]=$refers[$canonized_headline]; - # Prepend the number to the heading text - - if( $doNumberHeadings || $doShowToc ) { - $tocline = $numbering . ' ' . $tocline; - - # Don't number the heading if it is the only one (looks silly) - if( $doNumberHeadings && count( $matches[3] ) > 1) { - # the two are different if the line contains a link - $headline=$numbering . ' ' . $headline; - } + # Don't number the heading if it is the only one (looks silly) + if( $doNumberHeadings && count( $matches[3] ) > 1) { + # the two are different if the line contains a link + $headline=$numbering . ' ' . $headline; } # Create the anchor for linking from the TOC to the section @@ -2545,7 +2574,7 @@ class Parser $anchor .= '_' . $refcount[$headlineCount]; } if( $doShowToc && ( !isset($wgMaxTocLevel) || $toclevel<$wgMaxTocLevel ) ) { - $toc .= $sk->tocLine($anchor,$tocline,$toclevel); + $toc .= $sk->tocLine($anchor, $tocline, $numbering, $toclevel); } if( $showEditLink && ( !$istemplate || $templatetitle !== "" ) ) { if ( empty( $head[$headlineCount] ) ) { @@ -2575,8 +2604,8 @@ class Parser if( $doShowToc ) { $toclines = $headlineCount; - $toc .= $sk->tocUnindent( $toclevel ); - $toc = $sk->tocTable( $toc ); + $toc .= $sk->tocUnindent( $toclevel - 1 ); + $toc = $sk->tocList( $toc ); } # split up and insert constructed headlines diff --git a/skins/amethyst/main.css b/skins/amethyst/main.css index d852168d5c..898910c782 100644 --- a/skins/amethyst/main.css +++ b/skins/amethyst/main.css @@ -329,20 +329,50 @@ table.small { font-size: 100% } ** content styles */ +/* IE/mac fixes */ #toc { - /* border:1px solid #2f6fab;*/ - padding:0.5em; - border:1px solid #aaaaaa; - background-color: #2F333B; + display: inline-table; +} +#toc h2, #toc div, #toc ul, #toc li { + float: left; + clear: left; +} +@media all { + #toc { + display: block; + text-align: center; + } + #toc * { + float: none!important; + } +} +/* end IE/mac fixes */ + +#toc { + border: 1px solid #aaa; + background-color: #2f333b; + padding: 0.5em; font-size: 95%; + float: left; +} +#toc h2 { + display: inline; + border: none; + padding: 0; + font-size: 100%; + font-weight: bold; +} +#toc ul { + list-style-type: none; + list-style-image: none; + margin-left: 0; + padding-left: 0; + text-align: left; +} +#toc ul ul { + margin: 0 0 0 2em; } -#toc .toctitle { background: #2A3C61;} -#toc .tocindent { margin-left: 2em; } -#toc .tocline { margin-bottom: 0px; } -#toc p { margin: 0 } -#toc .toctoggle { font-size: 94%; } -#toc .editsection { - margin-top: 0.7em; +#toc .toctoggle { font-size: 94%; } diff --git a/skins/chick/main.css b/skins/chick/main.css index 18d435f0eb..a7191b17ab 100755 --- a/skins/chick/main.css +++ b/skins/chick/main.css @@ -241,9 +241,7 @@ table.small { font-size: 100% } padding:5px; font-size: 95%; } -#toc .tocindent { margin-left: 2em; } -#toc .tocline { margin-bottom: 0px; } -#toc p { margin: 0 } +#toc ul { margin-left: 2em; } #toc .toctoggle { font-size: 94%; } #toc .editsection { margin-top: 0.7em; diff --git a/skins/common/common.css b/skins/common/common.css index 9e93d9952c..9878684662 100644 --- a/skins/common/common.css +++ b/skins/common/common.css @@ -100,21 +100,53 @@ img { border: none; } img.tex { vertical-align: middle; } span.texhtml { font-family: serif; } +/* IE/mac fixes */ +#toc { + display: inline-table; +} +#toc h2, #toc div, #toc ul, #toc li { + float: left; + clear: left; +} +@media all { + #toc { + display: block; + text-align: center; + } + #toc * { + float: none!important; + } +} +/* end IE/mac fixes */ #toc { - border: 1px solid #8888aa; - background-color: #f7f8ff; - padding: 5px; - font-size: 95%; -} -#toc .tocindent { margin-left: 2em; } -#toc .tocline { margin-bottom: 0px; } -#toc p { margin: 0 } -#toc .toctoggle { font-size: 95%; } -#toc .editsection { - margin-top: 0.7em; - font-size: 94%; + border: 1px solid #88a; + background-color: #f7f8ff; + padding: 5px; + font-size: 95%; + float: left; +} +#toc h2 { + display: inline; + border: none; + padding: 0; + font-size: 100%; + font-weight: bold; +} +#toc ul { + list-style-type: none; + list-style-image: none; + margin-left: 0; + padding-left: 0; + text-align: left; } +#toc ul ul { + margin: 0 0 0 2em; +} +#toc .toctoggle { + font-size: 95%; +} + .error { color: red; diff --git a/skins/common/wikibits.js b/skins/common/wikibits.js index 47ec3c324d..07b44ad0da 100644 --- a/skins/common/wikibits.js +++ b/skins/common/wikibits.js @@ -205,33 +205,55 @@ function guessTimezone(box) { document.preferences.wpHourDiff.value = fetchTimezone(); } -function showTocToggle(show,hide) { - if(document.getElementById) { - document.writeln('[' + - '' + - '' + hide + '' - + ']'); - } -} +function showTocToggle() { + if (document.createTextNode) { + // Uses DOM calls to avoid document.write + XHTML issues + var linkHolder = document.getElementById('toctitle') + if (!linkHolder) return; -function toggleToc() { - var tocmain = document.getElementById('toc'); - var toc = document.getElementById('tocinside'); - var showlink=document.getElementById('showlink'); - var hidelink=document.getElementById('hidelink'); - if(toc.style.display == 'none') { - toc.style.display = tocWas; - hidelink.style.display=''; - showlink.style.display='none'; - tocmain.className = ''; + var outerSpan = document.createElement('span'); + outerSpan.className = 'toctoggle'; + + var toggleLink = document.createElement('a'); + toggleLink.id = 'togglelink'; + toggleLink.className = 'internal'; + toggleLink.href = 'javascript:toggleToc()'; + toggleLink.appendChild(document.createTextNode(tocHideText)); + + outerSpan.appendChild(document.createTextNode('[')); + outerSpan.appendChild(toggleLink); + outerSpan.appendChild(document.createTextNode(']')); + linkHolder.appendChild(document.createTextNode(' ')); + linkHolder.appendChild(outerSpan); + + var cookiePos = document.cookie.indexOf("hidetoc="); + if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) + toggleToc(); + } +} + +function changeText(el, newText) { + // Safari work around + if (el.innerText) + el.innerText = newText; + else if (el.firstChild && el.firstChild.nodeValue) + el.firstChild.nodeValue = newText; +} + +function toggleToc() { + var toc = document.getElementById('toc').getElementsByTagName('ul')[0]; + var toggleLink = document.getElementById('togglelink') + + if(toc && toggleLink && toc.style.display == 'none') { + changeText(toggleLink, tocHideText); + toc.style.display = 'block'; + document.cookie = "hidetoc=0"; } else { - tocWas = toc.style.display; + changeText(toggleLink, tocShowText); toc.style.display = 'none'; - hidelink.style.display='none'; - showlink.style.display=''; - tocmain.className = 'tochidden'; + document.cookie = "hidetoc=1"; } } diff --git a/skins/monobook/main.css b/skins/monobook/main.css index f564ee4754..e3e4645b9e 100644 --- a/skins/monobook/main.css +++ b/skins/monobook/main.css @@ -282,21 +282,63 @@ table.small { font-size: 100% } ** content styles */ +/* IE/mac fixes */ #toc { - /*border:1px solid #2f6fab;*/ - border:1px solid #aaaaaa; - background-color:#f9f9f9; - padding:5px; + display: inline-table; +} +#toc div, #toc h2, #toc ul, #toc li, #toc a { + float: left; + clear: left; +} +#toc .toctoggle * { + float: none; + clear: none; +} +#toc h2 { + margin-right: .3em; +} +@media all { + #toc { + display: block; + text-align: center; + } + #toc * { + float: none!important; + } + #toc h2 { + margin-right: 0; + } +} +/* end IE/mac fixes */ + +#toc { + border: 1px solid #aaa; + background-color: #f9f9f9; + padding: 5px; font-size: 95%; + float: left; } -#toc .tocindent { margin-left: 2em; } -#toc .tocline { margin-bottom: 0px; } -#toc p { margin: 0 } -#toc .toctoggle { font-size: 94%; } -#toc .editsection { - margin-top: 0.7em; - font-size: 94%; +#toc h2 { + display: inline; + border: none; + padding: 0; + font-size: 100%; + font-weight: bold; +} +#toc ul { + list-style-type: none; + list-style-image: none; + margin-left: 0; + padding-left: 0; + text-align: left; +} +#toc ul ul { + margin: 0 0 0 2em; } +#toc .toctoggle { + font-size: 94%; + } + /* images */ div.floatright, table.floatright { diff --git a/skins/monobook/rtl.css b/skins/monobook/rtl.css index 77b44ac562..fe22ac2b97 100644 --- a/skins/monobook/rtl.css +++ b/skins/monobook/rtl.css @@ -200,3 +200,15 @@ fieldset.operaprefsection { margin-left: 0 !important; margin-right: 15em; } + +#toc { + float: right; +} + +#toc ul { + text-align: right; +} + +#toc ul ul { + margin: 0 2em 0 0; +} \ No newline at end of file -- 2.20.1