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.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

ستحتاج إلى تثبيت إضافة مثل 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);