MediaWiki:Gadget-wikificator.js: различия между версиями

Материал из Каталог переславских телепередач
Перейти к навигации Перейти к поиску
 
(не показано 26 промежуточных версий этого же участника)
Строка 1: Строка 1:
( function () {
+
// <nowiki>
 
+
mw.loader.using( 'jquery.client', function () {
var wmCantWork = 'Викификатор не может работать в вашем браузере',
 
wmFullText = 'Викификатор обработает ВЕСЬ текст на этой странице. Продолжить?',
 
wmTalkPage = 'Викификатор не обрабатывает страницы обсуждения целиком.\n\nВыделите ваше сообщение — обработано будет только оно';
 
window.wfPlugins = window.wfPlugins || [];
 
  
 +
var clientProfile = $.client.profile();
 +
var hotkey = clientProfile.platform === 'mac' ? 'Ctrl+Shift+W' : 'Ctrl+Alt+W';
 +
var strings = {
 +
name: 'Викификатор',
 +
tooltip: 'Викификатор — автоматический обработчик текста (' + hotkey + ')',
 +
fullText: 'Викификатор обработает ВЕСЬ текст на этой странице. Продолжить?',
 +
talkPage: 'Викификатор не обрабатывает страницы обсуждения целиком.\n\nВыделите ваше сообщение — обработано будет только оно.'
 +
};
  
window.Wikify = function ( input ) {
+
// Function takes an input or text as an argument. If it is absent, it uses $( '#wpTextbox1' )
 +
// as an input.
 +
window.Wikify = function ( inputOrText ) {
 
'use strict';
 
'use strict';
var txt = '',
 
hidden = [],
 
winScroll = document.documentElement.scrollTop;
 
 
// Поверхностная проверка на то, что перед нами поле ввода
 
if ( !input || !input.tagName || input.value === undefined ) {
 
input = document.editform.wpTextbox1;
 
}
 
 
  
 
// FUNCTIONS
 
// FUNCTIONS
Строка 24: Строка 21:
 
txt = txt.replace( r1, r2 );
 
txt = txt.replace( r1, r2 );
 
}
 
}
+
 
 
function processText() {
 
function processText() {
var i,
+
var i;
u = '\u00A0'; // non-breaking space
+
 
if ( mw.config.get('wgNamespaceNumber') % 2 || mw.config.get('wgNamespaceNumber') === 4 ) { // is talk page
+
r( / +(\n|\r)/g, '$1' ); // spaces at EOL
var sigs = txt.match( /\d\d:\d\d, \d\d? \S{3,8} 20\d\d \(UTC\)/g );
+
txt = '\n' + txt + '\n';
if ( sigs && sigs.length > 1 ) {
+
 
alert( wmTalkPage );
+
r( /«|»|“|”|„/g, '"' ); // temp
return;
 
}
 
}
 
  
// Hyphens to em-dashes
+
// Hyphens and en dashes to pretty dashes
 +
r( /–/g, '-' ); // &ndash; -> hyphen
 
r( /(\s)-{1,3} /g, '$1— ' ); // hyphen -> &mdash;
 
r( /(\s)-{1,3} /g, '$1— ' ); // hyphen -> &mdash;
 
r( /(\d)--(\d)/g, '$1—$2' ); // -> &mdash;
 
r( /(\d)--(\d)/g, '$1—$2' ); // -> &mdash;
 
r( /«|»|“|”|„/g, '"' ); // temp
 
  
 
// "" → «»
 
// "" → «»
Строка 50: Строка 43:
 
}
 
}
  
r( 'ёё' , '</div>\n<hr class=newtheme>\n<div class=newtheme>\n' );
+
r( 'ёё' , '</div>\n<hr class=newtheme>\n<div class=newtheme>' );
 
r( 'ёёё' , '<hr class=newtheme>\n' );
 
r( 'ёёё' , '<hr class=newtheme>\n' );
  
 +
txt = txt.substr( 1, txt.length - 2 ); // compensation for "txt = '\n' + txt + '\n';"
 
}
 
}
  
 
function processAllText() {
 
function processAllText() {
txt = input.value;
+
txt = $input ? $input.textSelection( 'getContents' ) : text;
 
processText();
 
processText();
r( /^[\n\r]+/, '' );
+
if ( $input ) {
input.value = txt;
+
r( /^[\n\r]+/, '' );
txt = '';
+
 +
$input.textSelection( 'setContents', txt );
 +
if ( caretPosition ) {
 +
$input.textSelection( 'setSelection', {
 +
start: caretPosition[0] > txt.length ? txt.length : caretPosition[0]
 +
} );
 +
}
 +
} else {
 +
text = txt;
 +
}
 
}
 
}
  
 
+
// MAIN CODE
// Check regexp support
+
try {
+
// Check what's in the first parameter
txt = 'ая'.replace( /а/g, 'б' ).replace( /б(?=я)/, 'в' );
+
var text;
} catch ( e ) {}
+
var isInput;
if ( txt !== 'вя' ) {
+
var $input;
alert( wmCantWork );
+
if ( typeof inputOrText === 'string' ) {
return;
+
text = inputOrText;
 +
} else {
 +
isInput = (
 +
inputOrText &&
 +
(
 +
( inputOrText.nodeType && inputOrText.value !== undefined ) || // node
 +
( inputOrText.prop && inputOrText.prop( 'nodeType' ) ) // jQuery object
 +
)
 +
);
 +
$input = $( isInput ? inputOrText : '#wpTextbox1' );
 
}
 
}
  
input.focus();
+
var txt = '';
 
+
var hidden = [];
// Modern browsers
+
var winScroll = document.documentElement.scrollTop;
if ( typeof input.selectionStart !== 'undefined' ) {
+
var caretPosition;
var textScroll = input.scrollTop,
+
if ( $input ) {
startPos = input.selectionStart,
+
$input.focus();
endPos = input.selectionEnd;
+
txt = input.value.substring( startPos, endPos );
+
caretPosition = $input.textSelection( 'getCaretPosition', { startAndEnd: true } );
if ( txt === '' ) {
+
if ( caretPosition ) {
 +
var $CodeMirrorVscrollbar = $( '.CodeMirror-vscrollbar' );
 +
var textScroll = ( $CodeMirrorVscrollbar.length ? $CodeMirrorVscrollbar : $input )
 +
.scrollTop();
 +
if ( caretPosition[0] === caretPosition[1] ) {
 +
processAllText();
 +
} else {
 +
txt = $input.textSelection( 'getSelection' );
 +
processText();
 +
// replaceSelection doesn't work with MediaWiki 1.30 in case this gadget is loaded
 +
// from other wiki
 +
$input.textSelection( 'encapsulateSelection', {
 +
replace: true,
 +
peri: txt
 +
} );
 +
// In CodeMirror, the selection isn't preserved, so we do it explicitly
 +
$input.textSelection( 'setSelection', {
 +
start: caretPosition[0],
 +
end: caretPosition[0] + txt.length
 +
} );
 +
}
 +
( $CodeMirrorVscrollbar.length ? $CodeMirrorVscrollbar : $input )
 +
.scrollTop( textScroll );
 +
// If something went wrong
 +
} else if ( confirm( strings.fullText ) ) {
 
processAllText();
 
processAllText();
} else {
 
processText();
 
input.value = input.value.substring( 0, startPos ) +
 
txt + input.value.substring( endPos );
 
 
}
 
}
input.selectionStart = startPos;
+
} else {
input.selectionEnd = startPos + txt.length;
 
input.scrollTop = textScroll;
 
 
 
// IE
 
} else if ( document.selection && document.selection.createRange ) {
 
var range = document.selection.createRange();
 
txt = range.text;
 
if ( txt === '' ) {
 
processAllText();
 
} else {
 
processText();
 
range.text = txt;
 
if ( range.moveStart ) {
 
range.moveStart( 'character', -txt.length );
 
}
 
range.select();
 
}
 
 
 
// Other browsers
 
} else if ( confirm( wmFullText ) ) {
 
 
processAllText();
 
processAllText();
 +
return text;
 
}
 
}
  
document.documentElement.scrollTop = winScroll; // scroll back, for IE/Opera
+
// scroll back, for 2017 wikitext editor, IE, Opera
 +
document.documentElement.scrollTop = winScroll;
 
};
 
};
 +
 +
function registerWikificatorTool() {
 +
registerTool( {
 +
name: 'wikificator',
 +
position: 100,
 +
title: strings.name,
 +
label: strings.tooltip,
 +
callback: Wikify,
 +
classic: {
 +
icon: '//upload.wikimedia.org/wikipedia/commons/0/06/Wikify-toolbutton.png',
 +
},
 +
visual: {
 +
icon: '//upload.wikimedia.org/wikipedia/commons/thumb/4/41/Wikificator_VE_icon.svg/20px-Wikificator_VE_icon.svg.png',
 +
modes: [ 'source' ],
 +
addRightAway: true,
 +
},
 +
} );
 +
}
 +
 +
// загрузка викификатора
 +
$.when(
 +
mw.loader.using( [ 'mediawiki.util', 'user.options' ] ),
 +
$.getScript( 'https://ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-registerTool.js&action=raw&ctype=text/javascript' )
 +
).done( registerWikificatorTool );
  
 
}() );
 
}() );
 +
// </nowiki>

Текущая версия на 00:06, 7 января 2023

// <nowiki>
mw.loader.using( 'jquery.client', function () {

var clientProfile = $.client.profile();
var hotkey = clientProfile.platform === 'mac' ? 'Ctrl+Shift+W' : 'Ctrl+Alt+W';
var strings = {
	name: 'Викификатор',
	tooltip: 'Викификатор — автоматический обработчик текста (' + hotkey + ')',
	fullText: 'Викификатор обработает ВЕСЬ текст на этой странице. Продолжить?',
	talkPage: 'Викификатор не обрабатывает страницы обсуждения целиком.\n\nВыделите ваше сообщение — обработано будет только оно.'
};

// Function takes an input or text as an argument. If it is absent, it uses $( '#wpTextbox1' )
// as an input.
window.Wikify = function ( inputOrText ) {
	'use strict';

	// FUNCTIONS

	function r( r1, r2 ) {
		txt = txt.replace( r1, r2 );
	}

	function processText() {
		var i;

		r( / +(\n|\r)/g, '$1' ); // spaces at EOL
		txt = '\n' + txt + '\n';

		r( /«|»|“|”|„/g, '"' ); // temp

		// Hyphens and en dashes to pretty dashes
		r( /–/g, '-' ); // &ndash; -> hyphen
		r( /(\s)-{1,3} /g, '$1— ' ); // hyphen -> &mdash;
		r( /(\d)--(\d)/g, '$1—$2' ); // -> &mdash;

		// "" → «»
		for ( i = 1; i <= 2; i++ ) {
			r( /([\s\x02!|#'"\/([{;+\-])"([^"]*)([^\s"([{|])"([^a-zа-яё])/ig, '$1«$2$3»$4' ); // "
		}
		while ( /«[^»]*«/.test( txt ) ) {
			r( /«([^»]*)«([^»]*)»/g, '«$1„$2“' );
		}

		r( 'ёё' , '</div>\n<hr class=newtheme>\n<div class=newtheme>' );
		r( 'ёёё' , '<hr class=newtheme>\n' );

		txt = txt.substr( 1, txt.length - 2 ); // compensation for "txt = '\n' + txt + '\n';"
	}

	function processAllText() {
		txt = $input ? $input.textSelection( 'getContents' ) : text;
		processText();
		if ( $input ) {
			r( /^[\n\r]+/, '' );
			
			$input.textSelection( 'setContents', txt );
			if ( caretPosition ) {
				$input.textSelection( 'setSelection', {
					start: caretPosition[0] > txt.length ? txt.length : caretPosition[0]
				} );
			}
		} else {
			text = txt;
		}
	}

	// MAIN CODE
	
	// Check what's in the first parameter
	var text;
	var isInput;
	var $input;
	if ( typeof inputOrText === 'string' ) {
		text = inputOrText;
	} else {
		isInput = (
			inputOrText &&
			(
				( inputOrText.nodeType && inputOrText.value !== undefined ) || // node
				( inputOrText.prop && inputOrText.prop( 'nodeType' ) ) // jQuery object
			)
		);
		$input = $( isInput ? inputOrText : '#wpTextbox1' );
	}

	var txt = '';
	var hidden = [];
	var winScroll = document.documentElement.scrollTop;
	var caretPosition;
	if ( $input ) {
		$input.focus();
		
		caretPosition = $input.textSelection( 'getCaretPosition', { startAndEnd: true } );
		if ( caretPosition ) {
			var $CodeMirrorVscrollbar = $( '.CodeMirror-vscrollbar' );
			var textScroll = ( $CodeMirrorVscrollbar.length ? $CodeMirrorVscrollbar : $input )
				.scrollTop();
			if ( caretPosition[0] === caretPosition[1] ) {
				processAllText();
			} else {
				txt = $input.textSelection( 'getSelection' );
				processText();
				// replaceSelection doesn't work with MediaWiki 1.30 in case this gadget is loaded
				// from other wiki
				$input.textSelection( 'encapsulateSelection', {
					replace: true,
					peri: txt
				} );
				// In CodeMirror, the selection isn't preserved, so we do it explicitly
				$input.textSelection( 'setSelection', {
					start: caretPosition[0],
					end: caretPosition[0] + txt.length
				} );
			}
			( $CodeMirrorVscrollbar.length ? $CodeMirrorVscrollbar : $input )
				.scrollTop( textScroll );
		// If something went wrong
		} else if ( confirm( strings.fullText ) ) {
			processAllText();
		}
	} else {
		processAllText();
		return text;
	}

	// scroll back, for 2017 wikitext editor, IE, Opera
	document.documentElement.scrollTop = winScroll;
};

function registerWikificatorTool() {
	registerTool( {
		name: 'wikificator',
		position: 100,
		title: strings.name,
		label: strings.tooltip,
		callback: Wikify,
		classic: {
			icon: '//upload.wikimedia.org/wikipedia/commons/0/06/Wikify-toolbutton.png',
		},
		visual: {
			icon: '//upload.wikimedia.org/wikipedia/commons/thumb/4/41/Wikificator_VE_icon.svg/20px-Wikificator_VE_icon.svg.png',
			modes: [ 'source' ],
			addRightAway: true,
		},
	} );
}

// загрузка викификатора
	$.when(
		mw.loader.using( [ 'mediawiki.util', 'user.options' ] ),
		$.getScript( 'https://ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-registerTool.js&action=raw&ctype=text/javascript' )
	).done( registerWikificatorTool );

}() );
// </nowiki>