X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FSkin.php;h=f6ba839b3d1b750afde6f9ef81eb5a1e1d226cad;hb=399956f4209406fa49898022e34a9741d2c7035f;hp=2cc12a524cd9c501262ce4ec028a9263481a6e32;hpb=ef300f6adf551c7f4983e3a08ab0ceffd3a3e7a5;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Skin.php b/includes/Skin.php index 2cc12a524c..f6ba839b3d 100644 --- a/includes/Skin.php +++ b/includes/Skin.php @@ -1,22 +1,26 @@ addLink( array( 'rel' => 'shortcut icon', 'href' => $wgFavicon ) ); } - + if( false !== $wgAppleTouchIcon ) { $out->addLink( array( 'rel' => 'apple-touch-icon', 'href' => $wgAppleTouchIcon ) ); - } + } # OpenSearch description link - $out->addLink( array( - 'rel' => 'search', + $out->addLink( array( + 'rel' => 'search', 'type' => 'application/opensearchdescription+xml', - 'href' => "$wgScriptPath/opensearch_desc{$wgScriptExtension}", + 'href' => wfScript( 'opensearch_desc' ), 'title' => wfMsgForContent( 'opensearch-desc' ), )); $this->addMetadataLinks($out); $this->mRevisionId = $out->mRevisionId; - + $this->preloadExistence(); wfProfileOut( __METHOD__ ); @@ -203,8 +222,8 @@ class Skin extends Linker { $lb = new LinkBatch( $titles ); $lb->execute(); } - - function addMetadataLinks( &$out ) { + + function addMetadataLinks( OutputPage $out ) { global $wgTitle, $wgEnableDublinCoreRdf, $wgEnableCreativeCommonsRdf; global $wgRightsPage, $wgRightsUrl; @@ -240,13 +259,25 @@ class Skin extends Linker { } } - function outputPage( &$out ) { - global $wgDebugComments; + function setMembers(){ + global $wgTitle, $wgUser; + $this->mTitle = $wgTitle; + $this->mUser = $wgUser; + $this->userpage = $wgUser->getUserPage()->getPrefixedText(); + $this->usercss = false; + } + function outputPage( OutputPage $out ) { + global $wgDebugComments; wfProfileIn( __METHOD__ ); + + $this->setMembers(); $this->initPage( $out ); - $out->out( $out->headElement() ); + // See self::afterContentHook() for documentation + $afterContent = $this->afterContentHook(); + + $out->out( $out->headElement( $this ) ); $out->out( "\ngetBodyOptions(); @@ -264,10 +295,12 @@ class Skin extends Linker { $out->out( $out->mBodytext . "\n" ); $out->out( $this->afterContent() ); + + $out->out( $afterContent ); $out->out( $this->bottomScripts() ); - $out->out( $out->reportTime() ); + $out->out( wfReportTime() ); $out->out( "\n" ); wfProfileOut( __METHOD__ ); @@ -276,14 +309,14 @@ class Skin extends Linker { static function makeVariablesScript( $data ) { global $wgJsMimeType; - $r = "\n"; + $r[] = "/*]]>*/\n"; - return $r; + return implode( "\n\t\t", $r ); } /** @@ -300,18 +333,19 @@ class Skin extends Linker { global $wgUseAjax, $wgAjaxWatch; global $wgVersion, $wgEnableAPI, $wgEnableWriteAPI; global $wgRestrictionTypes, $wgLivePreview; + global $wgMWSuggestTemplate, $wgDBname, $wgEnableMWSuggest; $ns = $wgTitle->getNamespace(); $nsname = isset( $wgCanonicalNamespaceNames[ $ns ] ) ? $wgCanonicalNamespaceNames[ $ns ] : $wgTitle->getNsText(); - $vars = array( + $vars = array( 'skin' => $data['skinname'], 'stylepath' => $wgStylePath, 'wgArticlePath' => $wgArticlePath, 'wgScriptPath' => $wgScriptPath, 'wgScript' => $wgScript, 'wgVariantArticlePath' => $wgVariantArticlePath, - 'wgActionPaths' => $wgActionPaths, + 'wgActionPaths' => (object)$wgActionPaths, 'wgServer' => $wgServer, 'wgCanonicalNamespace' => $nsname, 'wgCanonicalSpecialPageName' => SpecialPage::resolveAlias( $wgTitle->getDBkey() ), @@ -331,6 +365,13 @@ class Skin extends Linker { 'wgEnableAPI' => $wgEnableAPI, 'wgEnableWriteAPI' => $wgEnableWriteAPI, ); + + if( $wgUseAjax && $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false )){ + $vars['wgMWSuggestTemplate'] = SearchEngine::getMWSuggestTemplate(); + $vars['wgDBname'] = $wgDBname; + $vars['wgSearchNamespaces'] = SearchEngine::userNamespaces( $wgUser ); + $vars['wgMWSuggestMessages'] = array( wfMsg('search-mwsuggest-enabled'), wfMsg('search-mwsuggest-disabled')); + } foreach( $wgRestrictionTypes as $type ) $vars['wgRestriction' . ucfirst( $type )] = $wgTitle->getRestrictions( $type ); @@ -350,32 +391,34 @@ class Skin extends Linker { $vars['wgAjaxWatch'] = $msgs; } + wfRunHooks('MakeGlobalVariablesScript', array(&$vars)); + return self::makeVariablesScript( $vars ); } function getHeadScripts( $allowUserJs ) { global $wgStylePath, $wgUser, $wgJsMimeType, $wgStyleVersion; - $r = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) ); + $vars = self::makeGlobalVariablesScript( array( 'skinname' => $this->getSkinName() ) ); - $r .= "\n"; + $r = array( "" ); global $wgUseSiteJs; if ($wgUseSiteJs) { $jsCache = $wgUser->isLoggedIn() ? '&smaxage=0' : ''; - $r .= "\n"; + "\">"; } if( $allowUserJs && $wgUser->isLoggedIn() ) { $userpage = $wgUser->getUserPage(); $userjs = htmlspecialchars( self::makeUrl( $userpage->getPrefixedText().'/'.$this->getSkinName().'.js', 'action=raw&ctype='.$wgJsMimeType)); - $r .= '\n"; + $r[] = '"; } - return $r; + return $vars . "\t\t" . implode ( "\n\t\t", $r ); } /** @@ -402,38 +445,24 @@ class Skin extends Linker { $wgRequest->getVal( 'wpEditToken' ) ); } - # get the user/site-specific stylesheet, SkinTemplate loads via RawPage.php (settings are cached that way) - function getUserStylesheet() { - global $wgStylePath, $wgRequest, $wgContLang, $wgSquidMaxage, $wgStyleVersion; - $sheet = $this->getStylesheet(); - $s = "@import \"$wgStylePath/common/shared.css?$wgStyleVersion\";\n"; - $s .= "@import \"$wgStylePath/common/oldshared.css?$wgStyleVersion\";\n"; - $s .= "@import \"$wgStylePath/$sheet?$wgStyleVersion\";\n"; - if($wgContLang->isRTL()) $s .= "@import \"$wgStylePath/common/common_rtl.css?$wgStyleVersion\";\n"; - - $query = "usemsgcache=yes&action=raw&ctype=text/css&smaxage=$wgSquidMaxage"; - $s .= '@import "' . self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) . "\";\n" . - '@import "' . self::makeNSUrl( ucfirst( $this->getSkinName() . '.css' ), $query, NS_MEDIAWIKI ) . "\";\n"; - - $s .= $this->doGetUserStyles(); - return $s."\n"; - } - /** - * This returns MediaWiki:Common.js, and derived classes may add other JS. - * Despite its name, it does *not* return any custom user JS from user - * subpages. The returned script is sitewide and publicly cacheable and - * therefore must not include anything that varies according to user, - * interface language, etc. (although it may vary by skin). See - * makeGlobalVariablesScript for things that can vary per page view and are - * not cacheable. + * generated JavaScript action=raw&gen=js + * This returns MediaWiki:Common.js and MediaWiki:[Skinname].js concate- + * nated together. For some bizarre reason, it does *not* return any + * custom user JS from subpages. Huh? * - * @return string Raw JavaScript to be returned + * There's absolutely no reason to have separate Monobook/Common JSes. + * Any JS that cares can just check the skin variable generated at the + * top. For now Monobook.js will be maintained, but it should be consi- + * dered deprecated. + * + * @return string */ - public function getUserJs() { + public function generateUserJs() { + global $wgStylePath; + wfProfileIn( __METHOD__ ); - global $wgStylePath; $s = "/* generated javascript */\n"; $s .= "var skin = '" . Xml::escapeJsString( $this->getSkinName() ) . "';\n"; $s .= "var stylepath = '" . Xml::escapeJsString( $wgStylePath ) . "';"; @@ -442,45 +471,35 @@ class Skin extends Linker { if ( !wfEmptyMsg ( 'common.js', $commonJs ) ) { $s .= $commonJs; } + + $s .= "\n\n/* MediaWiki:".ucfirst( $this->getSkinName() ).".js */\n"; + // avoid inclusion of non defined user JavaScript (with custom skins only) + // by checking for default message content + $msgKey = ucfirst( $this->getSkinName() ).'.js'; + $userJS = wfMsgForContent($msgKey); + if ( !wfEmptyMsg( $msgKey, $userJS ) ) { + $s .= $userJS; + } + wfProfileOut( __METHOD__ ); return $s; } /** - * Return html code that include User stylesheets + * generate user stylesheet for action=raw&gen=css */ - function getUserStyles() { - $s = "\n"; + public function generateUserStylesheet() { + wfProfileIn( __METHOD__ ); + $s = "/* generated user stylesheet */\n" . + $this->reallyGenerateUserStylesheet(); + wfProfileOut( __METHOD__ ); return $s; } - + /** - * Some styles that are set by user through the user settings interface. + * Split for easier subclassing in SkinSimple, SkinStandard and SkinCologneBlue */ - function doGetUserStyles() { - global $wgUser, $wgUser, $wgRequest, $wgTitle, $wgAllowUserCss; - - $s = ''; - - if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { # logged in - if($wgTitle->isCssSubpage() && $this->userCanPreview( $wgRequest->getText( 'action' ) ) ) { - $s .= $wgRequest->getText('wpTextbox1'); - } else { - $userpage = $wgUser->getUserPage(); - $s.= '@import "'.self::makeUrl( - $userpage->getPrefixedText().'/'.$this->getSkinName().'.css', - 'action=raw&ctype=text/css').'";'."\n"; - } - } - - return $s . $this->reallyDoGetUserStyles(); - } - - function reallyDoGetUserStyles() { + protected function reallyGenerateUserStylesheet(){ global $wgUser; $s = ''; if (($undopt = $wgUser->getOption("underline")) < 2) { @@ -506,7 +525,7 @@ a.stub:after, #quickbar a.stub:after { END; } if( $wgUser->getOption( 'justify' ) ) { - $s .= "#article, #bodyContent { text-align: justify; }\n"; + $s .= "#article, #bodyContent, #mw_content { text-align: justify; }\n"; } if( !$wgUser->getOption( 'showtoc' ) ) { $s .= "#toc { display: none; }\n"; @@ -517,6 +536,86 @@ END; return $s; } + /** + * @private + */ + function setupUserCss( OutputPage $out ) { + global $wgRequest, $wgContLang, $wgUser; + global $wgAllowUserCss, $wgUseSiteCss, $wgSquidMaxage, $wgStylePath; + + wfProfileIn( __METHOD__ ); + + $this->setupSkinUserCss( $out ); + + $siteargs = array( + 'action' => 'raw', + 'maxage' => $wgSquidMaxage, + ); + + // Add any extension CSS + foreach( $out->getExtStyle() as $tag ) { + $out->addStyle( $tag['href'] ); + } + + // If we use the site's dynamic CSS, throw that in, too + // Per-site custom styles + if( $wgUseSiteCss ) { + global $wgHandheldStyle; + $query = wfArrayToCGI( array( + 'usemsgcache' => 'yes', + 'ctype' => 'text/css', + 'smaxage' => $wgSquidMaxage + ) + $siteargs ); + # Site settings must override extension css! (bug 15025) + $out->addStyle( self::makeNSUrl( 'Common.css', $query, NS_MEDIAWIKI ) ); + $out->addStyle( self::makeNSUrl( 'Print.css', $query, NS_MEDIAWIKI ), 'print' ); + if( $wgHandheldStyle ) { + $out->addStyle( self::makeNSUrl( 'Handheld.css', $query, NS_MEDIAWIKI ), 'handheld' ); + } + $out->addStyle( self::makeNSUrl( $this->getSkinName() . '.css', $query, NS_MEDIAWIKI ) ); + } + + if( $wgUser->isLoggedIn() ) { + // Ensure that logged-in users' generated CSS isn't clobbered + // by anons' publicly cacheable generated CSS. + $siteargs['smaxage'] = '0'; + $siteargs['ts'] = $wgUser->mTouched; + } + // Per-user styles based on preferences + $siteargs['gen'] = 'css'; + if( ( $us = $wgRequest->getVal( 'useskin', '' ) ) !== '' ) { + $siteargs['useskin'] = $us; + } + $out->addStyle( self::makeUrl( '-', wfArrayToCGI( $siteargs ) ) ); + + // Per-user custom style pages + if( $wgAllowUserCss && $wgUser->isLoggedIn() ) { + $action = $wgRequest->getVal('action'); + # If we're previewing the CSS page, use it + if( $this->mTitle->isCssSubpage() && $this->userCanPreview( $action ) ) { + $previewCss = $wgRequest->getText('wpTextbox1'); + // @FIXME: properly escape the cdata! + $this->usercss = "/**/"; + } else { + $out->addStyle( self::makeUrl($this->userpage . '/' . $this->getSkinName() .'.css', + 'action=raw&ctype=text/css' ) ); + } + } + + wfProfileOut( __METHOD__ ); + } + + /** + * Add skin specific stylesheets + * @param $out OutputPage + */ + function setupSkinUserCss( OutputPage $out ) { + $out->addStyle( 'common/shared.css' ); + $out->addStyle( 'common/oldshared.css' ); + $out->addStyle( $this->getStylesheet() ); + $out->addStyle( 'common/common_rtl.css', '', '', 'rtl' ); + } + function getBodyOptions() { global $wgUser, $wgTitle, $wgOut, $wgRequest, $wgContLang; @@ -527,25 +626,33 @@ END; } else $a = array( 'bgcolor' => '#FFFFFF' ); if($wgOut->isArticle() && $wgUser->getOption('editondblclick') && - $wgTitle->userCan( 'edit' ) ) { + $wgTitle->quickUserCan( 'edit' ) ) { $s = $wgTitle->getFullURL( $this->editUrlOptions() ); $s = 'document.location = "' .wfEscapeJSString( $s ) .'";'; $a += array ('ondblclick' => $s); } $a['onload'] = $wgOut->getOnloadHandler(); - if( $wgUser->getOption( 'editsectiononrightclick' ) ) { - if( $a['onload'] != '' ) { - $a['onload'] .= ';'; - } - $a['onload'] .= 'setupRightClickEdit()'; - } $a['class'] = - 'mediawiki ns-'.$wgTitle->getNamespace(). - ' '.($wgContLang->isRTL() ? "rtl" : "ltr"). - ' '.Sanitizer::escapeClass( 'page-'.$wgTitle->getPrefixedText() ); + 'mediawiki' . + ' '.( $wgContLang->isRTL() ? "rtl" : "ltr" ). + ' '.$this->getPageClasses( $wgTitle ) . + ' skin-'. Sanitizer::escapeClass( $this->getSkinName( ) ); return $a; } + + function getPageClasses( $title ) { + $numeric = 'ns-'.$title->getNamespace(); + if( $title->getNamespace() == NS_SPECIAL ) { + $type = "ns-special"; + } elseif( $title->isTalkPage() ) { + $type = "ns-talk"; + } else { + $type = "ns-subject"; + } + $name = Sanitizer::escapeClass( 'page-'.$title->getPrefixedText() ); + return "$numeric $type $name"; + } /** * URL to the logo @@ -583,11 +690,11 @@ END; $s .= "\n
\n
\n" . "\n\n"; - $shove = ($qb != 0); - $left = ($qb == 1 || $qb == 3); - if($wgContLang->isRTL()) $left = !$left; + $shove = ( $qb != 0 ); + $left = ( $qb == 1 || $qb == 3 ); + if( $wgContLang->isRTL() ) $left = !$left; - if ( !$shove ) { + if( !$shove ) { $s .= "'; } elseif( $left ) { @@ -626,7 +733,7 @@ END; } - function getCategoryLinks () { + function getCategoryLinks() { global $wgOut, $wgTitle, $wgUseCategoryBrowser; global $wgContLang, $wgUser; @@ -643,13 +750,14 @@ END; $allCats = $wgOut->getCategoryLinks(); $s = ''; + $colon = wfMsgExt( 'colon-separator', 'escapenoentities' ); if ( !empty( $allCats['normal'] ) ) { $t = $embed . implode ( "{$pop} {$sep} {$embed}" , $allCats['normal'] ) . $pop; - - $msg = wfMsgExt( 'pagecategories', array( 'parsemag', 'escape' ), count( $allCats['normal'] ) ); + + $msg = wfMsgExt( 'pagecategories', array( 'parsemag', 'escapenoentities' ), count( $allCats['normal'] ) ); $s .= ''; + $this->link( Title::newFromText( wfMsgForContent('pagecategorieslink') ), $msg ) + . $colon . $t . ''; } # Hidden categories @@ -661,15 +769,15 @@ END; } else { $class = 'mw-hidden-cats-hidden'; } - $s .= "
" . - wfMsgExt( 'hidden-categories', array( 'parsemag', 'escape' ), count( $allCats['hidden'] ) ) . - ': ' . $embed . implode( "$pop $sep $embed", $allCats['hidden'] ) . $pop . + $s .= "
" . + wfMsgExt( 'hidden-categories', array( 'parsemag', 'escapenoentities' ), count( $allCats['hidden'] ) ) . + $colon . $embed . implode( "$pop $sep $embed", $allCats['hidden'] ) . $pop . "
"; } # optional 'dmoz-like' category browser. Will be shown under the list # of categories an article belong to - if($wgUseCategoryBrowser) { + if( $wgUseCategoryBrowser ){ $s .= '

'; # get a big array of the parents tree @@ -692,7 +800,7 @@ END; * @param &skin Object: skin passed by reference * @return String separated by >, terminate with "\n" */ - function drawCategoryBrowser($tree, &$skin) { + function drawCategoryBrowser( $tree, &$skin ){ $return = ''; foreach ($tree as $element => $parent) { if (empty($parent)) { @@ -703,16 +811,24 @@ END; $return .= Skin::drawCategoryBrowser($parent, $skin) . ' > '; } # add our current element to the list - $eltitle = Title::NewFromText($element); - $return .= $skin->makeLinkObj( $eltitle, $eltitle->getText() ) ; + $eltitle = Title::newFromText($element); + $return .= $skin->link( $eltitle, $eltitle->getText() ) ; } return $return; } function getCategories() { $catlinks=$this->getCategoryLinks(); - if(!empty($catlinks)) { - return ""; + + $classes = 'catlinks'; + + if( strpos( $catlinks, '
\n" . $this->logoText() . '