call JS onload hooks at the end of the html body in all skins
[lhc/web/wiklou.git] / includes / Skin.php
index 548f2cf..a99ff0a 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 if ( ! defined( 'MEDIAWIKI' ) )
-       die( -1 );
+       die( 1 );
 
 /**
  *
@@ -9,26 +9,6 @@ if ( ! defined( 'MEDIAWIKI' ) )
  */
 
 # See skin.txt
-require_once( 'Linker.php' );
-require_once( 'Image.php' );
-
-# Get a list of all skins available in /skins/
-# Build using the regular expression '^(.*).php$'
-# Array keys are all lower case, array value keep the case used by filename
-#
-
-$skinDir = dir($IP.'/skins');
-
-# while code from www.php.net
-while (false !== ($file = $skinDir->read())) {
-       // Skip non-PHP files, hidden files, and '.dep' includes
-       if(preg_match('/^([^.]*)\.php$/',$file, $matches)) {
-               $aSkin = $matches[1];
-               $wgValidSkinNames[strtolower($aSkin)] = $aSkin;
-       }
-}
-$skinDir->close();
-unset($matches);
 
 /**
  * The main skin class that provide methods and properties for all other skins.
@@ -53,8 +33,30 @@ class Skin extends Linker {
         * @return array of strings
         * @static
         */
-       function getSkinNames() {
+       static function &getSkinNames() {
                global $wgValidSkinNames;
+               static $skinsInitialised = false;
+               if ( !$skinsInitialised ) {
+                       # Get a list of available skins
+                       # Build using the regular expression '^(.*).php$'
+                       # Array keys are all lower case, array value keep the case used by filename
+                       #
+                       wfProfileIn( __METHOD__ . '-init' );
+                       global $wgStyleDirectory;
+                       $skinDir = dir( $wgStyleDirectory );
+
+                       # while code from www.php.net
+                       while (false !== ($file = $skinDir->read())) {
+                               // Skip non-PHP files, hidden files, and '.dep' includes
+                               if(preg_match('/^([^.]*)\.php$/',$file, $matches)) {
+                                       $aSkin = $matches[1];
+                                       $wgValidSkinNames[strtolower($aSkin)] = $aSkin;
+                               }
+                       }
+                       $skinDir->close();
+                       $skinsInitialised = true;
+                       wfProfileOut( __METHOD__ . '-init' );
+               }
                return $wgValidSkinNames;
        }
 
@@ -66,7 +68,7 @@ class Skin extends Linker {
         * @return string
         * @static
         */
-       function normalizeKey( $key ) {
+       static function normalizeKey( $key ) {
                global $wgDefaultSkin;
                $skinNames = Skin::getSkinNames();
 
@@ -105,20 +107,20 @@ class Skin extends Linker {
         * @return Skin
         * @static
         */
-       function &newFromKey( $key ) {
+       static function &newFromKey( $key ) {
+               global $wgStyleDirectory;
+               
                $key = Skin::normalizeKey( $key );
 
                $skinNames = Skin::getSkinNames();
                $skinName = $skinNames[$key];
 
-               global $IP;
-
                # Grab the skin class and initialise it.
                wfSuppressWarnings();
                // Preload base classes to work around APC/PHP5 bug
-               include_once( $IP.'/skins/'.$skinName.'.deps.php' );
+               include_once( "{$wgStyleDirectory}/{$skinName}.deps.php" );
                wfRestoreWarnings();
-               require_once( $IP.'/skins/'.$skinName.'.php' );
+               require_once( "{$wgStyleDirectory}/{$skinName}.php" );
 
                # Check if we got if not failback to default skin
                $className = 'Skin'.$skinName;
@@ -129,9 +131,9 @@ class Skin extends Linker {
                        # is no longer valid.
                        wfDebug( "Skin class does not exist: $className\n" );
                        $className = 'SkinStandard';
-                       require_once( $IP.'/skins/Standard.php' );
+                       require_once( "{$wgStyleDirectory}/Standard.php" );
                }
-               $skin =& new $className;
+               $skin = new $className;
                return $skin;
        }
 
@@ -253,14 +255,63 @@ class Skin extends Linker {
 
                $out->out( $this->afterContent() );
 
+               $out->out( $this->bottomScripts() );
+
                $out->out( $out->reportTime() );
 
                $out->out( "\n</body></html>" );
        }
 
+       /*static*/ function makeGlobalVariablesScript( $data ) {
+               $r = '<script type= "' . $data['jsmimetype'] . '">
+                       var skin = "' . Xml::escapeJsString( $data['skinname'] ) . '";
+                       var stylepath = "' . Xml::escapeJsString( $data['stylepath'] ) . '";
+
+                       var wgArticlePath = "' . Xml::escapeJsString( $data['articlepath'] ) . '";
+                       var wgScriptPath = "' . Xml::escapeJsString( $data['scriptpath'] ) . '";
+                       var wgServer = "' . Xml::escapeJsString( $data['serverurl'] ) . '";
+                        
+                       var wgCanonicalNamespace = "' . Xml::escapeJsString( $data['nscanonical'] ) . '";
+                       var wgPageName = "' . Xml::escapeJsString( $data['titleprefixeddbkey'] ) . '";
+                       var wgTitle = "' . Xml::escapeJsString( $data['titletext'] ) . '";
+                       var wgArticleId = ' . (int)$data['articleid'] . ';
+                        
+                       var wgUserName = ' . ( $data['username'] == NULL ? 'null' : ( '"' . Xml::escapeJsString( $data['username'] ) . '"' ) ) . ';
+                       var wgUserLanguage = "' . Xml::escapeJsString( $data['userlang'] ) . '";
+                       var wgContentLanguage = "' . Xml::escapeJsString( $data['lang'] ) . '";
+               </script>
+               ';
+               
+               return $r;
+       }
+
        function getHeadScripts() {
                global $wgStylePath, $wgUser, $wgAllowUserJs, $wgJsMimeType;
-               $r = "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/wikibits.js\"></script>\n";
+               global $wgArticlePath, $wgScriptPath, $wgServer, $wgContLang, $wgLang;
+               global $wgTitle, $wgCanonicalNamespaceNames;
+
+               $nsname = @$wgCanonicalNamespaceNames[ $wgTitle->getNamespace() ];
+               if ( $nsname === NULL ) $nsname = $wgTitle->getNsText();
+
+               $vars = array( 
+                       'jsmimetype' => $wgJsMimeType,
+                       'skinname' => $this->getSkinName(),
+                       'stylepath' => $wgStylePath,
+                       'articlepath' => $wgArticlePath,
+                       'scriptpath' => $wgScriptPath,
+                       'serverurl' => $wgServer,
+                       'nscanonical' => $nsname,
+                       'titleprefixeddbkey' => $wgTitle->getPrefixedDBKey(),
+                       'titletext' => $wgTitle->getText(),
+                       'articleid' => $wgTitle->getArticleId(),
+                       'username' => $wgUser->isAnon() ? NULL : $wgUser->getName(),
+                       'userlang' => $wgLang->getCode(),
+                       'lang' => $wgContLang->getCode(),
+               );
+
+               $r = Skin::makeGlobalVariablesScript( $vars );
+                
+               $r .= "<script type=\"{$wgJsMimeType}\" src=\"{$wgStylePath}/common/wikibits.js\"></script>\n";
                if( $wgAllowUserJs && $wgUser->isLoggedIn() ) {
                        $userpage = $wgUser->getUserPage();
                        $userjs = htmlspecialchars( $this->makeUrl(
@@ -337,7 +388,7 @@ class Skin extends Linker {
                $s = '';
 
                if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { # logged in
-                       if($wgTitle->isCssSubpage() && $this->userCanPreview( $action ) ) {
+                       if($wgTitle->isCssSubpage() && $this->userCanPreview( $wgRequest->getText( 'action' ) ) ) {
                                $s .= $wgRequest->getText('wpTextbox1');
                        } else {
                                $userpage = $wgUser->getUserPage();
@@ -502,16 +553,19 @@ END;
 
                if( count( $wgOut->mCategoryLinks ) == 0 ) return '';
 
+               # Separator
+               $sep = wfMsgHtml( 'catseparator' );
+
                // Use Unicode bidi embedding override characters,
                // to make sure links don't smash each other up in ugly ways.
                $dir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
                $embed = "<span dir='$dir'>";
                $pop = '</span>';
-               $t = $embed . implode ( "$pop | $embed" , $wgOut->mCategoryLinks ) . $pop;
+               $t = $embed . implode ( "{$pop} {$sep} {$embed}" , $wgOut->mCategoryLinks ) . $pop;
 
-               $msg = count( $wgOut->mCategoryLinks ) === 1 ? 'categories1' : 'categories';
+               $msg = wfMsgExt('categories', array('parsemag', 'escape'), count( $wgOut->mCategoryLinks ));
                $s = $this->makeKnownLinkObj( Title::makeTitle( NS_SPECIAL, 'Categories' ),
-                       wfMsg( $msg ), 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
+                       $msg, 'article=' . urlencode( $wgTitle->getPrefixedDBkey() ) )
                        . ': ' . $t;
 
                # optional 'dmoz-like' category browser. Will be shown under the list
@@ -568,14 +622,23 @@ END;
        }
 
        /**
-        * This gets called immediately before the \</body\> tag.
-        * @return String HTML to be put after \</body\> ???
+        * This gets called shortly before the \</body\> tag.
+        * @return String HTML to be put before \</body\> 
         */
        function afterContent() {
                $printfooter = "<div class=\"printfooter\">\n" . $this->printFooter() . "</div>\n";
                return $printfooter . $this->doAfterContent();
        }
 
+       /**
+        * This gets called shortly before the \</body\> tag.
+        * @return String HTML-wrapped JS code to be put before \</body\> 
+        */
+       function bottomScripts() {
+               global $wgJsMimeType;
+               return "\n\t\t<script type=\"$wgJsMimeType\">if (window.runOnloadHook) runOnloadHook();</script>\n";
+       }
+
        /** @return string Retrievied from HTML text */
        function printSource() {
                global $wgTitle;
@@ -657,7 +720,7 @@ END;
                        return wfMsg( $msg,
                                $this->makeKnownLink(
                                        $wgContLang->SpecialPage( 'Undelete/' . $wgTitle->getPrefixedDBkey() ),
-                                       wfMsg( 'restorelink' . ($n == 1 ? '1' : ''), $n ) ) );
+                                       wfMsgExt( 'restorelink', array( 'parsemag', 'escape' ), $n ) ) );
                }
                return '';
        }
@@ -798,7 +861,7 @@ END;
                  . '<input type="text" name="search" size="19" value="'
                  . htmlspecialchars(substr($search,0,256)) . "\" />\n"
                  . '<input type="submit" name="go" value="' . wfMsg ('go') . '" />&nbsp;'
-                 . '<input type="submit" name="fulltext" value="' . wfMsg ('search') . "\" />\n</form>";
+                 . '<input type="submit" name="fulltext" value="' . wfMsg ('searchbutton') . "\" />\n</form>";
 
                return $s;
        }
@@ -888,7 +951,7 @@ END;
                if ( !$wgDisableCounters ) {
                        $count = $wgLang->formatNum( $wgArticle->getCount() );
                        if ( $count ) {
-                               $s = wfMsg( 'viewcount', $count );
+                               $s = wfMsgExt( 'viewcount', array( 'parseinline' ), $count );
                        }
                }
 
@@ -1011,7 +1074,7 @@ END;
         * @TODO crash bug913. Need to be rewrote completly.
         */
        function specialPagesList() {
-               global $wgUser, $wgContLang, $wgServer, $wgRedirectScript, $wgAvailableRights;
+               global $wgUser, $wgContLang, $wgServer, $wgRedirectScript;
                require_once('SpecialPage.php');
                $a = array();
                $pages = SpecialPage::getPages();
@@ -1022,15 +1085,9 @@ END;
                }
 
                // Other special pages that are restricted.
-               // Copied from SpecialSpecialpages.php
-               foreach($wgAvailableRights as $right) {
-                       if( $wgUser->isAllowed($right) ) {
-                               /** Add all pages for this right */
-                               if(isset($pages[$right])) {
-                                       foreach($pages[$right] as $name => $page) {
-                                       $a[$name] = $page->getDescription();
-                                       }
-                               }
+               foreach ( $pages['restricted'] as $name => $page ) {
+                       if( $wgUser->isAllowed( $page->getRestriction() ) ) {
+                               $a[$name] = $page->getDescription();
                        }
                }
 
@@ -1325,7 +1382,7 @@ END;
                                $text = wfMsg('userpage');
                                break;
                        case NS_PROJECT:
-                               $text = wfMsg('wikipediapage');
+                               $text = wfMsg('projectpage');
                                break;
                        case NS_IMAGE:
                                $text = wfMsg('imagepage');
@@ -1344,13 +1401,24 @@ END;
        }
 
        function commentLink() {
-               global $wgTitle;
+               global $wgTitle, $wgOut;
 
                if ( $wgTitle->getNamespace() == NS_SPECIAL ) {
                        return '';
                }
-               return $this->makeKnownLinkObj( $wgTitle->getTalkPage(),
-                       wfMsg( 'postcomment' ), 'action=edit&section=new' );
+               
+               # __NEWSECTIONLINK___ changes behaviour here
+               # If it's present, the link points to this page, otherwise
+               # it points to the talk page
+               if( $wgTitle->isTalkPage() ) {
+                       $title =& $wgTitle;
+               } elseif( $wgOut->showNewSectionLink() ) {
+                       $title =& $wgTitle;
+               } else {
+                       $title =& $wgTitle->getTalkPage();
+               }
+               
+               return $this->makeKnownLinkObj( $title, wfMsg( 'postcomment' ), 'action=edit&section=new' );
        }
 
        /* these are used extensively in SkinTemplate, but also some other places */
@@ -1428,7 +1496,7 @@ END;
         */
        function buildSidebar() {
                global $wgDBname, $parserMemc, $wgEnableSidebarCache;
-               global $wgLanguageCode, $wgContLanguageCode;
+               global $wgLang, $wgContLang;
 
                $fname = 'SkinTemplate::buildSidebar';
 
@@ -1436,7 +1504,7 @@ END;
 
                $key = "{$wgDBname}:sidebar";
                $cacheSidebar = $wgEnableSidebarCache &&
-                       ($wgLanguageCode == $wgContLanguageCode);
+                       ($wgLang->getCode() == $wgContLang->getCode());
                
                if ($cacheSidebar) {
                        $cachedsidebar = $parserMemc->get( $key );