ResourceLoader/Průvodce migrací (uživatelé)
| ResourceLoader |
|---|
| Reference |
| Návody |
V průběhu času se základní JavaScriptové funkce a HTML výstupy MediaWiki zlepšily, zavedly nové metody, byly zastaralé nebo jinak změněny. Tento dokument si klade za cíl upozornit na nejčastější problémy, které je třeba vyřešit.
Přehled modulů dostupných v jádru MediaWiki naleznete v článku ResourceLoader/Moduly Core.
mediawiki.Uri
Modul mediawiki.Uri poskytuje API pro vytváření a manipulaci s URI MediaWiki.
Tato funkce již má nativní podporu prohlížeče a modul byl zastaralý. (T374314)
jquery.cookie
Modul jquery.cookie poskytuje API pro čtení a zápis nezpracovaných souborů cookie prohlížeče prostřednictvím modulu $.cookie.
Tato funkcionalita byla sloučena do modulu mediawiki.cookie.
Název modulu jquery.cookie je nyní zastaralý alias pro mediawiki.cookie.
Alias názvu modulu byl odstraněn v MediaWiki 1.42.
Modul mediawiki.cookie nyní poskytuje přímo hodnoty $.cookie i mw.cookie.
jquery.hoverIntent
Modul jquery.hoverIntent poskytuje pomocnou metodu pro spuštění kódu po umístění kurzoru nad elementem po minimální dobu.
Dělá to tak, že zpožďuje zpětné volání, takže i velmi krátké náhodné najetí myší nezpůsobí potenciálně "nezamýšlený" vizuální efekt.
Tento modul je nyní zastaralý (T311194).
Existují dvě migrační cesty:
- Použijte místo toho vestavěnou funkci jQuery
on()(s událostmimouseenteramouseleave), nebo - Znovu vytvořte podobný efekt s použitím
setTimeout.
Nejprve zvažte, zda stále potřebujete logiku hoverIntent.
Když jsme v roce 2010 představili hoverIntent (s MediaWiki 1.16), existovala řada pozoruhodných rozdílů oproti dnešku.
Mobilní zařízení byla mnohem méně významná pro gadgety a uživatelské skripty, očekávání ohledně vývoje a chování byla jiná a výkon byl vyvažován na základě jiných kompromisů mezi náklady na CPU a síť než dnes.
Zkuste převést na vestavěný on() a interagovat se svým zařízením.
Dokumentace:
var $btn = $( '.tpl-mybutton' );
// Starý kód (zastaralý)
$btn.hoverIntent( function () {
$btn.addClass( 'tpl-my-button--active' );
}, function () {
$btn.removeClass( 'tpl-my-button--active' );
} );
// Starý kód (zastaralý)
$btn.hoverIntent( {
interval: 300,
over: function () {
$btn.addClass( 'tpl-my-button--active' );
},
out: function () {
$btn.removeClass( 'tpl-my-button--active' );
}
} );
// Nový kód s funkcí on()
$btn
.on( 'mouseenter', function () {
$btn.addClass( 'tpl-my-button--active' );
} )
.on( 'mouseleave', function () {
$btn.removeClass( 'tpl-my-button--active' );
} );
Zlepší se to bez odkladu?
Pokud dáváte přednost zachování předchozího chování, můžete vytvořit podobný zpožďovací efekt s voláním setTimeout a dvěma lokálními proměnnými:
var pending, done;
$btn
.on( 'mouseenter', function () {
if ( pending ) {
return;
}
pending = setTimeout( function () {
$btn.addClass( 'tpl-mybutton--active' );
done = true;
}, 300 ); // zpoždění
} )
.on( 'mouseleave', function () {
if ( done ) {
$btn.removeClass( 'tpl-mybutton--active' );
}
clearTimeout( pending );
pending = done = null;
} );
Pro porovnání příkladů se podívejte na https://codepen.io/Krinkle/pen/VwGWgqN.
wpSave
Tlačítko Zveřejnit změny je od dubna 2017 stylizováno v OOUI (T111088, MediaWiki 1.39).
To znamená, že popisek tlačítka je ve výchozím nastavení tučný.
Následující CSS kód lze bezpečně odstranit.
Toto tlačítko je někdy označeno jako Uložit změny ($wgEditSubmitButtonLabelPublish).
#wpSave {
font-weight: bold;
}
jquery.jStorage
Modul jquery.jStorage byl v roce 2016 (MediaWiki 1.28) zastaralý.
Byl odstraněn v roce 2021 (MediaWiki 1.38).
Použijte místo toho mw.storage z modulu mediawiki.storage (T143034).
Související stránky: mw.storage
// Starý kód (zastaralý)
$.jStorage.set( 'mygadget-example', simple ); // simple = 'Hello'
$.jStorage.set( 'mygadget-example', object ); // object = { sub: 'Hello' }
simple = $.jStorage.get( 'mygadget-example' );
object = $.jStorage.get( 'mygadget-example' );
// Nové (náhrada)
mw.storage.set( 'mygadget-example', simple ); // simple = 'Hello'
mw.storage.setObject( 'mygadget-example', object ); // object = { sub: 'Hello' }
simple = mw.storage.get( 'mygadget-example' );
object = mw.storage.getObject( 'mygadget-example' )
Gadgety balíčku
Gadgety mohly mít vždy více souborů, ale ty se jednoduše sloučily a spouštěly jako jeden skript.
MediaWiki 1.33 zavedla funkci "Soubory balíčků", která umožňuje modulárnější návrh JavaScriptu s funkcí require() a vzorem module.exports pro odkazování na další soubory.
Navíc vám to umožňuje zahrnout data ze souborů JSON.
Tato funkce byla omezena na moduly v jádru MediaWiki a rozšíření.
Od verze MediaWiki 1.38 je tato funkce podporována také v modulu ResourceLoaderWikiModule a rozšíření Gadgets bylo aktualizováno, aby tuto funkci využívalo prostřednictvím nové definice s názvem "package".
Administrátoři (např. správce rozhraní na WMF wiki) by měli při psaní nebo kontrole JavaScriptového kódu, který vytváří HTML na základě textu ze stránek JSON, dbát na to, aby se těmto kódům vyhnuli a předešli tak bezpečnostním problémům.
Například:
* mygadget[ResourceLoader|package]|mygadget-main.js|mygadget-Foo.js|mygadget-data.json|mygadget.css
Kde je exportováno MediaWiki:Gadget-mygadget-Foo.js:
function Foo( config ) {
// ...
}
Foo.prototype.format = function () {
// ...
};
module.exports = Foo;
a MediaWiki:Gadget-mygadget-data.json:
{
"setting": [
"value1",
"value2"
],
"flag": true
}
Od MediaWiki:Gadget-mygadget-main.js pak můžete použít:
var Foo = require( './mygadget-Foo.js' ); // class Foo
var flag = require( './mygadget-data.json' ).flag; // true
Gadgety mohou také použít module.exports v hlavním souboru k definování veřejného rozhraní, ke kterému mohou přistupovat jiné gadgety s require( 'ext.gadget.mygadget' ), stejně jako jakýkoli jiný modul ResourceLoader.
jQuery Migrate 3
jQuery byl aktualizován na verzi 3 v MediaWiki 1.29 (vydané v roce 2017). V jQuery 3.0 bylo upstreamem odstraněno několik zastaralých funkcí. Dočasně jsme je přidali zpět prostřednictvím vrstvy jQuery Migrate, abychom umožnili postupný přechod (T280944).
V konzoli pro vývojáře se mohou zobrazit varování, jako například tato:
JQMIGRATE: jQuery.fn.size() is deprecated and removed; use the .length property.
JQMIGRATE: Attribute selector with '#' must be quoted
Můžete se také setkat s varováním, která pouze uvádějí, že něco "je zastaralé" bez upozornění "a odstraněno", například:
JQMIGRATE: jQuery.fn.bind() is deprecated
Varování, která uvádějí pouze "zastaralé", se týkají funkcí, které budou fungovat i po odstranění migrační vrstvy jQuery 3.
Chcete-li porozumět tomu, jak aktualizovat kód, použijte následující manuály:
- Referenční příručka k varováním v jQuery Migrate 3
- Průvodce aktualizací na jQuery 3.0
- Průvodce aktualizací na jQuery 3.5
Následující tři problémy mohou být obtížně k nalezení a mají pro ně několik dalších tipů:
- HTML tagy musí být správně vnořené: To znamená, že jste použili neplatnou zkratku, například
<div/><p/>. Ve starších verzích jQuery byl tento neplatný HTML kód automaticky opraven na <div> a následně na <p>. V jQuery 3 se dodržuje standardní chování prohlížeče, což znamená, že se to stane <p> uvnitř <div>, například<div><p>..</p></div>. Chcete-li zachovat staré chování, explicitně otevírejte a zavírejte HTML kód. Jako<div> </div> <p> </p>. - Požadavek AJAX mezi doménami s JSON-P: Pokud provádíte požadavky mezi doménami s
$.ajax()nebo$.get()na API, která vracejí spustitelné skripty JSON-P (místo prostého JSON), musíte přidat možnost{ dataType: "script" }. In previous versions, jQuery would guess between secure JSON and insecure JSON-P scripts. - Volání .load() jako metody události: Volání
$img.load(function)již není možné. Místo ní používejte přímo$img.on("load", function).
$wgIncludejQueryMigrate
Jako administrátor webu s MediaWiki 1.35.3 nebo novějším si můžete migraci vrstvy vypnout již dnes nastavením proměnné $wgIncludejQueryMigrate na false.
Vypnutí migrační vrstvy zlepšuje výkon načítání stránek a pomáhá ověřit, zda jsou vaše rozšíření a miniaplikace připraveny na aktualizaci.
Například pokud máte starý kód, který stále používá metody, které byly v jQuery 3 odstraněny, může to selhat následovně.
Uncaught TypeError: $elem.size is not a function.
V MediaWiki 1.37 bude migrační vrstva ve výchozím nastavení vypnuta. Správce webu jej může dočasně znovu zapnout, dokud nebudou problémy, jako jsou výše uvedené, vyřešeny.
V MediaWiki 1.38 bude migrační vrstva trvale odstraněna.
Tato verze není podporována.
Modul user.tokens
Modul user.tokens byl sloučen s balíčkem modulů user.options.
Starý název modulu je nyní alias a byl v MediaWiki 1.35 zastaralý.
Bude odstraněn v MediaWiki 1.36 někdy později v roce 2020. – T235457
Pro zachování kompatibility aktualizujte seznamy závislostí nebo příkazy zavaděče z "user.tokens" na "user.options".
mediawiki.notify
Modul mediawiki.notify byl začleněn do základního prostředí MediaWiki.
Tento modul byl zodpovědný za poskytování funkce mw.notify(), která následně líně načítá větší modul mediawiki.notification. – T233676
Pro zachování kompatibility jednoduše odstraňte "mediawiki.notify" ze všech seznamů závislostí nebo příkazů zavaděče.
Zastaralé moduly
jquery.ui.*
jQuery UI je již léta zastaralé, ale stále je k dispozici kvůli pomalému přechodu na alternativy. V rámci probíhajícího úsilí o snížení nákladů na šířku pásma bylo 27 zastaralých modulů jQuery UI sloučeno do jednoho, stále zastaralého megamodulu (Gerrit, T219604).
Pro zachování kompatibility aktualizujte seznamy závislostí a příkazy zavaděče z "jquery.ui.*" na "jquery.ui".
accessKeyLabel
Plugin jquery.accessKeyLabel je dostupný prostřednictvím mediawiki.util od roku 2014 (MediaWiki 1.24).
Přímá závislost na něm již není od verze MediaWiki 1.34 podporována. Aktualizujte seznamy závislostí a příkazy zavaděče z "jquery.accessKeyLabel" na "mediawiki.util", aby zůstala kompatibilita.
mediawiki.RegExp
Modul mediawiki.RegExp je k dispozici prostřednictvím mediawiki.util od roku 2015 (MediaWiki 1.25). – T218339
Přímá závislost na něm již není od verze MediaWiki 1.34 podporována. Aktualizujte seznamy závislostí a příkazy zavaděče z "mediawiki.RegExp" na "mediawiki.util", aby zůstala kompatibilita.
Funkce mw.RegExp.escape() byla také zastaralá (ačkoli byla zachována jako alias a dodávána s přezdívkou "mediawiki.util").
Použijte místo mw.util.escapeRegExp().
jquery.tabIndex
Modul jquery.tabIndex existoval proto, aby pomohl vypočítat nízký nebo vysoký index tabulace u zaměřitelných prvků na stránce.
Ve většině případů byl tento kód nadbytečný.
Řádky kódu obsahující firstTabIndex() nebo lastTabIndex() je často nejlepší zcela odstranit.
Modul je v MediaWiki 1.34 zastaralý.
// Jednoduše odstraňte
$thing.attr( 'tabindex', $( document ).lastTabIndex() + 1 );
Pokud je efekt tohoto kódu stále požadován, lze ho dosáhnout jednodušším způsobem bez tohoto JavaScriptového pluginu.
Například pro nastavení nízkého tabindexu použijte tabindex="0".
// Odstraněno
$thing.attr( 'tabindex', $( document ).firstTabIndex() );
// Přidat
$thing.attr( 'tabindex', '0' );
Nebo pro nastavení vysoké hodnoty tabindex použijte místo toho hodnotu tabindex="999", například takto:
// Odstraněno
$thing.attr( 'tabindex', $( document ).lastTabIndex() + 1 );
// Přidat
$thing.attr( 'tabindex', '999' );
Pokud potřebujete přesné chování původní funkce lastTabIndex, použijte následující:
// Odstraněno
$thing.attr( 'tabindex', $( document ).lastTabIndex() + 1 );
// Přidat
var lastIndex = Math.max.apply(null, $.map($('[tabindex]'), function (el) { return +el.tabIndex; }));
$thing.attr( 'tabindex', lastIndex + 1 );
mw.user.tokens editToken
Klíč editToken pro mw.user.tokens byl v roce 2016 zastaralý (MediaWiki 1.26).
Byl odstraněn v roce 2019 (MediaWiki 1.34). – T233442
Místo toho by se měl použít klíč csrfToken.
Například změňte mw.user.tokens.get('editToken') na mw.user.tokens.get('csrfToken').
Poznámka: Třída mw.Api se nezměnila. Kód jako mw.Api.getToken('edit') bude i nadále fungovat a neměl by se měnit.
Api modules
Všechny submoduly mediawiki.api.* byly sloučeny do hlavního modulu mediawiki.api, takže stačí vyžadovat pouze hlavní modul a vyžadování submodulů vygeneruje varování o zastarání.
Tyto submoduly byly ponechány jako zastaralé aliasy pro mediawiki.api a v MediaWiki 1.33 byly odstraněny.
wikiGetlink
Method mw.util.wikiGetlink(), which was deprecated since MediaWiki 1.23, has been removed.
Use mw.util.getUrl() instead.
wgEnableAPI
The wgEnableAPI and wgEnableWriteAPI keys of mw.config are deprecated as of MediaWiki 1.32, and will be removed in MediaWiki 1.35 (change).
The value of these configuration keys is always true.
Any check for them in JavaScript code is redundant and can be safely removed.
Internet Explorer 10 browser
With this version, we have stopped JavaScript support for IE10. See Compatibility for details.
jquery.placeholder
Deprecated in MediaWiki 1.29 (change), removed in MediaWiki 1.31.
The shim for the native placeholder attribute became obsolete as all supported browsers for JavaScript support this natively.
Simply remove the call to .placeholder().
jquery.mwExtension
The functionality was originally provided by a module called jquery.mwPrototypes in MediaWiki 1.17 (r76320). This was renamed to jquery.mwExtension in MediaWiki 1.19 (r94227).
The module was deprecated in MediaWiki 1.26, and removed in MediaWiki 1.30.
$.trimLeft,$.trimRight: These have native JavaScript methods available now.$.ucFirst: No replacement, rarely used. Simple enough to do in plain JavaScript asstr[0].toUpperCase + str.slice(1).$.escapeRE: Moved to mediawiki.RegExp; later moved tomediawiki.util.$.isDomElement: No replacement, rarely used. Use duck-type checks like!!obj.nodeTypeinstead.$.compareArray, $.compareObject, $.isEmpty: No replacement, rarely used.
Legacy removals
JavaScript functions and variables part of wikibits.js that had been deprecated since MediaWiki 1.17 or 1.18 have been removed:
User-Agent variables: is_gecko, is_chrome_mac, is_chrome, webkit_version, is_safari_win, is_safari, webkit_match, is_ff2, ff2_bugs, is_ff2_win, is_ff2_x11, opera95_bugs, opera7_bugs, opera6_bugs, is_opera_95, is_opera_preseven, is_opera, ie6_bugs, clientPC.
DOM manipulation: changeText, killEvt, addHandler, hookEvent, addClickHandler, removeHandler, getElementsByClassName, getInnerText.
Utilities: setupCheckboxShiftClick, addCheckboxClickHandlers, mwEditButtons, mwCustomEditButtons, injectSpinner, removeSpinner, escapeQuotes, escapeQuotesHTML, jsMsg, addPortletLink, appendCSS, tooltipAccessKeyPrefix, tooltipAccessKeyRegexp, updateTooltipAccessKeys.
How to migrate
Below is a table containing migration information for the wikibits functionality. Many of the replacements are part of the mediawiki.util module, which is not loaded by default. Please declare your dependency on this module if you refer to mw.util, as described in the development guide.
| Identifier | Type | Replaced by |
|---|---|---|
| clientPC | string | » navigator.userAgent
|
| is_gecko | boolean | » jQuery.client |
| is_safari | boolean | |
| is_safari_win | boolean | |
| is_chrome | boolean | |
| is_chrome_mac | boolean | |
| is_ff2 | boolean | |
| is_ff2_win | boolean | |
| is_ff2_x11 | boolean | |
| webkit_match | object | |
| ff2_bugs | boolean | obsolete |
| ie6_bugs | boolean | |
| doneOnloadHook | boolean |
» mw.hook » jQuery Use $( function () {
/* place code here to be executed after the page is loaded */
} );
// or:
function LoadMyApp() {
/* place code here to be executed after the page is loaded */
}
$( LoadMyApp );
|
| onloadFuncts | object | |
| addOnloadHook | function | |
| runOnloadHook | function | |
| killEvt | function |
» jQuery.Event: /**
* @param e {jQuery.Event} Cross-browser compatible/normalized event object
*/
$( '#mw-fooBar' ).click( function( e ) {
e.preventDefault();
/* do something else */
} );
|
| loadedScripts | object | redundant |
| importScriptURI | function |
// Full script url
mw.loader.load( 'https://www.mediawiki.org/w/index.php?title=MediaWiki:Gadget-UTCLiveClock.js&action=raw&ctype=text/javascript' );
// Local script url
mw.loader.load( '/w/index.php?title=MediaWiki:Gadget-HotCat.js&action=raw&ctype=text/javascript' );
// Full stylesheet url
mw.loader.load( 'https://www.mediawiki.org/w/index.php?title=User:Example/custom-foo.css&action=raw&ctype=text/css', 'text/css' );
// Local stylesheet
mw.loader.load( '/w/index.php?title=User:Example/custom-foo.css&action=raw&ctype=text/css', 'text/css' );
|
| importStylesheetURI | function | |
| appendCSS | function | » mw.util.addCSS |
| addHandler | function |
» jQuery Events Using // Attach multiple events to an element and attach an anonymous function
$( '#fooBar' ).on( 'mouseenter mouseleave', function() {
alert( '#fooBar is moused!' );
} );
// Attach multiple events with different handlers to a single element
$( '#fooBar' ).on( {
click: function() {
// do something on click
},
mouseenter: function() {
// do something on mouseenter
}
} );
// Attach a handler to the click events of an earlier defined DOM element
$( myElement ).click( myFunction );
|
| addClickHandler | function | |
| removeHandler | function | |
| hookEvent | function | |
| mwEditButtons | object | obsolete |
| mwCustomEditButtons | object |
» WikiEditor The new WikiEditor (which also works fine in Monobook, see here) has built-in function to customize the toolbar. For more info see Extension:WikiEditor/Toolbar customization. For examples to insert buttons using the native script see Extension:WikiEditor/Toolbar customization/Library. For a script to insert buttons using a simple syntax similar to the old way check out meta:User:Krinkle/Scripts/insertVectorButtons#Description mw.loader.load( '//meta.wikimedia.org/w/index.php?title=User:Krinkle/insertVectorButtons.js'
+ '&action=raw&ctype=text/javascript' );
function kCustomMainInsertButton_config(){
// {{Welcome}} ~~~~
kCustomMainInsertButton(
'welcome', // Id
'//commons.wikimedia.org/w/thumb.php?f=Nuvola_apps_edu_languages.svg&w=22', // File
'Welcome', // tooltip
'{\{Welcome}\}\~\~\~\~', // Open tag
'', // Close tag
'' // sampleText
);
// {{subst:Test2}} ~~~~
kCustomMainInsertButton(
'test2', // Id
'//commons.wikimedia.org/w/thumb.php?f=Nuvola_apps_important.svg&w=22', // File
'Test2', // tooltip
'{\{subst:test2|', // Open tag
'}\}\~\~\~\~', // Close tag
'' // sample text
);
}
|
| tooltipAccessKeyPrefix | string | » jquery.accessKeyLabel
// myElement.accessKey = 'x';
// myElement.title = 'Example [x]';
mw.loader.using('jquery.accessKeyLabel').then(function () {
$(myElement).updateTooltipAccessKeys();
});
|
| tooltipAccessKeyRegexp | object | |
| updateTooltipAccessKeys | function | |
| ta | object | MediaWiki:Accesskey-* and MediaWiki:Tooltip-*. |
| akeytt | function | obsolete |
| checkboxes | object | » jquery.checkboxShiftClick |
| lastCheckbox | object | |
| setupCheckboxShiftClick | function | |
| addCheckboxClickHandlers | function | |
| checkboxClickHandler | function | |
| showTocToggle | function | |
| toggleToc | function | |
| ts_image_path | string | » jquery.tablesorter |
| ts_image_up | string | |
| ts_image_down | string | |
| ts_image_none | string | |
| ts_europeandate | boolean | |
| ts_alternate_row_colors | boolean | |
| ts_number_transform_table | object | |
| ts_number_regex | object | |
| sortables_init | function | |
| ts_makeSortable | function | |
| ts_getInnerText | function | |
| ts_resortTable | function | |
| ts_initTransformTable | function | |
| ts_toLowerCase | function | |
| ts_dateToSortKey | function | |
| ts_parseFloat | function | |
| ts_currencyToSortKey | function | |
| ts_sort_generic | function | |
| ts_alternate | function | |
| changeText | function | » jQuery
Using // Set text of an earlier defined element
$( myElement ).text( 'New text!' );
// Set text for multiple elements at once
$( '.mw-userlink' ).text( 'Mr. Foobar' );
// Get the text of an element
$( myElement ).text();
|
| getInnerText | function | |
| escapeQuotes | function | |
| escapeQuotesHTML | function |
» mw.html |
| addPortletLink | function | |
| jsMsg | function | |
| injectSpinner | function | » jquery.spinner (Documentation)
jQuery( .. ).injectSpinner('some-id');
jQuery.removeSpinner('some-id');
|
| removeSpinner | function | |
| getElementsByClassName | function |
» jQuery Use the CSS Selector in jQuery to select elements by classname. Here are examples for the three most common usecases of // Get everything with a classname
$( '.myclass' );
// Get all of element X (ie. table) with a classname
$( 'table.wikitable' );
// Get all of something within another element
$( myDomElement ).find( '.myclass' );
$( myDomElement ).find( '> .myclass' ); // only direct children
// Get all class-elements that are direct children of an element
$( '#someElement .myclass' );
$( '#someElement > .myclass' ); // only direct children
|
| redirectToFragment | function |
Gadget type
Background
Since early 2011, gadgets with styles (both "only styles" and "styles and scripts") had their styles loaded twice. T42284 and change 308096 fix this bug.
What's new
This bug was addressed by adding support in the Gadgets extension for the ResourceLoader "type" feature. This allows gadget developers to configure how the module should be loaded
- type=styles: Load module styles via
<link rel="stylesheet">, and completely omits loading any JavaScript files. (Loads styles early, applies styles before skin and page are ready, also works when JavaScript is disabled.) - type=general: Load module scripts and/or styles via
mw.loader.load(). (Applies styles after the skin and page are ready, right before JS execution, has better caching.)
Gadgets with only styles, internally get type=styles by default. Gadgets with only scripts default to type=general.
Before MediaWiki 1.30, Gadgets with both scripts and styles defaulted to loading both ways, thus loading the styles portion twice. Before that, we sent a warning in the browser console in a transition period that asked developers to set the desired type. After the transition period, we made type=general the default for gadgets that have both scripts and styles.
To load styles through the type=styles system, while also loading JavaScript files, two separate gadget definitions need to be specified.
How to migrate
type=general. See phab:T42284.If you see this warning, that means your gadget contains both scripts and styles. Here are two ways to fix the warning:
- If the styles in your gadget are there to provide styling for things created by the gadget, add "
type=general" to your gadget definition ("MediaWiki:Gadgets-definition"). - Or – If the styles in your gadget are there to provide styling for things that are part of the skin or on the page, then these styles should not be together with the scripts in the same gadget. Convert the gadget to two separate gadgets. One gadget that is styles-only, and the other with the scripts. If the scripts gadget also has its own styles, then also set "
type=general" on the original gadget (per point 1). If you want to keep presenting the modules as one gadget on the Preferences page, use #Gadget peers.
As you can see, in most cases the solution is "type=general." And in the future, this will become the default and we will not load styles twice. Right now, loading twice remains the default for compatibility with older gadgets covered by point 2 above. Changing these mixed gadgets to type=general now would cause some styles to load too late and cause a "flash of unstyled content".
Gadget peers
For a long time, gadget authors have been interested in being able to provide a visual enhancement for all pages and also accompanying some scripting logic to apply related changes to interactive interfaces created by other modules. This requires the gadget to have both scripts and styles, but most of the styles are not required by the scripts – rather, the styles should apply directly to the page without waiting for JavaScript. So far this required either creating two gadgets (and requiring users to enable both), or creating a single gadget with the downside of the styles applying slightly after the page loads.
To accommodate the use case of a single gadget providing both page styles (which don't depend on JavaScript) and JavaScript code with its own styles, a new setting was introduced: peers. This is similar to dependencies, except that where dependencies load before the main module (not before the page itself), peers will allow one to reference a separate gadget module that will be loaded regardless of whether JavaScript is enabled.
For example:
* example [ResourceLoader|dependencies=mediawiki.util|peers=example-pagestyles] | example.js | example.css * example-pagestyles [hidden] | example-pagestyles.css
This will register a gadget named "Example" in the preferences which, if enabled, will load example-pagestyles before the page renders. And, once JavaScript is available, the example module will also be loaded with its own dependencies, styles and scripts.
Internet Explorer 9 and pre-ES5 browsers
With this version, we have stopped JavaScript support for IE9 and other browsers that do not support ES5. See Compatibility for details.
Classic toolbar
The 2006 wikitext editor was superseded by WikiEditor, which has been the default since 2010. The classic toolbar was loaded if you disabled the "Enable enhanced editing toolbar" user preference. The classic toolbar is now deprecated with console warnings as of April 2017 (T30856) in MediaWiki 1.29 (it was removed in October 2018 in MediaWiki 1.32). This means the mediawiki.toolbar module no longer exists.
If you have code that added toolbar buttons for both editors, you can now safely remove all code for mediawiki.toolbar. If you still have code for mwCustomEditButtons (from before 2011, see #Toolbar), you can safely remove that too. To learn how to add buttons to the WikiEditor toolbar, refer to Extension:WikiEditor/Toolbar customization.
// Classic toolbar
if ( [ 'edit', 'submit' ].includes( mw.config.get( 'wgAction' ) ) ) {
mw.loader.using( [ 'user.options', 'mediawiki.toolbar' ] ).then( function() {
if ( !mw.user.options.get( 'usebetatoolbar' ) ) {
mw.toolbar.addButtons( /* ... */ );
}
} );
}
// WikiEditor toolbar
mw.hook( 'wikiEditor.toolbarReady' ).add( function ( $textarea ) {
$textarea.wikiEditor( 'addToToolbar', {
/* ... */
} );
} );
This version is not supported.
Legacy default: mediawiki.util
The $wgPreloadJavaScriptMwUtil option was removed. This option allowed third-party MediaWiki administrators to re-enable the unconditional preload of mediawiki.util by default for all users (for backwards compatibility). It was disabled by default since MediaWiki 1.26, and has been disabled on Wikimedia wikis since 2014. Extensions, skins, gadgets and scripts that use the mediawiki.util module must express a dependency on it.
bits.wikimedia.org
The internal Wikimedia domain "bits.wikimedia.org" was deprecated sometime mid-2015. The following common paths should be migrated to avoid breakage once the domain is decommissioned (T107430).
bits.wikimedia.org/:domain/load.php→https://:domain/w/load.php. Moved back to local domains, alongside/w/index.phpand others.bits.wikimedia.org/static-current/*→https://:domain/static/current/: Moved to local domain, sharing a hostname-agonistic Varnish cache.bits.wikimedia.org/skins/*→https://:domain/static/current/skins
bits.wikimedia.org/static-1.xx-wmf.X/*→https://:domain/w/*: Specific versions can now be accessed through the regular script path. Wikimedia's multiversion entry point automatically serves the file from the wikis' current MediaWiki version. (T99096)bits.wikimedia.org/static-1.xx/skins/*→https://:domain/w/skins/*bits.wikimedia.org/static-1.xx/extensions/*→https://:domain/w/extensions/*bits.wikimedia.org/static-1.xx/resources/*→https://:domain/w/resources/*
Internet Explorer 8
Following the deactivation of JavaScript in Internet Explorer 6 and 7 in MediaWiki 1.24, JavaScript has been deactivated in Internet Explorer 8. See Compatibility for details.
Legacy gadgets
Gadgets are now required to use ResourceLoader. For many Gadgets, migrating to ResourceLoader will be as easy as adding [ResourceLoader] to its definition on MediaWiki:Gadgets-definition. If after adding that, the gadget is not working properly, consult the rest of this page to look for functionality that may have changed since the gadget was last maintained. If you run into any issues or find features that don't work without a clear way of making it work, please reach out to MediaWiki developers and fellow gadget authors on the talk page, via IRC, or on the wikitech-l mailing list. (T75810)
Global variables are not global
When ResourceLoader loads a gadget script, it is not executed in global context. This means that local variables you define in the script are actually local, and not assumed to be also global. They are local to the function your code is wrapped in. It's best to modularize your code to avoid using globals, see "Globals" in MediaWiki's JavaScript coding conventions. However, if you need to export a variable to the global scope, you can explicitly assign them as window properties. For example:
// This is a local variable
var foo;
// This is a local function
function bar() {
..
}
// This is a global variable (accessible from other scripts, and from legacy event handlers, e.g. onclick="javascript:Quux();"
window.Quux = function( width, height ) {
...
};
Code within your gadget can access foo and bar. Code outside the gadget (or code evaluated as separate programs, such as legacy onclick handlers), can only access Quux.
Font mw-geshi
The font-size of <syntaxhighlight> was often too small by default due to a font-family CSS bug. This was fixed in MediaWiki 1.26 (see (phab:T28204).
The mw-geshi, source-css, source-javascript and related classes no longer exist. Related code such as the following can be safely removed:
/* Fix <syntaxhighlight> text size. [[phab:T28204]] */
div.mw-geshi div,
div.mw-geshi div pre,
span.mw-geshi,
pre.source-css,
pre.source-javascript,
pre.source-lua {
font-family: monospace, Courier !important;
}
Inline scripts
To inject JavaScript inline, use ResourceLoader::makeInlineScript() to wrap the JavaScript code in an anonymous function that can access MediaWiki-related objects properly, and OutputPage::addScript() to add the results to the page source for execution.
For example:
$outputPage = RequestContext::getMain()->getOutput();
$js = 'alert("hello world");';
$wrappedJS = ResourceLoader::makeInlineScript($js);
$outputPage->addScript($wrappedScript);
Legacy removals
The jquery.delayedBind JavaScript module, deprecated in MediaWiki 1.23, has been removed. See phab:rMW8f2ebcbf6769.
Internet Explorer
Browser support for Internet Explorer 6 and 7 changed from Grade A to Grade C. This means JavaScript is no longer executed in these browser versions. See Compatibility for details.
mw.util.jsMessage
This method has been deprecated in favour of mw.notify.
The jsMessage message was designed to be a drop-in replacement fully compatible with the legacy wikibits jsMsg function (deprecated since 1.17, removed in 1.29). The 2012 notification system on the other hand was designed with developer usability and security in mind.
For most cases, the new method is just as easy to use as the old one, and requires only the same single parameter that represents the message. For example, with plain text:
// Deprecated (dependencies: mediawiki.util)
var msgText = 'Hello world';
mw.util.jsMessage(msgText);
// New, as of 2012 (dependencies: mediawiki.notify)
var msgText = 'Hello world';
mw.notify(msgText);
And another example, with a DOM element, or a jQuery object:
// Deprecated (dependencies: mediawiki.util)
var $myWidget = ExampleWidget.create( {
having: '2-buttons',
toggle: '#sidebar'
});
mw.util.jsMessage($myWidget);
// New, as of 2012 (dependencies: mediawiki.notify)
var $myWidget = ExampleWidget.create( {
having: '2-buttons',
toggle: '#sidebar'
});
mw.notify($myWidget);
If you're currently using raw HTML with mw.util.jsMessage(), the simplest way to migrate is to do what jsMessage used to do internally for you, which is to parse the HTML and place the node(s) in a jQuery object, as follows:
// Deprecated (dependencies: mediawiki.util)
var msgHtml = '<form><button>Click me</button></form>';
mw.util.jsMessage(msgHtml);
// New, as of 2012 (dependencies: mediawiki.notify)
var msgHtml = '<form><button>Click me</button></form>';
var $msg = $($.parseHTML(msgHtml));
mw.notify($msg);
New diff styles
This version introduces a new diff view, greatly improved in clarity especially for whitespace and other small changes and colour-blind users. If your wiki has custom CSS for the diffs, they may be in conflict with the new style (as happened on ptwiki and srwiki). You are recommended to remove the old code (or if still wanted by some users, update it to work with the new layout and create a gadget for it so that users can opt-in to it still).
wikitable style updates
As of MediaWiki 1.19 a few bugs have been fixed with the wikitable class (see phab:T32485 and phab:T35434 for more info). If your wiki maintains a legacy synonym of this class (e.g. "prettytable") you need to update its CSS to match the current style in core.
The current style as of 1.19 can be found here. Copy those rules to your wiki and replace "wikitable" with the synonym (example for nl.wikipedia).
If your wiki doesn't keep something like this, then no update is necessary and everything should take care of itself.
File page checkered background
The checkered background often applied to transparent file namespace pages is now part of the software. Local rules like the following should be removed (because they are redundant, and actually cause an additional unnecessary HTTP request for the image)
/* Put a checker background at the image description page.
Only visible if the image has transparent background.
*/
#file img {
background: url("//upload.wikimedia.org/wikipedia/commons/5/5d/Checker-16x16.png") repeat;
}
Trackbacks
Trackbacks were removed from MediaWiki core, so any styling targeting #mw_trackbacks can be removed.
Protocol-relative urls
- This change only applies to Wikimedia Foundation wikis.
As of MediaWiki 1.18 there is native support for protocol-relative wiki installations. This means that a wiki could be accessible from both http://example.org/ and https://example.org./ To make it possible to share a common cache for as much as possible, we make use of a technique called protocol-relative urls. Although browsers have supported this for ages, script writers generally weren't very familiar with it until fairly recently. Briefly explained, this means that <img src="//meta.wikimedia.org" /> when on "https://example.org" will be automatically expanded by the browser to https://meta.wikimedia.org./ This is much like (for example) <img src="foobar.jpg" /> or <img src="/w/foobar.jpg" />, which are automatically expanded to "http://mediawiki.org/w/foobar.jpg".
Depending on how the scripts were written this may require some changes to be made to your scripts. If you use the following method to detect whether the script is executed on a certain wiki, this change will break your script:
if ( wgServer === 'http://en.wikipedia.org' ) {
// Doesn't work anymore!
}
because wgServer is now "//en.wikipedia.org". For a few years there has been another config variable, called "wgDBname". You should use that instead to differentiate wikis, like:
if ( mw.config.get( 'wgDBname' ) === 'enwiki' ) {
// English Wikipedia!
}
Alternatively, you can use wgServerName which is without the protocol or port:
if ( mw.config.get( 'wgServerName' ) === 'en.wikipedia.org' ) {
// English Wikipedia!
}
"Enabled by default" (Gadgets extension)
As of the version of the Gadgets extension at the MW 1.18 branchpoint, there is a new feature that allows a gadget to be opt-out instead of opt-in based. By setting "[default]" (or adding "|default" to an existing section) the gadget will be enabled by default for everybody, unless a user has specifically opted out by unticking the checkbox on Special:Preferences#mw-prefsection-gadgets.
Note that this also loads it for all anonymous users. Gadgets that are only for logged-in users should be additionally restricted by, for example, requiring certain user rights.
See also Extension:Gadgets#Options.
mw.util.wikiScript
The actual paths have not changed, but getting the path to the API and index.php has become a lot easier. This also makes the code more portable as it has no hardcoded wiki-specific paths.
This is how it used to go in many gadgets.
var foo = 'bar';
var apiUrl = '//www.mediawiki.org/w/api.php?foo=' + encodeURIComponent( foo ) + '&baz=quux';
$.ajax( { url: apiUrl, ... } );
Instead use something like one of the following:
// Behold, mw.util.wikiScript!
var foo = 'bar';
var apiUrl = mw.util.wikiScript( 'api' ) + '?foo=' + encodeURIComponent( foo ) + '&baz=quux';
$.ajax( {
url: apiUrl,
...
} );
You may also want to use $.param to automatically escape and create things properly in the query string:
// $.param is also awesome. No need for encodeURIComponent that way :)
var foo = 'bar';
var apiUrl = mw.util.wikiScript( 'api' ) + '?' + $.param( {
foo: foo,
baz: 'quux'
} );
$.ajax( {
url: apiUrl,
...
} );
You can even use the data option of $.ajax, that abstracts away the need to deal with the query string entirely:
// No longer needed to inject the '?' or '&' in the url
$.ajax( {
url: mw.util.wikiScript( 'api' ),
data: {
foo: 'bar',
baz: 'quux'
}, ...
} );
jQuery
- See also jQuery
As of 1.17 the jQuery library is loaded by default on all MediaWiki pages. Each MediaWiki release will keep it up to date with the latest version of jQuery. If you used to load jQuery from within your script, (e.g. from ajax.googleapis.com), make sure you remove that. If you load jQuery more than once on a page, it overwrites the earlier version. Other scripts break because they may not work with an older version of jQuery.
Also, by overwriting the jQuery object, any plugins that were bound to that object are also lost.
Global identifier "$j" has been deprecated. Use jQuery or $ instead.
Tabs (vector)
In 1.17 the HTML construction for the navigation tabs has changed from <li><a><span /></a></li> to <li><span><a /></span></li>. The most common situation in which this causes problems is where scripts assume the presence of the span element when, for example, customizing the tab for "Main Page". Before 1.17 this usually meant that wikis had a different implementation for Monobook and one for Vector (or only one for each and the other was distorted).
Please use MediaWiki:Mainpage-nstab or refer to Snippets/Main Page tab for a script that will work in both Vector and Monobook for 1.17.
Adding portlet links
The legacy function addPortletLink has been rewritten as mw.util.addPortletLink. The syntax and argument order is fully backwards compatible. The differences are:
- Support for all core skins now
- Support for simple id-selector as 'nextNode' (see documentation for details).
Some wikis may have re-defined / overwritten the addPortlinkLink function to support a few extra skins. This is no longer needed. The function definition should be removed and calls adjusted to mw.util.addPortletLink.
The legacy version of addPortlinkLink has been preserved as-is in case some edge cases would behave differently (for that reason the addPortlinkLink does not redirect to mw.util.addPortlinkLink).
Toolbar
The legacy array mwCustomEditButtons has been refactored into the mw.toolbar library. The global array still exists in wikibits to avoid fatal errors but is no longer used due to race conditions. Note that (unlike mwCustomEditButtons) the mw.toolbar.addButton API works also after the toolbar is visible. You can add late entries.
Note that mw.toolbar, just like the old mwCustomEditButtons array, is only for the classic toolbar. The current default wikitext editor is WikiEditor, which has its own API. See Extension:WikiEditor/Toolbar customization for more information.
Sajax
The legacy functions such as sajax_init_object have been deprecated. Instead, use mw.Api from the mediawiki.api module, or jQuery.ajax.
Migration guide:
| Identifikátor | Typ | Nahrazeno |
|---|---|---|
| sajax_debug_mode | string | » jQuery.ajax
Pro přímý přístup ke stránkám a API použijte funkce $( '#mybox' ).load( '/wiki/Template:ResourceLoader_navigation #bodyContent' );
$.get(
mw.config.get( 'wgScript' ), {
title: 'ResourceLoader',
action: 'raw'
},
function( data ) {
/* Call was successful do something with "data" */
}
);
$.getJSON(
mw.util.wikiScript( 'api' ), {
format: 'json',
action: 'query',
titles: 'Main Page',
prop: 'info'
},
function( obj ) {
/* API call was successful do something with obj */
}
);
Více informací naleznete v dokumentaci k funkcím .load(), .get(), .getJSON() a dalším funkcím jQuery Ajax. Viz také tato příručka z uživatelských skriptů WikiProjektu, kde je příklad, jak upravit wikistránku pomocí AJAX. |
| sajax_request_type | string | |
| sajax_debug | function | |
| sajax_init_object | function | |
| wfSupportsAjax | function | |
| sajax_do_call | function |
$.get(
mw.util.wikiScript(), {
action: 'ajax',
rs: 'SomeExtensionFunction',
rsargs: [arg1, arg2, arg3] // becomes &rsargs[]=arg1&rsargs[]=arg2...
}
);
Poznámka: Tato volání používající action=ajax by měla být přepsána tak, aby používala API modul. |
Testování klienta
Kontrola prohlížeče, platformy, layout enginu atd., který klient používá, by nyní měla být provedena pomocí jQuery.client.
is_safari,is_chromeatd. jsou zastaralé- Není třeba používat
navigator.userAgent.indexOf("MSIE 6")==-1atd.
Sysop script
New in MediaWiki 1.17 is a user groups module that can automatically load scripts and styles from the MediaWiki namespace for a particular user group. For example, if the wiki has MediaWiki:Group-sysop.js, this script is automatically loaded for all users in that group.
This should replace customisations you may have for importing a page for sysops with importScript inside Common.js.
// Old - MediaWiki:Common.js
if ( mw.config.get( 'wgUserGroups' ).includes( 'sysop' ) ) {
importScript('MediaWiki:Sysop.js'); // Remove
importScript('MediaWiki:Sysop-something.js'); // Remove
importScript('MediaWiki:Shared-something.js'); // Move to Group-sysop.js
}
// Old - MediaWiki:Sysop.js -> MediaWiki:Group-sysop.js
console.log( 'Hello sysop' );
// Old - MediaWiki:Sysop-something.js -> MediaWiki:Group-sysop.js
console.log( 'Hello sysop something' );
// New - MediaWiki:Common.js
// (nothing here)
// New - MediaWiki:Group-sysop.js
console.log( 'Hello sysop' );
console.log( 'Hello sysop something' );
importScript('MediaWiki:Shared-something.js');
mw.loader
If you need certain scripts like jQuery UI's dialog or datepicker, instead of doing something like:
importStylesheetURI( mw.config.get( 'wgExtensionAssetsPath' ) + '/Example/css/jquery-ui-1.7.2.css' );
$.getScript( mw.config.get( 'wgExtensionAssetsPath' ) + '/Example/js/jui.combined.min.js', function () {
MyTool.init();
} );
Instead use this:
mw.loader.using( ['jquery.ui.dialog', 'jquery.ui.datepicker'], MyTool.init );
Or if you need to delay initialization until document.ready:
mw.loader.using( ['jquery.ui.dialog', 'jquery.ui.datepicker'], function () {
$( document ).ready( MyTool.init );
} );
Dependencies
When a script depends on another module, such as oojs or mediawiki.util, you will need to declare this as a "dependency". This is because modules are loaded on-demand and asynchronously (in consecutive order: all at the same time), so a script needs to make sure a module has been loaded before it can use its methods. On-site modules, like gadgets, have a registry to declare these dependencies. For user scripts, one has to wrap code with mw.loader.using().
While this has been required since 2011, many scripts have continued to work without declaring their dependencies. Scripts may have worked before by accident as long as at least one user script (that used the same methods) did declare their dependencies and happened to load earlier.
With MediaWiki 1.19, page view performance has been optimised to use fewer modules by default. This makes it increasingly more important to declare the dependencies. Otherwise, your script may fail because any of the 1000+ modules you might refer to in your code would not be loaded yet. Loading everything all the time would be much too slow.
The only two base modules that are always present are mediawiki and jquery.
In practice
Use mw.loader.using() to declare any modules that you need before executing the contents of "function". You can pass multiple modules as an array of strings.
mw.loader.using( ['mediawiki.util', 'oojs', 'jquery.cookie'], function () {
/* some other script that uses $.cookie */
/* some other script that uses mw.util and OO.EventEmitter() */
} );
Global wg variables
As of MediaWiki 1.17, the global config variables are deprecated. Rationale is to clear the global namespace, working towards a reality where most of the core libraries will be object oriented as part of the mw object. Configuration is managed through an instance of mw.Map in mw.config. It is also supporting the behaviour of more scripts executing in their own local/private scope as opposed to the global scope.
Legacy globals will be kept for backwards compatibility, but people should start migrating so that they may be removed in a future version of MediaWiki (T35837).
// One variable
if ( mw.config.get( 'wgCanonicalSpecialPageName' ) === 'Search' ) {
// Example for Special:Search
}
if ( mw.config.get( 'wgGlobalGroups', [] ).indexOf( 'global-rollbacker' ) !== -1 ) {
// Example for users in the global group "global-rollbacker".
}
// Multiple variables
var conf = mw.config.get( [
'wgScript',
'wgAction'
] );
if ( conf.wgAction === 'edit' ) {
console.log( 'Example when editing a page', config.wgScript );
}
More info: ResourceLoader/Default modules#mw.config
Ready, onload, hook
Check JavaScript deprecation overview for "addOnloadHook". Use $( function ); instead, or $( fn ); for short.
New CSS declarations in core
Headings overflow hidden
overflow:hidden for any of h1, h2, h3, h4, h5 and/or h6 can be safely removed from stylesheets as this is now part of the core.
Italic redirects
Links to redirects now appear italicized by default on Special:AllPages, Special:PrefixIndex, Special:Watchlist/edit and in category listings. Overrides like the following are redundant and can be safely removed.
.allpagesredirect,
.redirect-in-category,
.watchlistredir {
font-style: italic;
}
wpSummary
Per phab:T22276, input#wpSummary's width is now set in Vector as well (instead of just Monobook).
UsabilityInitiative no more
As of 1.17 the functionality developed by the UsabilityInitiative has been extracted to stand-alone extensions. Buttons like "#pt-optin-try" no longer exist. You can enable/disable these functions like other extensions via Special:Preferences.
Scripts and styles doing things like "HideUsabilityOptIn":
#pt-optin-try {
display: none !important;
}
should therefore be deleted entirely as the button no longer exists.
Preformatted JS/CSS pages
It's no longer useful to wrap these pages in /* <pre> */ or // <syntaxhighlight lang="javascript"> etc. In newer versions of MediaWiki, these pages are rendered as code automatically (including syntax highlighting when available). See also T6801.
Table sorter
The old table sorter in wikibits.js was removed in favour of jquery.tablesorter.
Variables such as ts_alternate_row_colors, and functions like ts_parseFloat and ts_dateToSortKey no longer exist.
MediaWiki 1.16 and before
importScript
As of 2008, the importScript function commonly defined by communities locally became a built-in part of MediaWiki ("wikibits.js"). Wikis that previously defined this function themselves, are able to remove that. The new built-in function is automatically used. The same also applies to importStylesheet, importStylesheetURI and importScriptURI.
Note that importStylesheetURI and importScriptURI were subsequently deprecated in 2011 with MediaWiki 1.17, and disabled on mobile sites like https://en.m.wikipedia.org/. Use mw.loader.load instead.
addPortletLink
As of 2008, the function addPortletLink is part of MediaWiki. Many wikis and gadgets have created functions like addLink, addLiLink, addlilink etc. these should be removed as they most likely don't support different skins (ie. only Monobook, not Vector or older skins). Be sure to check the syntax as there is no way of knowing whether the creator of those local functions used the same parameter order.
- Note: The global function was deprecated in 2012 and moved to the mediawiki.util module as
mw.util.addPortletLink()
appendCSS
As of 2008, the function appendCSS is part of MediaWiki. Wikis that have defined this function themselves may remove that. It will automatically use the new function.
- Note: The global function was deprecated in 2012 and moved to the mediawiki.util module as
mw.util.addCSS()
HTML bugs in core
html lang
This bugfix is obsolete as MediaWiki does this correctly by default. (example)
var htmlE = document.documentElement;
htmlE.setAttribute('lang', mw.config.get('wgUserLanguage'));
CSS declarations new in core
wikitable
The .wikitable CSS class is part of MediaWiki. Wikis that previously defined this class in their Common.css should remove it. Do check if the wiki has any customisations that should be retained (e.g. different background-color, or font-size).
plainlinks
The .plainlinks CSS class is part of MediaWiki. Wikis that previously defined this class in their Common.css should remove it.
Alternative names for this feature, that were in popular use on Wikimedia Foundation wikis, include: .plainlinksneverexpand and .nounderlines. Replace any usage on wiki pages "plainlinks", and afterward these alternate styles may also be removed. For example, use search and query for insource:plainlinksneverexpand.
mw-plusminus
The CSS classes .mw-plusminus-pos, .mw-plusminus-null, and .mw-plusminus-neg are now implemented by MediaWiki.
External URLs
Icons for protocols like HTTP, IRC, etc. and file types like PDF are now supported by MediaWiki.
Tooltip and accesskeys
Scripts like ta['pt-userpage'] = new Array('.','My user page'); are ignored. It was deprecated in 2009.
The function akeytt() no longer exists. Tooltips and accesskeys are now supported from core. The most common values that wikis used with ta[] are the same that have now been integrated into the core (ie. "." for "my user page"). They can still be modified, if really needed, by sysops in MediaWiki-messages (no need for JavaScript workarounds anymore).
As of MediaWiki 1.19 the global dummy placeholder ta = new Object(); was removed from wikibits.js. Code trying to add members to it will likely emit an exception.
Best practices
The below are additional advices not related to a particular MediaWiki release, but rather general best practices.
Avoid document.write()
Do not use this method, as it can cause a page to become visually blanked. Instead, use jQuery to modify the document (adding elements, changing things etc.). To load external resources, use the import/loader functions instead.
Example: replace
document.write('<script type="text/javascript" src="'
+ 'https://commons.wikimedia.org/w/index.php?title=MediaWiki:Gadget-HotCat.js'
+ '&action=raw&ctype=text/javascript"></script>');
with
mw.loader.load('https://commons.wikimedia.org/w/index.php?title=MediaWiki:Gadget-HotCat.js&action=raw&ctype=text/javascript');
Event binding
Binding input events to callback functions can be hard to do in cross-browser compatible way for all browsers that MediaWiki supports.
It is recommended that you use jQuery for event binding. See the JavaScript deprecation overview on "addHandler" for examples.
Encoding and escaping
When working with regular expressions, user input and/or urls must always be encoded or escaped.
- Regexes:
mw.util.escapeRegExp(provided bymediawiki.utilmodule). - HTML:
mw.html.escape(provided by default). - URL:
mw.util.wikiUrlencodefor page titles,mw.util.rawurlencodefor other values (provided bymediawiki.utilmodule).
Prototyping
Do not extend native JavaScript constructors with non-standard methods (e.g. String.prototype.foobar, Regex.myMethod, Array.prototype.inArray etc.).
Such non-standard methods should be defined in your own namespace instead, for example MyThing.foobar, or using module.exports/require.
Polyfills
Before 2015, it was common for user scripts and gadgets to define fallback method for standard features of newer JavaScript engines. This is no longer needed in most cases, because the Base environment already ensures ES5 or later. This means ES5 methods such as String#trim and Array#forEach can be used directly.
Before MediaWiki 1.32, the es5-shim module was bundled with MediaWiki to automatically define polyfills if needed. It could be used like so:
// This using() command will immediately execute as "then()" in modern browsers.
// In older browsers, it loads es5-shim.js first, and then executes your "then()".
mw.loader.using( 'es5-shim').then( function () {
console.log( ' bar '.trim() ); // "bar"
[ 'a', 'b' ].forEach( function ( val ) {
/* .. */
} );
} );
Getting URL parameter values
Functions like getURLParamValue, getParamVal, getParamValue, etc. are very common across wikis. Some are better than others (i.e. what if a parameter appears twice? (it should return the last one), does it ignore anything after the #tag? ...). As of 1.17 mw.util.getParamValue is available everywhere and takes these factors into account.
Perform a full-text all-namespace search for these function names. If they are widely used perhaps make a note about it in the local village pump. Any site-wide scripts should be updated to use the mw.util function. If there are any serious problems with the local implementation (like not escaping the value for regex), it may be wise to redirect the function:
function getURLParamValue( p, url ) {
return mw.util.getParamValue( p, url );
}
Avoid use of !important
CSS stands for Cascading Style Sheets. Cascading means what comes later overwrites what came earlier. In most cases there is no need to use !important. See the following example:
.my-element { color: blue; }
.my-element { color: green; }
Text inside <strong class="my-element"> will now be green.
Keep gadgets central
Use Meta.wikimedia.org or MediaWiki.org to store Gadgets' code, then import it into the local mediawiki.
Interface administrators: To update a gadget on your wiki:
- Check MediaWiki:Gadgets-definition on your wiki and find the gadget in question.
- The part after the pipe (
|) is the scriptname (eg. "UTCLiveClock.js"). - Go to MediaWiki:Gadget-<scriptname> (eg. MediaWiki:Gadget-UTCLiveClock.js)
- Remove everything and replace with the code in they grey area below the scriptname in the list. For an example on how this is done, check out LiveClock on Simple Wikipedia.
Below is a list of gadgets that:
- are centrally stored,
- are compatible with 1.17,
- work in Monobook and Vector, and
- can be loaded into any mediawiki, from WMF or external.
Gadgets
- UTCLiveClock
mw.loader.load('https://www.mediawiki.org/w/index.php?title=MediaWiki:Gadget-UTCLiveClock.js&action=raw&ctype=text/javascript');
- contribsrange
mw.loader.load('https://www.mediawiki.org/w/index.php?title=MediaWiki:Gadget-contribsrange.js&action=raw&ctype=text/javascript');
- modrollback
mw.loader.load('https://www.mediawiki.org/w/index.php?title=MediaWiki:Gadget-modrollback.js&action=raw&ctype=text/javascript');
- ShortDiff
mw.loader.load('https://meta.wikimedia.org/w/index.php?title=MediaWiki:Gadget-ShortDiff.js&action=raw&ctype=text/javascript');
- lastdiff Check Snippets/Last revision action
- HotCat
/**
* This imports the latest version of HotCat from Commons.
* HotCat is a gadget to make changes to categories much easier.
* Full documentation can be found at https://commons.wikimedia.org/wiki/Help:Gadget-HotCat
*/
mw.loader.load('https://commons.wikimedia.org/w/index.php?title=MediaWiki:Gadget-HotCat.js&action=raw&ctype=text/javascript');
- WikiMiniAtlas
/**
* WikiMiniAtlas is a popup click and drag world map.
* See [[meta:WikiMiniAtlas]] for more information.
* Maintainers: [[w:User:Dschwen]]
*/
mw.loader.load('https://meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript');
- Navigation Popups (MediaWiki:Gadget-popups.js and MediaWiki:Gadget-popups.css respectively)
mw.loader.load('https://en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-popups.js&action=raw&ctype=text/javascript');
@import url('https://en.wikipedia.org/w/index.php?title=MediaWiki:Gadget-navpop.css&action=raw&ctype=text/css');
jQuery optimization
- Optimization for jQuery
- jQuery for Performance & Common mistakes
- http://www.smashingmagazine.com/2008/09/16/jquery-examples-and-best-practices/
Use API instead of index.php
XML retrieved by invoking GET and POST methods on index.php is incompatible with HTML 5, which is the default as of 1.16 (and WMF sites since ). You should update code to use api.php, JSON format and jQuery.ajax immediately. Use the ResourceLoader modules that do this for you to simplify interacting with the API, including mediawiki.api.
A temporary fix for problems with DOM parsing of XML retrieved via AJAX: For example the method getElementById("foobar") on a XML object from Mozilla's DOMParser stopped to work as before. Replacing the getElementById with $('#foobar', client.responseText).get(0) might work without many other changes to your code. Updating your script to the above mentioned methods is strongly recommended, however.
Conventions
- Příručka:Kódovací konvence/JavaScript – keep if statements with brackets, use proper indention (block B in block A is indented more, visualize the tree), etc.
- Příručka:Konvence pro psaní kódu/CSS – combine selectors, remove stuff now in core, etc.