Dillinger.io

Adds the ability to export and import documents from local storage in raw format (see "Export as" and "Import from" menus). When exporting documents, you can select the option to automatically delete documents after exporting.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        Dillinger.io
// @namespace   https://github.com/XelaNimed
// @version     0.1.6
// @description Adds the ability to export and import documents from local storage in raw format (see "Export as" and "Import from" menus). When exporting documents, you can select the option to automatically delete documents after exporting.
// @author      XelaNimed
// @copyright   2021, XelaNimed (https://github.com/XelaNimed)
// @supportURL  https://github.com/XelaNimed/dillinger-io-user-script/issues
// @homepageURL https://github.com/XelaNimed/dillinger-io-user-script
// @license     MIT; https://raw.githubusercontent.com/XelaNimed/dillinger-io-user-script/master/LICENSE
// @match       https://dillinger.io/
// @icon        https://www.google.com/s2/favicons?domain=dillinger.io&sz=32
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js#sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=
// @grant       none
// ==/UserScript==
/* global Swal, jQuery */
(function($) {

    'use strict';

    $(document).ready(function() {

        const exportMenuSelector = '.menu.menu-utilities>li:nth-child(2)>ul';
        const importMenuSelector = '.menu.menu-utilities>li:nth-child(4)>ul';
        const exportMenu = $(exportMenuSelector);
        const importMenu = $(importMenuSelector);
        const exportText = 'Raw';
        const importText = 'Raw';
        const localStorageFilesKey = 'files';
        const localStorageCurrentDocumentKey = 'currentDocument';
        const jsonFileName = 'dilinger_raw';
        const confirmMessageByOverwrite = 'Keep in mind that the script does not check the syntax of the imported data and assumes that the imported file was previously exported. After applying the settings, the page will reload and all saved documents will be overwritten. Continue?';
        const confirmMessageByExport = 'Delete saved documents after exporting and then reloading the page?';
        const inp = document.createElement('input');

        const getDateTime = function() {
            return new Date().toISOString()
                .slice(0, -5)
                .replace('T', '_')
                .split(':').join('-');
        };

        const saveJSON = function (data, filename) {

            if(typeof data === 'object') {
                data = JSON.stringify(data, undefined, 4);
            }

            const blob = new Blob([data], {type: 'text/json'}),
                  a = document.createElement('a'),
                  evt = new MouseEvent("click", {
                      bubbles: true,
                      cancelable: true,
                      view: window
                  });

            a.download = filename + '_' + getDateTime() + '.json';
            a.href = window.URL.createObjectURL(blob);
            a.dataset.downloadurl = ['text/json', a.download, a.href].join(':');
            a.dispatchEvent(evt);
            a.remove();
        };

        const readJSON = function (files) {
            if(files && files.length === 1) {
                const fr = new FileReader();
                fr.readAsText(files[0]);
                fr.onload = function(e){
                    if(confirm(confirmMessageByOverwrite)) {
                        const json = JSON.parse(e.target.result);
                        localStorage.setItem(localStorageCurrentDocumentKey, JSON.stringify(json[0]));
                        localStorage.setItem(localStorageFilesKey, e.target.result);
                        window.location.reload();
                    } else {
                        inp.value = null;
                    }
                };
            }
        };

        const addExportRaw = function() {
            let a = document.createElement('a');
                a.innerText = exportText;
                a.addEventListener('click', function(e) {
                    let deleteSavedDocs = confirm(confirmMessageByExport);
                    saveJSON(localStorage.getItem(localStorageFilesKey), jsonFileName);
                    if(deleteSavedDocs){
                        localStorage.removeItem(localStorageFilesKey);
                        localStorage.removeItem(localStorageCurrentDocumentKey);
                        window.location.reload();
                    }
                    e.preventDefault();
                });

            let li = document.createElement('li');
                li.appendChild(a);

            exportMenu[0].appendChild(li);
        };

        const addImportRaw = function() {
                inp.type = 'file';
                inp.multiple = false;
                inp.accept = 'application/json';
                inp.style.display = 'none';
                inp.onchange = function() {
                    readJSON(this.files);
                };

            let span = document.createElement('span');
                span.innerText = importText;

            let a = document.createElement('a');
                a.appendChild(span);
                a.addEventListener('click', function(e) {
                    inp.click();
                    e.preventDefault();
                });

            let li = document.createElement('li');
                li.appendChild(a);
                li.appendChild(inp);
                importMenu[0].appendChild(li);
        };

        if(exportMenu.length > 0) {
            addExportRaw();
        } else {
            console.error("Export menu not found by selector: %s", exportMenuSelector);
        }

        if(importMenu.length > 0) {
            addImportRaw();
        } else {
            console.error("Import menu not found by selector: %s", importMenuSelector);
        }

    });

})(window.jQuery);