require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/JSON.sortify'} }); define([ '/api/config?cb=' + Math.random().toString(16).substring(2), '/customize/messages.js?pad=slide', '/bower_components/chainpad-netflux/chainpad-netflux.js', '/bower_components/chainpad-crypto/crypto.js', '/bower_components/textpatcher/TextPatcher.amd.js', '/common/cryptpad-common.js', '/slide/slide.js', '/common/notify.js', '/common/visible.js', '/common/clipboard.js', 'json.sortify', '/bower_components/file-saver/FileSaver.min.js', '/bower_components/jquery/dist/jquery.min.js', '/customize/pad.js' ], function (Config, Messages, Realtime, Crypto, TextPatcher, Cryptpad, Slide, Notify, Visible, Clipboard, JSONSortify) { var $ = window.jQuery; var saveAs = window.saveAs; /* TODO * patch in changes using DiffDOM * predraw some things in case they use external assets * strip out script tags? * better CSS * use codemirror instead of a text editor * add ability to link to a rendered slide * ui hint for escaping presentation mode */ Cryptpad.styleAlerts(); var secret = Cryptpad.getSecrets(); var readOnly = secret.keys && !secret.keys.editKeyStr; Slide.readOnly = readOnly; if (!secret.keys) { secret.keys = secret.key; } var APP = window.APP = { TextPatcher: TextPatcher, Slide: Slide, }; var Stringify = APP.Stringify = JSONSortify; var initializing = true; var $textarea = $('textarea'); var suggestName = function () { var title = ''; var patt = /^#\s+(.*)\s*$/; $textarea.val().split("\n").some(function (line) { if (!patt.test(line)) { return; } line.replace(patt, function (a, b) { title = b; }); return true; }); return title; }; var unnotify = function () { if (!(APP.tabNofification && typeof(APP.tabNofification.cancel) === 'function')) { return; } APP.tabNofification.cancel(); }; var notify = function () { if (!(Visible.isSupported() && !Visible.currently())) { return; } unnotify(); APP.tabNofification = Notify.tab(1000, 10); }; var $modal = $('#modal'); var $content = $('#content'); Slide.setModal($modal, $content); var enterPresentationMode = function (shouldLog) { Slide.show(true, $textarea.val()); if (shouldLog) { Cryptpad.log(Messages.presentSuccess); } }; if (readOnly) { enterPresentationMode(false); } var config = APP.config = { initialState: '{}', websocketURL: Config.websocketURL, channel: secret.channel, crypto: Crypto.createEncryptor(secret.keys), validateKey: secret.keys.validateKey || undefined, readOnly: readOnly, }; var setEditable = function (bool) { if (readOnly && bool) { return; } $textarea.attr('disabled', !bool); }; var canonicalize = function (text) { return text.replace(/\r\n/g, '\n'); }; setEditable(false); var safelyParseContent = function (S, k, first) { if (!first) { return JSON.parse(S); } try { return JSON.parse(S); } catch (err) { console.log("Migrating text content to object form"); var O = {}; O[k] = S; return O; } }; var getUserObj = function (rt) { return safelyParseContent(rt.getUserDoc(), 'content'); }; var onLocal = config.onLocal = function () { if (initializing) { return; } if (readOnly) { return; } var textContent = canonicalize($textarea.val()); var userObj = getUserObj(APP.realtime); userObj.content = textContent; var content = Stringify(userObj); APP.patchText(content); Slide.update(textContent); }; var Button = function (opt) { return $('