LLWiki正在建设中,欢迎加入我们

MediaWiki:Gadget-Wikiplus-highlight.js

来自LLWiki
跳转到导航 跳转到搜索

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

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Edge:按住Ctrl的同时单击刷新,或按Ctrl-F5
//<nowiki>
"use strict";
/*global OO, CodeMirror, Wikiplus*/
const contentModel = mw.config.get( 'wgPageContentModel' ),
	modes = {css: ['css', 'ext.CodeMirror.lib.mode.css'],
	javascript: ['javascript', 'ext.CodeMirror.lib.mode.javascript'],
	json: ['javascript', 'ext.CodeMirror.lib.mode.javascript'],
	Scribunto: ['lua', '//cdn.jsdelivr.net/npm/[email protected]/mode/lua/lua.min.js'],
	wikitext: ['mediawiki', 'ext.CodeMirror.mode.mediawiki']
},
	existing = mw.config.get( 'wgArticleId' ),
	revid = mw.config.get( 'wgRevisionId' );
if (mw.config.get( 'wgIsArticle' ) && mw.config.get( 'wgArticleId' ) &&
	(mw.isModule('Wikiplus', true) || mw.isModule('mobile-Wikiplus', true))) {
	var promise, cm, mode, lastPtn = '';
	const $search = $('<input>', {id: 'Wikiplus-Quickedit-Search', placeholder: '查找'}),
		$searchClose = $('<span>', {text: '×', id:'Wikiplus-Quickedit-Search-Close'}),
		overlay = {token: function() {}},
		onInput = function() { $search.css('background-color', '').off( 'input', onInput ); },
		token = function(str) {
		const ini = new RegExp( '[^' + mw.util.escapeRegExp( str[0] ) + ']', 'i' );
		return function(stream) {
			if (stream.match( str, true, true )) { return 'search'; }
			stream.next();
			stream.eatWhile( ini );
		};
	},
		findNext = function() { cm.operation(function() {
		const ptn = $search.val(),
			cmPos = CodeMirror.Pos;
		if (!ptn) { return; }
		if (ptn != lastPtn) {
			cm.removeOverlay( overlay );
			overlay.token = token( ptn );
			cm.addOverlay( overlay );
			lastPtn = ptn;
		}
		const regexp = new RegExp( mw.util.escapeRegExp( ptn ), 'i' ),
			line = cm.getCursor().line,
			ch = cm.getCursor().ch;
		var anchor, head,
			search = cm.getLine( line ).slice( ch ).search( regexp );
		if (search >= 0) {
			anchor = cmPos(line, ch + search);
			head = cmPos(line, ch + search + ptn.length);
		} else {
			const count = cm.lineCount();
			var i;
			for (i = line + 1; i <= line + count; i++) {
				search = cm.getLine( i % count ).search( regexp );
				if (search >= 0) { break; }
			}
			if (i <= line + count) {
				anchor = {line: i % count, ch: search};
				head = {line: i % count, ch: search + ptn.length};
			} else {
				$search.css('background-color', 'pink').on('input', onInput);
				return;
			}
		}
		cm.setSelection(anchor, head);
		cm.scrollIntoView({from: anchor, to: head});
	}); },
		highlight = function($textarea) {
		const height = $textarea.height(),
			$summary = $textarea.nextAll( '#Wikiplus-Quickedit-Summary-Input' ),
			$submit = $textarea.nextAll( 'button' ).mousedown(function() { cm.save(); }).first(),
			$minor = $submit.prev().children( '#Wikiplus-Quickedit-MinorEdit' ),
			$searchContainer = $('<div>', {id: 'Wikiplus-Quickedit-Search-Div', html: [$search, $searchClose]})
			.hide().insertBefore( $textarea ),
			findNew = function() {
			$searchContainer.show();
			$search.select().focus()[0].scrollIntoView( {behavior: 'smooth'} );
		};
		$('<span>', {class: 'Wikiplus-Btn', text: '查找'}).click( findNew ).insertAfter( '#Wikiplus-Quickedit-Jump' );
		$searchClose.click(function() {
			cm.removeOverlay( overlay );
			$searchContainer.hide();
			lastPtn = '';
		});
		if (cm) { cm.toTextArea(); }
		cm = CodeMirror.fromTextArea($textarea[0], $.extend({
			mode: mode[0], mwConfig: mw.config.get( 'extCodeMirrorConfig' ), lineWrapping: true, lineNumbers: true
		}, mode[0] == 'mediawiki' ? {matchBrackets: true, matchTags: true} : {
			indentUnit: 4, indentWithTabs: true, matchBrackets: {bracketRegex: /[(){}[\]]/}
		}, contentModel == 'json' ? {json: true, matchBrackets: true} : {}));
		mw.hook( 'wiki-codemirror' ).fire( cm );
		cm.setSize(null, height);
		cm.addKeyMap({'Ctrl-S': function() {
			cm.save();
			$submit.triggerHandler( 'click' );
		}, 'Shift-Ctrl-S': function() {
			cm.save();
			$minor.click();
			$submit.triggerHandler( 'click' );
		}});
		$textarea.closest( '.Wikiplus-InterBox' ).keydown(function(e) {
			if (!e.metaKey && !e.ctrlKey || !['f', 'g'].includes( e.key )) { return; }
			e.preventDefault();
			if (e.key == 'f') { findNew(); }
			else { findNext(); }
		});
		$summary.add([ $minor[0], $search[0] ]).off( 'keydown' ).keydown(function(e) {
			if (!e.metaKey && !e.ctrlKey || e.keyCode != 83) { return; }
			e.stopImmediatePropagation();
			cm.save();
			if (e.shiftKey) { $minor.click(); }
			$submit.triggerHandler( 'click' );
		});
		if (Wikiplus.getSetting( 'esc_to_exit_quickedit' )) {
			cm.addKeyMap({ 'Esc': function() { $('#Wikiplus-Quickedit-Back').click(); } });
		}
	},
		init = function($node) {
		const $textarea = $node.find( '#Wikiplus-Quickedit' ),
			text = $textarea[0].value;
		$search.keyup(function(e) { if (e.key == 'Enter') { findNext(); } });
		new Promise(function(resolve) {
			if (contentModel != 'Scribunto' || !existing) {
				resolve( contentModel );
				return;
			}
			resolve( OO.ui.confirm( '请选择内容模型:', {actions: [
				{label: 'Lua'}, {label: 'Wikitext', action: 'accept'}
			]}).then(function(bool) { return bool ? 'wikitext' : 'Scribunto'; }) );
		}).then(function(model) {
			mode = modes[ model ];
			const getExt = (window.CodeMirror ? Promise.resolve() : mw.loader.using( 'ext.CodeMirror.lib' ))
				.then(function() {
				return (window.CodeMirror || {modes: {}}).modes[ mode[0] ] ? Promise.resolve() :
				mode[0] == 'lua' ? $.get({dataType: 'script', cache: true, url: mode[1]}) : mw.loader.using( mode[1] );
			}),
				getJSON = mw.config.get( 'extCodeMirrorConfig' ) || model != 'wikitext' ? Promise.resolve() :
				mw.loader.using( 'ext.CodeMirror' );
			promise = Promise.all([getJSON, getExt]);
			promise.then(function() { highlight( $textarea ) });
		});
	},
		callback = function(records) {
		const $node = $( records[0].addedNodes[0] );
		if (!$node.is( '.Wikiplus-InterBox:has( #Wikiplus-Quickedit )' )) { return; }
		init( $node );
		observer2.disconnect();
		observer2.observe( $node.find( '#Wikiplus-Quickedit-Preview-Output' )[0], {childList: true} );
	},
		observer = new MutationObserver( callback ),
		callback2 = function(records) {
		const $node = $( records[0].addedNodes[1] );
		if ($node.hasClass( 'mw-body-content' )) { mw.hook( 'wikipage.content' ).fire( $node ); }
	},
		observer2 = new MutationObserver( callback2 );
	observer.observe(document.body, {childList: true});
	
	// 以下内容引自[[MW:Extension:CodeMirror]]
	$.valHooks.textarea = {
		get: function(ele) { return ele.id == 'Wikiplus-Quickedit' && cm ? cm.getValue() : ele.value; },
		set: function(ele, value) { ele.id == 'Wikiplus-Quickedit' && cm ? cm.setValue( value ) : ele.value = value; }
	};
}