사용자:하늘/EditTools.js

참고: 설정을 저장한 후에 바뀐 점을 확인하기 위해서는 브라우저의 캐시를 새로 고쳐야 합니다.

  • 파이어폭스 / 사파리: Shift 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5 또는 Ctrl-R을 입력 (Mac에서는 ⌘-R)
  • 구글 크롬: Ctrl-Shift-R키를 입력 (Mac에서는 ⌘-Shift-R)
  • 인터넷 익스플로러 / 엣지: Ctrl 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5를 입력.
  • 오페라: Ctrl-F5를 입력.
class EditToolsBox {

	constructor(data) {
		
		// Find Wiki-Editor
		window.$currentFocused = $('#wpTextbox1');
		// Find any textarea or input:text
		$(document).on('focus', 'textarea, input:text', e => window.$currentFocused = $(e.target));
		
		data = Object.assign(window.charinsert, window.charinsertCustom);
		
		const specialchars_box = $('<div id="editpage-specialchars" class="nopopups"></div>');
		specialchars_box[0].title = '편집 창에 입력할 글자 혹은 태그를 클릭하세요';
		
		// 문자셋 드랍다운 메뉴를 만듭니다.
		const options = [];
		for (const i in data) {
			options.push(new OO.ui.MenuOptionWidget({ label: i, data: data[i] }));
		}
		
		/** @type {Array<HTMLDivElement>} */
		const SubsetBoxes = [];

		/**
		 * @type {OO.ui.DropdownWidget}
		 */
		const DropdownWidget = new OO.ui.DropdownWidget();
		DropdownWidget.setLabel('Choose character subset');

		const DropdownMenu = DropdownWidget.getMenu();
		DropdownMenu.addItems(options);
		DropdownMenu.on('choose', (seletedItem) => {

			let seletedIndex = DropdownMenu.getItemIndex(seletedItem);

			if (SubsetBoxes.length === 0 || !SubsetBoxes[seletedIndex]) {
				const box = this.makeSubsetBox(seletedItem.getData());
				if (box != null) {
					specialchars_box.append(box.$element);
					SubsetBoxes[seletedIndex] = box.$element[0];
				}
			}

			SubsetBoxes.forEach(e => { e.style.display = 'none' })
			SubsetBoxes[seletedIndex].style.display = 'inline';
		});
		DropdownMenu.chooseItem(options[0]);

		$(".wikiEditor-ui").append(specialchars_box);
		specialchars_box.before(DropdownWidget.$element);

	}

	/**
	 * 
	 * @param {Number} token 
	 * @returns {OO.ui.ButtonWidget}}
	 */
	makeButton(token) {
		const Button = new OO.ui.ButtonWidget({
			useInputTag: true,
			framed: false,
			label: token
		});
		Button.$element.on('click', event => {
			event.preventDefault();

			if (window.$currentFocused && window.$currentFocused.length && !window.$currentFocused.prop('readonly')) {

				let splitterIndex;
				if ((splitterIndex = token.indexOf("+")) > 0) {
					window.$currentFocused.textSelection('encapsulateSelection', { pre: token.substr(0, splitterIndex), post: token.substr(splitterIndex + 1) });
				} else {
					window.$currentFocused.textSelection('encapsulateSelection', { pre: token });
				}
			}
		})
		return Button;
	}

	makeSubsetBox(curSubset) {

		const tokens = []

		if (typeof curSubset == "undefined") {
			return null;
		}
		else if (Array.isArray(curSubset)) {
			for (const token of curSubset) {
				tokens.push(this.makeButton(token));
			}
		} else {
			for (const tokenKey in curSubset) {
				const tokenArray = curSubset[tokenKey];
				tokens.push(new OO.ui.LabelWidget({ label: `${tokenKey} ` }));
				for (const token of tokenArray) {
					tokens.push(this.makeButton(token));
				}
			}
		}

		return new OO.ui.ButtonGroupWidget({ items: tokens });
	}
}

mw.loader.using(['oojs-ui'], () => {
	/** @type {String} */
	let EditToolsUrl = mw.util.getUrl('User:' + mw.config.get("wgUserName") + '/$1', { action: 'raw' })

	mw.loader.load(EditToolsUrl.replace('$1', 'EditTools.css') + '&ctype=text/css', 'text/css');

	let promise = undefined;
	promise = fetch(EditToolsUrl.replace('$1', 'EditTools-custom.json') + '&ctype=application/json').then(res => res.text())
	promise.then(text => {
		try { window.charinsertCustom = JSON.parse(text) }
		catch { }
		finally {
			promise = fetch(EditToolsUrl.replace('$1', 'EditTools.json') + '&ctype=application/json').then(res => res.json())
			promise.then(data => {
				window.charinsert = data;
				mw.hook('wikiEditor.toolbarReady').add(() => new EditToolsBox());
			});
		}
	});
});