var $mCategoryLinks = array(), $mLanguageLinks = array();
var $mScriptLoaderClassList = array();
- // the most recent id of any script that is grouped in the script request
- var $mLatestScriptRevID = 0;
+
+ // The most recent revision ID of any script that is grouped in the script request
+ var $mLatestScriptRevID = 0;
var $mScripts = '', $mLinkColours, $mPageLinkTitle = '', $mHeadItems = array();
var $mTemplateIds = array();
array_push( $this->mKeywords, $text );
}
}
- function addScript( $script ) { $this->mScripts .= "\t\t" . $script . "\n"; }
+ function addScript( $script ) {
+ $this->mScripts .= $script . "\n";
+ }
/**
- * Register and add a stylesheet from an extension directory.
+ * Register and add a stylesheet from an extension directory.
* @param $url String path to sheet. Provide either a full url (beginning
* with 'http', etc) or a relative path from the document root
* (beginning with '/'). Otherwise it behaves identically to
* addStyle() and draws from the /skins folder.
*/
public function addExtensionStyle( $url ) {
- $linkarr = array( 'rel' => 'stylesheet', 'href' => $url, 'type' => 'text/css' );
- array_push( $this->mExtStyles, $linkarr );
+ array_push( $this->mExtStyles, $url );
}
/**
* @param string $file filename in skins/common or complete on-server path (/foo/bar.js)
*/
function addScriptFile( $file ) {
- global $wgStylePath, $wgStyleVersion, $wgJsMimeType, $wgScript, $wgUser;
+ global $wgStylePath, $wgScript, $wgUser;
global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgEnableScriptLoader, $wgScriptPath;
if( substr( $file, 0, 1 ) == '/' ) {
$path = "{$wgStylePath}/common/{$file}";
}
- if( $wgEnableScriptLoader ){
- if( strpos( $path, $wgScript ) !== false ){
+ if( $wgEnableScriptLoader ) {
+ if( strpos( $path, $wgScript ) !== false ) {
$reqPath = str_replace( $wgScript . '?', '', $path );
$reqArgs = explode( '&', $reqPath );
$reqSet = array();
- foreach( $reqArgs as $arg ){
+ foreach( $reqArgs as $arg ) {
list( $key, $var ) = explode( '=', $arg );
$reqSet[$key] = $var;
}
if( isset( $reqSet['title'] ) && $reqSet != '' ) {
- // extract any extra param (for now just skin)
- $ext_param = ( isset( $reqSet['useskin'] ) && $reqSet['useskin'] != '' ) ? '|useskin=' . ucfirst( $reqSet['useskin'] ) : '';
+ // Extract any extra parameters (for now just skin)
+ $ext_param = ( isset( $reqSet['useskin'] ) && $reqSet['useskin'] != '' )
+ ? '|useskin=' . ucfirst( $reqSet['useskin'] ) : '';
$this->mScriptLoaderClassList[] = 'WT:' . $reqSet['title'] . $ext_param ;
- // add the title revision to the key
+ // Add the title revision to the key.
+ // If there is no title, we will just use $wgStyleVersion,
+ // which should be updated on the relevant commits.
$t = Title::newFromText( $reqSet['title'] );
- // if there is no title (don't worry we just use the $wgStyleVersion var (which should be updated on relevant commits)
- if( $t && $t->exists() ){
+ if( $t && $t->exists() ) {
if( $t->getLatestRevID() > $this->mLatestScriptRevID )
$this->mLatestScriptRevID = $t->getLatestRevID();
}
}
}
- // check for class from path:
+ // If the class can be determined, add it to the class list to be loaded later
$js_class = $this->getJsClassFromPath( $path );
- if( $js_class ){
- // add to the class list:
+ if( $js_class ) {
$this->mScriptLoaderClassList[] = $js_class;
return true;
}
}
- // if the script loader did not find a way to add the script than add using addScript
- $this->addScript(
- Xml::element( 'script',
- array(
- 'type' => $wgJsMimeType,
- 'src' => wfAppendQuery( $path, $this->getURIDparam() ),
- ),
- '', false
- )
- );
+ // If the script loader could not be used, just add the script to the header
+ $this->addScript( Html::linkedScript( wfAppendQuery( $path, $this->getURIDparam() ) ) );
}
/**
- * This is the core script that is included on every page
- * (they are requested separately to improve caching across
- * different page load types (edit, upload, view, etc)
+ * Add the core scripts that are included on every page, for later output into the header
*/
function addCoreScripts2Top(){
- global $wgEnableScriptLoader, $wgStyleVersion, $wgJSAutoloadLocalClasses, $wgJsMimeType, $wgScriptPath, $wgEnableJS2system;
- //@@todo we should deprecate wikibits in favor of mv_embed and native jQuery functions
+ global $wgEnableScriptLoader, $wgJSAutoloadLocalClasses, $wgScriptPath, $wgEnableJS2system;
+ // @todo We should deprecate wikibits in favor of mv_embed and jQuery
if( $wgEnableJS2system ){
$core_classes = array( 'window.jQuery', 'mv_embed', 'wikibits' );
$so = '';
foreach( $core_classes as $s ){
if( isset( $wgJSAutoloadLocalClasses[$s] ) ){
- $so.= Xml::element( 'script', array(
- 'type' => $wgJsMimeType,
- 'src' => "{$wgScriptPath}/{$wgJSAutoloadLocalClasses[$s]}?" . $this->getURIDparam()
- ),
- '', false
- );
+ $so .= Html::linkedScript( "{$wgScriptPath}/{$wgJSAutoloadLocalClasses[$s]}?" . $this->getURIDparam() );
}
}
$this->mScripts = $so . $this->mScripts;
}
/**
- * @param $js_class String: name of JavaScript class
- * @return Boolean: false if class wasn't found, true on success
+ * @param $js_class string Name of the JavaScript class
+ * @return boolean False if the class wasn't found, true on success
*/
function addScriptClass( $js_class ){
- global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgJsMimeType,
+ global $wgDebugJavaScript, $wgJSAutoloadLocalClasses, $wgJSAutoloadClasses,
$wgEnableScriptLoader, $wgStyleVersion, $wgScriptPath;
- if( isset( $wgJSAutoloadClasses[$js_class] ) || isset( $wgJSAutoloadLocalClasses[$js_class] ) ){
- if( $wgEnableScriptLoader ){
- if( !in_array( $js_class, $this->mScriptLoaderClassList ) ){
+ if( isset( $wgJSAutoloadClasses[$js_class] )
+ || isset( $wgJSAutoloadLocalClasses[$js_class] ) )
+ {
+ if( $wgEnableScriptLoader ) {
+ // Register it with the script loader
+ if( !in_array( $js_class, $this->mScriptLoaderClassList ) ) {
$this->mScriptLoaderClassList[] = $js_class;
}
} else {
- // do a normal load of without the script-loader:
+ // Source the script directly
$path = $wgScriptPath . '/';
- $path.= isset( $wgJSAutoloadClasses[$js_class] ) ? $wgJSAutoloadClasses[$js_class]:
- $wgJSAutoloadLocalClasses[$js_class];
- $this->addScript(
- Xml::element( 'script',
- array(
- 'type' => $wgJsMimeType,
- 'src' => "$path?$wgStyleVersion",
- ),
- '', false
- )
- );
+ if( isset( $wgJSAutoloadClasses[$js_class] ) ) {
+ $path .= $wgJSAutoloadClasses[$js_class];
+ } elseif( isset( $wgJSAutoloadLocalClasses[$js_class] ) ) {
+ $path .= $wgJSAutoloadLocalClasses[$js_class];
+ }
+ $urlAppend = ( $wgDebugJavaScript ) ? time() : $wgStyleVersion;
+ $this->addScript( Html::linkedScript( "$path?$urlAppend" ) );
}
return true;
}
}
/**
- * gets the scriptLoader javascript include
- * @param $forcClassAry Boolean: false by default
+ * Get the <script> tag which will invoke the script loader
+ * @param $classAry A class array which, if given, overrides $this->mScriptLoaderClassList
*/
- function getScriptLoaderJs( $forceClassAry = false ){
- global $wgScriptPath, $wgJsMimeType, $wgStyleVersion, $wgRequest, $wgDebugJavaScript;
-
- if( !$forceClassAry ){
- $class_list = implode( ',', $this->mScriptLoaderClassList );
- } else {
- $class_list = implode( ',', $forceClassAry );
+ function getScriptLoaderJs( $classAry = array() ) {
+ global $wgRequest, $wgDebugJavaScript;
+ // If no class array was provided, use mScriptLoaderClassList
+ if( !count( $classAry ) ) {
+ $classAry = $this->mScriptLoaderClassList;
}
+ $class_list = implode( ',', $classAry );
$debug_param = ( $wgDebugJavaScript ||
$wgRequest->getVal( 'debug' ) == 'true' ||
$wgRequest->getVal( 'debug' ) == '1' )
? '&debug=true' : '';
- //@@todo intelligent unique id generation based on svn version of file (rather than just grabbing the $wgStyleVersion var)
- //@@todo we should check the packaged message text in this javascript file for updates and update the $mScriptLoaderURID id (in getJsClassFromPath)
-
- //generate the unique request param (combine with the most recent revision id of any wiki page with the $wgStyleVersion var)
-
-
- return Xml::element( 'script',
- array(
- 'type' => $wgJsMimeType,
- 'src' => "$wgScriptPath/mwScriptLoader.php?class={$class_list}{$debug_param}&".$this->getURIDparam(),
- ),
- '', false
- );
+ return Html::linkedScript( wfScript( 'mwScriptLoader' ) .
+ "?class={$class_list}{$debug_param}&" . $this->getURIDparam( $classAry) );
}
- function getURIDparam(){
- global $wgDebugJavaScript, $wgStyleVersion;
- if( $wgDebugJavaScript ){
+ /**
+ * Get the unique request ID parameter for the script-loader request
+ */
+ function getURIDparam( $classAry = array() ) {
+ global $wgDebugJavaScript, $wgStyleVersion, $IP, $wgScriptModifiedCheck;
+ if( $wgDebugJavaScript ) {
return 'urid=' . time();
} else {
- return "urid={$wgStyleVersion}_{$this->mLatestScriptRevID}";
+ $ftime=0;
+ if($wgScriptModifiedCheck) {
+ foreach( $classAry as $class ) {
+ $js_path = jsScriptLoader::getJsPathFromClass( $class );
+ if( $js_path ) {
+ $cur_ftime = filemtime ( $IP ."/". $js_path );
+ if( $cur_ftime > $ftime )
+ $ftime = $cur_ftime;
+ }
+ }
+ }
+ $urid = "urid={$wgStyleVersion}";
+
+ // Add the latest revision ID if we have it
+ if($this->mLatestScriptRevID != 0 )
+ $urid .= "_{$this->mLatestScriptRevID}";
+
+ // Add the file modification time
+ if( $ftime != 0 )
+ $urid .= "_".$ftime;
+
+ return $urid;
}
}
- function getJsClassFromPath( $path ){
+ /**
+ * Given a script path, get the JS class name, or false if no such path is registered.
+ * @param $path string
+ */
+ function getJsClassFromPath( $path ) {
global $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses, $wgScriptPath;
$scriptLoaderPaths = array_merge( $wgJSAutoloadClasses, $wgJSAutoloadLocalClasses );
- foreach( $scriptLoaderPaths as $js_class => $js_path ){
+ foreach( $scriptLoaderPaths as $js_class => $js_path ) {
$js_path = "{$wgScriptPath}/{$js_path}";
if( $path == $js_path )
return $js_class;
* @param string $script JavaScript text, no <script> tags
*/
function addInlineScript( $script ) {
- global $wgJsMimeType;
- $this->mScripts .= "\t\t<script type=\"$wgJsMimeType\">/*<![CDATA[*/\n\t\t$script\n\t\t/*]]>*/</script>\n";
+ $this->mScripts .= Html::inlineScript( "\n$script\n" ) . "\n";
}
+ /**
+ * Get all registered JS and CSS tags for the header.
+ */
function getScript() {
global $wgEnableScriptLoader;
if( $wgEnableScriptLoader ){
- //include $this->mScripts (for anything that we could not package into the scriptloader
return $this->mScripts . "\n" . $this->getScriptLoaderJs() . $this->getHeadItems();
} else {
return $this->mScripts . $this->getHeadItems();
function setETag($tag) { $this->mETag = $tag; }
function setArticleBodyOnly($only) { $this->mArticleBodyOnly = $only; }
- function getArticleBodyOnly($only) { return $this->mArticleBodyOnly; }
+ function getArticleBodyOnly() { return $this->mArticleBodyOnly; }
function addLink( $linkarr ) {
# $linkarr should be an associative array of attributes. We'll escape on output.
* @return null
*/
public function setRobotPolicy( $policy ) {
- $policy = explode( ',', $policy );
- $policy = array_map( 'trim', $policy );
-
- # The default policy is follow, so if nothing is said explicitly, we
- # do that.
- if( in_array( 'nofollow', $policy ) ) {
- $this->mFollowPolicy = 'nofollow';
- } else {
- $this->mFollowPolicy = 'follow';
- }
+ $policy = Article::formatRobotPolicy( $policy );
- if( in_array( 'noindex', $policy ) ) {
- $this->mIndexPolicy = 'noindex';
- } else {
- $this->mIndexPolicy = 'index';
- }
+ if( isset( $policy['index'] ) ){
+ $this->setIndexPolicy( $policy['index'] );
+ }
+ if( isset( $policy['follow'] ) ){
+ $this->setFollowPolicy( $policy['follow'] );
+ }
}
/**
$this->mNewSectionLink = $parserOutput->getNewSection();
$this->mHideNewSectionLink = $parserOutput->getHideNewSection();
- if( is_null( $wgExemptFromUserRobotsControl ) ) {
- $bannedNamespaces = $wgContentNamespaces;
- } else {
- $bannedNamespaces = $wgExemptFromUserRobotsControl;
- }
- if( !in_array( $this->getTitle()->getNamespace(), $bannedNamespaces ) ) {
- # FIXME (bug 14900): This overrides $wgArticleRobotPolicies, and it
- # shouldn't
- $this->setIndexPolicy( $parserOutput->getIndexPolicy() );
- }
-
$this->mParseWarnings = $parserOutput->getWarnings();
if ( $parserOutput->getCacheTime() == -1 ) {
$this->enableClientCache( false );
public function output() {
global $wgUser, $wgOutputEncoding, $wgRequest;
global $wgContLanguageCode, $wgDebugRedirects, $wgMimeType;
- global $wgJsMimeType, $wgUseAjax, $wgAjaxWatch;
+ global $wgUseAjax, $wgAjaxWatch;
global $wgEnableMWSuggest, $wgUniversalEditButton;
global $wgArticle;
$sk = $wgUser->getSkin();
- // add our core scripts to output
+ // Add our core scripts to output
$this->addCoreScripts2Top();
if ( $wgUseAjax ) {
$this->addScriptFile( 'rightclickedit.js' );
}
+ global $wgUseAJAXCategories;
+ if ($wgUseAJAXCategories) {
+ $this->addScriptClass( 'ajaxCategories' );
+ }
+
if( $wgUniversalEditButton ) {
if( isset( $wgArticle ) && $this->getTitle() && $this->getTitle()->quickUserCan( 'edit' )
&& ( $this->getTitle()->exists() || $this->getTitle()->quickUserCan( 'create' ) ) ) {
// Original UniversalEditButton
+ $msg = wfMsg('edit');
$this->addLink( array(
'rel' => 'alternate',
'type' => 'application/x-wiki',
- 'title' => wfMsg( 'edit' ),
+ 'title' => $msg,
'href' => $this->getTitle()->getLocalURL( 'action=edit' )
) );
// Alternate edit link
$this->addLink( array(
'rel' => 'edit',
- 'title' => wfMsg( 'edit' ),
+ 'title' => $msg,
'href' => $this->getTitle()->getLocalURL( 'action=edit' )
) );
}
if ( $returnto == null ) {
$returnto = $wgRequest->getText( 'returnto' );
}
-
+
if ( $returntoquery == null ) {
$returntoquery = $wgRequest->getText( 'returntoquery' );
}
$this->setHTMLTitle( wfMsg( 'pagetitle', $this->getPageTitle() ));
}
- $dir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
+ $dir = $wgContLang->getDir();
if ( $wgHtml5 ) {
$ret .= "<!doctype html>\n";
$ret .= "xml:lang=\"$wgContLanguageCode\" lang=\"$wgContLanguageCode\" dir=\"$dir\">\n";
}
- $ret .= "<head>\n\t<title>" . htmlspecialchars( $this->getHTMLTitle() ) . "</title>\n\t";
+ $ret .= "<head>\n";
+ $ret .= "<title>" . htmlspecialchars( $this->getHTMLTitle() ) . "</title>\n";
$ret .= implode( "\n", array(
$this->getHeadLinks(),
$this->buildCssLinks(),
$this->getHeadItems(),
));
if( $sk->usercss ){
- $ret .= "<style type='text/css'>{$sk->usercss}</style>";
+ $ret .= Html::inlineStyle( $sk->usercss );
}
if( $wgEnableScriptLoader )
}
}
- return implode( "\n\t", $tags ) . "\n";
+ return implode( "\n", $tags ) . "\n";
}
/**
*/
public function addStyle( $style, $media='', $condition='', $dir='' ) {
$options = array();
+ // Even though we expect the media type to be lowercase, but here we
+ // force it to lowercase to be safe.
if( $media )
$options['media'] = $media;
if( $condition )
* @param $style_css Mixed: inline CSS
*/
public function addInlineStyle( $style_css ){
- $this->mScripts .= "<style type=\"text/css\">$style_css</style>";
+ $this->mScripts .= Html::inlineStyle( $style_css );
}
/**
$links[] = $link;
}
- return "\t" . implode( "\n\t", $links );
+ return implode( "\n", $links );
}
protected function styleLink( $style, $options ) {
if( isset( $options['dir'] ) ) {
global $wgContLang;
- $siteDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
+ $siteDir = $wgContLang->getDir();
if( $siteDir != $options['dir'] )
return '';
}
return '';
}
} else {
- $media = '';
+ $media = 'all';
}
if( substr( $style, 0, 1 ) == '/' ||
$url = $wgStylePath . '/' . $style . '?' . $wgStyleVersion;
}
- $attribs = array(
- 'rel' => 'stylesheet',
- 'href' => $url,
- 'type' => 'text/css' );
- if( $media ) {
- $attribs['media'] = $media;
- }
-
- $link = Xml::element( 'link', $attribs );
+ $link = Html::linkedStyle( $url, $media );
if( isset( $options['condition'] ) ) {
$condition = htmlspecialchars( $options['condition'] );