* @alternateClassName mediaWiki
* @singleton
*/
-/*jshint latedef:false */
+
+/* eslint-disable no-use-before-define */
+
( function ( $ ) {
'use strict';
* @return {string} hash as an seven-character base 36 string
*/
function fnv132( str ) {
- /*jshint bitwise:false */
+ /* eslint-disable no-bitwise */
var hash = 0x811C9DC5,
i;
}
return hash;
+ /* eslint-enable no-bitwise */
}
StringSet = window.Set || ( function () {
var text;
if ( !this.exists() ) {
- // Use <key> as text if key does not exist
- if ( this.format === 'escaped' || this.format === 'parse' ) {
- // format 'escaped' and 'parse' need to have the brackets and key html escaped
- return mw.html.escape( '<' + this.key + '>' );
- }
- return '<' + this.key + '>';
+ // Use ⧼key⧽ as text if key does not exist
+ // Err on the side of safety, ensure that the output
+ // is always html safe in the event the message key is
+ // missing, since in that case its highly likely the
+ // message key is user-controlled.
+ // '⧼' is used instead of '<' to side-step any
+ // double-escaping issues.
+ // (Keep synchronised with Message::toString() in PHP.)
+ return '⧼' + mw.html.escape( this.key ) + '⧽';
}
if ( this.format === 'plain' || this.format === 'text' || this.format === 'parse' ) {
log.deprecate = !Object.defineProperty ? function ( obj, key, val ) {
obj[ key ] = val;
} : function ( obj, key, val, msg, logName ) {
+ var logged = new StringSet();
logName = logName || key;
msg = 'Use of "' + logName + '" is deprecated.' + ( msg ? ( ' ' + msg ) : '' );
- var logged = new StringSet();
function uniqueTrace() {
var trace = new Error().stack;
if ( logged.has( trace ) ) {
}
if ( registry[ module ].skip !== null ) {
- /*jshint evil:true */
+ // eslint-disable-next-line no-new-func
skip = new Function( registry[ module ].skip );
registry[ module ].skip = null;
if ( skip() ) {
) );
}
- unresolved.add( module );
+ unresolved.add( module );
sortDependencies( deps[ i ], resolved, unresolved );
}
}
* @private
* @param {string[]} modules Array of string module names
* @return {Array} List of dependencies, including 'module'.
+ * @throws {Error} If an unregistered module or a dependency loop is encountered
*/
function resolve( modules ) {
var resolved = [];
} );
};
- implicitDependencies = ( $.inArray( module, legacyModules ) !== -1 )
- ? []
- : legacyModules;
+ implicitDependencies = ( $.inArray( module, legacyModules ) !== -1 ) ?
+ [] :
+ legacyModules;
if ( module === 'user' ) {
// Implicit dependency on the site module. Not real dependency because
implicitDependencies.push( 'site' );
}
- legacyWait = implicitDependencies.length
- ? mw.loader.using( implicitDependencies )
- : $.Deferred().resolve();
+ legacyWait = implicitDependencies.length ?
+ mw.loader.using( implicitDependencies ) :
+ $.Deferred().resolve();
legacyWait.always( function () {
try {
prefix = modules[ i ].substr( 0, lastDotIndex );
suffix = modules[ i ].slice( lastDotIndex + 1 );
- bytesAdded = hasOwn.call( moduleMap, prefix )
- ? suffix.length + 3 // '%2C'.length == 3
- : modules[ i ].length + 3; // '%7C'.length == 3
+ bytesAdded = hasOwn.call( moduleMap, prefix ) ?
+ suffix.length + 3 : // '%2C'.length == 3
+ modules[ i ].length + 3; // '%7C'.length == 3
// If the url would become too long, create a new one,
// but don't create empty requests
return true;
} );
asyncEval( implementations, function ( err ) {
+ var failed;
// Not good, the cached mw.loader.implement calls failed! This should
// never happen, barring ResourceLoader bugs, browser bugs and PEBKACs.
// Depending on how corrupt the string is, it is likely that some
mw.track( 'resourceloader.exception', { exception: err, source: 'store-eval' } );
// Re-add the failed ones that are still pending back to the batch
- var failed = $.grep( sourceModules, function ( module ) {
+ failed = $.grep( sourceModules, function ( module ) {
return registry[ module ].state === 'loading';
} );
batchRequest( failed );
deferred.fail( error );
}
- // Resolve entire dependency map
- dependencies = resolve( dependencies );
+ try {
+ // Resolve entire dependency map
+ dependencies = resolve( dependencies );
+ } catch ( e ) {
+ return deferred.reject( e ).promise();
+ }
if ( allReady( dependencies ) ) {
// Run ready immediately
deferred.resolve( mw.loader.require );
// Partial descriptor
// (e.g. skipped module, or style module with state=ready)
$.inArray( undefined, [ descriptor.script, descriptor.style,
- descriptor.messages, descriptor.templates ] ) !== -1
+ descriptor.messages, descriptor.templates ] ) !== -1
) {
// Decline to store
return false;
* - this.Raw: The raw value is directly included.
* - this.Cdata: The raw value is directly included. An exception is
* thrown if it contains any illegal ETAGO delimiter.
- * See <http://www.w3.org/TR/html401/appendix/notes.html#h-B.3.2>.
+ * See <https://www.w3.org/TR/html401/appendix/notes.html#h-B.3.2>.
* @return {string} HTML
*/
element: function ( name, attrs, contents ) {