Complete TOC recode: proper HTML list; CSS for layout; JS recode; hidden TOC stays...
authorTom Gilder <tomgilder@users.mediawiki.org>
Sat, 15 Jan 2005 23:21:52 +0000 (23:21 +0000)
committerTom Gilder <tomgilder@users.mediawiki.org>
Sat, 15 Jan 2005 23:21:52 +0000 (23:21 +0000)
includes/Linker.php
includes/Parser.php
skins/amethyst/main.css
skins/chick/main.css
skins/common/common.css
skins/common/wikibits.js
skins/monobook/main.css
skins/monobook/rtl.css

index dc4bf14..7a725c4 100644 (file)
@@ -735,37 +735,39 @@ class Linker {
                return $comment;
        }
        
-       function tocIndent($level) {
-               return str_repeat( '<div class="tocindent">'."\n", $level>0 ? $level : 0 );
+       function tocIndent() {
+               return "\n<ul>";
        }
 
        function tocUnindent($level) {
-               return str_repeat( "</div>\n", $level>0 ? $level : 0 );
+               return "</li>\n" . str_repeat( "</ul>\n</li>\n", $level>0 ? $level : 0 );
        }
 
        /**
         * parameter level defines if we are on an indentation level
         */
-       function tocLine( $anchor, $tocline, $level ) {
-               $link = '<a href="#'.$anchor.'">'.$tocline.'</a><br />';
-               if($level) {
-                       return $link."\n";
-               } else {
-                       return '<div class="tocline">'.$link."</div>\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 = ' <script type="text/javascript">showTocToggle("' . addslashes( wfMsg('showtoc') ) . '","' . addslashes( wfMsg('hidetoc') ) . '")</script>';
-               return
-               '<table border="0" id="toc"><tr id="toctitle"><td align="center">'."\n".
-               '<b>'.wfMsgForContent('toc').'</b>' .
-               $hideline .
-               '</td></tr><tr id="tocinside"><td>'."\n".
-               $toc."</td></tr></table>\n";
+       function tocLine( $anchor, $tocline, $tocnumber, $level ) {
+               return "\n<li class='toclevel-$level'><a href=\"#" . $anchor . '"><span class="tocnumber">' . $tocnumber . '</span> <span class="toctext">' . $tocline . '</span></a>';
+       }
+
+       function tocLineEnd()
+       {
+               return "</li>\n";
+       }
+
+       function tocList($toc) {
+               return "<div id='toc'>\n" 
+                          . "<div id='toctitle'><h2>" . wfMsg('toc') . "</h2></div>\n"
+                    . $toc
+                                . "</ul>\n</div>\n"
+                                . '<script type="text/javascript">'
+                                . ' if (window.showTocToggle) {'
+                                . ' var tocShowText = "' . addslashes( wfMsg('showtoc') ) . '";'
+                                . ' var tocHideText = "' . addslashes( wfMsg('hidetoc') ) . '"; '
+                                . ' showTocToggle();'
+                                . ' } '
+                                . '</script>'
+                                . "<div class='visualClear'></div>\n";
        }
 
        /**
index a0f5a1f..e2407e7 100644 (file)
@@ -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("/<!--MWTEMPLATESECTION=([^&]+)&([^_]+)-->/", $headline, $mat)) {
                                $istemplate = 1;
@@ -2467,28 +2476,54 @@ class Parser
                                $headline = preg_replace("/<!--MWTEMPLATESECTION=([^&]+)&([^_]+)-->/", "", $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
index d852168..898910c 100644 (file)
@@ -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%;
 }
 
index 18d435f..a7191b1 100755 (executable)
@@ -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;
index 9e93d99..9878684 100644 (file)
@@ -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;
index 47ec3c3..07b44ad 100644 (file)
@@ -205,33 +205,55 @@ function guessTimezone(box) {
        document.preferences.wpHourDiff.value = fetchTimezone();
 }
 
-function showTocToggle(show,hide) {
-       if(document.getElementById) {
-               document.writeln('<span class=\'toctoggle\'>[<a href="javascript:toggleToc()" class="internal">' +
-               '<span id="showlink" style="display:none;">' + show + '</span>' +
-               '<span id="hidelink">' + hide + '</span>'
-               + '</a>]</span>');
-       }
-}
+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";
        }
 }
 
index f564ee4..e3e4645 100644 (file)
@@ -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 {
index 77b44ac..fe22ac2 100644 (file)
@@ -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