/**
* @module multiButtonConfirm
* @description A confirmation dialog that can have multiple customised buttons.
* Derived from <https://en.wikipedia.org/wiki/User:Evad37/XFDcloser/v3.js>.
* @author User:Evad37
* @version 1.0.0
* @requires mediawiki.util
* @requires oojs-ui-core
* @requires oojs-ui-widgets
* @requires oojs-ui-windows
* @exports {Function} multiButtonConfirm
* @param {Object} config configuartion options
* @param {String} config.title Title for the dialogue
* @param {String} config.message Message for the dialogue. HTML tags (except
* for <br>, <p>, <ul>, <li>, <hr>, and <pre> --plain tags only, no
* attributes allowed) are escaped; wikilinks are turned into real links.
* @param {Object[]} config.actions Optional. Array of configuration objects for
* OO.ui.ActionWidget <https://doc.wikimedia.org/oojs-ui/master/js/#!/api/OO.ui.ActionWidget>.
* If not specified, the default actions are 'accept' (with label 'OK') and
* 'reject' (with label 'Cancel').
* @param {String} config.size Symbolic name of the dialog size: small,
* medium, large, larger or full.
* @returns {Promise<String>} action taken by user
*/
Window.exportScriptModule('multiButtonConfirm', (function() {
var dependenciesLoaded = $.Deferred();
mw.loader.using(
['mediawiki.util', 'oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui-windows'],
dependenciesLoaded.resolve,
dependenciesLoaded.reject
);
return dependenciesLoaded.then(function() {
/**
* Un-escapes some HTML tags (<br>, <p>, <ul>, <li>, <hr>, and <pre>);
* turns wikilinks into real links. Ignores anyting within
* <pre>...</pre> tags.
* Input will first be escaped using mw.html.escape() unless specified
* otherwise.
* @param {String} text
* @param {Object} config Configuration options
* @param {Boolean} config.noEscape - do not escape the input first
* @returns {String} unescaped text
*/
var safeUnescape = function(text, config) {
var path = 'https:' + mw.config.get('wgServer') + '/wiki/';
return ( config && config.noEscape && text || mw.html.escape(text) )
// Step 1: unescape <pre> tags
.replace(
/<(\/?pre\s?\/?)>/g,
'<$1>'
)
// Step 2: replace piped wikilinks with real links (unless inside <pre> tags)
.replace(
/\[\[([^\|\]]*?)\|([^\|\]]*?)\]\](?![^<]*?<\/pre>)/g,
'<a href="' + path + mw.util.wikiUrlencode('$1') + '" target="_blank">$2</a>'
)
// Step 3: replace other wikilinks with real links (unless inside <pre> tags)
.replace(
/\[\[([^\|\]]+?)]\](?![^<]*?<\/pre>)/g,
'<a href="' + path + mw.util.wikiUrlencode('$1') + '" target="_blank">$1</a>'
)
// Step 4: unescape other tags: <br>, <p>, <ul>, <li>, <hr> (unless inside <pre> tags)
.replace(
/<(\/?(?:br|p|ul|li|hr)\s?\/?)>(?![^<]*?<\/pre>)/g,
'<$1>'
);
};
/** @see #exports */
var multiButtonConfirm = function(config) {
var dialogClosed = $.Deferred();
// Wrap message in a HtmlSnippet to prevent escaping
var htmlSnippetMessage = new OO.ui.HtmlSnippet(
safeUnescape(config.message)
);
var windowManager = new OO.ui.WindowManager();
var messageDialog = new OO.ui.MessageDialog();
$('body').append( windowManager.$element );
windowManager.addWindows( [ messageDialog ] );
windowManager.openWindow( messageDialog, {
'title': config.title,
'message': htmlSnippetMessage,
'actions': config.actions,
'size': config.size
} );
windowManager.on('closing', function(_win, promise) {
promise.then(function(data) {
dialogClosed.resolve(data && data.action);
windowManager.destroy();
});
});
return dialogClosed.promise();
};
return multiButtonConfirm;
});
})());