사용자:하늘/EditTools.js

< 사용자:하늘
하늘 (토론 | 기여)님의 2024년 2월 7일 (수) 00:34 판

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

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

    constructor(data) {
        /** @type {Array<HTMLDivElement>} */
        const SubsetBoxes = [];

        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 {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]);

        // Find the element that is focused
        this.$currentFocused = $('#wpTextbox1');
        // Apply to dynamically created textboxes as well as normal ones
        $(document).on('focus', 'textarea, input:text', () => this.$currentFocused = $(this));

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

    }

    /**
     * 
     * @param {String} token 
     * @returns {OO.ui.ButtonWidget}}
     */
    makeButton(token) {
        const Button = new OO.ui.ButtonWidget({
            useInputTag: true,
            framed: false,
            label: token
        });
        Button.$element.on('click', { toInsert: token }, this.InsertOnClick);
        return Button;
    }

    InsertOnClick(e) {
        e.preventDefault();

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

            let splitterIndex;
            if ((splitterIndex = e.data.toInsert.indexOf("+")) > 0) {
                this.$currentFocused.textSelection(
                    'encapsulateSelection', {
                    pre: e.data.toInsert.substr(0, splitterIndex),
                    post: e.data.toInsert.substr(splitterIndex + 1)
                });
            } else {
                this.$currentFocused.textSelection(
                    'encapsulateSelection', {
                    pre: e.data.toInsert
                }
                );
            }
        }
    }
    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');

	fetch(EditToolsUrl.replace('$1', 'EditTools.json') + '&ctype=application/json')
		.then(res => res.json()).then(data => {
			window.charinsert = data;
		});

	fetch(EditToolsUrl.replace('$1', 'EditTools-custom.json') + '&ctype=application/json')
		.then(res => res.json()).then(data => {
			window.charinsertCustom = data;
		});

	// 편집할 시점에는 이미 json 데이터를 디스크 캐시로 불러온 상태.
	// 그렇더라도 캐시를 다 불러오기 전에 호출하면 소용없음?
	mw.hook('wikiEditor.toolbarReady').add(() => new EditToolsBox(data));
});