MediaWiki:Gadget-SelectionCounter.js

Maintenance script​(留言 | 贡献)2026年7月16日 (四) 16:59的版本 (维护 SelectionCounter:显式依赖和本地化文本)

注意:在发布之后,您可能需要清除浏览器缓存才能看到所作出的更改的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
  • Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
  • Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5。
/* MediaWiki Gadget: SelectionCounter */
( function () {
	'use strict';

	mw.loader.using( [ 'jquery', 'mediawiki.util' ] ).then( function () {
		var $counter;
		var rafId = null;
		var pollTimer = null;
		var lastText = '';
		var lastTime = 0;
		var isSelecting = false;

		if ( window.SelectionCounterLoaded ) {
			return;
		}
		window.SelectionCounterLoaded = true;

		function label( count ) {
			var lang = mw.config.get( 'wgUserLanguage' ) || mw.config.get( 'wgContentLanguage' ) || 'zh-cn';
			return lang.toLowerCase().indexOf( 'en' ) === 0 ? 'Selected ' + count + ' chars' : '已选 ' + count + ' 字';
		}

		function getSelectionText() {
			var selection = window.getSelection();
			if ( !selection || selection.rangeCount === 0 || selection.isCollapsed ) {
				return '';
			}
			return selection.toString();
		}

		function showCount( text ) {
			var compact = text.replace( /\s+/g, '' );
			var count;
			if ( !compact ) {
				return false;
			}
			count = Array.from( compact ).length;
			$counter.text( label( count ) ).show();
			return true;
		}

		function updateCounter() {
			var text;
			rafId = null;
			text = getSelectionText();

			if ( text ) {
				lastText = text;
				lastTime = Date.now();
				showCount( text );
				return;
			}

			if ( lastText && Date.now() - lastTime < 1200 ) {
				showCount( lastText );
				return;
			}

			$counter.hide();
		}

		function scheduleUpdate() {
			if ( !rafId ) {
				rafId = window.requestAnimationFrame( updateCounter );
			}
		}

		function scheduleUpdateDelayed() {
			window.setTimeout( scheduleUpdate, 0 );
		}

		function startPolling() {
			if ( !pollTimer ) {
				pollTimer = window.setInterval( updateCounter, 500 );
			}
		}

		function stopPolling() {
			if ( pollTimer ) {
				window.clearInterval( pollTimer );
				pollTimer = null;
			}
		}

		function onSelectMove() {
			if ( isSelecting ) {
				scheduleUpdate();
			}
		}

		$( function () {
			$counter = $( '#mw-selection-counter' );
			if ( !$counter.length ) {
				$counter = $( '<div id="mw-selection-counter" class="mw-selection-counter" role="status" aria-live="polite"></div>' )
					.hide()
					.appendTo( 'body' );
			}

			document.addEventListener( 'selectionchange', function () {
				var text = getSelectionText();
				if ( text ) {
					lastText = text;
					lastTime = Date.now();
				}
				scheduleUpdate();
			} );
			document.addEventListener( 'mousedown', function () {
				isSelecting = true;
			}, true );
			document.addEventListener( 'mouseup', function () {
				isSelecting = false;
				scheduleUpdateDelayed();
			}, true );
			document.addEventListener( 'mousemove', onSelectMove, true );
			document.addEventListener( 'touchstart', function () {
				isSelecting = true;
			}, { passive: true, capture: true } );
			document.addEventListener( 'touchmove', onSelectMove, { passive: true, capture: true } );
			document.addEventListener( 'touchend', function () {
				isSelecting = false;
				scheduleUpdateDelayed();
			}, { passive: true, capture: true } );
			document.addEventListener( 'keyup', scheduleUpdate );
			window.addEventListener( 'focus', startPolling );
			window.addEventListener( 'blur', stopPolling );
			document.addEventListener( 'visibilitychange', function () {
				if ( document.hidden ) {
					stopPolling();
					return;
				}
				startPolling();
			} );

			startPolling();
		} );
	} );
}() );