미디어위키:Gadget-PluginCore.js

리버티게임, 모두가 만들어가는 자유로운 게임
imported>Senouis님의 2020년 12월 28일 (월) 14:17 판 (이동해옴)
(차이) ← 이전 판 | 최신판 (차이) | 다음 판 → (차이)

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

  • 파이어폭스 / 사파리: Shift 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5 또는 Ctrl-R을 입력 (Mac에서는 ⌘-R)
  • 구글 크롬: Ctrl-Shift-R키를 입력 (Mac에서는 ⌘-Shift-R)
  • 인터넷 익스플로러 / 엣지: Ctrl 키를 누르면서 새로 고침을 클릭하거나, Ctrl-F5를 입력.
  • 오페라: Ctrl-F5를 입력.
/** [[틀:플러그인]]을 사용 가능하게 해 줍니다. 사용자의 허락을 맡고 사용자의 commonjs 편집을 허가 할 수 있는 문서입니다.
 * 작성자: [[사용자:BANIP|BANIP]]
 * [[백괴게임:관리자 요청/2018년 1월]]에서 BANIP님 요청으로 퍼왔습니다.
 */
function pluginCore() {
    // 사용자의 commonjs의 문서 이름을 획득
    var commonjs = "사용자:" + mw.config.get("wgUserName") + "/common.js";
    var plugins = {},
        docPlugins = {},
        uninstalledPlugins = {},
        unupdatedPlugins = {};
    var preloadedplugins = [],
        needPlugins = [];
    var api = MediaWikiAPI();
    var jsdoc = api.getDocument(commonjs);

    //commonjs에서 특정 플러그인 제거
    function removePluginByDoc(pluginTitle, doc) {
        var reg = new RegExp("\\/\\*\\* 플러그인 " + pluginTitle + "([\\s\\S]*)\\/\\* " + pluginTitle + " 끝 \\*\\/", "g");
        doc = doc.replace(reg, "");
        return doc;
    }

    // 플러그인이 비어있는지 확인
    function isPluginsEmpty(plugins) {
        return Object.keys(plugins).length === 0;
    }

    //플러그인의 모든 키 순회
    function forEach(object, callback) {
        for (var key in object) {
            var variable = object[key];
            callback(variable, key);
        }
    }

    // 문서에서 사용하는 플러그인들을 체크합니다. use-script클래스를 가진 모든 돔 요소를 조사하고
    // 그 돔에 내장된 플러그인 데이터를 docPlugins에 추가합니다.
    var checkDocPlugin = (function(docPlugins) {
        function getPluginData($this) {
            return {
                name: $this.attr("data-name"), // 플러그인 이름
                descript: $this.attr("data-descript"), // 플러그인 내용
                version: $this.attr("data-version"), // 플러그인 이름
                local: ($this.attr("data-local") === "true") ? true : false,
                creat: $this.attr("data-creat"),
                state: $this.attr("data-state"),
                link: $this.attr("data-link"),
                executable: $this.attr("data-executable") === "true" ? true : false,
            };
        }

        function getAllPluginsName(plugins) {
            var pluginNames = [];
            forEach(plugins, function(plugin) {
                var pluginName = plugin.name;
                pluginNames.push(pluginName);
            });

            return pluginNames;
        }

        var loadAllPlugins2 = (function(docPlugins) {
            $(".use-script").each(function() {
                const plugin = getPluginData($(this));
                docPlugins[plugin.name] = plugin;
            });
        })(docPlugins);

        var loadAllPlugins = (function(docPlugins) {
            if (!isPluginsEmpty(docPlugins)) {
                var subTitle = " " + getAllPluginsName(docPlugins).join(", ") + " 플러그인 가동중";
                $("#siteSub").text(function(i, v) {
                    return v + subTitle;
                });
            }
        })(docPlugins);
    })(docPlugins);

    // 사용자가 가지고 있는 플러그인들을 체크합니다.
    var checkHavePlugin = (function() {
        function getUserPlugins(jsdoc) {
            var userplugins = [];
            // plugins.---가 있는지 체크하는 정규식
            var pluginreg = /JSON \=\> ([\S]+) = (\{.*\})/g;
            var nameMatch = pluginreg.exec(jsdoc);
            while (nameMatch) {
                userplugins.push(JSON.parse(nameMatch[2]));
                nameMatch = pluginreg.exec(jsdoc);
            }
            return userplugins;
        }

        function isSamePlugin(pluginFirst, pluginSecond) {
            return pluginFirst.name == pluginSecond.name;
        }

        function isSameVersionPlugin(pluginFirst, plugiSecond) {
            return pluginFirst.version == plugiSecond.version;
        }

        function addNeedPlugins(targetPlugins) {
            //global docPlugins, needPlugins
            for (var key in targetPlugins) {
                var pluginName = docPlugins[key].name;
                needPlugins.push(pluginName);
            }
        }

        if (!isPluginsEmpty(docPlugins)) {
            preloadedplugins = getUserPlugins(jsdoc);
            forEach(docPlugins, function(docplugin) {
                var isHavePlugin = false;
                forEach(preloadedplugins, function(myplugin) {
                    if (!isSamePlugin(docplugin, myplugin)) return;
                    if (!isSameVersionPlugin(docplugin, myplugin)) {
                        unupdatedPlugins[docplugin.name] = docplugin;
                    }
                    isHavePlugin = true;
                });

                if (!isHavePlugin) {
                    uninstalledPlugins[docplugin.name] = docplugin;
                }
            });
            addNeedPlugins(uninstalledPlugins);
            addNeedPlugins(unupdatedPlugins);
        }
    })();

    function onPluginInstall() {
        function getPluginCode(plugin) {
            // html로 구성된 코드를 텍스트로
            function entityDecode(doc) {
                return $('<p></p>').html(doc).text();
            }

            function getDocHead(plugin) {
                var docHead = "";
                var toJSONPlugin = Object.assign({}, plugin);
                toJSONPlugin.code = undefined;
                toJSONPlugin.link = undefined;
                docHead += "\n";
                docHead += "\n/** 플러그인 " + plugin["name"] + "***************************\n";
                docHead += "* " + plugin["descript"] + "\n";
                docHead += "* 버전 => " + plugin["version"] + "\n";
                docHead += "* 작성자 : [[사용자:" + plugin["creat"] + "|" + plugin["creat"] + "]] \n";
                docHead += "* JSON => " + plugin["name"] + " = " + JSON.stringify(toJSONPlugin) + "; \n";
                docHead += "*/ \n";
                docHead += "function plugin_" + plugin["name"] + "(){\n";
                if (plugin.local) docHead += "  if($(\"[data-name='" + plugin["name"] + "']\").length >= 1){\n";
                return docHead;
            }

            function getDocFoot(plugin) {
                var docFoot = "";
                if (plugin.local) docFoot += "\n  }\n";
                docFoot += "\n}\n";
                if (plugin.executable) docFoot += "$( plugin_" + plugin["name"] + " );\n";
                docFoot += "/* " + plugin["name"] + " 끝 */\n\n";
                return docFoot;
            }

            var docHead = getDocHead(plugin),
                docFoot = getDocFoot(plugin);
            return entityDecode(docHead + plugin["code"] + docFoot);
        }

        $(".install-button").text("설치중..");
        $(".install-button").off("click");

        var doc = "";
        forEach(needPlugins, function(pluginName) {
            var plugin = docPlugins[pluginName];
            jsdoc = removePluginByDoc(pluginName, jsdoc);
            doc += getPluginCode(plugin);
        });
        api.changeDocument(commonjs, "플러그인 " + needPlugins + "설치", jsdoc + doc);
    }

    var checkinstalledPlugin = function() {
        function appendBox(plugin, status) {
            var pluginName = plugin.name;
            var box = $(".cloneable.p-box").clone().removeClass("cloneable");
            var code = api.readDocument(plugin.state).find("pre.script").html();
            docPlugins[pluginName].code = code;
            box.find(".p-status").html(status);
            box.find(".p-code").html(code.replace(/\s{1,}$/, ""));
            box.find(".p-name").text(pluginName);
            box.find(".p-descript").text(plugin["descript"]);
            if (status == "버전업") {
                var thisVersion;
                for (var key in preloadedplugins) {
                    if (preloadedplugins[key].name == plugin["name"]) {
                        thisVersion = preloadedplugins[key].version;
                    }
                }
                box.find(".p-version").text(thisVersion + " => " + plugin["version"]);
            } else {
                box.find(".p-version").text(plugin["version"]);
            }
            box.find(".p-local").text(plugin["local"] == true ? "일부 문서만" : "문서 전체");
            box.find(".p-creat").text(plugin["creat"]);
            $.ajax({
                url: "/w/api.php?action=query&prop=revisions&rvdir=older&titles=" + plugin.state,
                success: function(v, i) {
                    var datas = JSON.parse($(v).find("pre").text());
                    var titleKey = Object.keys(datas["query"]["pages"])[0];
                    var lastModified = datas["query"]["pages"][titleKey]["revisions"][0]["user"] + "(" + datas["query"]["pages"][titleKey]["revisions"][0]["timestamp"] + ")";
                    box.find(".p-last").text(lastModified);
                },
                async: false
            })
            $(".box-article").append(box);
        }

        if (isPluginsEmpty(docPlugins) || (isPluginsEmpty(unupdatedPlugins) && isPluginsEmpty(uninstalledPlugins))) return;
        var doc = $("#mw-content-text");
        var setupMeta = api.readDocument("틀:플러그인/setup");
        doc.html(setupMeta);
        forEach(uninstalledPlugins, function(uninstalledPlugin) {
            appendBox(uninstalledPlugin, "설치");
        });
        forEach(unupdatedPlugins, function(unupdatedPlugin) {
            appendBox(unupdatedPlugin, "버전업");
        });
        $(".install-button").on("click", onPluginInstall);
    }

    var showPluginTemplet = (function() {
        if (isPluginsEmpty(needPlugins)) {
            return;
        }

        if ($(".plugin-install").length >= 1) {
            $(".plugin-install").eq(0).closest("table").show();
            $(".plugin-name").eq(0).text(needPlugins);
            $(".plugin-install").on("click", checkinstalledPlugin);
        } else {
            checkinstalledPlugin();
        }
    })();
}
$(pluginCore)