사용자:하늘/EditTools.js

< 사용자:하늘
하늘 (토론 | 기여)님의 2024년 2월 6일 (화) 23:21 판

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

  • 파이어폭스 / 사파리: Shift 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5 또는 Ctrl-R을 입력 (Mac에서는 ⌘-R)
  • 구글 크롬: Ctrl-Shift-R키를 입력 (Mac에서는 ⌘-Shift-R)
  • 인터넷 익스플로러 / 엣지: Ctrl 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5를 입력.
  • 오페라: Ctrl-F5를 입력.
window.charinsert = {
  기본: {
    괄호: [
      "(+)",
      "[+]",
      "{+}",
      "〔+〕",
      "〈+〉",
      "【+】"
    ],
    위키텍스트: [
      "{{크기||+}}",
      "[[+]]",
      "[[#+]]",
      "{{+}}",
      "<!--+-->",
      " /*+*/",
      "\[[분류:+]]",
      "\[[분류:+|_]]",
      "[[파일:+]]",
      "&nbsp;",
      "<del>+</del>",
      "<br/>",
      "<hr/>",
      "----",
      "{{-}}",
      "{{각주}}",
      "<ref>+</ref>",
      "<ref.name='+' />",
      "{{URL|+}}",
      "__TOC__",
      "<span.id='+'/>"
    ],
    : [
      "{{색||+}}",
      "{{lang||+}}",
      "{{llang||+}}",
      "{{|+}}",
      "{{문서이름}}",
      "{{전체문서이름}}",
      "{{삭제|+}}",
      "{{특정판.삭제|+}}",
      "{{유튜브|+}}",
      "{{퍼온문서|문서=+|판=_|퍼온곳=_}}",
      "{{번역된.문서|en|+||}}",
      "{{string|+}}",
      "{{배지|+}}",
      "{{PD-author}}"
    ]
  },
  "틀 작성": [
    "{{{+}}}",
    "{{{+|}}}",
    "<onlyinclude>+</onlyinclude>",
    "<includeonly>+</includeonly>",
    "<noinclude>+</noinclude>",
    "{{풀기:+}}",
    "<templatestyles.src='+/styles.css'/>"
  ],
  "파서함수": [
    "{{#expr:+}}",
    "{{#if:+}}",
    "{{#ifeq:+}}",
    "{{#iferror:+}}",
    "{{#ifexist:+}}",
    "{{#switch:+}}",
    "{{#time:+}}",
    "{{#titlepart:+}}",
    "{{#invoke:|}}"
  ],
  "HTML": [
    "<p>+</p>",
    "<div>+</div>",
    "<div.style=''>+</div>",
    "<div.class=''.style=''>+</div>",
    "<span>+</span>",
    "<span.style=''>+</span>",
    "<span.class=''.style=''>+</span>",
    "<code>+</code>",
    "<code><nowiki>+</nowiki></code>",
    "<pre>+</pre>",
    "<syntaxhighlight.lang='+'>\n\n</syntaxhighlight>"
  ],
  "파일 저작권": [
    "{{PD-self}}",
    "{{PD-old}}",
    "{{PD-author}}",
    "{{CC-BY-3.0}}",
    "{{CC-BY-SA-3.0}}"
  ]
};

class EditToolsBox {

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

        const 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']).then(() => {
	mw.hook('wikiEditor.toolbarReady').add(() => new EditToolsBox(data));
	mw.loader.load('//librewiki.net/index.php?title=User:하늘/EditTools.css&action=raw&ctype=text/css', 'text/css');
});