MediaWiki:Gadget-fastbuttons.js

From Wikipedia, the free encyclopedia

Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: hold down the Ctrl key and click the Refresh or Reload button. Firefox: hold down the Shift key while clicking Reload (or press Ctrl-Shift-R). Google Chrome and Safari users can just click the Reload button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.

/** FastButtons
 * @author: [[es:User:Racso]] (versão original do script, na Wikipédia em espanhol)
 * @author: [[en:User:Macy]] (versão adaptada para a Wikipédia inglesa)
 * @author: Outros editores que aparecem no histórico
 * @source: [[en:User:Macy/FastButtons.js]] (//en.wikipedia.org/w/index.php?oldid=230473471)
 * @source: [[es:Special:PrefixIndex/User:Racso/FB]]
 */
/*jslint browser: true, white: true, devel: true, plusplus: true, continue: true */
/*global jQuery, mediaWiki */
( function ( $, mw /* , undefined */ ) {
'use strict';
var fb = {
	// Replace this string by 5~ before saving:
	version: '14h28min de 30 de junho de 2012 (UTC)',
	ns: mw.config.get('wgNamespaceNumber'),
	title: mw.config.get('wgTitle'),
	submenu: {},
	$menu: $( '<div id="fb-menu"></div>' ),
	$submenu: $( '<div id="fb-submenu"></div>' )
},
// FIXME: Move these variables to the scope where they are really needed
esbText = '',
esbText2 = '';

/* Create new button links
 * @param {(jQuery|Array|Object)}
 *                 $target A jQuery object representing the target or
 *                         an object representing a button (see 'buttons' param below)
 *                         an Array of this kind of objects
 *                 (Defaults to fb.$menu if the it is not an instance of jQuery)
 * @param {{action: (string|function()), text: string, title: string, prompt: string, label: string, disable: boolean}=}
 *                 buttons Atributes and other information for the new button
 * @return {boolean} true Not useful so far
 */
fb.addButton = function ( $target, buttons ) {
	var	comment, props, button, i,
		doNothing = function(e){
			e.preventDefault();
		},
		buttonClick = function( btn ){
			return function(e){
				var question = typeof btn.action === 'string'
						&& btn.action.substr(0,2) === 'ER'
					? 'Se necessário, coloque uma observação.'
					: btn.prompt, promptCallback;
				e.preventDefault();
                promptCallback = function  ( comment ){
                    if( $.isFunction( btn.action ) ) {
                        btn.action();
                    } else {
                        fb.run( btn.action, comment);
                    }
                };
                if ( question ) {
					comment = fb.nicePrompt( question, btn.label, promptCallback );
				} else {
                promptCallback ( comment );
                }
			};
		};
	if ( !$target.jquery ) {
		// if $target is not an instance of jQuery, use it as 'buttons'
		buttons = $target;
		$target = fb.$menu;
	}
	if ( !$.isArray( buttons ) ){
		buttons = [ buttons ];
	}
	for(i=0; i<buttons.length; i++ ){
		button = buttons[i];
		props = {
			title: button.title,
			text: button.text
		};
		if( button.disable ){
			props['class'] = 'fb-button fb-disabled-button';
			props.click = doNothing;
		} else {
			props['class'] = $.isFunction( button.action )
				? 'fb-button fb-menu-button'
				: 'fb-button fb-action-button';
			props.click = buttonClick( button );
		}
		$( '<a></a>', props ).appendTo( $target ).after(' ');
	}
	return true;
};

fb.catScanOptions = function(){
	var	i, catScanUrl, list;
	list = [
		{
			text: 'sem fontes',
			desc: 'Procurar páginas desta categoria que precisam de fontes',
			url: 'ts&templates=Sem-fontes'
		},
		{
			text: 'revisão',
			desc: 'Procurar páginas desta categoria que precisam de revisão',
			url: 'ts&templates=Revis%C3%A3o'
		},
		{
			text: 'wikificação',
			desc: 'Procurar páginas desta categoria que precisam de wikificação',
			url: 'ts&templates=Wikifica%C3%A7%C3%A3o'
		},
		{
			text: 'menos de 1 000 bytes ou 4 links',
			desc: 'Procurar páginas desta categoria que possuem menos de 1 000 bytes ou 4 links',
			url: 'ss&size=1000&stubop=or&links=4'
		},
		{
			text: 'menos de 500 bytes ou 2 links',
			desc: 'Procurar páginas desta categoria que possuem menos de 500 bytes ou 2 links',
			url: 'ss&size=500&stubop=or&links=2'
		}
	];

	catScanUrl = '//toolserver.org/~daniel/WikiSense/CategoryIntersect.php?' +
		$.param( {
			wikilang:  mw.config.get('wgContentLanguage'),
			wikifam: '.wikipedia.org',
			userlang: mw.config.get('wgUserLanguage'),
			basecat: mw.config.get('wgTitle'),
			basedeep: '1',
			go: 'Examinar',
			format: 'html',
			mode: ''
		} );
	fb.$submenu.append( 'Procurar nesta categoria:' );
	for(i=0; i<list.length; i++){
		fb.$submenu.append( ' ', $('<a></a>', {
			'class': 'fb-button',
			'href': catScanUrl + list[i].url,
			'text': list[i].text,
			'title': list[i].desc
		}) );
	}
};

fb.addSearchOptions = function(){
	var	i,
		$searchOptions = $('<span class="plainlinks"></span>'),
		search = encodeURIComponent(
			fb.title.indexOf( ' ' ) > -1
				? '"' + fb.title + '"'
				: fb.title
		),
		list = [ {
			text: 'Google',
			desc: 'Pesquisar o título desta página no Google',
			url: '//www.google.com/search?&as_eq=wikipedia&as_epq=',
			after: ' — '
  },
	{
			text: 'notícias',
			desc: 'Pesquisar o título desta página no Google Notícias',
			url: '//news.google.com/archivesearch?&as_src=-newswire+-wire+-presswire+-PR+-press+-release&as_epq=',
			after: ', '
		}, {
			text: 'livros',
			desc: 'Pesquisar o título desta página no Google Livros',
			url: '//books.google.com/books?&as_brr=0&as_epq=',
			after: ', '
		}, {
			text: 'acadêmico',
			desc: 'Pesquisar o título desta página no Google Acadêmico',
			url: '//scholar.google.com/scholar?as_epq=',
			after: ' — '
		}, {
			text: 'Scirus',
			desc: 'Pesquisar o título desta página no Scirus',
			url: '//www.scirus.com/srsapp/search?t=all&sort=0&g=s&q='
		} ];
	for(i=0; i<list.length; i++){
		$searchOptions.append( $('<a></a>', {
			'class': 'external text',
			'href': list[i].url + search,
			'text': list[i].text,
			'title': list[i].desc
		}) );
		if( list[i].after ){
			$searchOptions.append( list[i].after );
		}
	}
	fb.$submenu.append( $searchOptions );
};

fb.addFieldForOtherESROptions = function(){
	var $otherInput, $okButton;

	$otherInput = $('<input type="text" id="fb-esr-input" size=55/>')
		.keypress( function(evt){
			fb.ok(evt, 'ESR');
		} );
	$okButton = $('<input type="button" value="OK"/>')
		.mousedown( function (){
			fb.ok('ok', 'ESR');
		} );

	fb.$submenu.append( 'outra: ', $otherInput, $okButton );
};

fb.addFieldForStubs = function(){
	var $stubInput, $okButton;

	$stubInput = $('<input id="fb-esb-input" size=14/>')
		.keyup( function(){
			fb.callAPI('esb');
		} )
		.keypress( function(evt){
			fb.ok(evt, 'esb');
		} );
	$okButton = $('<input type="button" value="OK"/>')
		.mousedown( function (){
			fb.ok('ok', 'esb');
		} );

	fb.$submenu.append( ' esboço-', $stubInput, $okButton );
};

/*** Submenu [ER] ***/
fb.submenu.ER = [
	{
		action: 'ER|1',
		text: '1',
		title: '???',
		disable: true
	},
	{
		action: 'ER|5',
		text: '5',
		title: 'Aparecimento recorrente (se o conteúdo for igual ao eliminado por votação)'
	},
	{
		action: 'ER|6',
		text: '6',
		title: 'Título é SPAM',
		disable: $.inArray(fb.ns, [0, 102]) === -1
	},
	{
		action: 'ER|7',
		text: '7',
		title: 'Próprio criador reconhece que se enganou'
	},
	{
		action: 'ER|8',
		text: '8',
		title: 'Eliminações temporárias sem perda de histórico para resolver problemas técnicos',
		disable: $.inArray('sysop', mw.config.get('wgUserGroups')) === -1
	},
	{
		action: 'ER|9',
		text: '9',
		title: 'Eliminar redirect, página sem histórico relevante' +
			' (mover página redirecionada para cá)'
	},
	{
		action: 'ER|10',
		text: '10',
		title: 'Namespaces que não existem (WikipÉdia, AjUda)',
		disable: fb.ns !== 0
	},
	{
		action: 'ER|11',
		text: '11',
		title: 'Má configuração do teclado (Página, Usuário:Sicrano)'
	},
	{
		action: 'ER|12',
		text: '12',
		title: 'Imagens, somente por quem a carregou',
		disable: fb.ns !== 6
	},
	{
		action: 'ER|13',
		text: '13',
		title: 'Páginas sem histórico relevante que são violações flagrantes de' +
			' direitos autorais de outras páginas na internet.',
		disable: $.inArray(fb.ns, [0, 102]) === -1
	},
	{
		action: 'ER|14',
		text: '14',
		title: 'Ficheiros (arquivos) duplicados',
		disable: fb.ns !== 6
	},
	{
		action: 'ER|17',
		text: '17',
		title: 'Salto de domínio'
	},
	{
		action: 'ER|18',
		text: '18',
		title: 'Discussão cujos artigos não existem',
		disable: fb.ns !== 1
	},
	{
		action: 'ER|19',
		text: '19',
		title: 'Ficheiros (domínio Ficheiro:) que não são som, imagem ou vídeo',
		disable: fb.ns !== 6
	},
	{
		action: 'ER|20',
		text: '20',
		title: 'Impróprio'
	},
	{
		action: 'ER|21',
		text: '21',
		title: 'Página de eliminação de um artigo antes de passados 6 meses da última votação',
		disable: mw.config.get('wgPageName').indexOf('Wikipédia:Páginas_para_eliminar/') !== 0
	},
	{
		action: 'ER|A1',
		text: 'A1',
		title: 'Páginas com o título malformatado, absurdo, com palavras que não' +
			' o são, com erros devidos à má configuração do teclado, com codificação' +
			' incorreta do sistema ou que expressem domínios que não existem.',
		disable: $.inArray(fb.ns, [0, 102]) === -1
	},
	{
		action: 'ER|C1',
		text: 'C1',
		title: 'Categorias vazias, desnecessárias ou substituídas',
		disable: fb.ns !== 14
	},
	{
		action: 'ER|D1',
		text: 'D1',
		title: 'Discussões de páginas inexistentes',
		disable: fb.ns % 2 === 0
	},
	{
		action: 'ER|D2',
		text: 'D2',
		title: 'Discussões de páginas para eliminação ou com histórico irrelevante',
		disable: fb.ns % 2 === 0
	},
	{
		action: 'ER|U1',
		text: 'U1',
		title: 'Uso impróprio da página de usuário',
		disable: $.inArray(fb.ns, [2, 3]) === -1
	},
	{
		action: 'ER|U2',
		text: 'U2',
		title: 'Página de usuário criada por outro usuário',
		disable: fb.ns !== 2
	},
	{
		action: 'ER|P1',
		text: 'P1',
		title: 'Predefinições vazias, desnecessárias ou substituídas',
		disable: fb.ns !== 10
	},
	{
		action: 'ER|R1',
		text: 'R1',
		title: 'Redirecionamento indevido, desnecessário, sem afluentes,' +
			' para páginas inexistente ou eliminadas'
	},
	{
		action: 'ER|R2',
		text: 'R2',
		title: 'Redirecionamento de página de discussão sem afluentes',
		disable: fb.ns % 2 === 0
	}
];

/*** Submenu [ESR] ***/
fb.submenu.ESR = [
	{
		action: 'subst:ESR-banda|1=~~' + '~~',
		text: 'banda',
		title: 'Artigo sobre banda sem fontes e sem notoriedade'
	},
	{
		action: 'subst:ESR-bio|1=~~' + '~~',
		text: 'biografia',
		title: 'Biografia sem fontes e sem notoriedade'
	},
	{
		action: 'subst:ESR-empresa|1=~~' + '~~',
		text: 'empresa',
		title: 'Empresa sem fontes e sem notoriedade'
	},
	fb.addFieldForOtherESROptions
];

/*** Submenu [esboço] ***/
fb.submenu.esb = [
	{
		action: 'mínimo',
		text: 'mínimo',
		title: 'Artigo com apenas uma frase'
	},
	{
		action: 'esboço',
		text: 'esboço',
		title: 'Artigo ainda pouco desenvolvido'
	},
	fb.addFieldForStubs
];

/*** Submenu [manuteção] ***/
fb.submenu.man = [
	{
		action: 'subst:wkf',
		text: 'wikificar',
		title: 'Não está formatado de acordo com o livro de estilo'
	},
	{
		action: 'subst:s-fontes',
		text: 'sem fontes',
		title: 'Página não cita nenhuma fonte ou referência'
	},
	{
		action: 'subst:s-cat',
		text: 'sem cat',
		title: 'Página não está em nenhuma categoria'
	},
	{
		action: 'subst:rec',
		text: 'reciclagem',
		title: 'Página precisa ser reciclada de acordo com o livro de estilo'
	},
	{
		action: 'parcial',
		text: 'parcial',
		title: 'Artigo possui passagens que não respeitam o princípio da imparcialidade'
	},
	{
		action: 'subst:ctx',
		text: 'contexto',
		title: 'Página carece de contexto'
	},
	{
		action: 'controverso|artigo',
		text: 'controverso',
		title: 'controverso devido às disputas sobre o seu conteúdo'
	},
	{
		action: 'subst:f-referências',
		text: 'formatar referências',
		title: 'Artigo contém referências que necessitam de formatação'
	},
	{
		action: 'subst:m-notas',
		text: 'mais notas',
		title: 'Página cita fontes fiáveis, mas não cobre todo o texto'
	},
	{
		action: 'subst:s-notas',
		text: 'sem notas',
		title: 'Existem fontes no final da página, mas não são citadas no corpo do artigo'
	},
	{
		action: 'subst:s-fontes-bpv',
		text: 'bpv sem fontes',
		title: 'Biografia de pessoa viva que não cita nenhuma fonte'
	},
	{
		action: 'subst:fpr',
		text: 'fonte primária',
		title: 'Artigo necessita de fontes secundárias fiáveis publicadas por terceiros'
	},
	{
		action: 'subst:fu',
		text: 'fusão',
		title: 'Artigo necessita de fusão',
		prompt: 'Com qual página esta deve ser feita fusão?',
        label: 'Página:'
	},
	{
		action: 'subst:f-de',
		text: 'fusão de',
		title: 'Artigo necessita de fusão',
		prompt: 'De qual página esta deve ser feita fusão?',
        label: 'Página:'
	},
	{
		action: 'subst:f-com',
		text: 'fusão com',
		title: 'Artigo necessita de fusão',
		prompt: 'Com qual página esta deve ser feita fusão?',
        label: 'Página:'
	}
];

/*** Submenu [aviso] ***/
fb.submenu.warn = [
	{
		action: 'subst:bem-vindo IP',
		text: 'BV-IP',
		title: 'Boas-vindas para usuário(a) não registrado(a)'
	},
	{
		action: 'subst:bem-vindo',
		text: 'BV',
		title: 'Bem-vindo(a) à Wikipédia'
	},
	{
		action: 'subst:bem-vinda',
		text: 'BVª',
		title: 'Bem-vinda à Wikipédia'
	},
	{
		action: 'subst:bv-av',
		text: 'av-BV-IP',
		title: 'Aviso sobre erro em artigo e boas-vindas para usuário(a) não registrado(a)',
		prompt: 'Aviso sobre qual artigo?',
        label: 'Artigo:'
	},
	{
		action: 'subst:bv-av-registrado',
		text: 'av-BV',
		title: 'Aviso sobre erro em artigo e boas-vindas para usuário(a) registrado',
		prompt: 'Aviso sobre qual artigo?',
        label: 'Artigo:'
	},
	{
		action: 'subst:aviso-ER',
		text: 'av-ER',
		title: 'Aviso sobre eliminação rápida',
		prompt: 'Qual página foi proposta para eliminação?',
        label: 'Página:'
	},
	{
		action: 'subst:av-bv-ER',
		text: 'av-BV-ER',
		title: 'Aviso sobre eliminação rápida + boas-vindas',
		prompt: 'Qual página foi proposta para eliminação?',
        label: 'Página:'
	},
	{
		action: 'subst:aviso-ESR',
		text: 'av-ESR',
		title: 'Aviso sobre eliminação semirrápida',
		prompt: 'Qual página foi proposta para eliminação?',
        label: 'Página:'
	},
	{
		action: 'subst:aviso-PE',
		text: 'av-PE',
		title: 'Aviso sobre eliminação por votação',
		prompt: 'Qual página foi proposta para eliminação?',
        label: 'Página:'
	},
	{
		action: 'subst:bv-propaganda',
		text: 'prop-BV',
		title: 'Caro editor,por favor não faça propaganda, [...] Apesar disso, bem-vindo à Wikipédia'
	},
	{
		action: 'subst:propaganda',
		text: 'prop',
		title: 'Caro editor, por favor não faça propaganda...',
		prompt: 'Em que página foi feita propaganda?',
        label: 'Página:'
	},
	{
		action: 'subst:aviso',
		text: 'av',
		title: 'Aviso sobre erro em artigo',
		prompt: 'Aviso sobre qual artigo?',
        label: 'Artigo:'
	},
	{
		action: 'subst:aviso2',
		text: 'av2',
		title: 'Aviso sobre vandalismo',
		prompt: 'Qual página foi vandalizada?',
        label: 'Página:'
	},
	{
		action: 'subst:BSRE',
		text: 'BSRE',
		title: 'Aviso de biografia sem relevo enciclopédico',
		prompt: 'Qual artigo?',
        label: 'Artigo:'
	},
	{
		action: 'subst:cópia',
		text: 'cópia',
		title: 'Aviso sobre artigo copiado de fonte externa/VDA',
		prompt: 'Qual a página da Wikipédia? E qual a URL da página copiada?',
        label: 'Página:|2=URL:'
	},
	{
		action: 'subst:linguagem incorreta',
		text: 'linguagem',
		title: 'Não insulte nem use linguagem inadequada em artigos ou discussões'
	},
	{
		action: 'subst:ortografia',
		text: 'ortografia',
		title: 'Não mude a versão da língua',
		prompt: 'Em qual artigo a versão da língua foi alterada?',
        label: 'Artigo:'
	},
	{
		action: 'subst:mostrar previsão',
		text: 'salvamento sucessivo',
		title: 'Não faça salvamentos sucessivos, utilize o botão \'Mostrar previsão\'',
		prompt: 'Em que artigo foram feitos salvamentos sucessivos?',
        label: 'Página:'
	},
	{
		action: 'subst:av-boas vindas',
		text: 'aviso-BV',
		title: 'Não dê boas-vindas a usuários que não contribuíram com pelo menos uma edição válida'
	},
	{
		action: 'subst:av-página de usuário',
		text: 'av-PU',
		title: 'Considere refazer a página de usuário(a)'
	},
	{
		action: 'subst:não remova',
		text: 'não remova',
		title: 'Não remova marcações de eliminação das páginas',
		prompt: 'Qual página em que a marcação de eliminação foi removida?' +
			'Se desejar, pode especificar o tipo de marcação.',
        label: 'Página:|2=Tipo de marcação:'
	},
	{
		action: 'subst:autobiografia',
		text: 'autobiografia',
		title: 'Não crie autobiografias',
		prompt: 'Qual autobiografia foi criada?',
        label: 'Página:'
	},
	{
		action: 'subst:av-teste',
		text: 'av-teste',
		title: 'Não faça testes nos artigos',
		prompt: 'Qual o nível do aviso? E em que página foram feitos testes?',
        label: 'Nível:|2=Página:'
	},
	{
		action: 'subst:av-data',
		text: 'av-data',
		title: 'Não insira seu nome e data de nascimento em páginas de datas',
		prompt: 'Em que página de data foram inseridos o nome e a data de nascimento?',
        label: 'Página:'
	},
	{
		action: 'subst:aviso-matrad',
		text: 'aviso-matrad',
		title: 'Aviso sobre má tradução',
		prompt: 'Qual página foi marcada como má tradução?',
        label: 'Página:'
	},
	{
		action: 'subst:bloqueado',
		text: 'bloqueado',
		title: 'Notificação de bloqueio',
		prompt: 'Especifique o tempo e o motivo do bloqueio.',
        label: 'Tempo:|2=Motivo'
	},
	{
		action: 'subst:bloqueado-disc',
		text: 'bloqueado-disc',
		title: 'Notificação de bloqueio com discussão',
		prompt: 'Especifique o tempo e o motivo do bloqueio.',
        label: 'Tempo:|2=Motivo'
	},
	{
		action: 'subst:bloqueado-CPV',
		text: 'bloqueado-CPV',
		title: 'Notificação de bloqueio para contas para vandalismo'
	},
	{
		action: 'proxy',
		text: 'proxy',
		title: 'Notificação de proxy bloqueado'
	},
	{
		action: 'subst:cite fonte',
		text: 'citar fontes',
		title: 'Faltou citar fontes à página',
		prompt: 'Qual foi a página?',
        label: 'Página:'
	}
];

/** Submenu [busca] **/
fb.submenu.search = fb.addSearchOptions;

/** Submenu [CatScan] **/
fb.submenu.cat = fb.catScanOptions;

// FIXME: Consider using jQuery: $('#target').keypress()
fb.ok = function( evt, option ) {
	if (window.event && window.event.keyCode === 13) {
		evt = 'ok';
	} else if (evt && evt.which === 13) {
		evt = 'ok';
	}
	if (evt === 'ok') {
		if ( option === 'esb' ) {
			fb.run('esboço-' + $( '#fb-esb-input').val());
		} else if ( option === 'ESR' ) {
			fb.run('subst:ESR', $( '#fb-esr-input').val() + ' ~~' + '~~');
		}
	}
};

/* Patrol the edit currently displayed
 * @param {function()} succes Callback function to be executed after the edit is pattroled
 */
fb.patrolRevision = function ( rcid, success ) {
	$.getJSON(
		mw.util.wikiScript( 'api' ), {
			format: 'json',
			action: 'query',
			list: 'recentchanges',
			rctoken: 'patrol',
			rcprop: '',
			rclimit: '1'
		},
		function( data ) {
			var	query = data.query,
				rc = query && query.recentchanges,
				token = rc && rc[ 0 ] && rc[ 0 ].patroltoken;
			if ( !token ) {
				mw.log( 'Não foi possível obter um token para patrulhar a edição.' );
				return false;
			}
			if ( !rcid ) {
				mw.log( 'Não foi possível identificar a edição a ser patrulhada.' );
				return false;
			}
			$.post(
				mw.util.wikiScript( 'api' ), {
					action: 'patrol',
					format: 'json',
					token: token,
					rcid: rcid
				},
				function( data ) {
					if ( data.error ) {
						mw.log( 'Não foi possível patrulhar a edição: ' + data.error.info );
						return false;
					}
					if ( $.isFunction( success ) ){
						success();
					}
					mw.log( 'A edição foi marcada como patrulhada.' );
					return true;
				}
			).error(function() {
				alert( 'Houve um erro inesperado ao usar a API do MediaWiki.' );
				return false;
			});
		}
	).error(function() {
		alert( 'A API retornou um erro ao tentar obter um token para patrulhar a edição.' );
		return false;
	});
};

/* Função de edição
 * @param: {string} code A template name, possibly preceded by "subst:",
 *                         and optionally followed by "|" and some parameter(s)
 * @param: {(string|null)=} extraText Extra text for templates and redirects (optional)
 * @return: {boolean} Returns false if the user canceled or the page already has a template
 */
fb.run = function (code, extraText) {
	var	$patrol, rcid,
		$textBox = $('#wpTextbox1'),
		value = $textBox.val(),
		url = mw.util.wikiGetlink( mw.config.get('wgPageName') ) + '?',
		data = {
			action: 'edit',
			fastb: code
		},
		summary = ' (usando [[WP:FB|FastButtons]])',
		// FIXME: Move this to the definition of each button
		summaries = {
			'subst:VDA': 'Página marcada como [[WP:VDA|VDA]]',
			'subst:apagar': 'Página proposta para [[WP:Eliminação' +
				' por votação|eliminação por votação]]',
			'subst:s-fontes': 'Página marcada como sem fontes',
			'subst:s-cat': 'Página marcada como sem categoria',
			'subst:wkf': 'Página marcada para [[WP:WKF|wikificação]]',
			'subst:rec': 'Página marcada para [[WP:RECI|reciclagem]]',
			'parcial': 'Página marcada como parcial',
			'subst:ctx': 'Página marcada como sem contexto',
			'controverso|artigo': 'Marcado como controverso',
			'subst:f-referências': 'Marcado que existem referências sem formatação',
			'subst:m-notas': 'Marcado que carece de mais fontes',
			'subst:s-notas': 'Página marcada como sem notas',
			'subst:s-fontes-bpv': 'Marcado como [[WP:BPV|biografia de pessoa' +
					' viva]] sem fontes',
			'subst:fpr': 'Página marcada como sem fontes secundárias fiáveis',
			'subst:ESR': 'Página proposta para [[WP:ESR|eliminação semirrápida]]',
			'subst:matrad': 'Página marcada como [[WP:Tradução|má tradução]]',
			'subst:suspeito': 'Página marcada como suspeita de [[WP:VDA|VDA]]',
			'subst:fu': 'Página marcada para [[WP:Fusão|fusão]]',
			'subst:f-de': 'Página marcada para [[WP:Fusão|fusão]]',
			'subst:f-com': 'Página marcada para [[WP:Fusão|fusão]]'
		};
	if (extraText === null) {
		// Do nothing if the user canceled the prompt box
		return false;
	}
	switch (mw.config.get('wgAction')) {
	case 'view':
		if( extraText ){
			data.fbtxt = extraText;
		}
		$patrol = mw.util.$content.find('span.patrollink a').first();
		rcid = mw.util.getParamValue( 'rcid', $patrol.attr('href') || '' );
		if ( rcid ) {
			fb.patrolRevision( rcid, function(){
				location.href = url + $.param( data );
			} );
		} else{
			location.href = url + $.param( data );
		}
		break;
	case 'edit':
		if ( value.match(/\{\{(?:subst:)?(?:ER|ESR(?:2?|-banda|-bio|-empresa|-bsre|-organização)|VDA|Usuário(?:\(a\))?\:Salebot\/Impróprio)[\|\}]/i) ) {
			alert('Já existe uma predefinição de eliminação nesta página.');
			return false;
		}
		if (code.indexOf('ER') === 0) {
			extraText = extraText? '|3=' + extraText: '';
			extraText = '{' + '{' + code + '|2=~~' + '~~' + extraText + '}}\n';
			$textBox.val( extraText + value );
			if (fb.save) {
				document.editform.wpSummary.value = 'Página proposta para' +
					' [[WP:ER|eliminação rápida]] (regra ' +
					code.substring(3) + ')' + summary;
			}
		} else if (code === 'redirect') {
			if (mw.config.get('wgNamespaceNumber') === 14) {
				if (extraText) {
					$textBox.val( '{' + '{redirecionamento de categoria|' +
						extraText + '}}' );
				}
				if (fb.save) {
					document.editform.wpSummary.value = 'Redirecionando para' +
						' a [[categoria:' + extraText + ']]' + summary;
				}
			} else {
				if (extraText) {
					$textBox.val( '#Redirecionamento [[' + extraText + ']]' );
				}
			}
		} else {
			extraText = extraText? '|1=' + extraText: '';
			extraText = '{' + '{' + code + extraText + '}}';
			if (mw.config.get('wgNamespaceNumber') === 3) {
				value += '\n\n' + extraText + ' ~~' + '~~';
			} else if (code === 'mínimo' || code.indexOf('esboço') === 0) {
				if (value.match(/\n\n\[\[/)) {
					value = value.substring(0, value.search(/\n\n\[\[/)) + '\n\n' +
						extraText + value.substring(value.search(/\n\n\[\[/));
				} else {
					value += '\n\n' + extraText;
				}
				fb.save = (code === 'mínimo') ?
					'Página marcada como [[WP:M|mínimo]]' :
					'Página marcada como [[WP:EBC|esboço]]';
			} else if ($.inArray( code, [ 'subst:VDA' , 'subst:matrad' ]) > -1) {
				value = extraText;
			} else {
				value = extraText + '\n' + value;
			}
			$textBox.val(value );
			if (fb.save) {
				if (mw.config.get('wgNamespaceNumber') === 3) {
					fb.save = 'Adicionando aviso';
				} else {
					if ( code.indexOf( 'subst:ESR' ) === 0 ) {
						code = 'subst:ESR';
					}
					fb.save = summaries[ code ] || 'Adicionando marcação';
				}
				document.editform.wpSummary.value = fb.save + summary;
			}
		}
		// FIXME: It should not submit if in edit mode and (code === 'mínimo' || code.indexOf('esboço') === 0)
		if (fb.save) {
			document.editform.submit();
		}
		break;
	}
};

/* Changes the content of the submenu
 * @param {string} items The new buttons for the new submenu
 */
fb.changeSubmenu = function ( items ) {
	var i;
	fb.$submenu.empty();
	if( !$.isArray( items ) ){
		items = [ items ];
	}
	for(i=0;i<items.length; i++){
		if( $.isFunction( items[i] ) ){
			items[i]();
		} else if ( typeof items[i] === 'string' ){
			fb.$submenu.append( items[i] );
		} else {
			fb.addButton( fb.$submenu, items[i] );
		}
	}
	fb.$submenu.find( 'a, span' ).tipsy();
};

/* Callback function for API calls
 * @param {string} code An abreviation such as "esb", "PV",
 */
fb.callAPI = function ( code ) {
	var esb, apiParams, callbacks;
	apiParams = {
		esb: {
			list: 'allpages',
			aplimit: '1',
			apnamespace: '10'
		},
		PV: {
			list: 'watchlist',
			wlprop: 'user|comment|title|sizes',
			wlexcludeuser: mw.config.get('wgUserName')
		},
		PN: {
			list: 'recentchanges',
			rctype: 'new',
			rcnamespace: '0',
			rcshow: '!patrolled',
			rcprop: 'user|comment|title|sizes|ids'
		},
		MR: {
			list: 'recentchanges',
			rctype: 'edit',
			rcnamespace: '0',
			rcshow: 'anon',
			rcprop: 'user|comment|title|sizes'
		},
		usu: {
			list: 'allusers',
			aulimit: '1',
			auprop: 'editcount|registration',
			aufrom: mw.config.get('wgTitle').split('/')[0]
		},
		anon: {
			list: 'usercontribs',
			uclimit: '500',
			ucprop: 'timestamp',
			ucuser: mw.config.get('wgTitle').split('/')[0]
		}
	};
	callbacks = {
		esb: fb.processStubs,
		PV: fb.processRecentEdits,
		PN: fb.processRecentEdits,
		MR: fb.processRecentEdits,
		usu: fb.processUserInfo,
		anon: fb.processUserInfo
	};
	if ( 'esb' === code ) {
		esb = $( '#fb-esb-input' ).val();
		if ( $.inArray( esb, [ esbText, esbText2 ] ) !== -1 ) {
			return;
		}
		esbText = esb;
		if (esbText === esb.substr(0, (esb.length - 1))) {
			return;
		}
		apiParams.esb.apprefix = 'Esboço-' + esb;
	}
	apiParams[ code ].format = 'json';
	apiParams[ code ].action = 'query';
	$.getJSON(
		mw.util.wikiScript( 'api' ),
		apiParams[ code ], function( data ) {
			if( !data ){
				mw.log(
					'Não foi possível obter a lista "' +
					apiParams[ code ].list + '" a partir da API.'
				);
				return;
			}
			callbacks[ code ]( data, code );
		}
	);
};

/* Callback function for backlinks request
 * @param {Object} data JSON content returned by API
 */
fb.processBackLinks = function(data) {
	var	info, catLine, backlinks, $hiddenCats, quality,
		query = data.query;
	info = '(';
	info += (document.getElementById('Refer.C3.AAncias')
			|| document.getElementById('Notas_e_refer.C3.AAncias')) ?
				'ref' :
				'<span class="fb-missing" title="Esta página ainda não possui referências">ref</span>';
	catLine = document.getElementById( 'mw-normal-catlinks' );
	// FIXME: Use the API (instead of 'screen scraping') to get this information!
	if (catLine && catLine.innerHTML.indexOf( '><a href="' + mw.config.get('wgArticlePath').replace('$1', '')) > -1) {
		info += ' · cat';
	} else {
		info += ' · <span class="fb-missing" title="Esta página ainda não foi categorizada">cat</span>';
	}
	info += ( $( '#p-lang' ).length ) ?
		' · iw' :
		' · <span class="fb-missing" title="Esta página ainda não' +
			' possui links para outros idiomas">iw</span>';

	// Afluentes
	backlinks = query && query.backlinks;
	if ( !backlinks ) {
		mw.log( 'The backlinks query returned no data.' );
	} else if ( backlinks.length ) {
		info += ' · <a href="' +
			mw.util.wikiGetlink( 'Especial:Páginas afluentes/' + mw.config.get('wgPageName') ) +
			'" title="afluentes">afl</a>)';
	} else {
		info += ' · <span class="fb-missing" title="Esta página ainda não possui afluentes">afl</span>)';
	}
	fb.changeSubmenu( info );
	if ( !$( '#ca-talk' ).hasClass('new') ) {
		$.getJSON(
			mw.util.wikiScript( 'api' ), {
				format: 'json',
				action: 'query',
				prop: 'categories',
				indexpageids: '1',
				titles: mw.config.get('wgFormattedNamespaces')[ mw.config.get('wgNamespaceNumber') + 1 ] +
					':' + mw.config.get('wgTitle')
			}, function( data ) {
				fb.processPageQuality( data );
			}
		);
	} else {
		$hiddenCats = $('#mw-hidden-catlinks');
		if ( $hiddenCats.length ) {
			quality = $hiddenCats.html();
			if (quality.indexOf('!Artigos de qualidade') > -1) {
				quality = quality.substr(quality.indexOf('!Artigos de qualidade') + 22, 1);
				if (quality === 'd') {
					quality = '?';
				}
				fb.$submenu.append(
					'<span title="Qualidade do artigo"> Q-<b>' +
					quality + '</b></span>'
				).find( 'a, span' ).tipsy();
			}
		}
	}
};


/* Callback function for the request of talk page categories
 * @param {Object} data JSON content returned by API
 */
fb.processPageQuality = function(data) {
	var	cats, pageids, i, cat, quality,
		query = data.query;
	if ( query ) {
		cats = query.pages;
		pageids = query.pageids;
		if ( cats && pageids && pageids.length ) {
			cats = cats[ pageids[0] ].categories;
			if ( !cats ){
				mw.log( 'The categories query returned incomplete data.' );
				return false;
			}
		} else {
			mw.log( 'The categories query returned incomplete data.' );
			return false;
		}
	} else {
		mw.log( 'The categories query returned no data.' );
		return false;
	}
	// Qualidade do artigo
	for (i = 0; i < cats.length; i++) {
		cat = cats[i].title;
		if ( cat && cat.indexOf( '!Artigos de qualidade' ) > -1 ){
			// Categoria:!Artigos de qualidade 1 sobre ...
			//                                 ^
			quality = cat.substr( 32, 1 );
			if (quality === 'd') {
				quality = '?';
			}
			fb.$submenu.append(
				'<span title="Qualidade do artigo"> Q-<b>' +
					quality + '</b></span>'
			).find( 'a, span' ).tipsy();
			break;
		}
	}
};

/* Callback function for the request of stub templates
 * @param {Object} data JSON content returned by API
 */
fb.processStubs = function(data) {
	var	template, start, sel,
		esb = document.getElementById( 'fb-esb-input' ),
		query = data.query;
	if ( query ) {
		template = query.allpages && query.allpages[0] && query.allpages[0].title;
		if ( !template ) {
			mw.log( 'The categories query returned incomplete data.' );
			return false;
		}
		template = template.replace( /^Predefinição:Esboço-/gi, '' );
	} else {
		mw.log( 'The categories query returned no data.' );
		return false;
	}
	if ((esb.setSelectionRange
			|| esb.createTextRange
			|| ( typeof esb.selectionStart !== 'undefined'
				&& typeof esb.selectionEnd !== 'undefined'
			)
		)
		&& esb.value === template.substr(0, esb.value.length)
	) {
		// Exibe sugestões. Baseado no script do HotCat
		start = esb.value.length;
		esb.value = template;
		esbText2 = template;
		if (esb.setSelectionRange) {
			esb.setSelectionRange(start, template.length);
		} else if (esb.createTextRange) {
			sel = esb.createTextRange();
			sel.move( 'character', start );
			sel.moveEnd( 'character', template.length - start );
			sel.select();
		} else {
			esb.selectionStart = start;
			esb.selectionEnd = template.length;
		}
	}
};

/* Callback function for the request of recent edits (from watchlist or recent changes)
 * @param {Object} data JSON content returned by API
 */
fb.processRecentEdits = function(data, code) {
	var	listName, summaryChanges, urlParam, list, max, i,
		item, title, length, comment, j,
		pages = [],
		charnum = 0,
		query = data.query;

	listName = {
		PV: 'watchlist',
		MR: 'recentchanges',
		PN: 'recentchanges'
	};
	summaryChanges = {
		PV: [
			[ '[[Ajuda:SEA|←]]', '' ],
			[ '/*', '→' ],
			[ '*/', ':' ]
		],
		MR: [
			[ '/*', '→' ],
			[ '*/', ':' ]
		],
		PN: [
			[ '[[Ajuda:SEA|?]] ', '' ]
		]
	};
	urlParam = {
		PV: 'diff=last',
		MR: 'diff=last',
		PN: 'redirect=no&rcid='
	};
	list = query[ listName[ code ] ];
	max = ( list.length < 10 )? list.length : 10;

	for ( i = 0; i < max; i++ ) {
		item = list[ i ];
		if ( !item ){
			continue;
		}
		title = item.title;
		charnum += title.length;
		if (charnum > 180) {
			break;
		}
		length = item.newlen - item.oldlen;
		if (length > 0) {
			length = '+' + length;
		}
		comment = item.comment || '';
		for ( j=0; j < summaryChanges[ code ].length; j++ ){
			comment = comment.replace(
				summaryChanges[ code ][0],
				summaryChanges[ code ][1]
			);
		}
		if (comment) {
			comment = '(' + comment + ')';
		}
		if ( code === 'PN' ){
			urlParam[ code ] += item.rcid;
		}
		pages.push(
			'<a href="' + mw.util.wikiGetlink( title ) + '?' +
			urlParam[ code ] + '" title="(' + length + ') ' + item.user +
			' ' + comment + '">' + title + '</a>'
		);
	}
	fb.changeSubmenu( '<div class="horizontal">' + pages.join( ' ' ) + '</div>' );
};

/* Callback function for the request of user info
 * @param {Object} data JSON content returned by API
 */
fb.processUserInfo = function(data, code) {
	var	contribs, regDate, encUser,
		user = {},
		query = data.query;

	// Informações do(a) usuário(a)
	if ( !query ) {
		mw.log( 'The categories query returned no data.' );
		return false;
	}
	if( code === 'anon' ){
		if( !query.usercontribs ){
			return;
		}
		contribs = query.usercontribs;
		user.name = contribs[0].user;
		user.editcount = contribs.length;
		user.registration = contribs[ contribs.length - 1 ].timestamp;
		if( data[ 'query-continue' ] ){
			user.editcount = 'mais de ' + user.editcount;
			user.registration = 'antes de ' + user.registration;
		}
	} else {
		user = query.allusers && query.allusers[0];
	}
	if ( user ) {
		// Ex.: YYYY-MM-DDThh:mm:ssZ
		regDate = user.registration;
		regDate = regDate.substr(8, 2) + '/' + regDate.substr(5, 2) +
			'/' + regDate.substr(0, 4);
		encUser = encodeURI( user.name );
		//FIXME: Simplify this!
		fb.changeSubmenu( [
				user.editcount + ' edições desde ' + regDate + '.',
				'<a class="fb-button" href="' +
					mw.util.wikiGetlink( 'Especial:Contribuições/' ) + encUser +
					'" title="Abrir a lista de contribuições deste editor" >contribuições</a>',
				'<a class="fb-button" href="' +
					mw.util.wikiGetlink( 'Especial:Registo/' ) + encUser +
					'" title="Abrir a lista de registros deste editor" >registros</a>',
				'<a class="fb-button" href="' +
					mw.util.wikiGetlink( 'Especial:Registo' ) + '?type=block&page=User%3A' + encUser +
					'" title="Abrir a lista de registros de bloqueio deste editor">registros de bloqueio</a>',
				'<span class="plainlinks"><a class="external text fb-button"' +
					'title="Abrir a contagem de edições deste editor"' +
					' href="//toolserver.org/~river/cgi-bin/count_edits?user=' +
					encUser + '&dbname=' + mw.config.get('wgDBname') + '_p">contador de edições</a></span>'
			].join( ' ' )
		);
	} else {
		return;
	}
};

/* Initialize the gadget */
fb.init = function () {
	var	inUserNS, basePageName,
		param = mw.util.getParamValue('fastb');
	if ($.inArray(mw.config.get('wgAction'), ['view', 'edit']) !== -1) {
		// FIXME: Is this still necessary? maybe fb.$submenu.empty()?
		fb.changeSubmenu( '' );
		/*** Menu Principal ***/
		if (mw.config.get('wgNamespaceNumber') > -1) {
			inUserNS = $.inArray(mw.config.get('wgNamespaceNumber'), [2, 3]) > -1
				&& mw.config.get('wgTitle').indexOf(mw.config.get('wgUserName')) === 0;
			fb.$menu.empty();
			if (inUserNS) {
				fb.addButton({
					action: 'ER|1',
					text: 'ER1',
					title: 'Marcar subpágina do próprio usuário para eliminação'
				});
			} else {
				fb.addButton({
					action: function(){
						fb.changeSubmenu(fb.submenu.ER);
					},
					text: 'ER',
					title: 'Exibir regras para a eliminação rápida'
				});
			}
		}
		if ($.inArray(mw.config.get('wgNamespaceNumber'), [0, 102]) !== -1) {
			fb.addButton([
				{
					action: function(){
						fb.changeSubmenu(fb.submenu.ESR);
					},
					text: 'ESR',
					title: 'Exibir regras para a eliminação semi-rápida'
				},
				{
					action: 'subst:apagar',
					text: 'PE',
					title: 'Marcar para eliminação por votação'
				},
				{
					action: function(){
						fb.nicePrompt(
							'Informe o url da página copiada',
							'Url :', function (obs) { fb.run('subst:VDA', obs);}
						);
					},
					text: 'VDA',
					title: 'Marcar como cópia ou violação de direito autoral'
				},
				{
					action: 'subst:suspeito',
					text: 'susp',
					title: 'Marcar como suspeito de violação de direitos autorais'
				},
				{
					action: 'subst:matrad',
					text: 'trad',
					title: 'Marcar esta tradução como sendo de baixa qualidade',
					prompt: 'De qual língua a página foi maltraduzida (ca, de, en, es,' +
						' fr, it, ja, nl, no, pl, ru, sv, zh)?',
                    label: 'Página:'
				},
				{
					action: 'redirect',
					text: '#R',
					title: 'Redirecionar para outro título',
					prompt: 'Redirecionar para qual página?',
                    label: 'Página:'
				},
				{
					action: function(){
						fb.changeSubmenu(fb.submenu.man);
					},
					text: 'manutenção',
					title: 'Exibir predefinições para manutenção'
				},
				{
					action: function(){
						fb.changeSubmenu(fb.submenu.esb);
					},
					text: 'esboço',
					title: 'Exibir predefinições para esboços'
				},
				{
					action: function(){
						fb.changeSubmenu(fb.submenu.search);
					},
					text: 'busca',
					title: 'Exibir opções para a busca de fontes'
				}
			]);
			if (mw.config.get('wgAction') === 'view') {
				$.getJSON(
					mw.util.wikiScript( 'api' ), {
						format: 'json',
						action: 'query',
						list: 'backlinks',
						bllimit: '1',
						blfilterredir: 'nonredirects',
						blnamespace: '0',
						bltitle: mw.config.get('wgPageName')
					},
					fb.processBackLinks
				);
			}
		} else {
			if ($.inArray(mw.config.get('wgNamespaceNumber'), [2, 10]) !== -1) {
				fb.addButton({
					action: 'subst:apagar',
					text: 'PE',
					title: 'Marcar para eliminação por votação'
				});
			}
			if (mw.config.get('wgNamespaceNumber') % 2 === 0) {
				fb.addButton({
					action: 'redirect',
					text: '#R',
					title: 'Redirecionar para outro título',
					prompt: 'Redirecionar para qual página?',
                    label: 'Página:'
				});
			}
			if (mw.config.get('wgNamespaceNumber') === 14) {
				fb.addButton({
					action: function(){
						fb.changeSubmenu(fb.submenu.cat);
					},
					text: 'CatScan',
					title: 'Exibir opções do CatScan para procurar páginas nesta categoria'
				});
			}
		}
		if (mw.config.get('wgNamespaceNumber') === 3) {
			fb.addButton({
				action: function(){
					fb.changeSubmenu(fb.submenu.warn);
				},
				text: 'aviso',
				title: 'Exibir lista de predefinições para avisos'
			});
		}
		if ($.inArray(mw.config.get('wgNamespaceNumber'), [2, 3]) !== -1) {
			basePageName = mw.config.get('wgTitle').split('/')[0];
			if ( mw.util.isIPv4Address( basePageName ) || mw.util.isIPv6Address( basePageName ) ) {
				fb.addButton({
					action: function(){
						fb.callAPI('anon');
					},
					text: 'sobre o IP',
					title: 'Exibir informações sobre este IP'
				});
			} else {
				fb.addButton({
					action: function(){
						fb.callAPI('usu');
					},
					text: 'sobre a conta',
					title: 'Exibir informações sobre esta conta'
				});
			}

		}
	}
	fb.addButton([
		{
			action: function(){
				fb.callAPI('PV');
			},
			text: 'PV',
			title: 'Exibir páginas vigiadas que foram alteradas recentemente'
		},
		{
			action: function(){
				fb.callAPI('PN');
			},
			text: 'PN',
			title: 'Exibir páginas novas que ainda não foram patrulhadas'
		},
		{
			action: function(){
				fb.callAPI('MR');
			},
			text: 'MR',
			title: 'Exibir mudanças recentes feitas por IPs em páginas do domínio principal'
		}
	]);
	if( mw.config.get('skin') === 'modern' ){
		$( '#contentSub' ).before( fb.$menu ).before( fb.$submenu );
	} else {
		$( 'h1' ).first().after( fb.$submenu ).after( fb.$menu );
	}

	switch (mw.config.get('wgAction')) {
	case 'edit':
		// FIXME: Use API to edit, because pseudo actions may be dangerous
		// (see [[commons:Commons:Administrators' noticeboard/Archive 34#MediaWiki:Gadget-autodel.js]])
		fb.save = (param !== null);
		if (fb.save) {
			fb.run(param, mw.util.getParamValue('fbtxt') || '');
		}
		break;
	case 'markpatrolled':
		// FIXME: Use API to patrol, because pseudo actions may be dangerous (see above)
		if (param !== null) {
			location.href = mw.util.wikiGetlink( mw.config.get('wgPageName') ) +
				'?action=edit&fastb=' + param;
		}
		break;
	default:
		// Não faz nada nas demais ações
	}
	fb.$menu.find( 'a' ).tipsy();
};
    fb.nicePrompt = function (title, label, callback) {
        'use strict';
        var twoQuestions = label.search('/|2='), $dialog = $('<div id="nprompt-dialog" class="ui-widget"></div>');
        if (twoQuestions !== -1) {
            $dialog.append('<label for="nprompt-input1">' + label.substring(0, twoQuestions - 1) + '</label>' + '<input type="text" id="nprompt-input1"> </input> <label for="nprompt-input2">' + label.substring(twoQuestions + 2) + '</label>' + '<input type="text" id="nprompt-input2"> </input>');
        } else {
            $dialog.append('<label for="nprompt-input">' + label + '</label>' + '<input type="text" id="nprompt-input"> </input>');
        }
        $dialog.dialog({
            title: title,
            open: function () {
                $(".ui-dialog-titlebar-close").hide();
            },
            close: function () {
            $('#nprompt-dialog').dialog('destroy');
            $('#nprompt-dialog').remove();
            },
            buttons: {
                "OK": function () {
                    var answer;
                    if (twoQuestions === -1) {
                        callback($('#nprompt-input').val());
                    } else {
                        answer = ($('#nprompt-input1').val() + '|2=' + $('#nprompt-input2').val());
                        callback(answer);
                    }
                    $(this).dialog("close");
                },
                Cancelar: function() {
                    fb.useDialog('Ah!', 'Você cancelou!', 'nprompt-dialog');
                }
            }         
        });
    };
    fb.useDialog = function (title, message, id) {
        'use strict';
        $('#' + id).empty();
        $('#' + id).dialog("option", "title", title);
        $('#' + id).append($('<div>' + message + '</div>'));
        $('#' + id).dialog("option", "buttons", { "Fechar": function() {
            $(this).dialog("close");
        } } );
    };
/* Executes the gadget when document is ready */
window.fb = fb;
mw.loader.using( 'jquery.tipsy', function() {
	$( fb.init );
} );

}( jQuery, mediaWiki ) );