X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FOutputPage.php;h=2c9e064a8f93de3bae260f7136160ca698e304b3;hb=8b3ffea9c2c949b2539bd85b6b902cc90f91dbb6;hp=9f4d61e8e384f19165e956e814076659691c1ed0;hpb=ffa7a050a4dc5cd801af3ac6bd70c709a9536249;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 9f4d61e8e3..2c9e064a8f 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -9,13 +9,22 @@ if ( !defined( 'MEDIAWIKI' ) ) { class OutputPage { var $mMetatags = array(), $mKeywords = array(), $mLinktags = array(); var $mExtStyles = array(); - var $mPagetitle = '', $mBodytext = '', $mDebugtext = ''; + var $mPagetitle = '', $mBodytext = ''; + + /** + * Holds the debug lines that will be outputted as comments in page source if + * $wgDebugComments is enabled. See also $wgShowDebug. + * TODO: make a getter method for this + */ + public $mDebugtext = ''; + var $mHTMLtitle = '', $mIsarticle = true, $mPrintable = false; var $mSubtitle = '', $mRedirect = '', $mStatusCode; var $mLastModified = '', $mETag = false; var $mCategoryLinks = array(), $mCategories = array(), $mLanguageLinks = array(); var $mScripts = '', $mLinkColours, $mPageLinkTitle = '', $mHeadItems = array(); + var $mModules = array(), $mModuleScripts = array(), $mModuleStyles = array(), $mModuleMessages = array(); var $mInlineMsg = array(); var $mTemplateIds = array(); @@ -183,15 +192,19 @@ class OutputPage { * * @param $file String: filename in skins/common or complete on-server path * (/foo/bar.js) + * @param $version String: style version of the file. Defaults to $wgStyleVersion */ - public function addScriptFile( $file ) { + public function addScriptFile( $file, $version = null ) { global $wgStylePath, $wgStyleVersion; + // See if $file parameter is an absolute URL or begins with a slash if( substr( $file, 0, 1 ) == '/' || preg_match( '#^[a-z]*://#i', $file ) ) { $path = $file; } else { $path = "{$wgStylePath}/common/{$file}"; } - $this->addScript( Html::linkedScript( wfAppendQuery( $path, $wgStyleVersion ) ) ); + if ( is_null( $version ) ) + $version = $wgStyleVersion; + $this->addScript( Html::linkedScript( wfAppendQuery( $path, $version ) ) ); } /** @@ -212,6 +225,85 @@ class OutputPage { return $this->mScripts . $this->getHeadItems(); } + /** + * Get the list of modules to include on this page + * + * @return Array of module names + */ + public function getModules() { + return $this->mModules; + } + + /** + * Add one or more modules recognized by the resource loader. Modules added + * through this function will be loaded by the resource loader when the + * page loads. + * + * @param $modules Mixed: module name (string) or array of module names + */ + public function addModules( $modules ) { + $this->mModules = array_merge( $this->mModules, (array)$modules ); + } + + /** + * Get the list of module JS to include on this page + * @return array of module names + */ + public function getModuleScripts() { + return $this->mModuleScripts; + } + + /** + * Add only JS of one or more modules recognized by the resource loader. Module + * scripts added through this function will be loaded by the resource loader when + * the page loads. + * + * @param $modules Mixed: module name (string) or array of module names + */ + public function addModuleScripts( $modules ) { + $this->mModuleScripts = array_merge( $this->mModuleScripts, (array)$modules ); + } + + /** + * Get the list of module CSS to include on this page + * + * @return Array of module names + */ + public function getModuleStyles() { + return $this->mModuleStyles; + } + + /** + * Add only CSS of one or more modules recognized by the resource loader. Module + * styles added through this function will be loaded by the resource loader when + * the page loads. + * + * @param $modules Mixed: module name (string) or array of module names + */ + public function addModuleStyles( $modules ) { + $this->mModuleStyles = array_merge( $this->mModuleStyles, (array)$modules ); + } + + /** + * Get the list of module messages to include on this page + * + * @return Array of module names + */ + public function getModuleMessages() { + return $this->mModuleMessages; + } + + /** + * Add only messages of one or more modules recognized by the resource loader. + * Module messages added through this function will be loaded by the resource + * loader when the page loads. + * + * @param $modules Mixed: module name (string) or array of module names + */ + public function addModuleMessages( $modules ) { + $this->mModuleMessages = array_merge( $this->mModuleMessages, (array)$modules ); + } + /** * Get all header items in a string * @@ -506,7 +598,7 @@ class OutputPage { if ( $this->mTitle instanceof Title ) { return $this->mTitle; } else { - wfDebug( __METHOD__ . ' called and $mTitle is null. Return $wgTitle for sanity' ); + wfDebug( __METHOD__ . " called and \$mTitle is null. Return \$wgTitle for sanity\n" ); global $wgTitle; return $wgTitle; } @@ -765,7 +857,7 @@ class OutputPage { $pageTable = $dbr->tableName( 'page' ); $where = $lb->constructSet( 'page', $dbr ); $propsTable = $dbr->tableName( 'page_props' ); - $sql = "SELECT page_id, page_namespace, page_title, page_len, page_is_redirect, pp_value + $sql = "SELECT page_id, page_namespace, page_title, page_len, page_is_redirect, page_latest, pp_value FROM $pageTable LEFT JOIN $propsTable ON pp_propname='hiddencat' AND pp_page=page_id WHERE $where"; $res = $dbr->query( $sql, __METHOD__ ); @@ -1050,7 +1142,7 @@ class OutputPage { $popts, true, true, $this->mRevisionId ); $popts->setTidy( false ); - if ( $cache && $article && $parserOutput->getCacheTime() != -1 ) { + if ( $cache && $article && $parserOutput->isCacheable() ) { $parserCache = ParserCache::singleton(); $parserCache->save( $parserOutput, $article, $popts ); } @@ -1078,11 +1170,12 @@ class OutputPage { $this->mHideNewSectionLink = $parserOutput->getHideNewSection(); $this->mParseWarnings = $parserOutput->getWarnings(); - if ( $parserOutput->getCacheTime() == -1 ) { + if ( !$parserOutput->isCacheable() ) { $this->enableClientCache( false ); } $this->mNoGallery = $parserOutput->getNoGallery(); $this->mHeadItems = array_merge( $this->mHeadItems, $parserOutput->getHeadItems() ); + $this->addModules( $parserOutput->getModules() ); // Versioning... foreach ( (array)$parserOutput->mTemplateIds as $ns => $dbks ) { if ( isset( $this->mTemplateIds[$ns] ) ) { @@ -1264,7 +1357,7 @@ class OutputPage { $cvCookies = $this->getCacheVaryCookies(); foreach ( $cvCookies as $cookieName ) { # Check for a simple string match, like the way squid does it - if ( strpos( $cookieHeader, $cookieName ) ) { + if ( strpos( $cookieHeader, $cookieName ) !== false ) { wfDebug( __METHOD__ . ": found $cookieName\n" ); return true; } @@ -1476,10 +1569,10 @@ class OutputPage { */ public function output() { global $wgUser, $wgOutputEncoding, $wgRequest; - global $wgContLanguageCode, $wgDebugRedirects, $wgMimeType; + global $wgLanguageCode, $wgDebugRedirects, $wgMimeType; global $wgUseAjax, $wgAjaxWatch; global $wgEnableMWSuggest, $wgUniversalEditButton; - global $wgArticle, $wgJQueryOnEveryPage; + global $wgArticle; if( $this->mDoNothing ) { return; @@ -1516,24 +1609,27 @@ class OutputPage { } $sk = $wgUser->getSkin(); - + + // Add base resources + $this->addModules( array( 'mediawiki.legacy.wikibits' ) ); + + // Add various resources if required if ( $wgUseAjax ) { - $this->addScriptFile( 'ajax.js' ); + $this->addModules( 'mediawiki.legacy.ajax' ); wfRunHooks( 'AjaxAddScript', array( &$this ) ); if( $wgAjaxWatch && $wgUser->isLoggedIn() ) { - $this->includeJQuery(); - $this->addScriptFile( 'ajaxwatch.js' ); + $this->addModules( 'mediawiki.legacy.ajaxwatch' ); } if ( $wgEnableMWSuggest && !$wgUser->getOption( 'disablesuggest', false ) ) { - $this->addScriptFile( 'mwsuggest.js' ); + $this->addModules( 'mediawiki.legacy.mwsuggest' ); } } if( $wgUser->getBoolOption( 'editsectiononrightclick' ) ) { - $this->addScriptFile( 'rightclickedit.js' ); + $this->addModules( 'mediawiki.legacy.rightclickedit' ); } if( $wgUniversalEditButton ) { @@ -1556,15 +1652,12 @@ class OutputPage { } } - if ( $wgJQueryOnEveryPage ) { - $this->includeJQuery(); - } # Buffer output; final headers may depend on later processing ob_start(); $wgRequest->response()->header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" ); - $wgRequest->response()->header( 'Content-language: ' . $wgContLanguageCode ); + $wgRequest->response()->header( 'Content-language: ' . $wgLanguageCode ); if ( $this->mArticleBodyOnly ) { $this->out( $this->mBodytext ); @@ -1789,20 +1882,6 @@ class OutputPage { $this->returnToMain(); } - /** - * @deprecated use permissionRequired() - */ - public function sysopRequired() { - throw new MWException( "Call to deprecated OutputPage::sysopRequired() method\n" ); - } - - /** - * @deprecated use permissionRequired() - */ - public function developerRequired() { - throw new MWException( "Call to deprecated OutputPage::developerRequired() method\n" ); - } - /** * Produce the stock "please login to use the wiki" page */ @@ -1851,7 +1930,6 @@ class OutputPage { if ( $action == null ) { $text = wfMsgNoTrans( 'permissionserrorstext', count( $errors ) ) . "\n\n"; } else { - global $wgLang; $action_desc = wfMsgNoTrans( "action-$action" ); $text = wfMsgNoTrans( 'permissionserrorstext-withaction', @@ -1914,19 +1992,10 @@ class OutputPage { if ( !empty( $reasons ) ) { // Permissions error if( $source ) { - $this->setPageTitle( wfMsg( 'viewsource' ) ); - $this->setSubtitle( - wfMsg( - 'viewsourcefor', - $skin->link( - $this->getTitle(), - null, - array(), - array(), - array( 'known', 'noclasses' ) - ) - ) - ); + $title = $this->getTitle(); + $link = $skin->linkKnown( $title ); + $this->mPagetitle = wfMessage( 'viewsourceheader' )->rawParams( $link )->escaped(); + $this->mHTMLtitle = wfMessage( 'viewsourcetitle', $title->getPrefixedText() )->escaped(); } else { $this->setPageTitle( wfMsg( 'badaccess' ) ); } @@ -1935,7 +2004,7 @@ class OutputPage { // Wiki is read only $this->setPageTitle( wfMsg( 'readonly' ) ); $reason = wfReadOnlyReason(); - $this->wrapWikiMsg( "
\n$1
", array( 'readonlytext', $reason ) ); + $this->wrapWikiMsg( "
\n$1\n
", array( 'readonlytext', $reason ) ); } // Show source, if supplied @@ -1968,6 +2037,28 @@ class OutputPage { } } + /** + * Adds JS-based password security checker + * @param $passwordId String ID of input box containing password + * @param $retypeId String ID of input box containing retyped password + * @return none + */ + public function addPasswordSecurity( $passwordId, $retypeId ) { + $this->includeJQuery(); + $data = array( + 'password' => '#' . $passwordId, + 'retype' => '#' . $retypeId, + 'messages' => array(), + ); + foreach ( array( 'password-strength', 'password-strength-bad', 'password-strength-mediocre', + 'password-strength-acceptable', 'password-strength-good', 'password-retype', 'password-retype-mismatch' + ) as $message ) { + $data['messages'][$message] = wfMsg( $message ); + } + $this->addScript( Html::inlineScript( 'var passwordSecurity=' . FormatJson::encode( $data ) ) ); + $this->addModules( 'mediawiki.legacy.password' ); + } + /** @deprecated */ public function errorpage( $title, $msg ) { wfDeprecated( __METHOD__ ); @@ -2102,18 +2193,16 @@ class OutputPage { * @return String: The doctype, opening , and head element. */ public function headElement( Skin $sk, $includeStyle = true ) { - global $wgContLanguageCode, $wgOutputEncoding, $wgMimeType; - global $wgContLang, $wgUseTrackbacks, $wgStyleVersion, $wgHtml5; + global $wgOutputEncoding, $wgMimeType; + global $wgUseTrackbacks, $wgHtml5; global $wgUser, $wgRequest, $wgLang; if ( $sk->commonPrintStylesheet() ) { - $this->addStyle( 'common/wikiprintable.css', 'print' ); + $this->addModuleStyles( 'mediawiki.legacy.wikiprintable' ); } $sk->setupUserCss( $this ); - $dir = $wgContLang->getDir(); - $htmlAttribs = array( 'lang' => $wgContLanguageCode, 'dir' => $dir ); - $ret = Html::htmlHeader( $htmlAttribs ); + $ret = Html::htmlHeader( array( 'lang' => wfUILang()->getCode() ) ); if ( $this->getHTMLTitle() == '' ) { $this->setHTMLTitle( wfMsg( 'pagetitle', $this->getPageTitle() ) ); @@ -2136,9 +2225,9 @@ class OutputPage { $ret .= Html::element( 'title', null, $this->getHTMLTitle() ) . "\n"; $ret .= implode( "\n", array( - $this->getHeadLinks(), + $this->getHeadLinks( $sk ), $this->buildCssLinks(), - $this->getHeadScripts( $sk ) . $this->getHeadItems(), + $this->getHeadItems(), ) ); if ( $sk->usercss ) { $ret .= Html::inlineStyle( $sk->usercss ); @@ -2168,6 +2257,7 @@ class OutputPage { } # Class bloat + $dir = wfUILang()->getDir(); $bodyAttrs['class'] = "mediawiki $dir"; if ( $wgLang->capitalizeAllNouns() ) { @@ -2189,56 +2279,164 @@ class OutputPage { return $ret; } - + + // TODO: Document + static function makeResourceLoaderLink( $skin, $modules, $only, $useESI = false ) { + global $wgUser, $wgLang, $wgRequest, $wgLoadScript, $wgResourceLoaderDebug, $wgResourceLoaderUseESI, + $wgResourceLoaderInlinePrivateModules; + // TODO: Should this be a static function of ResourceLoader instead? + // TODO: Divide off modules starting with "user", and add the user parameter to them + $query = array( + 'lang' => $wgLang->getCode(), + 'debug' => $wgRequest->getFuzzyBool( 'debug', $wgResourceLoaderDebug ) ? 'true' : 'false', + 'skin' => $wgUser->getSkin()->getSkinName(), + 'only' => $only, + ); + // Remove duplicate module requests + $modules = array_unique( (array) $modules ); + // Sort module names so requests are more uniform + sort( $modules ); + // Create keyed-by-group list of module objects from modules list + $groups = array(); + foreach ( (array) $modules as $name ) { + $module = ResourceLoader::getModule( $name ); + $group = $module->getGroup(); + if ( !isset( $groups[$group] ) ) { + $groups[$group] = array(); + } + $groups[$group][$name] = $module; + } + $links = ''; + foreach ( $groups as $group => $modules ) { + $query['modules'] = implode( '|', array_keys( $modules ) ); + // Special handling for user-specific groups + if ( ( $group === 'user' || $group === 'private' ) && $wgUser->isLoggedIn() ) { + $query['user'] = $wgUser->getName(); + } + // Support inlining of private modules if configured as such + if ( $group === 'private' && $wgResourceLoaderInlinePrivateModules ) { + $context = new ResourceLoaderContext( new FauxRequest( $query ) ); + if ( $only == 'styles' ) { + $links .= Html::inlineStyle( + ResourceLoader::makeLoaderConditionalScript( + ResourceLoader::makeModuleResponse( $context, $modules ) + ) + ); + } else { + $links .= Html::inlineScript( + ResourceLoader::makeLoaderConditionalScript( + ResourceLoader::makeModuleResponse( $context, $modules ) + ) + ); + } + continue; + } + // Special handling for user and site groups; because users might change their stuff on-wiki like site or + // user pages, or user preferences; we need to find the highest timestamp of these user-changable modules so + // we can ensure cache misses on change + if ( $group === 'user' || $group === 'site' ) { + // Create a fake request based on the one we are about to make so modules return correct times + $context = new ResourceLoaderContext( new FauxRequest( $query ) ); + // Get the maximum timestamp + $timestamp = 0; + foreach ( $modules as $module ) { + $timestamp = max( $timestamp, $module->getModifiedTime( $context ) ); + } + // Add a version parameter so cache will break when things change + $query['version'] = wfTimestamp( TS_ISO_8601, round( $timestamp, -2 ) ); + } + // Make queries uniform in order + ksort( $query ); + + $url = wfAppendQuery( $wgLoadScript, $query ); + if ( $useESI && $wgResourceLoaderUseESI ) { + $esi = Xml::element( 'esi:include', array( 'src' => $url ) ); + if ( $only == 'styles' ) { + $links .= Html::inlineStyle( $esi ); + } else { + $links .= Html::inlineScript( $esi ); + } + } else { + // Automatically select style/script elements + if ( $only === 'styles' ) { + $links .= Html::linkedStyle( wfAppendQuery( $wgLoadScript, $query ) ) . "\n"; + } else { + $links .= Html::linkedScript( wfAppendQuery( $wgLoadScript, $query ) ) . "\n"; + } + } + } + return $links; + } + /** * Gets the global variables and mScripts; also adds userjs to the end if - * enabled + * enabled. Despite the name, these scripts are no longer put in the + * but at the bottom of the * * @param $sk Skin object to use * @return String: HTML fragment */ function getHeadScripts( Skin $sk ) { - global $wgUser, $wgRequest, $wgJsMimeType, $wgUseSiteJs; - global $wgStylePath, $wgStyleVersion; - - $scripts = Skin::makeGlobalVariablesScript( $sk->getSkinName() ) . "\n"; - $scripts .= Html::linkedScript( "{$wgStylePath}/common/wikibits.js?$wgStyleVersion" ); - - // add site JS if enabled - if( $wgUseSiteJs ) { - $jsCache = $wgUser->isLoggedIn() ? '&smaxage=0' : ''; - $this->addScriptFile( - Skin::makeUrl( - '-', - "action=raw$jsCache&gen=js&useskin=" . - urlencode( $sk->getSkinName() ) - ) - ); + global $wgUser, $wgRequest, $wgUseSiteJs, $wgResourceLoaderDebug; + + // Startup - this will immediately load jquery and mediawiki modules + $scripts = self::makeResourceLoaderLink( $sk, 'startup', 'scripts', true ); + + // Configuration -- This could be merged together with the load and go, but makeGlobalVariablesScript returns a + // whole script tag -- grumble grumble... + $scripts .= Skin::makeGlobalVariablesScript( $sk->getSkinName() ) . "\n"; + + // Script and Messages "only" + if ( $wgRequest->getFuzzyBool( 'debug', $wgResourceLoaderDebug ) ) { + // Scripts + foreach ( $this->getModuleScripts() as $name ) { + $scripts .= self::makeResourceLoaderLink( $sk, $name, 'scripts' ); + } + // Messages + foreach ( $this->getModuleMessages() as $name ) { + $scripts .= self::makeResourceLoaderLink( $sk, $name, 'messages' ); + } + } else { + // Scripts + if ( count( $this->getModuleScripts() ) ) { + $scripts .= self::makeResourceLoaderLink( $sk, $this->getModuleScripts(), 'scripts' ); + } + // Messages + if ( count( $this->getModuleMessages() ) ) { + $scripts .= self::makeResourceLoaderLink( $sk, $this->getModuleMessages(), 'messages' ); + } } - - // add user JS if enabled - if( $this->isUserJsAllowed() && $wgUser->isLoggedIn() ) { + + // Modules - let the client calculate dependencies and batch requests as it likes + if ( $this->getModules() ) { + $modules = FormatJson::encode( $this->getModules() ); + $scripts .= Html::inlineScript( + "if ( window.mediaWiki ) { mediaWiki.loader.load( {$modules} ); mediaWiki.loader.go(); }" + ) . "\n"; + } + + // Add user JS if enabled - trying to load user.options as a bundle if possible + $userOptionsAdded = false; + if ( $this->isUserJsAllowed() && $wgUser->isLoggedIn() ) { $action = $wgRequest->getVal( 'action', 'view' ); if( $this->mTitle && $this->mTitle->isJsSubpage() && $sk->userCanPreview( $action ) ) { # XXX: additional security check/prompt? $this->addInlineScript( $wgRequest->getText( 'wpTextbox1' ) ); } else { - $userpage = $wgUser->getUserPage(); - $names = array( 'common', $sk->getSkinName() ); - foreach( $names as $name ) { - $scriptpage = Title::makeTitleSafe( - NS_USER, - $userpage->getDBkey() . '/' . $name . '.js' - ); - if ( $scriptpage && $scriptpage->exists() ) { - $userjs = $scriptpage->getLocalURL( 'action=raw&ctype=' . $wgJsMimeType ); - $this->addScriptFile( $userjs ); - } - } + $scripts .= self::makeResourceLoaderLink( $sk, array( 'user', 'user.options' ), 'scripts' ); + $userOptionsAdded = true; } } - + if ( !$userOptionsAdded ) { + $scripts .= self::makeResourceLoaderLink( $sk, 'user.options', 'scripts' ); + } $scripts .= "\n" . $this->mScripts; + + // Add site JS if enabled + if ( $wgUseSiteJs ) { + $scripts .= self::makeResourceLoaderLink( $sk, 'site', 'scripts' ); + } + return $scripts; } @@ -2286,8 +2484,8 @@ class OutputPage { /** * @return string HTML tag links to be put in the header. */ - public function getHeadLinks() { - global $wgFeed; + public function getHeadLinks( $sk ) { + global $wgFeed, $wgRequest, $wgResourceLoaderDebug; // Ideally this should happen earlier, somewhere. :P $this->addDefaultMeta(); @@ -2357,6 +2555,17 @@ class OutputPage { } } + // Support individual script requests in debug mode + if ( $wgRequest->getFuzzyBool( 'debug', $wgResourceLoaderDebug ) ) { + foreach ( $this->getModuleStyles() as $name ) { + $tags[] = self::makeResourceLoaderLink( $sk, $name, 'styles' ); + } + } else { + if ( count( $this->getModuleStyles() ) ) { + $tags[] = self::makeResourceLoaderLink( $sk, $this->getModuleStyles(), 'styles' ); + } + } + return implode( "\n", $tags ); } @@ -2415,15 +2624,18 @@ class OutputPage { * These will be applied to various media & IE conditionals. */ public function buildCssLinks() { + return implode( "\n", $this->buildCssLinksArray() ); + } + + public function buildCssLinksArray() { $links = array(); foreach( $this->styles as $file => $options ) { $link = $this->styleLink( $file, $options ); if( $link ) { - $links[] = $link; + $links[$file] = $link; } } - - return implode( "\n", $links ); + return $links; } /** @@ -2436,8 +2648,7 @@ class OutputPage { */ protected function styleLink( $style, $options ) { if( isset( $options['dir'] ) ) { - global $wgContLang; - $siteDir = $wgContLang->getDir(); + $siteDir = wfUILang()->getDir(); if( $siteDir != $options['dir'] ) { return ''; } @@ -2587,11 +2798,11 @@ class OutputPage { * * For example: * - * $wgOut->wrapWikiMsg( "
\n$1
", 'some-error' ); + * $wgOut->wrapWikiMsg( "
\n$1\n
", 'some-error' ); * * Is equivalent to: * - * $wgOut->addWikiText( "
\n" . wfMsgNoTrans( 'some-error' ) . '
' ); + * $wgOut->addWikiText( "
\n" . wfMsgNoTrans( 'some-error' ) . "\n
" ); * * The newline after opening div is needed in some wikitext. See bug 19226. */ @@ -2625,20 +2836,10 @@ class OutputPage { * @param $modules Array: list of jQuery modules which should be loaded * @return Array: the list of modules which were not loaded. * @since 1.16 + * @deprecated No longer needed as of 1.17 */ public function includeJQuery( $modules = array() ) { - global $wgStylePath, $wgStyleVersion, $wgJQueryVersion, $wgJQueryMinified; - - $supportedModules = array( /** TODO: add things here */ ); - $unsupported = array_diff( $modules, $supportedModules ); - - $min = $wgJQueryMinified ? '.min' : ''; - $url = "$wgStylePath/common/jquery-$wgJQueryVersion$min.js?$wgStyleVersion"; - if ( !$this->mJQueryDone ) { - $this->mJQueryDone = true; - $this->mScripts = Html::linkedScript( $url ) . "\n" . $this->mScripts; - } - return $unsupported; + return array(); } }