define([ 'jquery', '/bower_components/chainpad-crypto/crypto.js', '/bower_components/textpatcher/TextPatcher.js', '/common/toolbar3.js', 'json.sortify', '/bower_components/chainpad-json-validator/json-ot.js', '/common/cryptpad-common.js', '/common/cryptget.js', '/common/diffMarked.js', '/bower_components/nthen/index.js', '/common/sframe-common.js', '/api/config', '/common/common-realtime.js', '/slide/slide.js', 'cm/lib/codemirror', 'css!/bower_components/bootstrap/dist/css/bootstrap.min.css', 'css!/bower_components/components-font-awesome/css/font-awesome.min.css', 'less!/customize/src/less2/main.less', 'css!cm/lib/codemirror.css', 'css!cm/addon/dialog/dialog.css', 'css!cm/addon/fold/foldgutter.css', 'cm/mode/markdown/markdown', 'cm/addon/mode/loadmode', 'cm/mode/meta', 'cm/addon/mode/overlay', 'cm/addon/mode/multiplex', 'cm/addon/mode/simple', 'cm/addon/edit/closebrackets', 'cm/addon/edit/matchbrackets', 'cm/addon/edit/trailingspace', 'cm/addon/selection/active-line', 'cm/addon/search/search', 'cm/addon/search/match-highlighter', 'cm/addon/search/searchcursor', 'cm/addon/dialog/dialog', 'cm/addon/fold/foldcode', 'cm/addon/fold/foldgutter', 'cm/addon/fold/brace-fold', 'cm/addon/fold/xml-fold', 'cm/addon/fold/markdown-fold', 'cm/addon/fold/comment-fold', 'cm/addon/display/placeholder', ], function ( $, Crypto, TextPatcher, Toolbar, JSONSortify, JsonOT, Cryptpad, Cryptget, DiffMd, nThen, SFCommon, ApiConfig, CommonRealtime, Slide, CMeditor) { window.CodeMirror = CMeditor; var Messages = Cryptpad.Messages; var APP = window.APP = { Cryptpad: Cryptpad, }; var SLIDE_BACKCOLOR_ID = "cp-app-slide-toolbar-backcolor"; var SLIDE_COLOR_ID = "cp-app-slide-toolbar-color"; var stringify = function (obj) { return JSONSortify(obj); }; var toolbar; var isPresentMode; var onConnectError = function () { Cryptpad.errorLoadingScreen(Messages.websocketError); }; var andThen = function (editor, CodeMirror, common) { var readOnly = false; var cpNfInner; var metadataMgr; var $bar = $('#cme_toolbox'); var isHistoryMode = false; var setEditable = APP.setEditable = function (bool) { if (readOnly && bool) { return; } editor.setOption('readOnly', !bool); }; var Title; var config = { readOnly: readOnly, transformFunction: JsonOT.validate, // cryptpad debug logging (default is 1) // logLevel: 0, validateContent: function (content) { try { JSON.parse(content); return true; } catch (e) { console.log("Failed to parse, rejecting patch"); return false; } } }; var canonicalize = function (t) { return t.replace(/\r\n/g, '\n'); }; var setHistory = function (bool, update) { isHistoryMode = bool; setEditable(!bool); if (!bool && update) { config.onRemote(); } }; var $contentContainer = $('#cp-app-slide-editor'); var $modal = $('#cp-app-slide-modal'); var $content = $('#cp-app-slide-modal-content'); var $print = $('#cp-app-slide-print'); var slideOptions = {}; var initialState = Messages.slideInitialState; var textColor; var backColor; $content.click(function (e) { if (!e.target) { return; } var $t = $(e.target); if ($t.is('a') || $t.parents('a').length) { e.preventDefault(); var $a = $t.is('a') ? $t : $t.parents('a').first(); var href = $a.attr('href'); window.open(href); } }); Slide.setModal(common, $modal, $content, slideOptions, initialState); var enterPresentationMode = function (shouldLog) { Slide.show(true, editor.getValue()); if (shouldLog) { Cryptpad.log(Messages.presentSuccess); } }; if (isPresentMode) { enterPresentationMode(true); } CommonRealtime.onInfiniteSpinner(function () { setEditable(false); }); setEditable(false); var initializing = true; var stringifyInner = function (textValue) { var obj = { content: textValue, metadata: metadataMgr.getMetadataLazy() }; // stringify the json and send it into chainpad return stringify(obj); }; var onLocal = config.onLocal = function () { if (initializing) { return; } if (isHistoryMode) { return; } if (readOnly) { return; } editor.save(); var textValue = canonicalize(CodeMirror.$textarea.val()); var shjson = stringifyInner(textValue); APP.patchText(shjson); Slide.update(textValue); if (APP.realtime.getUserDoc() !== shjson) { console.error("realtime.getUserDoc() !== shjson"); } }; var updateSlideOptions = function (newOpt) { if (stringify(newOpt) !== stringify(slideOptions)) { $.extend(slideOptions, newOpt); // TODO: manage realtime + cursor in the "options" modal ?? Slide.updateOptions(); } }; var updateLocalOptions = function (newOpt) { updateSlideOptions(newOpt); var metadata = JSON.parse(JSON.stringify(metadataMgr.getMetadata())); metadata.slideOptions = slideOptions; metadataMgr.updateMetadata(metadata); onLocal(); }; var updateColors = function (text, back) { if (text) { textColor = text; $modal.css('color', text); $modal.css('border-color', text); $('#' + SLIDE_COLOR_ID).css('color', text); } if (back) { backColor = back; $modal.css('background-color', back); $('#' + SLIDE_BACKCOLOR_ID).css('color', back); } }; var updateLocalColors = function (text, back) { updateColors(text, back); var metadata = JSON.parse(JSON.stringify(metadataMgr.getMetadata())); if (backColor) { metadata.backColor = backColor; } if (textColor) { metadata.color = textColor; } metadataMgr.updateMetadata(metadata); onLocal(); console.log(metadataMgr.getMetadata()); }; var createPrintDialog = function () { var slideOptionsTmp = { title: false, slide: false, date: false, transition: true, style: '' }; $.extend(slideOptionsTmp, slideOptions); var $container = $('
'); var $container2 = $('
').appendTo($container); var $div = $('
').appendTo($container2); var $p = $('

', {'class': 'msg'}).appendTo($div); $('').text(Messages.printOptions).appendTo($p); $p.append($('
')); // Slide number $('', { type: 'checkbox', id: 'cp-app-slide-options-number', checked: slideOptionsTmp.slide }).on('change', function () { var c = this.checked; slideOptionsTmp.slide = c; }).appendTo($p).css('width', 'auto'); $('