Участница:Gryllida/js/feedbackstuff.js

Материал из Википедии — свободной энциклопедии
// - adds 'feedback' button next to 'log out'
// - converts <span id="grysFeedbackStuff-comments" title="current"></span> to buttons which add topics as configured by relevant target
// - edit 'targets' variable as needed for your project
// - edit 'msgs' variable as needed for your language
mw.loader.using([ 'mediawiki.feedback', 'mediawiki.api', 'jquery.chosen', 'jquery.spinner', 'mediawiki.util']).then(function () {
	var grysFeedbackStuff = {
		ready: 0,
		name: 'gryfeedbackstuff',
		nameId: '#gryfeedbackstuff',
		targets: {
			'current': {
				'ns': [0],
				'pageName': 'Talk:' + mw.config.get('wgPageName'),
				'mode': 'bottom-post', // Качество этой страницы  = 'this page quality'; здесь = here
				'title': 'Качество этой страницы (<a href="' + mw.util.getUrl('Talk:' + mw.config.get('wgPageName')) + '">здесь</a>)'
			},
			'project':{
				'ns': ['*'],
				'pageName': 'Википедия:Форум/Вопросы',
				'mode': 'bottom-post', // Общий вопрос по проекту = general project question; здесь = here
				'title': 'Общий вопрос по проекту (<a href="' + mw.util.getUrl('Википедия:Форум/Вопросы') + '">здесь</a>)'
			},
			'software':{
				'ns': ['*'],
				'pageName': 'Википедия:Форум/Технический',
				'mode': 'top-post', // Программное обеспечение сайта = website software; здесь = here
				'title': 'Программное обеспечение сайта (<a href="' + mw.util.getUrl('Википедия:Форум/Технический') + '">здесь</a>)'
			}
		},
		msgs: {
			'send': 'Отправить', // Send
			'onCurrentPage': 'на текущую страницу', // onto current page
			'newSection': 'новый раздел', // new section
			'addTopic': 'Добавить тему', // add topic
			'title': 'Оставить отзыв', // leave feedback
			'sending': 'Отправяю...', // sending ...
			'fail': 'Не получилось :(', // failed :(
			'success': 'Отправлено :)', // sent successfully :)
			'preview': 'Предпросмотр', // preview
			'feedback': 'Обратная связь' // feedback
		},
		/*
		 * DOM bits and bytes
		 */
		makeRadio: function(){
			$(grysFeedbackStuff.nameId).append("<form id='gryfeedback-form' style='clear:both;'></form>");
			// For each choice
			var t = new mw.Title( mw.config.get('wgPageName') );
			ns = t.getNamespaceId(); // 6
			$.each(grysFeedbackStuff.targets, function(k,v){
				if (v.ns.indexOf('*') > -1 || v.ns.indexOf(ns) > -1 ) {
					// Generate the input radio thing
					id = grysFeedbackStuff.name + '-' + k;
					$input = $("<input type='radio'/>")
						.prop("id",id)
						.prop("name",grysFeedbackStuff.name)
						.prop('value',k);
					// Generate the label with a "for" prop
					$label=$("<label></label>").prop("for",id).html(v.title);
					// Append a line break and an input, then the label
					$('#gryfeedback-form').append($input);
					$input.after($label);
					$('#gryfeedback-form').append("<br/>");
					// Debug output
					console.log('#'+k + " ... " + v.title + ',,,'+$('#grysFeedbackStuff-comments').prop('title')+'---');
					console.log(k == $('#grysFeedbackStuff-comments').prop('title'));
					// Select this option if it's primary (as indicated by span title)
					if(k == $('#grysFeedbackStuff-comments').prop('title')){
						$input.attr('checked','checked');
					}
				}
			});
			grysFeedbackStuff.ready=1;
		},
		prepareDialog:function(){
			// Make the in-dialog html
			grysFeedbackStuff.$dialog = $( '<div></div>' ).prop('id',grysFeedbackStuff.name)
			.append("<input id='gryfeedbackstuff-subject' class='feedback-subject' style='width:100%' type='text'>")
			.append("<textarea id ='gryfeedbackstuff-message' class='feedback-message' style='width:100%'></textarea>")
			.append("<br/><div id='gryfeedbackstuff-previewthings' style='border:2px inset;padding:5px;border-radius:5px;'></div>");
			//.append("<input id='gryfeedbackstuff-summary' class='feedback-summary' style='width:100%' type='text'>");
			// Make the dialog buttons (and what they do)
			var formButtons={};
			formButtons[ grysFeedbackStuff.msgs.send ] = {
				'click':function () {
	               grysFeedbackStuff.submit();
	        	},
	        	id: grysFeedbackStuff.name + '-button',
	        	text: grysFeedbackStuff.msgs.send
			};
			formButtons[ grysFeedbackStuff.msgs.preview ] = {
				'click':function () {
	               grysFeedbackStuff.preview();
	        	},
	        	id: grysFeedbackStuff.name + '-preview-button',
	        	text: grysFeedbackStuff.msgs.preview
			};
	        // Construct the dialog
			grysFeedbackStuff.$dialog.dialog( {
	                   width: 500,
	                   autoOpen: false,
	                   title: grysFeedbackStuff.msgs.title,
	                   modal: true,
	                   buttons: formButtons
	        } );
		},
		preview: function(){
			subject = $('#gryfeedbackstuff-subject').val();
			message = $('#gryfeedbackstuff-message').val();
			summary = $('#gryfeedbackstuff-summary').val();
			// auto-sign <nowiki>
			if ( message.indexOf( '~~~~' ) === -1 ) {
				message += ' --~~~~';
			}
			// </nowiki>
			sectionText = '=='+subject+'==\n'+message+'\n\n';
			// wiki things
			api = new mw.Api();
			api.get( {
				'action' : 'parse',
				'text' : sectionText,
				'pst': ''
			}).done(function(result) {
				markup = result.parse.text['*'];
				//var page = result.pages[result.pageids[0]];
				//var text = page.revisions[0]['*'];
				console.log(markup);
				$('#gryfeedbackstuff-previewthings').html(markup);
			});
		},
		doStuff : function() {
			var $a = $("<a href='#'></a>")
				.attr('id','gryfeedbackstuff-menuitem')
				.text(grysFeedbackStuff.msgs.feedback);
			var $li = $("<li></li>")
				.append($a)
				.click( grysFeedbackStuff.openDialog )
				.insertBefore('#pt-login,#pt-logout');
			// dialog contents (html)
			grysFeedbackStuff.prepareDialog();
	        // show the dialog (currently whenever a page loads; once it works, this will be only by request)
	        $('#grysFeedbackStuff-comments')
			.attr({class: 'ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only ui-state-focus'})
			.prepend(
			$( '<span>' )
				.text( grysFeedbackStuff.msgs.addTopic )
				.addClass( 'gry-feedbackLink' )
				.addClass( 'ui-button-text' )
			).click( grysFeedbackStuff.openDialog );
		},
		/* shows the dialog on the screen */
		openDialog: function(){
			// Choices
	    	if(grysFeedbackStuff.ready===0){grysFeedbackStuff.makeRadio();}
	    	$('#gryfeedbackstuff-subject').focus();
			grysFeedbackStuff.$dialog.dialog( 'open' );
		},
		/*
		 * Wiki things (submitting the message)
		 */
		submit: function(){
			// Disable the button, update its text
			id = grysFeedbackStuff.nameId + '-button';
			$(id + "  > .ui-button-text").text(grysFeedbackStuff.msgs.sending);
			$(id).attr('disabled','disabled');
			// (optional) adjust pagetitle to the relevant comments page name
			subject = $('#gryfeedbackstuff-subject').val();
			message = $('#gryfeedbackstuff-message').val();
			summary = $('#gryfeedbackstuff-summary').val();
			// auto-sign <nowiki>
			if ( message.indexOf( '~~~~' ) === -1 ) {
				message += ' --~~~~';
			}
			// </nowiki>
			// get page title and post mode
			key = $("#gryfeedback-form input[type='radio']:checked").val();
			pageTitle = grysFeedbackStuff.targets[key].pageName;
			mode = grysFeedbackStuff.targets[key].mode;
			// things for the wiki
			api = new mw.Api();
			if(mode == 'top-post'){
				editSummary = '/* ' + subject + ' */ ' + grysFeedbackStuff.msgs.newSection;
				sectionText = '=='+subject+'==\n'+message+'\n\n';
				// Get page content
				api.get( {
					'action' : 'query',
					'titles' : pageTitle,
					'prop'   : 'revisions|info',
					'intoken' : 'edit',
					'rvprop' : 'content',
					'indexpageids' : 1
				}).done(function(result) {
					result = result.query;
					var page = result.pages[result.pageids[0]];
					var text = page.revisions[0]['*'];
					// Add my section at the top [with necessary changes]
					arry = text.split("==");
					text = arry[0];
					arry.shift();
					text = text +sectionText+"=="+arry.join("==");
					// Submit the edit
					api.postWithEditToken(
						{
							'action' : 'edit',
							'title' : pageTitle,
							'text' : text,
							'summary' : editSummary
						}
					).done(grysFeedbackStuff.ok).fail(grysFeedbackStuff.fail);
				}).fail(grysFeedbackStuff.fail);
			} else if (mode =='bottom-post'){
				api.newSection( pageTitle, subject, message ).done( grysFeedbackStuff.ok ).fail( grysFeedbackStuff.fail );
			}
		},
		/*
		 * Again DOM bits and bytes (relating to the end)
		 */
		ok: function(){
			id = grysFeedbackStuff.nameId + '-button  > .ui-button-text';
			$(id).text(grysFeedbackStuff.msgs.success);
			/*// Success; remove the OK button
			grysFeedbackStuff.$dialog.dialog( {
				buttons: []
			});
			// Show a success message
			$a=$('<a></a>').append(grysFeedbackStuff.msgs.onCurrentPage);
			$a.attr('href',window.location.pathname);
			$msg = $('<p></p>')
			.append(grysFeedbackStuff.msgs.success)
			.append('<b></b>')
			.append($a);
			$('#gryfeedbackstuff').prepend($msg);*/
		},
		fail: function(){
			id = grysFeedbackStuff.nameId + '-button';
			$(id+'  > .ui-button-text').text(grysFeedbackStuff.msgs.fail);
			$(id).prop('disabled', false);
		}
	};
	 
	$( function() { 
		grysFeedbackStuff.doStuff();
	});
});