Don't use autodiscovery for core skins, move them to separate directories
authorBartosz Dziewoński <matma.rex@gmail.com>
Sun, 25 May 2014 21:58:05 +0000 (23:58 +0200)
committerOri.livneh <ori@wikimedia.org>
Tue, 10 Jun 2014 02:49:17 +0000 (02:49 +0000)
Step one on the way to killing the autodiscovery mechanism and making
the core skins less intertwined with core.

This only moves the files and fixes hardcoded paths throughout core.
Any further changes will be done in separate patch(es).

Moved files:
* skins/MonoBook.php → skins/monobook/MonoBook.php
* skins/Vector.php   → skins/vector/Vector.php

Bug: 65748
Change-Id: Ib4bdda5ed3c133fce0113eb17fa39950aa812f87

includes/AutoLoader.php
includes/Setup.php
includes/Skin.php
resources/Resources.php
skins/.gitignore
skins/MonoBook.php [deleted file]
skins/Vector.php [deleted file]
skins/monobook/MonoBook.php [new file with mode: 0644]
skins/vector/Vector.php [new file with mode: 0644]

index 05d4c1f..e7411a4 100644 (file)
@@ -1180,10 +1180,10 @@ $wgAutoloadLocalClasses = array(
        'MyLocalSettingsGenerator' => 'mw-config/overrides.php',
 
        # skins
-       'MonoBookTemplate' => 'skins/MonoBook.php',
-       'SkinMonoBook' => 'skins/MonoBook.php',
-       'SkinVector' => 'skins/Vector.php',
-       'VectorTemplate' => 'skins/Vector.php',
+       'MonoBookTemplate' => 'skins/monobook/MonoBook.php',
+       'SkinMonoBook' => 'skins/monobook/MonoBook.php',
+       'SkinVector' => 'skins/vector/Vector.php',
+       'VectorTemplate' => 'skins/vector/Vector.php',
 );
 
 class AutoLoader {
index a1bca22..51368b1 100644 (file)
@@ -601,6 +601,13 @@ $wgTitle = null;
 
 $wgDeferredUpdateList = array();
 
+// Enable default skins.
+// This is hacky and bad, but it will go away before 1.24 release (or so I hope).
+// These lines should eventually be placed in skins' meta definition files, and loaded by a
+// require_once for each skin file generated by the installer and placed in LocalSettings.php.
+$wgValidSkinNames['monobook'] = 'MonoBook';
+$wgValidSkinNames['vector'] = 'Vector';
+
 wfProfileOut( $fname . '-globals' );
 wfProfileIn( $fname . '-extensions' );
 
index 06f39b1..84dd3de 100644 (file)
@@ -63,6 +63,19 @@ abstract class Skin extends ContextSource {
 
                                        if ( preg_match( '/^([^.]*)\.php$/', $file, $matches ) ) {
                                                $aSkin = $matches[1];
+
+                                               // Explicitly disallow loading core skins via the autodiscovery mechanism.
+                                               //
+                                               // They should be loaded already (in a non-autodicovery way), but old files might still
+                                               // exist on the server because our MW version upgrade process is widely documented as
+                                               // requiring just copying over all files, without removing old ones.
+                                               //
+                                               // This is one of the reasons we should have never used autodiscovery in the first
+                                               // place. This hack can be safely removed when autodiscovery is gone.
+                                               if ( in_array( $aSkin, array( 'CologneBlue', 'Modern', 'MonoBook', 'Vector' ) ) ) {
+                                                       continue;
+                                               }
+
                                                $wgValidSkinNames[strtolower( $aSkin )] = $aSkin;
                                        }
                                }
@@ -184,7 +197,6 @@ abstract class Skin extends ContextSource {
                                # is no longer valid.
                                wfDebug( "Skin class does not exist: $className\n" );
                                $className = 'SkinVector';
-                               require_once "{$wgStyleDirectory}/Vector.php";
                        }
                }
                $skin = new $className( $key );
index d7df027..6926d13 100644 (file)
@@ -1227,7 +1227,7 @@ return array(
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.js',
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.css',
                'skinStyles' => array(
-                       'vector' => 'skins/vector/special.less',
+                       'vector' => 'skins/vector/special.less', // FIXME this should use $wgStyleDirectory
                ),
        ),
        'mediawiki.special.block' => array(
@@ -1276,7 +1276,7 @@ return array(
                'styles' => 'resources/src/mediawiki.special/mediawiki.special.preferences.css',
                'position' => 'top',
                'skinStyles' => array(
-                       'vector' => 'skins/vector/special.preferences.less',
+                       'vector' => 'skins/vector/special.preferences.less', // FIXME this should use $wgStyleDirectory
                ),
                'messages' => array(
                        'prefs-tabs-navigation-hint',
index 3ab8af2..a35670e 100644 (file)
@@ -7,5 +7,3 @@
 !vector/*
 
 *.php
-!MonoBook.php
-!Vector.php
diff --git a/skins/MonoBook.php b/skins/MonoBook.php
deleted file mode 100644 (file)
index 7385d0e..0000000
+++ /dev/null
@@ -1,411 +0,0 @@
-<?php
-/**
- * MonoBook nouveau.
- *
- * Translated from gwicke's previous TAL template version to remove
- * dependency on PHPTAL.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @todo document
- * @file
- * @ingroup Skins
- */
-
-if ( !defined( 'MEDIAWIKI' ) ) {
-       die( -1 );
-}
-
-/**
- * Inherit main code from SkinTemplate, set the CSS and template filter.
- * @todo document
- * @ingroup Skins
- */
-class SkinMonoBook extends SkinTemplate {
-       /** Using monobook. */
-       public $skinname = 'monobook';
-       public $stylename = 'monobook';
-       public $template = 'MonoBookTemplate';
-
-       /**
-        * @param OutputPage $out
-        */
-       function setupSkinUserCss( OutputPage $out ) {
-               parent::setupSkinUserCss( $out );
-
-               $out->addModuleStyles( array( 'mediawiki.skinning.interface', 'skins.monobook.styles' ) );
-
-               // TODO: Migrate all of these
-               $out->addStyle( 'monobook/IE60Fixes.css', 'screen', 'IE 6' );
-               $out->addStyle( 'monobook/IE70Fixes.css', 'screen', 'IE 7' );
-       }
-}
-
-/**
- * @todo document
- * @ingroup Skins
- */
-class MonoBookTemplate extends BaseTemplate {
-
-       /**
-        * Template filter callback for MonoBook skin.
-        * Takes an associative array of data set from a SkinTemplate-based
-        * class, and a wrapper for MediaWiki's localization database, and
-        * outputs a formatted page.
-        *
-        * @access private
-        */
-       function execute() {
-               // Suppress warnings to prevent notices about missing indexes in $this->data
-               wfSuppressWarnings();
-
-               $this->html( 'headelement' );
-               ?><div id="globalWrapper">
-               <div id="column-content">
-                       <div id="content" class="mw-body-primary" role="main">
-                               <a id="top"></a>
-                               <?php
-                               if ( $this->data['sitenotice'] ) {
-                                       ?>
-                                       <div id="siteNotice"><?php
-                                       $this->html( 'sitenotice' )
-                                       ?></div><?php
-                               }
-                               ?>
-
-                               <h1 id="firstHeading" class="firstHeading" lang="<?php
-                               $this->data['pageLanguage'] =
-                                       $this->getSkin()->getTitle()->getPageViewLanguage()->getHtmlCode();
-                               $this->text( 'pageLanguage' );
-                               ?>"><span dir="auto"><?php $this->html( 'title' ) ?></span></h1>
-
-                               <div id="bodyContent" class="mw-body">
-                                       <div id="siteSub"><?php $this->msg( 'tagline' ) ?></div>
-                                       <div id="contentSub"<?php
-                                       $this->html( 'userlangattributes' ) ?>><?php $this->html( 'subtitle' )
-                                               ?></div>
-                                       <?php if ( $this->data['undelete'] ) { ?>
-                                               <div id="contentSub2"><?php $this->html( 'undelete' ) ?></div>
-                                       <?php
-}
-                                       ?><?php
-                                       if ( $this->data['newtalk'] ) {
-                                               ?>
-                                               <div class="usermessage"><?php $this->html( 'newtalk' ) ?></div>
-                                       <?php
-                                       }
-                                       ?>
-                                       <div id="jump-to-nav" class="mw-jump"><?php
-                                               $this->msg( 'jumpto' )
-                                               ?> <a href="#column-one"><?php
-                                                       $this->msg( 'jumptonavigation' )
-                                                       ?></a><?php
-                                               $this->msg( 'comma-separator' )
-                                               ?><a href="#searchInput"><?php
-                                                       $this->msg( 'jumptosearch' )
-                                                       ?></a></div>
-
-                                       <!-- start content -->
-                                       <?php $this->html( 'bodytext' ) ?>
-                                       <?php
-                                       if ( $this->data['catlinks'] ) {
-                                               $this->html( 'catlinks' );
-                                       }
-                                       ?>
-                                       <!-- end content -->
-                                       <?php
-                                       if ( $this->data['dataAfterContent'] ) {
-                                               $this->html( 'dataAfterContent'
-                                               );
-                                       }
-                                       ?>
-                                       <div class="visualClear"></div>
-                               </div>
-                       </div>
-               </div>
-               <div id="column-one"<?php $this->html( 'userlangattributes' ) ?>>
-                       <h2><?php $this->msg( 'navigation-heading' ) ?></h2>
-                       <?php $this->cactions(); ?>
-                       <div class="portlet" id="p-personal" role="navigation">
-                               <h3><?php $this->msg( 'personaltools' ) ?></h3>
-
-                               <div class="pBody">
-                                       <ul<?php $this->html( 'userlangattributes' ) ?>>
-                                               <?php foreach ( $this->getPersonalTools() as $key => $item ) { ?>
-                                                       <?php echo $this->makeListItem( $key, $item ); ?>
-
-                                               <?php
-}
-                                               ?>
-                                       </ul>
-                               </div>
-                       </div>
-                       <div class="portlet" id="p-logo" role="banner">
-                               <?php
-                               echo Html::element( 'a', array(
-                                               'href' => $this->data['nav_urls']['mainpage']['href'],
-                                               'style' => "background-image: url({$this->data['logopath']});" )
-                                       + Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ); ?>
-
-                       </div>
-                       <?php
-                       $this->renderPortals( $this->data['sidebar'] );
-                       ?>
-               </div><!-- end of the left (by default at least) column -->
-               <div class="visualClear"></div>
-               <?php
-               $validFooterIcons = $this->getFooterIcons( "icononly" );
-               $validFooterLinks = $this->getFooterLinks( "flat" ); // Additional footer links
-
-               if ( count( $validFooterIcons ) + count( $validFooterLinks ) > 0 ) {
-                       ?>
-                       <div id="footer" role="contentinfo"<?php $this->html( 'userlangattributes' ) ?>>
-                       <?php
-                       $footerEnd = '</div>';
-               } else {
-                       $footerEnd = '';
-               }
-
-               foreach ( $validFooterIcons as $blockName => $footerIcons ) {
-                       ?>
-                       <div id="f-<?php echo htmlspecialchars( $blockName ); ?>ico">
-                               <?php foreach ( $footerIcons as $icon ) { ?>
-                                       <?php echo $this->getSkin()->makeFooterIcon( $icon ); ?>
-
-                               <?php
-}
-                               ?>
-                       </div>
-               <?php
-               }
-
-               if ( count( $validFooterLinks ) > 0 ) {
-                       ?>
-                       <ul id="f-list">
-                               <?php
-                               foreach ( $validFooterLinks as $aLink ) {
-                                       ?>
-                                       <li id="<?php echo $aLink ?>"><?php $this->html( $aLink ) ?></li>
-                               <?php
-                               }
-                               ?>
-                       </ul>
-               <?php
-               }
-
-               echo $footerEnd;
-               ?>
-
-               </div>
-               <?php
-               $this->printTrail();
-               echo Html::closeElement( 'body' );
-               echo Html::closeElement( 'html' );
-               wfRestoreWarnings();
-       } // end of execute() method
-
-       /*************************************************************************************************/
-
-       /**
-        * @param array $sidebar
-        */
-       protected function renderPortals( $sidebar ) {
-               if ( !isset( $sidebar['SEARCH'] ) ) {
-                       $sidebar['SEARCH'] = true;
-               }
-               if ( !isset( $sidebar['TOOLBOX'] ) ) {
-                       $sidebar['TOOLBOX'] = true;
-               }
-               if ( !isset( $sidebar['LANGUAGES'] ) ) {
-                       $sidebar['LANGUAGES'] = true;
-               }
-
-               foreach ( $sidebar as $boxName => $content ) {
-                       if ( $content === false ) {
-                               continue;
-                       }
-
-                       if ( $boxName == 'SEARCH' ) {
-                               $this->searchBox();
-                       } elseif ( $boxName == 'TOOLBOX' ) {
-                               $this->toolbox();
-                       } elseif ( $boxName == 'LANGUAGES' ) {
-                               $this->languageBox();
-                       } else {
-                               $this->customBox( $boxName, $content );
-                       }
-               }
-       }
-
-       function searchBox() {
-               global $wgUseTwoButtonsSearchForm;
-               ?>
-               <div id="p-search" class="portlet" role="search">
-                       <h3><label for="searchInput"><?php $this->msg( 'search' ) ?></label></h3>
-
-                       <div id="searchBody" class="pBody">
-                               <form action="<?php $this->text( 'wgScript' ) ?>" id="searchform">
-                                       <input type='hidden' name="title" value="<?php $this->text( 'searchtitle' ) ?>"/>
-                                       <?php echo $this->makeSearchInput( array( "id" => "searchInput" ) ); ?>
-
-                                       <?php
-                                       echo $this->makeSearchButton(
-                                               "go",
-                                               array( "id" => "searchGoButton", "class" => "searchButton" )
-                                       );
-
-                                       if ( $wgUseTwoButtonsSearchForm ) {
-                                               ?>&#160;
-                                               <?php echo $this->makeSearchButton(
-                                                       "fulltext",
-                                                       array( "id" => "mw-searchButton", "class" => "searchButton" )
-                                               );
-                                       } else {
-                                               ?>
-
-                                               <div><a href="<?php
-                                               $this->text( 'searchaction' )
-                                               ?>" rel="search"><?php $this->msg( 'powersearch-legend' ) ?></a></div><?php
-                                       } ?>
-
-                               </form>
-
-                               <?php $this->renderAfterPortlet( 'search' ); ?>
-                       </div>
-               </div>
-       <?php
-       }
-
-       /**
-        * Prints the cactions bar.
-        * Shared between MonoBook and Modern
-        */
-       function cactions() {
-               ?>
-               <div id="p-cactions" class="portlet" role="navigation">
-                       <h3><?php $this->msg( 'views' ) ?></h3>
-
-                       <div class="pBody">
-                               <ul><?php
-                                       foreach ( $this->data['content_actions'] as $key => $tab ) {
-                                               echo '
-                               ' . $this->makeListItem( $key, $tab );
-                                       } ?>
-
-                               </ul>
-                               <?php $this->renderAfterPortlet( 'cactions' ); ?>
-                       </div>
-               </div>
-       <?php
-       }
-
-       /*************************************************************************************************/
-       function toolbox() {
-               ?>
-               <div class="portlet" id="p-tb" role="navigation">
-                       <h3><?php $this->msg( 'toolbox' ) ?></h3>
-
-                       <div class="pBody">
-                               <ul>
-                                       <?php
-                                       foreach ( $this->getToolbox() as $key => $tbitem ) {
-                                               ?>
-                                               <?php echo $this->makeListItem( $key, $tbitem ); ?>
-
-                                       <?php
-                                       }
-                                       wfRunHooks( 'MonoBookTemplateToolboxEnd', array( &$this ) );
-                                       wfRunHooks( 'SkinTemplateToolboxEnd', array( &$this, true ) );
-                                       ?>
-                               </ul>
-                               <?php $this->renderAfterPortlet( 'tb' ); ?>
-                       </div>
-               </div>
-       <?php
-       }
-
-       /*************************************************************************************************/
-       function languageBox() {
-               if ( $this->data['language_urls'] !== false ) {
-                       ?>
-                       <div id="p-lang" class="portlet" role="navigation">
-                               <h3<?php $this->html( 'userlangattributes' ) ?>><?php $this->msg( 'otherlanguages' ) ?></h3>
-
-                               <div class="pBody">
-                                       <ul>
-                                               <?php foreach ( $this->data['language_urls'] as $key => $langlink ) { ?>
-                                                       <?php echo $this->makeListItem( $key, $langlink ); ?>
-
-                                               <?php
-}
-                                               ?>
-                                       </ul>
-
-                                       <?php $this->renderAfterPortlet( 'lang' ); ?>
-                               </div>
-                       </div>
-               <?php
-               }
-       }
-
-       /*************************************************************************************************/
-       /**
-        * @param string $bar
-        * @param array|string $cont
-        */
-       function customBox( $bar, $cont ) {
-               $portletAttribs = array(
-                       'class' => 'generated-sidebar portlet',
-                       'id' => Sanitizer::escapeId( "p-$bar" ),
-                       'role' => 'navigation'
-               );
-
-               $tooltip = Linker::titleAttrib( "p-$bar" );
-               if ( $tooltip !== false ) {
-                       $portletAttribs['title'] = $tooltip;
-               }
-               echo '  ' . Html::openElement( 'div', $portletAttribs );
-               $msgObj = wfMessage( $bar );
-               ?>
-
-               <h3><?php echo htmlspecialchars( $msgObj->exists() ? $msgObj->text() : $bar ); ?></h3>
-               <div class='pBody'>
-                       <?php
-                       if ( is_array( $cont ) ) {
-                               ?>
-                               <ul>
-                                       <?php
-                                       foreach ( $cont as $key => $val ) {
-                                               ?>
-                                               <?php echo $this->makeListItem( $key, $val ); ?>
-
-                                       <?php
-                                       }
-                                       ?>
-                               </ul>
-                       <?php
-                       } else {
-                               # allow raw HTML block to be defined by extensions
-                               print $cont;
-                       }
-
-                       $this->renderAfterPortlet( $bar );
-                       ?>
-               </div>
-               </div>
-       <?php
-       }
-} // end of class
diff --git a/skins/Vector.php b/skins/Vector.php
deleted file mode 100644 (file)
index 9544d55..0000000
+++ /dev/null
@@ -1,661 +0,0 @@
-<?php
-/**
- * Vector - Modern version of MonoBook with fresh look and many usability
- * improvements.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @todo document
- * @file
- * @ingroup Skins
- */
-
-if ( !defined( 'MEDIAWIKI' ) ) {
-       die( -1 );
-}
-
-/**
- * SkinTemplate class for Vector skin
- * @ingroup Skins
- */
-class SkinVector extends SkinTemplate {
-       public $skinname = 'vector';
-       public $stylename = 'vector';
-       public $template = 'VectorTemplate';
-
-       protected static $bodyClasses = array( 'vector-animateLayout' );
-
-       /**
-        * Initializes output page and sets up skin-specific parameters
-        * @param OutputPage $out Object to initialize
-        */
-       public function initPage( OutputPage $out ) {
-               global $wgLocalStylePath;
-
-               parent::initPage( $out );
-
-               // Append CSS which includes IE only behavior fixes for hover support -
-               // this is better than including this in a CSS file since it doesn't
-               // wait for the CSS file to load before fetching the HTC file.
-               $min = $this->getRequest()->getFuzzyBool( 'debug' ) ? '' : '.min';
-               $out->addHeadItem( 'csshover',
-                       '<!--[if lt IE 7]><style type="text/css">body{behavior:url("' .
-                               htmlspecialchars( $wgLocalStylePath ) .
-                               "/{$this->stylename}/csshover{$min}.htc\")}</style><![endif]-->"
-               );
-
-               $out->addModules( array( 'skins.vector.js' ) );
-       }
-
-       /**
-        * Loads skin and user CSS files.
-        * @param OutputPage $out
-        */
-       function setupSkinUserCss( OutputPage $out ) {
-               parent::setupSkinUserCss( $out );
-
-               $styles = array( 'mediawiki.skinning.interface', 'skins.vector.styles' );
-               wfRunHooks( 'SkinVectorStyleModules', array( $this, &$styles ) );
-               $out->addModuleStyles( $styles );
-       }
-
-       /**
-        * Adds classes to the body element.
-        *
-        * @param OutputPage $out
-        * @param array &$bodyAttrs Array of attributes that will be set on the body element
-        */
-       function addToBodyAttributes( $out, &$bodyAttrs ) {
-               if ( isset( $bodyAttrs['class'] ) && strlen( $bodyAttrs['class'] ) > 0 ) {
-                       $bodyAttrs['class'] .= ' ' . implode( ' ', static::$bodyClasses );
-               } else {
-                       $bodyAttrs['class'] = implode( ' ', static::$bodyClasses );
-               }
-       }
-}
-
-/**
- * QuickTemplate class for Vector skin
- * @ingroup Skins
- */
-class VectorTemplate extends BaseTemplate {
-       /* Functions */
-
-       /**
-        * Outputs the entire contents of the (X)HTML page
-        */
-       public function execute() {
-               global $wgVectorUseIconWatch;
-
-               // Build additional attributes for navigation urls
-               $nav = $this->data['content_navigation'];
-
-               if ( $wgVectorUseIconWatch ) {
-                       $mode = $this->getSkin()->getUser()->isWatched( $this->getSkin()->getRelevantTitle() )
-                               ? 'unwatch'
-                               : 'watch';
-
-                       if ( isset( $nav['actions'][$mode] ) ) {
-                               $nav['views'][$mode] = $nav['actions'][$mode];
-                               $nav['views'][$mode]['class'] = rtrim( 'icon ' . $nav['views'][$mode]['class'], ' ' );
-                               $nav['views'][$mode]['primary'] = true;
-                               unset( $nav['actions'][$mode] );
-                       }
-               }
-
-               $xmlID = '';
-               foreach ( $nav as $section => $links ) {
-                       foreach ( $links as $key => $link ) {
-                               if ( $section == 'views' && !( isset( $link['primary'] ) && $link['primary'] ) ) {
-                                       $link['class'] = rtrim( 'collapsible ' . $link['class'], ' ' );
-                               }
-
-                               $xmlID = isset( $link['id'] ) ? $link['id'] : 'ca-' . $xmlID;
-                               $nav[$section][$key]['attributes'] =
-                                       ' id="' . Sanitizer::escapeId( $xmlID ) . '"';
-                               if ( $link['class'] ) {
-                                       $nav[$section][$key]['attributes'] .=
-                                               ' class="' . htmlspecialchars( $link['class'] ) . '"';
-                                       unset( $nav[$section][$key]['class'] );
-                               }
-                               if ( isset( $link['tooltiponly'] ) && $link['tooltiponly'] ) {
-                                       $nav[$section][$key]['key'] =
-                                               Linker::tooltip( $xmlID );
-                               } else {
-                                       $nav[$section][$key]['key'] =
-                                               Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( $xmlID ) );
-                               }
-                       }
-               }
-               $this->data['namespace_urls'] = $nav['namespaces'];
-               $this->data['view_urls'] = $nav['views'];
-               $this->data['action_urls'] = $nav['actions'];
-               $this->data['variant_urls'] = $nav['variants'];
-
-               // Reverse horizontally rendered navigation elements
-               if ( $this->data['rtl'] ) {
-                       $this->data['view_urls'] =
-                               array_reverse( $this->data['view_urls'] );
-                       $this->data['namespace_urls'] =
-                               array_reverse( $this->data['namespace_urls'] );
-                       $this->data['personal_urls'] =
-                               array_reverse( $this->data['personal_urls'] );
-               }
-               // Output HTML Page
-               $this->html( 'headelement' );
-               ?>
-               <div id="mw-page-base" class="noprint"></div>
-               <div id="mw-head-base" class="noprint"></div>
-               <div id="content" class="mw-body" role="main">
-                       <a id="top"></a>
-
-                       <div id="mw-js-message" style="display:none;"<?php $this->html( 'userlangattributes' ) ?>></div>
-                       <?php
-                       if ( $this->data['sitenotice'] ) {
-                               ?>
-                               <div id="siteNotice"><?php $this->html( 'sitenotice' ) ?></div>
-                       <?php
-                       }
-                       ?>
-                       <h1 id="firstHeading" class="firstHeading" lang="<?php
-                       $this->data['pageLanguage'] =
-                               $this->getSkin()->getTitle()->getPageViewLanguage()->getHtmlCode();
-                       $this->text( 'pageLanguage' );
-                       ?>"><span dir="auto"><?php $this->html( 'title' ) ?></span></h1>
-                       <?php $this->html( 'prebodyhtml' ) ?>
-                       <div id="bodyContent" class="mw-body-content">
-                               <?php
-                               if ( $this->data['isarticle'] ) {
-                                       ?>
-                                       <div id="siteSub"><?php $this->msg( 'tagline' ) ?></div>
-                               <?php
-                               }
-                               ?>
-                               <div id="contentSub"<?php
-                               $this->html( 'userlangattributes' )
-                               ?>><?php $this->html( 'subtitle' ) ?></div>
-                               <?php
-                               if ( $this->data['undelete'] ) {
-                                       ?>
-                                       <div id="contentSub2"><?php $this->html( 'undelete' ) ?></div>
-                               <?php
-                               }
-                               ?>
-                               <?php
-                               if ( $this->data['newtalk'] ) {
-                                       ?>
-                                       <div class="usermessage"><?php $this->html( 'newtalk' ) ?></div>
-                               <?php
-                               }
-                               ?>
-                               <div id="jump-to-nav" class="mw-jump">
-                                       <?php $this->msg( 'jumpto' ) ?>
-                                       <a href="#mw-navigation"><?php
-                                               $this->msg( 'jumptonavigation' )
-                                               ?></a><?php
-                                       $this->msg( 'comma-separator' )
-                                       ?>
-                                       <a href="#p-search"><?php $this->msg( 'jumptosearch' ) ?></a>
-                               </div>
-                               <?php $this->html( 'bodycontent' ) ?>
-                               <?php
-                               if ( $this->data['printfooter'] ) {
-                                       ?>
-                                       <div class="printfooter">
-                                               <?php $this->html( 'printfooter' ); ?>
-                                       </div>
-                               <?php
-                               }
-                               ?>
-                               <?php
-                               if ( $this->data['catlinks'] ) {
-                                       ?>
-                                       <?php
-                                       $this->html( 'catlinks' );
-                                       ?>
-                               <?php
-                               }
-                               ?>
-                               <?php
-                               if ( $this->data['dataAfterContent'] ) {
-                                       ?>
-                                       <?php
-                                       $this->html( 'dataAfterContent' );
-                                       ?>
-                               <?php
-                               }
-                               ?>
-                               <div class="visualClear"></div>
-                               <?php $this->html( 'debughtml' ); ?>
-                       </div>
-               </div>
-               <div id="mw-navigation">
-                       <h2><?php $this->msg( 'navigation-heading' ) ?></h2>
-
-                       <div id="mw-head">
-                               <?php $this->renderNavigation( 'PERSONAL' ); ?>
-                               <div id="left-navigation">
-                                       <?php $this->renderNavigation( array( 'NAMESPACES', 'VARIANTS' ) ); ?>
-                               </div>
-                               <div id="right-navigation">
-                                       <?php $this->renderNavigation( array( 'VIEWS', 'ACTIONS', 'SEARCH' ) ); ?>
-                               </div>
-                       </div>
-                       <div id="mw-panel">
-                               <div id="p-logo" role="banner"><a style="background-image: url(<?php
-                                       $this->text( 'logopath' )
-                                       ?>);" href="<?php
-                                       echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] )
-                                       ?>" <?php
-                                       echo Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) )
-                                       ?>></a></div>
-                               <?php $this->renderPortals( $this->data['sidebar'] ); ?>
-                       </div>
-               </div>
-               <div id="footer" role="contentinfo"<?php $this->html( 'userlangattributes' ) ?>>
-                       <?php
-                       foreach ( $this->getFooterLinks() as $category => $links ) {
-                               ?>
-                               <ul id="footer-<?php
-                               echo $category
-                               ?>">
-                                       <?php
-                                       foreach ( $links as $link ) {
-                                               ?>
-                                               <li id="footer-<?php
-                                               echo $category
-                                               ?>-<?php
-                                               echo $link
-                                               ?>"><?php
-                                                       $this->html( $link )
-                                                       ?></li>
-                                       <?php
-                                       }
-                                       ?>
-                               </ul>
-                       <?php
-                       }
-                       ?>
-                       <?php $footericons = $this->getFooterIcons( "icononly" );
-                       if ( count( $footericons ) > 0 ) {
-                               ?>
-                               <ul id="footer-icons" class="noprint">
-                                       <?php
-                                       foreach ( $footericons as $blockName => $footerIcons ) {
-                                               ?>
-                                               <li id="footer-<?php
-                                               echo htmlspecialchars( $blockName ); ?>ico">
-                                                       <?php
-                                                       foreach ( $footerIcons as $icon ) {
-                                                               ?>
-                                                               <?php
-                                                               echo $this->getSkin()->makeFooterIcon( $icon );
-                                                               ?>
-
-                                                       <?php
-                                                       }
-                                                       ?>
-                                               </li>
-                                       <?php
-                                       }
-                                       ?>
-                               </ul>
-                       <?php
-                       }
-                       ?>
-                       <div style="clear:both"></div>
-               </div>
-               <?php $this->printTrail(); ?>
-
-       </body>
-</html>
-       <?php
-       }
-
-       /**
-        * Render a series of portals
-        *
-        * @param array $portals
-        */
-       protected function renderPortals( $portals ) {
-               // Force the rendering of the following portals
-               if ( !isset( $portals['SEARCH'] ) ) {
-                       $portals['SEARCH'] = true;
-               }
-               if ( !isset( $portals['TOOLBOX'] ) ) {
-                       $portals['TOOLBOX'] = true;
-               }
-               if ( !isset( $portals['LANGUAGES'] ) ) {
-                       $portals['LANGUAGES'] = true;
-               }
-               // Render portals
-               foreach ( $portals as $name => $content ) {
-                       if ( $content === false ) {
-                               continue;
-                       }
-
-                       switch ( $name ) {
-                               case 'SEARCH':
-                                       break;
-                               case 'TOOLBOX':
-                                       $this->renderPortal( 'tb', $this->getToolbox(), 'toolbox', 'SkinTemplateToolboxEnd' );
-                                       break;
-                               case 'LANGUAGES':
-                                       if ( $this->data['language_urls'] !== false ) {
-                                               $this->renderPortal( 'lang', $this->data['language_urls'], 'otherlanguages' );
-                                       }
-                                       break;
-                               default:
-                                       $this->renderPortal( $name, $content );
-                                       break;
-                       }
-               }
-       }
-
-       /**
-        * @param string $name
-        * @param array $content
-        * @param null|string $msg
-        * @param null|string|array $hook
-        */
-       protected function renderPortal( $name, $content, $msg = null, $hook = null ) {
-               if ( $msg === null ) {
-                       $msg = $name;
-               }
-               $msgObj = wfMessage( $msg );
-               ?>
-               <div class="portal" role="navigation" id='<?php
-               echo Sanitizer::escapeId( "p-$name" )
-               ?>'<?php
-               echo Linker::tooltip( 'p-' . $name )
-               ?> aria-labelledby='<?php echo Sanitizer::escapeId( "p-$name-label" ) ?>'>
-                       <h3<?php
-                       $this->html( 'userlangattributes' )
-                       ?> id='<?php
-                       echo Sanitizer::escapeId( "p-$name-label" )
-                       ?>'><?php
-                               echo htmlspecialchars( $msgObj->exists() ? $msgObj->text() : $msg );
-                               ?></h3>
-
-                       <div class="body">
-                               <?php
-                               if ( is_array( $content ) ) {
-                                       ?>
-                                       <ul>
-                                               <?php
-                                               foreach ( $content as $key => $val ) {
-                                                       ?>
-                                                       <?php echo $this->makeListItem( $key, $val ); ?>
-
-                                               <?php
-                                               }
-                                               if ( $hook !== null ) {
-                                                       wfRunHooks( $hook, array( &$this, true ) );
-                                               }
-                                               ?>
-                                       </ul>
-                               <?php
-                               } else {
-                                       ?>
-                                       <?php
-                                       echo $content; /* Allow raw HTML block to be defined by extensions */
-                               }
-
-                               $this->renderAfterPortlet( $name );
-                               ?>
-                       </div>
-               </div>
-       <?php
-       }
-
-       /**
-        * Render one or more navigations elements by name, automatically reveresed
-        * when UI is in RTL mode
-        *
-        * @param array $elements
-        */
-       protected function renderNavigation( $elements ) {
-               global $wgVectorUseSimpleSearch;
-
-               // If only one element was given, wrap it in an array, allowing more
-               // flexible arguments
-               if ( !is_array( $elements ) ) {
-                       $elements = array( $elements );
-                       // If there's a series of elements, reverse them when in RTL mode
-               } elseif ( $this->data['rtl'] ) {
-                       $elements = array_reverse( $elements );
-               }
-               // Render elements
-               foreach ( $elements as $name => $element ) {
-                       switch ( $element ) {
-                               case 'NAMESPACES':
-                                       ?>
-                                       <div id="p-namespaces" role="navigation" class="vectorTabs<?php
-                                       if ( count( $this->data['namespace_urls'] ) == 0 ) {
-                                               echo ' emptyPortlet';
-                                       }
-                                       ?>" aria-labelledby="p-namespaces-label">
-                                               <h3 id="p-namespaces-label"><?php $this->msg( 'namespaces' ) ?></h3>
-                                               <ul<?php $this->html( 'userlangattributes' ) ?>>
-                                                       <?php
-                                                       foreach ( $this->data['namespace_urls'] as $link ) {
-                                                               ?>
-                                                               <li <?php
-                                                               echo $link['attributes']
-                                                               ?>><span><a href="<?php
-                                                                               echo htmlspecialchars( $link['href'] )
-                                                                               ?>" <?php
-                                                                               echo $link['key']
-                                                                               ?>><?php
-                                                                                       echo htmlspecialchars( $link['text'] )
-                                                                                       ?></a></span></li>
-                                                       <?php
-                                                       }
-                                                       ?>
-                                               </ul>
-                                       </div>
-                                       <?php
-                                       break;
-                               case 'VARIANTS':
-                                       ?>
-                                       <div id="p-variants" role="navigation" class="vectorMenu<?php
-                                       if ( count( $this->data['variant_urls'] ) == 0 ) {
-                                               echo ' emptyPortlet';
-                                       }
-                                       ?>" aria-labelledby="p-variants-label">
-                                               <h3 id="mw-vector-current-variant">
-                                                       <?php
-                                                       foreach ( $this->data['variant_urls'] as $link ) {
-                                                               ?>
-                                                               <?php
-                                                               if ( stripos( $link['attributes'], 'selected' ) !== false ) {
-                                                                       ?>
-                                                                       <?php
-                                                                       echo htmlspecialchars( $link['text'] )
-                                                                       ?>
-                                                               <?php
-                                                               }
-                                                               ?>
-                                                       <?php
-                                                       }
-                                                       ?>
-                                               </h3>
-
-                                               <h3 id="p-variants-label"><span><?php $this->msg( 'variants' ) ?></span><a href="#"></a></h3>
-
-                                               <div class="menu">
-                                                       <ul>
-                                                               <?php
-                                                               foreach ( $this->data['variant_urls'] as $link ) {
-                                                                       ?>
-                                                                       <li<?php
-                                                                       echo $link['attributes']
-                                                                       ?>><a href="<?php
-                                                                               echo htmlspecialchars( $link['href'] )
-                                                                               ?>" lang="<?php
-                                                                               echo htmlspecialchars( $link['lang'] )
-                                                                               ?>" hreflang="<?php
-                                                                               echo htmlspecialchars( $link['hreflang'] )
-                                                                               ?>" <?php
-                                                                               echo $link['key']
-                                                                               ?>><?php
-                                                                                       echo htmlspecialchars( $link['text'] )
-                                                                                       ?></a></li>
-                                                               <?php
-                                                               }
-                                                               ?>
-                                                       </ul>
-                                               </div>
-                                       </div>
-                                       <?php
-                                       break;
-                               case 'VIEWS':
-                                       ?>
-                                       <div id="p-views" role="navigation" class="vectorTabs<?php
-                                       if ( count( $this->data['view_urls'] ) == 0 ) {
-                                               echo ' emptyPortlet';
-                                       }
-                                       ?>" aria-labelledby="p-views-label">
-                                               <h3 id="p-views-label"><?php $this->msg( 'views' ) ?></h3>
-                                               <ul<?php
-                                               $this->html( 'userlangattributes' )
-                                               ?>>
-                                                       <?php
-                                                       foreach ( $this->data['view_urls'] as $link ) {
-                                                               ?>
-                                                               <li<?php
-                                                               echo $link['attributes']
-                                                               ?>><span><a href="<?php
-                                                                               echo htmlspecialchars( $link['href'] )
-                                                                               ?>" <?php
-                                                                               echo $link['key']
-                                                                               ?>><?php
-                                                                                       // $link['text'] can be undefined - bug 27764
-                                                                                       if ( array_key_exists( 'text', $link ) ) {
-                                                                                               echo array_key_exists( 'img', $link )
-                                                                                                       ? '<img src="' . $link['img'] . '" alt="' . $link['text'] . '" />'
-                                                                                                       : htmlspecialchars( $link['text'] );
-                                                                                       }
-                                                                                       ?></a></span></li>
-                                                       <?php
-                                                       }
-                                                       ?>
-                                               </ul>
-                                       </div>
-                                       <?php
-                                       break;
-                               case 'ACTIONS':
-                                       ?>
-                                       <div id="p-cactions" role="navigation" class="vectorMenu<?php
-                                       if ( count( $this->data['action_urls'] ) == 0 ) {
-                                               echo ' emptyPortlet';
-                                       }
-                                       ?>" aria-labelledby="p-cactions-label">
-                                               <h3 id="p-cactions-label"><span><?php $this->msg( 'vector-more-actions' ) ?></span><a href="#"></a></h3>
-
-                                               <div class="menu">
-                                                       <ul<?php $this->html( 'userlangattributes' ) ?>>
-                                                               <?php
-                                                               foreach ( $this->data['action_urls'] as $link ) {
-                                                                       ?>
-                                                                       <li<?php
-                                                                       echo $link['attributes']
-                                                                       ?>>
-                                                                               <a href="<?php
-                                                                               echo htmlspecialchars( $link['href'] )
-                                                                               ?>" <?php
-                                                                               echo $link['key'] ?>><?php echo htmlspecialchars( $link['text'] )
-                                                                                       ?></a>
-                                                                       </li>
-                                                               <?php
-                                                               }
-                                                               ?>
-                                                       </ul>
-                                               </div>
-                                       </div>
-                                       <?php
-                                       break;
-                               case 'PERSONAL':
-                                       ?>
-                                       <div id="p-personal" role="navigation" class="<?php
-                                       if ( count( $this->data['personal_urls'] ) == 0 ) {
-                                               echo ' emptyPortlet';
-                                       }
-                                       ?>" aria-labelledby="p-personal-label">
-                                               <h3 id="p-personal-label"><?php $this->msg( 'personaltools' ) ?></h3>
-                                               <ul<?php $this->html( 'userlangattributes' ) ?>>
-                                                       <?php
-                                                       $personalTools = $this->getPersonalTools();
-                                                       foreach ( $personalTools as $key => $item ) {
-                                                               echo $this->makeListItem( $key, $item );
-                                                       }
-                                                       ?>
-                                               </ul>
-                                       </div>
-                                       <?php
-                                       break;
-                               case 'SEARCH':
-                                       ?>
-                                       <div id="p-search" role="search">
-                                               <h3<?php $this->html( 'userlangattributes' ) ?>>
-                                                       <label for="searchInput"><?php $this->msg( 'search' ) ?></label>
-                                               </h3>
-
-                                               <form action="<?php $this->text( 'wgScript' ) ?>" id="searchform">
-                                                       <?php
-                                                       if ($wgVectorUseSimpleSearch) {
-                                                       ?>
-                                                       <div id="simpleSearch">
-                                                               <?php
-                                                       } else {
-                                                       ?>
-                                                               <div>
-                                                                       <?php
-                                                       }
-                                                       ?>
-                                                       <?php
-                                                       echo $this->makeSearchInput( array( 'id' => 'searchInput' ) );
-                                                       echo Html::hidden( 'title', $this->get( 'searchtitle' ) );
-                                                       // We construct two buttons (for 'go' and 'fulltext' search modes),
-                                                       // but only one will be visible and actionable at a time (they are
-                                                       // overlaid on top of each other in CSS).
-                                                       // * Browsers will use the 'fulltext' one by default (as it's the
-                                                       //   first in tree-order), which is desirable when they are unable
-                                                       //   to show search suggestions (either due to being broken or
-                                                       //   having JavaScript turned off).
-                                                       // * The mediawiki.searchSuggest module, after doing tests for the
-                                                       //   broken browsers, removes the 'fulltext' button and handles
-                                                       //   'fulltext' search itself; this will reveal the 'go' button and
-                                                       //   cause it to be used.
-                                                       echo $this->makeSearchButton(
-                                                               'fulltext',
-                                                               array( 'id' => 'mw-searchButton', 'class' => 'searchButton mw-fallbackSearchButton' )
-                                                       );
-                                                       echo $this->makeSearchButton(
-                                                               'go',
-                                                               array( 'id' => 'searchButton', 'class' => 'searchButton' )
-                                                       );
-                                                       ?>
-                                                               </div>
-                                               </form>
-                                       </div>
-                                       <?php
-
-                                       break;
-                       }
-               }
-       }
-}
diff --git a/skins/monobook/MonoBook.php b/skins/monobook/MonoBook.php
new file mode 100644 (file)
index 0000000..7385d0e
--- /dev/null
@@ -0,0 +1,411 @@
+<?php
+/**
+ * MonoBook nouveau.
+ *
+ * Translated from gwicke's previous TAL template version to remove
+ * dependency on PHPTAL.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @todo document
+ * @file
+ * @ingroup Skins
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+       die( -1 );
+}
+
+/**
+ * Inherit main code from SkinTemplate, set the CSS and template filter.
+ * @todo document
+ * @ingroup Skins
+ */
+class SkinMonoBook extends SkinTemplate {
+       /** Using monobook. */
+       public $skinname = 'monobook';
+       public $stylename = 'monobook';
+       public $template = 'MonoBookTemplate';
+
+       /**
+        * @param OutputPage $out
+        */
+       function setupSkinUserCss( OutputPage $out ) {
+               parent::setupSkinUserCss( $out );
+
+               $out->addModuleStyles( array( 'mediawiki.skinning.interface', 'skins.monobook.styles' ) );
+
+               // TODO: Migrate all of these
+               $out->addStyle( 'monobook/IE60Fixes.css', 'screen', 'IE 6' );
+               $out->addStyle( 'monobook/IE70Fixes.css', 'screen', 'IE 7' );
+       }
+}
+
+/**
+ * @todo document
+ * @ingroup Skins
+ */
+class MonoBookTemplate extends BaseTemplate {
+
+       /**
+        * Template filter callback for MonoBook skin.
+        * Takes an associative array of data set from a SkinTemplate-based
+        * class, and a wrapper for MediaWiki's localization database, and
+        * outputs a formatted page.
+        *
+        * @access private
+        */
+       function execute() {
+               // Suppress warnings to prevent notices about missing indexes in $this->data
+               wfSuppressWarnings();
+
+               $this->html( 'headelement' );
+               ?><div id="globalWrapper">
+               <div id="column-content">
+                       <div id="content" class="mw-body-primary" role="main">
+                               <a id="top"></a>
+                               <?php
+                               if ( $this->data['sitenotice'] ) {
+                                       ?>
+                                       <div id="siteNotice"><?php
+                                       $this->html( 'sitenotice' )
+                                       ?></div><?php
+                               }
+                               ?>
+
+                               <h1 id="firstHeading" class="firstHeading" lang="<?php
+                               $this->data['pageLanguage'] =
+                                       $this->getSkin()->getTitle()->getPageViewLanguage()->getHtmlCode();
+                               $this->text( 'pageLanguage' );
+                               ?>"><span dir="auto"><?php $this->html( 'title' ) ?></span></h1>
+
+                               <div id="bodyContent" class="mw-body">
+                                       <div id="siteSub"><?php $this->msg( 'tagline' ) ?></div>
+                                       <div id="contentSub"<?php
+                                       $this->html( 'userlangattributes' ) ?>><?php $this->html( 'subtitle' )
+                                               ?></div>
+                                       <?php if ( $this->data['undelete'] ) { ?>
+                                               <div id="contentSub2"><?php $this->html( 'undelete' ) ?></div>
+                                       <?php
+}
+                                       ?><?php
+                                       if ( $this->data['newtalk'] ) {
+                                               ?>
+                                               <div class="usermessage"><?php $this->html( 'newtalk' ) ?></div>
+                                       <?php
+                                       }
+                                       ?>
+                                       <div id="jump-to-nav" class="mw-jump"><?php
+                                               $this->msg( 'jumpto' )
+                                               ?> <a href="#column-one"><?php
+                                                       $this->msg( 'jumptonavigation' )
+                                                       ?></a><?php
+                                               $this->msg( 'comma-separator' )
+                                               ?><a href="#searchInput"><?php
+                                                       $this->msg( 'jumptosearch' )
+                                                       ?></a></div>
+
+                                       <!-- start content -->
+                                       <?php $this->html( 'bodytext' ) ?>
+                                       <?php
+                                       if ( $this->data['catlinks'] ) {
+                                               $this->html( 'catlinks' );
+                                       }
+                                       ?>
+                                       <!-- end content -->
+                                       <?php
+                                       if ( $this->data['dataAfterContent'] ) {
+                                               $this->html( 'dataAfterContent'
+                                               );
+                                       }
+                                       ?>
+                                       <div class="visualClear"></div>
+                               </div>
+                       </div>
+               </div>
+               <div id="column-one"<?php $this->html( 'userlangattributes' ) ?>>
+                       <h2><?php $this->msg( 'navigation-heading' ) ?></h2>
+                       <?php $this->cactions(); ?>
+                       <div class="portlet" id="p-personal" role="navigation">
+                               <h3><?php $this->msg( 'personaltools' ) ?></h3>
+
+                               <div class="pBody">
+                                       <ul<?php $this->html( 'userlangattributes' ) ?>>
+                                               <?php foreach ( $this->getPersonalTools() as $key => $item ) { ?>
+                                                       <?php echo $this->makeListItem( $key, $item ); ?>
+
+                                               <?php
+}
+                                               ?>
+                                       </ul>
+                               </div>
+                       </div>
+                       <div class="portlet" id="p-logo" role="banner">
+                               <?php
+                               echo Html::element( 'a', array(
+                                               'href' => $this->data['nav_urls']['mainpage']['href'],
+                                               'style' => "background-image: url({$this->data['logopath']});" )
+                                       + Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ); ?>
+
+                       </div>
+                       <?php
+                       $this->renderPortals( $this->data['sidebar'] );
+                       ?>
+               </div><!-- end of the left (by default at least) column -->
+               <div class="visualClear"></div>
+               <?php
+               $validFooterIcons = $this->getFooterIcons( "icononly" );
+               $validFooterLinks = $this->getFooterLinks( "flat" ); // Additional footer links
+
+               if ( count( $validFooterIcons ) + count( $validFooterLinks ) > 0 ) {
+                       ?>
+                       <div id="footer" role="contentinfo"<?php $this->html( 'userlangattributes' ) ?>>
+                       <?php
+                       $footerEnd = '</div>';
+               } else {
+                       $footerEnd = '';
+               }
+
+               foreach ( $validFooterIcons as $blockName => $footerIcons ) {
+                       ?>
+                       <div id="f-<?php echo htmlspecialchars( $blockName ); ?>ico">
+                               <?php foreach ( $footerIcons as $icon ) { ?>
+                                       <?php echo $this->getSkin()->makeFooterIcon( $icon ); ?>
+
+                               <?php
+}
+                               ?>
+                       </div>
+               <?php
+               }
+
+               if ( count( $validFooterLinks ) > 0 ) {
+                       ?>
+                       <ul id="f-list">
+                               <?php
+                               foreach ( $validFooterLinks as $aLink ) {
+                                       ?>
+                                       <li id="<?php echo $aLink ?>"><?php $this->html( $aLink ) ?></li>
+                               <?php
+                               }
+                               ?>
+                       </ul>
+               <?php
+               }
+
+               echo $footerEnd;
+               ?>
+
+               </div>
+               <?php
+               $this->printTrail();
+               echo Html::closeElement( 'body' );
+               echo Html::closeElement( 'html' );
+               wfRestoreWarnings();
+       } // end of execute() method
+
+       /*************************************************************************************************/
+
+       /**
+        * @param array $sidebar
+        */
+       protected function renderPortals( $sidebar ) {
+               if ( !isset( $sidebar['SEARCH'] ) ) {
+                       $sidebar['SEARCH'] = true;
+               }
+               if ( !isset( $sidebar['TOOLBOX'] ) ) {
+                       $sidebar['TOOLBOX'] = true;
+               }
+               if ( !isset( $sidebar['LANGUAGES'] ) ) {
+                       $sidebar['LANGUAGES'] = true;
+               }
+
+               foreach ( $sidebar as $boxName => $content ) {
+                       if ( $content === false ) {
+                               continue;
+                       }
+
+                       if ( $boxName == 'SEARCH' ) {
+                               $this->searchBox();
+                       } elseif ( $boxName == 'TOOLBOX' ) {
+                               $this->toolbox();
+                       } elseif ( $boxName == 'LANGUAGES' ) {
+                               $this->languageBox();
+                       } else {
+                               $this->customBox( $boxName, $content );
+                       }
+               }
+       }
+
+       function searchBox() {
+               global $wgUseTwoButtonsSearchForm;
+               ?>
+               <div id="p-search" class="portlet" role="search">
+                       <h3><label for="searchInput"><?php $this->msg( 'search' ) ?></label></h3>
+
+                       <div id="searchBody" class="pBody">
+                               <form action="<?php $this->text( 'wgScript' ) ?>" id="searchform">
+                                       <input type='hidden' name="title" value="<?php $this->text( 'searchtitle' ) ?>"/>
+                                       <?php echo $this->makeSearchInput( array( "id" => "searchInput" ) ); ?>
+
+                                       <?php
+                                       echo $this->makeSearchButton(
+                                               "go",
+                                               array( "id" => "searchGoButton", "class" => "searchButton" )
+                                       );
+
+                                       if ( $wgUseTwoButtonsSearchForm ) {
+                                               ?>&#160;
+                                               <?php echo $this->makeSearchButton(
+                                                       "fulltext",
+                                                       array( "id" => "mw-searchButton", "class" => "searchButton" )
+                                               );
+                                       } else {
+                                               ?>
+
+                                               <div><a href="<?php
+                                               $this->text( 'searchaction' )
+                                               ?>" rel="search"><?php $this->msg( 'powersearch-legend' ) ?></a></div><?php
+                                       } ?>
+
+                               </form>
+
+                               <?php $this->renderAfterPortlet( 'search' ); ?>
+                       </div>
+               </div>
+       <?php
+       }
+
+       /**
+        * Prints the cactions bar.
+        * Shared between MonoBook and Modern
+        */
+       function cactions() {
+               ?>
+               <div id="p-cactions" class="portlet" role="navigation">
+                       <h3><?php $this->msg( 'views' ) ?></h3>
+
+                       <div class="pBody">
+                               <ul><?php
+                                       foreach ( $this->data['content_actions'] as $key => $tab ) {
+                                               echo '
+                               ' . $this->makeListItem( $key, $tab );
+                                       } ?>
+
+                               </ul>
+                               <?php $this->renderAfterPortlet( 'cactions' ); ?>
+                       </div>
+               </div>
+       <?php
+       }
+
+       /*************************************************************************************************/
+       function toolbox() {
+               ?>
+               <div class="portlet" id="p-tb" role="navigation">
+                       <h3><?php $this->msg( 'toolbox' ) ?></h3>
+
+                       <div class="pBody">
+                               <ul>
+                                       <?php
+                                       foreach ( $this->getToolbox() as $key => $tbitem ) {
+                                               ?>
+                                               <?php echo $this->makeListItem( $key, $tbitem ); ?>
+
+                                       <?php
+                                       }
+                                       wfRunHooks( 'MonoBookTemplateToolboxEnd', array( &$this ) );
+                                       wfRunHooks( 'SkinTemplateToolboxEnd', array( &$this, true ) );
+                                       ?>
+                               </ul>
+                               <?php $this->renderAfterPortlet( 'tb' ); ?>
+                       </div>
+               </div>
+       <?php
+       }
+
+       /*************************************************************************************************/
+       function languageBox() {
+               if ( $this->data['language_urls'] !== false ) {
+                       ?>
+                       <div id="p-lang" class="portlet" role="navigation">
+                               <h3<?php $this->html( 'userlangattributes' ) ?>><?php $this->msg( 'otherlanguages' ) ?></h3>
+
+                               <div class="pBody">
+                                       <ul>
+                                               <?php foreach ( $this->data['language_urls'] as $key => $langlink ) { ?>
+                                                       <?php echo $this->makeListItem( $key, $langlink ); ?>
+
+                                               <?php
+}
+                                               ?>
+                                       </ul>
+
+                                       <?php $this->renderAfterPortlet( 'lang' ); ?>
+                               </div>
+                       </div>
+               <?php
+               }
+       }
+
+       /*************************************************************************************************/
+       /**
+        * @param string $bar
+        * @param array|string $cont
+        */
+       function customBox( $bar, $cont ) {
+               $portletAttribs = array(
+                       'class' => 'generated-sidebar portlet',
+                       'id' => Sanitizer::escapeId( "p-$bar" ),
+                       'role' => 'navigation'
+               );
+
+               $tooltip = Linker::titleAttrib( "p-$bar" );
+               if ( $tooltip !== false ) {
+                       $portletAttribs['title'] = $tooltip;
+               }
+               echo '  ' . Html::openElement( 'div', $portletAttribs );
+               $msgObj = wfMessage( $bar );
+               ?>
+
+               <h3><?php echo htmlspecialchars( $msgObj->exists() ? $msgObj->text() : $bar ); ?></h3>
+               <div class='pBody'>
+                       <?php
+                       if ( is_array( $cont ) ) {
+                               ?>
+                               <ul>
+                                       <?php
+                                       foreach ( $cont as $key => $val ) {
+                                               ?>
+                                               <?php echo $this->makeListItem( $key, $val ); ?>
+
+                                       <?php
+                                       }
+                                       ?>
+                               </ul>
+                       <?php
+                       } else {
+                               # allow raw HTML block to be defined by extensions
+                               print $cont;
+                       }
+
+                       $this->renderAfterPortlet( $bar );
+                       ?>
+               </div>
+               </div>
+       <?php
+       }
+} // end of class
diff --git a/skins/vector/Vector.php b/skins/vector/Vector.php
new file mode 100644 (file)
index 0000000..9544d55
--- /dev/null
@@ -0,0 +1,661 @@
+<?php
+/**
+ * Vector - Modern version of MonoBook with fresh look and many usability
+ * improvements.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @todo document
+ * @file
+ * @ingroup Skins
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+       die( -1 );
+}
+
+/**
+ * SkinTemplate class for Vector skin
+ * @ingroup Skins
+ */
+class SkinVector extends SkinTemplate {
+       public $skinname = 'vector';
+       public $stylename = 'vector';
+       public $template = 'VectorTemplate';
+
+       protected static $bodyClasses = array( 'vector-animateLayout' );
+
+       /**
+        * Initializes output page and sets up skin-specific parameters
+        * @param OutputPage $out Object to initialize
+        */
+       public function initPage( OutputPage $out ) {
+               global $wgLocalStylePath;
+
+               parent::initPage( $out );
+
+               // Append CSS which includes IE only behavior fixes for hover support -
+               // this is better than including this in a CSS file since it doesn't
+               // wait for the CSS file to load before fetching the HTC file.
+               $min = $this->getRequest()->getFuzzyBool( 'debug' ) ? '' : '.min';
+               $out->addHeadItem( 'csshover',
+                       '<!--[if lt IE 7]><style type="text/css">body{behavior:url("' .
+                               htmlspecialchars( $wgLocalStylePath ) .
+                               "/{$this->stylename}/csshover{$min}.htc\")}</style><![endif]-->"
+               );
+
+               $out->addModules( array( 'skins.vector.js' ) );
+       }
+
+       /**
+        * Loads skin and user CSS files.
+        * @param OutputPage $out
+        */
+       function setupSkinUserCss( OutputPage $out ) {
+               parent::setupSkinUserCss( $out );
+
+               $styles = array( 'mediawiki.skinning.interface', 'skins.vector.styles' );
+               wfRunHooks( 'SkinVectorStyleModules', array( $this, &$styles ) );
+               $out->addModuleStyles( $styles );
+       }
+
+       /**
+        * Adds classes to the body element.
+        *
+        * @param OutputPage $out
+        * @param array &$bodyAttrs Array of attributes that will be set on the body element
+        */
+       function addToBodyAttributes( $out, &$bodyAttrs ) {
+               if ( isset( $bodyAttrs['class'] ) && strlen( $bodyAttrs['class'] ) > 0 ) {
+                       $bodyAttrs['class'] .= ' ' . implode( ' ', static::$bodyClasses );
+               } else {
+                       $bodyAttrs['class'] = implode( ' ', static::$bodyClasses );
+               }
+       }
+}
+
+/**
+ * QuickTemplate class for Vector skin
+ * @ingroup Skins
+ */
+class VectorTemplate extends BaseTemplate {
+       /* Functions */
+
+       /**
+        * Outputs the entire contents of the (X)HTML page
+        */
+       public function execute() {
+               global $wgVectorUseIconWatch;
+
+               // Build additional attributes for navigation urls
+               $nav = $this->data['content_navigation'];
+
+               if ( $wgVectorUseIconWatch ) {
+                       $mode = $this->getSkin()->getUser()->isWatched( $this->getSkin()->getRelevantTitle() )
+                               ? 'unwatch'
+                               : 'watch';
+
+                       if ( isset( $nav['actions'][$mode] ) ) {
+                               $nav['views'][$mode] = $nav['actions'][$mode];
+                               $nav['views'][$mode]['class'] = rtrim( 'icon ' . $nav['views'][$mode]['class'], ' ' );
+                               $nav['views'][$mode]['primary'] = true;
+                               unset( $nav['actions'][$mode] );
+                       }
+               }
+
+               $xmlID = '';
+               foreach ( $nav as $section => $links ) {
+                       foreach ( $links as $key => $link ) {
+                               if ( $section == 'views' && !( isset( $link['primary'] ) && $link['primary'] ) ) {
+                                       $link['class'] = rtrim( 'collapsible ' . $link['class'], ' ' );
+                               }
+
+                               $xmlID = isset( $link['id'] ) ? $link['id'] : 'ca-' . $xmlID;
+                               $nav[$section][$key]['attributes'] =
+                                       ' id="' . Sanitizer::escapeId( $xmlID ) . '"';
+                               if ( $link['class'] ) {
+                                       $nav[$section][$key]['attributes'] .=
+                                               ' class="' . htmlspecialchars( $link['class'] ) . '"';
+                                       unset( $nav[$section][$key]['class'] );
+                               }
+                               if ( isset( $link['tooltiponly'] ) && $link['tooltiponly'] ) {
+                                       $nav[$section][$key]['key'] =
+                                               Linker::tooltip( $xmlID );
+                               } else {
+                                       $nav[$section][$key]['key'] =
+                                               Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( $xmlID ) );
+                               }
+                       }
+               }
+               $this->data['namespace_urls'] = $nav['namespaces'];
+               $this->data['view_urls'] = $nav['views'];
+               $this->data['action_urls'] = $nav['actions'];
+               $this->data['variant_urls'] = $nav['variants'];
+
+               // Reverse horizontally rendered navigation elements
+               if ( $this->data['rtl'] ) {
+                       $this->data['view_urls'] =
+                               array_reverse( $this->data['view_urls'] );
+                       $this->data['namespace_urls'] =
+                               array_reverse( $this->data['namespace_urls'] );
+                       $this->data['personal_urls'] =
+                               array_reverse( $this->data['personal_urls'] );
+               }
+               // Output HTML Page
+               $this->html( 'headelement' );
+               ?>
+               <div id="mw-page-base" class="noprint"></div>
+               <div id="mw-head-base" class="noprint"></div>
+               <div id="content" class="mw-body" role="main">
+                       <a id="top"></a>
+
+                       <div id="mw-js-message" style="display:none;"<?php $this->html( 'userlangattributes' ) ?>></div>
+                       <?php
+                       if ( $this->data['sitenotice'] ) {
+                               ?>
+                               <div id="siteNotice"><?php $this->html( 'sitenotice' ) ?></div>
+                       <?php
+                       }
+                       ?>
+                       <h1 id="firstHeading" class="firstHeading" lang="<?php
+                       $this->data['pageLanguage'] =
+                               $this->getSkin()->getTitle()->getPageViewLanguage()->getHtmlCode();
+                       $this->text( 'pageLanguage' );
+                       ?>"><span dir="auto"><?php $this->html( 'title' ) ?></span></h1>
+                       <?php $this->html( 'prebodyhtml' ) ?>
+                       <div id="bodyContent" class="mw-body-content">
+                               <?php
+                               if ( $this->data['isarticle'] ) {
+                                       ?>
+                                       <div id="siteSub"><?php $this->msg( 'tagline' ) ?></div>
+                               <?php
+                               }
+                               ?>
+                               <div id="contentSub"<?php
+                               $this->html( 'userlangattributes' )
+                               ?>><?php $this->html( 'subtitle' ) ?></div>
+                               <?php
+                               if ( $this->data['undelete'] ) {
+                                       ?>
+                                       <div id="contentSub2"><?php $this->html( 'undelete' ) ?></div>
+                               <?php
+                               }
+                               ?>
+                               <?php
+                               if ( $this->data['newtalk'] ) {
+                                       ?>
+                                       <div class="usermessage"><?php $this->html( 'newtalk' ) ?></div>
+                               <?php
+                               }
+                               ?>
+                               <div id="jump-to-nav" class="mw-jump">
+                                       <?php $this->msg( 'jumpto' ) ?>
+                                       <a href="#mw-navigation"><?php
+                                               $this->msg( 'jumptonavigation' )
+                                               ?></a><?php
+                                       $this->msg( 'comma-separator' )
+                                       ?>
+                                       <a href="#p-search"><?php $this->msg( 'jumptosearch' ) ?></a>
+                               </div>
+                               <?php $this->html( 'bodycontent' ) ?>
+                               <?php
+                               if ( $this->data['printfooter'] ) {
+                                       ?>
+                                       <div class="printfooter">
+                                               <?php $this->html( 'printfooter' ); ?>
+                                       </div>
+                               <?php
+                               }
+                               ?>
+                               <?php
+                               if ( $this->data['catlinks'] ) {
+                                       ?>
+                                       <?php
+                                       $this->html( 'catlinks' );
+                                       ?>
+                               <?php
+                               }
+                               ?>
+                               <?php
+                               if ( $this->data['dataAfterContent'] ) {
+                                       ?>
+                                       <?php
+                                       $this->html( 'dataAfterContent' );
+                                       ?>
+                               <?php
+                               }
+                               ?>
+                               <div class="visualClear"></div>
+                               <?php $this->html( 'debughtml' ); ?>
+                       </div>
+               </div>
+               <div id="mw-navigation">
+                       <h2><?php $this->msg( 'navigation-heading' ) ?></h2>
+
+                       <div id="mw-head">
+                               <?php $this->renderNavigation( 'PERSONAL' ); ?>
+                               <div id="left-navigation">
+                                       <?php $this->renderNavigation( array( 'NAMESPACES', 'VARIANTS' ) ); ?>
+                               </div>
+                               <div id="right-navigation">
+                                       <?php $this->renderNavigation( array( 'VIEWS', 'ACTIONS', 'SEARCH' ) ); ?>
+                               </div>
+                       </div>
+                       <div id="mw-panel">
+                               <div id="p-logo" role="banner"><a style="background-image: url(<?php
+                                       $this->text( 'logopath' )
+                                       ?>);" href="<?php
+                                       echo htmlspecialchars( $this->data['nav_urls']['mainpage']['href'] )
+                                       ?>" <?php
+                                       echo Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) )
+                                       ?>></a></div>
+                               <?php $this->renderPortals( $this->data['sidebar'] ); ?>
+                       </div>
+               </div>
+               <div id="footer" role="contentinfo"<?php $this->html( 'userlangattributes' ) ?>>
+                       <?php
+                       foreach ( $this->getFooterLinks() as $category => $links ) {
+                               ?>
+                               <ul id="footer-<?php
+                               echo $category
+                               ?>">
+                                       <?php
+                                       foreach ( $links as $link ) {
+                                               ?>
+                                               <li id="footer-<?php
+                                               echo $category
+                                               ?>-<?php
+                                               echo $link
+                                               ?>"><?php
+                                                       $this->html( $link )
+                                                       ?></li>
+                                       <?php
+                                       }
+                                       ?>
+                               </ul>
+                       <?php
+                       }
+                       ?>
+                       <?php $footericons = $this->getFooterIcons( "icononly" );
+                       if ( count( $footericons ) > 0 ) {
+                               ?>
+                               <ul id="footer-icons" class="noprint">
+                                       <?php
+                                       foreach ( $footericons as $blockName => $footerIcons ) {
+                                               ?>
+                                               <li id="footer-<?php
+                                               echo htmlspecialchars( $blockName ); ?>ico">
+                                                       <?php
+                                                       foreach ( $footerIcons as $icon ) {
+                                                               ?>
+                                                               <?php
+                                                               echo $this->getSkin()->makeFooterIcon( $icon );
+                                                               ?>
+
+                                                       <?php
+                                                       }
+                                                       ?>
+                                               </li>
+                                       <?php
+                                       }
+                                       ?>
+                               </ul>
+                       <?php
+                       }
+                       ?>
+                       <div style="clear:both"></div>
+               </div>
+               <?php $this->printTrail(); ?>
+
+       </body>
+</html>
+       <?php
+       }
+
+       /**
+        * Render a series of portals
+        *
+        * @param array $portals
+        */
+       protected function renderPortals( $portals ) {
+               // Force the rendering of the following portals
+               if ( !isset( $portals['SEARCH'] ) ) {
+                       $portals['SEARCH'] = true;
+               }
+               if ( !isset( $portals['TOOLBOX'] ) ) {
+                       $portals['TOOLBOX'] = true;
+               }
+               if ( !isset( $portals['LANGUAGES'] ) ) {
+                       $portals['LANGUAGES'] = true;
+               }
+               // Render portals
+               foreach ( $portals as $name => $content ) {
+                       if ( $content === false ) {
+                               continue;
+                       }
+
+                       switch ( $name ) {
+                               case 'SEARCH':
+                                       break;
+                               case 'TOOLBOX':
+                                       $this->renderPortal( 'tb', $this->getToolbox(), 'toolbox', 'SkinTemplateToolboxEnd' );
+                                       break;
+                               case 'LANGUAGES':
+                                       if ( $this->data['language_urls'] !== false ) {
+                                               $this->renderPortal( 'lang', $this->data['language_urls'], 'otherlanguages' );
+                                       }
+                                       break;
+                               default:
+                                       $this->renderPortal( $name, $content );
+                                       break;
+                       }
+               }
+       }
+
+       /**
+        * @param string $name
+        * @param array $content
+        * @param null|string $msg
+        * @param null|string|array $hook
+        */
+       protected function renderPortal( $name, $content, $msg = null, $hook = null ) {
+               if ( $msg === null ) {
+                       $msg = $name;
+               }
+               $msgObj = wfMessage( $msg );
+               ?>
+               <div class="portal" role="navigation" id='<?php
+               echo Sanitizer::escapeId( "p-$name" )
+               ?>'<?php
+               echo Linker::tooltip( 'p-' . $name )
+               ?> aria-labelledby='<?php echo Sanitizer::escapeId( "p-$name-label" ) ?>'>
+                       <h3<?php
+                       $this->html( 'userlangattributes' )
+                       ?> id='<?php
+                       echo Sanitizer::escapeId( "p-$name-label" )
+                       ?>'><?php
+                               echo htmlspecialchars( $msgObj->exists() ? $msgObj->text() : $msg );
+                               ?></h3>
+
+                       <div class="body">
+                               <?php
+                               if ( is_array( $content ) ) {
+                                       ?>
+                                       <ul>
+                                               <?php
+                                               foreach ( $content as $key => $val ) {
+                                                       ?>
+                                                       <?php echo $this->makeListItem( $key, $val ); ?>
+
+                                               <?php
+                                               }
+                                               if ( $hook !== null ) {
+                                                       wfRunHooks( $hook, array( &$this, true ) );
+                                               }
+                                               ?>
+                                       </ul>
+                               <?php
+                               } else {
+                                       ?>
+                                       <?php
+                                       echo $content; /* Allow raw HTML block to be defined by extensions */
+                               }
+
+                               $this->renderAfterPortlet( $name );
+                               ?>
+                       </div>
+               </div>
+       <?php
+       }
+
+       /**
+        * Render one or more navigations elements by name, automatically reveresed
+        * when UI is in RTL mode
+        *
+        * @param array $elements
+        */
+       protected function renderNavigation( $elements ) {
+               global $wgVectorUseSimpleSearch;
+
+               // If only one element was given, wrap it in an array, allowing more
+               // flexible arguments
+               if ( !is_array( $elements ) ) {
+                       $elements = array( $elements );
+                       // If there's a series of elements, reverse them when in RTL mode
+               } elseif ( $this->data['rtl'] ) {
+                       $elements = array_reverse( $elements );
+               }
+               // Render elements
+               foreach ( $elements as $name => $element ) {
+                       switch ( $element ) {
+                               case 'NAMESPACES':
+                                       ?>
+                                       <div id="p-namespaces" role="navigation" class="vectorTabs<?php
+                                       if ( count( $this->data['namespace_urls'] ) == 0 ) {
+                                               echo ' emptyPortlet';
+                                       }
+                                       ?>" aria-labelledby="p-namespaces-label">
+                                               <h3 id="p-namespaces-label"><?php $this->msg( 'namespaces' ) ?></h3>
+                                               <ul<?php $this->html( 'userlangattributes' ) ?>>
+                                                       <?php
+                                                       foreach ( $this->data['namespace_urls'] as $link ) {
+                                                               ?>
+                                                               <li <?php
+                                                               echo $link['attributes']
+                                                               ?>><span><a href="<?php
+                                                                               echo htmlspecialchars( $link['href'] )
+                                                                               ?>" <?php
+                                                                               echo $link['key']
+                                                                               ?>><?php
+                                                                                       echo htmlspecialchars( $link['text'] )
+                                                                                       ?></a></span></li>
+                                                       <?php
+                                                       }
+                                                       ?>
+                                               </ul>
+                                       </div>
+                                       <?php
+                                       break;
+                               case 'VARIANTS':
+                                       ?>
+                                       <div id="p-variants" role="navigation" class="vectorMenu<?php
+                                       if ( count( $this->data['variant_urls'] ) == 0 ) {
+                                               echo ' emptyPortlet';
+                                       }
+                                       ?>" aria-labelledby="p-variants-label">
+                                               <h3 id="mw-vector-current-variant">
+                                                       <?php
+                                                       foreach ( $this->data['variant_urls'] as $link ) {
+                                                               ?>
+                                                               <?php
+                                                               if ( stripos( $link['attributes'], 'selected' ) !== false ) {
+                                                                       ?>
+                                                                       <?php
+                                                                       echo htmlspecialchars( $link['text'] )
+                                                                       ?>
+                                                               <?php
+                                                               }
+                                                               ?>
+                                                       <?php
+                                                       }
+                                                       ?>
+                                               </h3>
+
+                                               <h3 id="p-variants-label"><span><?php $this->msg( 'variants' ) ?></span><a href="#"></a></h3>
+
+                                               <div class="menu">
+                                                       <ul>
+                                                               <?php
+                                                               foreach ( $this->data['variant_urls'] as $link ) {
+                                                                       ?>
+                                                                       <li<?php
+                                                                       echo $link['attributes']
+                                                                       ?>><a href="<?php
+                                                                               echo htmlspecialchars( $link['href'] )
+                                                                               ?>" lang="<?php
+                                                                               echo htmlspecialchars( $link['lang'] )
+                                                                               ?>" hreflang="<?php
+                                                                               echo htmlspecialchars( $link['hreflang'] )
+                                                                               ?>" <?php
+                                                                               echo $link['key']
+                                                                               ?>><?php
+                                                                                       echo htmlspecialchars( $link['text'] )
+                                                                                       ?></a></li>
+                                                               <?php
+                                                               }
+                                                               ?>
+                                                       </ul>
+                                               </div>
+                                       </div>
+                                       <?php
+                                       break;
+                               case 'VIEWS':
+                                       ?>
+                                       <div id="p-views" role="navigation" class="vectorTabs<?php
+                                       if ( count( $this->data['view_urls'] ) == 0 ) {
+                                               echo ' emptyPortlet';
+                                       }
+                                       ?>" aria-labelledby="p-views-label">
+                                               <h3 id="p-views-label"><?php $this->msg( 'views' ) ?></h3>
+                                               <ul<?php
+                                               $this->html( 'userlangattributes' )
+                                               ?>>
+                                                       <?php
+                                                       foreach ( $this->data['view_urls'] as $link ) {
+                                                               ?>
+                                                               <li<?php
+                                                               echo $link['attributes']
+                                                               ?>><span><a href="<?php
+                                                                               echo htmlspecialchars( $link['href'] )
+                                                                               ?>" <?php
+                                                                               echo $link['key']
+                                                                               ?>><?php
+                                                                                       // $link['text'] can be undefined - bug 27764
+                                                                                       if ( array_key_exists( 'text', $link ) ) {
+                                                                                               echo array_key_exists( 'img', $link )
+                                                                                                       ? '<img src="' . $link['img'] . '" alt="' . $link['text'] . '" />'
+                                                                                                       : htmlspecialchars( $link['text'] );
+                                                                                       }
+                                                                                       ?></a></span></li>
+                                                       <?php
+                                                       }
+                                                       ?>
+                                               </ul>
+                                       </div>
+                                       <?php
+                                       break;
+                               case 'ACTIONS':
+                                       ?>
+                                       <div id="p-cactions" role="navigation" class="vectorMenu<?php
+                                       if ( count( $this->data['action_urls'] ) == 0 ) {
+                                               echo ' emptyPortlet';
+                                       }
+                                       ?>" aria-labelledby="p-cactions-label">
+                                               <h3 id="p-cactions-label"><span><?php $this->msg( 'vector-more-actions' ) ?></span><a href="#"></a></h3>
+
+                                               <div class="menu">
+                                                       <ul<?php $this->html( 'userlangattributes' ) ?>>
+                                                               <?php
+                                                               foreach ( $this->data['action_urls'] as $link ) {
+                                                                       ?>
+                                                                       <li<?php
+                                                                       echo $link['attributes']
+                                                                       ?>>
+                                                                               <a href="<?php
+                                                                               echo htmlspecialchars( $link['href'] )
+                                                                               ?>" <?php
+                                                                               echo $link['key'] ?>><?php echo htmlspecialchars( $link['text'] )
+                                                                                       ?></a>
+                                                                       </li>
+                                                               <?php
+                                                               }
+                                                               ?>
+                                                       </ul>
+                                               </div>
+                                       </div>
+                                       <?php
+                                       break;
+                               case 'PERSONAL':
+                                       ?>
+                                       <div id="p-personal" role="navigation" class="<?php
+                                       if ( count( $this->data['personal_urls'] ) == 0 ) {
+                                               echo ' emptyPortlet';
+                                       }
+                                       ?>" aria-labelledby="p-personal-label">
+                                               <h3 id="p-personal-label"><?php $this->msg( 'personaltools' ) ?></h3>
+                                               <ul<?php $this->html( 'userlangattributes' ) ?>>
+                                                       <?php
+                                                       $personalTools = $this->getPersonalTools();
+                                                       foreach ( $personalTools as $key => $item ) {
+                                                               echo $this->makeListItem( $key, $item );
+                                                       }
+                                                       ?>
+                                               </ul>
+                                       </div>
+                                       <?php
+                                       break;
+                               case 'SEARCH':
+                                       ?>
+                                       <div id="p-search" role="search">
+                                               <h3<?php $this->html( 'userlangattributes' ) ?>>
+                                                       <label for="searchInput"><?php $this->msg( 'search' ) ?></label>
+                                               </h3>
+
+                                               <form action="<?php $this->text( 'wgScript' ) ?>" id="searchform">
+                                                       <?php
+                                                       if ($wgVectorUseSimpleSearch) {
+                                                       ?>
+                                                       <div id="simpleSearch">
+                                                               <?php
+                                                       } else {
+                                                       ?>
+                                                               <div>
+                                                                       <?php
+                                                       }
+                                                       ?>
+                                                       <?php
+                                                       echo $this->makeSearchInput( array( 'id' => 'searchInput' ) );
+                                                       echo Html::hidden( 'title', $this->get( 'searchtitle' ) );
+                                                       // We construct two buttons (for 'go' and 'fulltext' search modes),
+                                                       // but only one will be visible and actionable at a time (they are
+                                                       // overlaid on top of each other in CSS).
+                                                       // * Browsers will use the 'fulltext' one by default (as it's the
+                                                       //   first in tree-order), which is desirable when they are unable
+                                                       //   to show search suggestions (either due to being broken or
+                                                       //   having JavaScript turned off).
+                                                       // * The mediawiki.searchSuggest module, after doing tests for the
+                                                       //   broken browsers, removes the 'fulltext' button and handles
+                                                       //   'fulltext' search itself; this will reveal the 'go' button and
+                                                       //   cause it to be used.
+                                                       echo $this->makeSearchButton(
+                                                               'fulltext',
+                                                               array( 'id' => 'mw-searchButton', 'class' => 'searchButton mw-fallbackSearchButton' )
+                                                       );
+                                                       echo $this->makeSearchButton(
+                                                               'go',
+                                                               array( 'id' => 'searchButton', 'class' => 'searchButton' )
+                                                       );
+                                                       ?>
+                                                               </div>
+                                               </form>
+                                       </div>
+                                       <?php
+
+                                       break;
+                       }
+               }
+       }
+}