define([ "jquery", "underscore", "utils", "settings", "extensionMgr", "mousetrap", "text!html/settingsTemplateTooltip.html", "text!html/settingsUserCustomExtensionTooltip.html", "storage", "config", "libs/bootstrap", "libs/layout", "libs/Markdown.Editor" ], function($, _, utils, settings, extensionMgr, mousetrap, settingsTemplateTooltipHTML, settingsUserCustomExtensionTooltipHTML) { var core = {}; // Used for periodic tasks var intervalId = undefined; var periodicCallbacks = [ extensionMgr.onPeriodicRun ]; core.runPeriodically = function(callback) { periodicCallbacks.push(callback); }; // Used to detect user activity var userReal = false; var userActive = false; var windowUnique = true; var userLastActivity = 0; function setUserActive() { userReal = true; userActive = true; userLastActivity = utils.currentTime; } function isUserActive() { if(userActive === true && utils.currentTime - userLastActivity > USER_IDLE_THRESHOLD) { userActive = false; } return userActive && windowUnique; } // Used to only have 1 window of the application in the same browser var windowId = undefined; function checkWindowUnique() { if(userReal === false || windowUnique === false) { return; } if(windowId === undefined) { windowId = utils.randomString(); localStorage["frontWindowId"] = windowId; } var frontWindowId = localStorage["frontWindowId"]; if(frontWindowId != windowId) { windowUnique = false; if(intervalId !== undefined) { clearInterval(intervalId); } $(".modal").modal("hide"); $('#modal-non-unique').modal({ backdrop: "static", keyboard: false }); } } // Offline management core.isOffline = false; var offlineTime = utils.currentTime; core.setOffline = function() { offlineTime = utils.currentTime; if(core.isOffline === false) { core.isOffline = true; extensionMgr.onOfflineChanged(true); } }; function setOnline() { if(core.isOffline === true) { core.isOffline = false; extensionMgr.onOfflineChanged(false); } } function checkOnline() { // Try to reconnect if we are offline but we have some network if(core.isOffline === true && navigator.onLine === true && offlineTime + CHECK_ONLINE_PERIOD < utils.currentTime) { offlineTime = utils.currentTime; // Try to download anything to test the connection $.ajax({ url: "//www.google.com/jsapi", timeout: AJAX_TIMEOUT, dataType: "script" }).done(function() { setOnline(); }); } } // Load settings in settings dialog function loadSettings() { // Layout orientation utils.setInputRadio("radio-layout-orientation", settings.layoutOrientation); // Theme utils.setInputValue("#input-settings-theme", localStorage.theme); // Lazy rendering utils.setInputChecked("#input-settings-lazy-rendering", settings.lazyRendering); // Editor font family utils.setInputValue("#input-settings-editor-font-family", settings.editorFontFamily); // Editor font size utils.setInputValue("#input-settings-editor-font-size", settings.editorFontSize); // Default content utils.setInputValue("#textarea-settings-default-content", settings.defaultContent); // Commit message utils.setInputValue("#input-settings-publish-commit-msg", settings.commitMsg); // Template utils.setInputValue("#textarea-settings-publish-template", settings.template); // SSH proxy utils.setInputValue("#input-settings-ssh-proxy", settings.sshProxy); // Load extension settings extensionMgr.onLoadSettings(); } // Save settings from settings dialog function saveSettings(event) { var newSettings = {}; // Layout orientation newSettings.layoutOrientation = utils.getInputRadio("radio-layout-orientation"); // Theme var theme = utils.getInputValue("#input-settings-theme"); // Lazy Rendering newSettings.lazyRendering = utils.getInputChecked("#input-settings-lazy-rendering"); // Editor font family newSettings.editorFontFamily = utils.getInputTextValue("#input-settings-editor-font-family", event); // Editor font size newSettings.editorFontSize = utils.getInputIntValue("#input-settings-editor-font-size", event, 1, 99); // Default content newSettings.defaultContent = utils.getInputValue("#textarea-settings-default-content"); // Commit message newSettings.commitMsg = utils.getInputTextValue("#input-settings-publish-commit-msg", event); // Template newSettings.template = utils.getInputTextValue("#textarea-settings-publish-template", event); // SSH proxy newSettings.sshProxy = utils.checkUrl(utils.getInputTextValue("#input-settings-ssh-proxy", event), true); // Save extension settings newSettings.extensionSettings = {}; extensionMgr.onSaveSettings(newSettings.extensionSettings, event); if(!event.isPropagationStopped()) { $.extend(settings, newSettings); localStorage.settings = JSON.stringify(settings); localStorage.theme = theme; } } // Create the layout var layout = undefined; function createLayout() { if(viewerMode === true) { return; } var layoutGlobalConfig = { closable: true, resizable: false, slidable: false, livePaneResizing: true, enableCursorHotkey: false, spacing_open: 15, spacing_closed: 15, togglerLength_open: 90, togglerLength_closed: 90, stateManagement__enabled: false, center__minWidth: 200, center__minHeight: 200 }; extensionMgr.onLayoutConfigure(layoutGlobalConfig); if(settings.layoutOrientation == "horizontal") { $(".ui-layout-south").remove(); $(".preview-container").html('
'); layout = $('body').layout($.extend(layoutGlobalConfig, { east__resizable: true, east__size: .5, east__minSize: 200 })); } else if(settings.layoutOrientation == "vertical") { $(".ui-layout-east").remove(); $(".preview-container").html(''); layout = $('body').layout($.extend(layoutGlobalConfig, { south__resizable: true, south__size: .5, south__minSize: 200 })); } $(".navbar").click(function() { layout.allowOverflow('north'); }); $(".ui-layout-toggler-north").addClass("btn").append($("").addClass("caret")); $(".ui-layout-toggler-south").addClass("btn").append($("").addClass("caret")); $(".ui-layout-toggler-east").addClass("btn").append($("").addClass("caret")); extensionMgr.onLayoutCreated(layout); } ; // Create the PageDown editor var editor = undefined; var fileDesc = undefined; var documentContent = undefined; core.initEditor = function(fileDescParam) { if(fileDesc !== undefined) { extensionMgr.onFileClosed(fileDesc); } fileDesc = fileDescParam; documentContent = undefined; var initDocumentContent = fileDesc.content; var editorElt = $("#wmd-input"); editorElt.val(initDocumentContent); if(editor !== undefined) { // If the editor is already created editor.undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop); editor.refreshPreview(); extensionMgr.onFileOpen(fileDesc); return; } var previewContainerElt = $(".preview-container"); // Store editor scrollTop on scroll event editorElt.scroll(function() { if(documentContent !== undefined) { fileDesc.editorScrollTop = $(this).scrollTop(); } }); // Store editor selection on change editorElt.bind("keyup mouseup", function() { if(documentContent !== undefined) { fileDesc.editorStart = this.selectionStart; fileDesc.editorEnd = this.selectionEnd; } }); // Store preview scrollTop on scroll event previewContainerElt.scroll(function() { if(documentContent !== undefined) { fileDesc.previewScrollTop = $(this).scrollTop(); } }); // Create the converter and the editor var converter = new Markdown.Converter(); editor = new Markdown.Editor(converter); // Custom insert link dialog editor.hooks.set("insertLinkDialog", function(callback) { core.insertLinkCallback = callback; utils.resetModalInputs(); $("#modal-insert-link").modal(); return true; }); // Custom insert image dialog editor.hooks.set("insertImageDialog", function(callback) { core.insertLinkCallback = callback; if(core.catchModal) { return true; } utils.resetModalInputs(); $("#modal-insert-image").modal(); return true; }); function checkDocumentChanges() { var newDocumentContent = editorElt.val(); if(documentContent !== undefined && documentContent != newDocumentContent) { fileDesc.content = newDocumentContent; extensionMgr.onContentChanged(fileDesc); } documentContent = newDocumentContent; } var previewWrapper; if(settings.lazyRendering === true) { previewWrapper = function(makePreview) { var debouncedMakePreview = _.debounce(makePreview, 500); return function() { if(documentContent === undefined) { makePreview(); editorElt.scrollTop(fileDesc.editorScrollTop); previewContainerElt.scrollTop(fileDesc.previewScrollTop); } else { debouncedMakePreview(); } checkDocumentChanges(); }; }; } else { previewWrapper = function(makePreview) { return function() { makePreview(); if(documentContent === undefined) { previewContainerElt.scrollTop(fileDesc.previewScrollTop); } checkDocumentChanges(); }; }; } extensionMgr.onEditorConfigure(editor); editor.hooks.chain("onPreviewRefresh", extensionMgr.onAsyncPreview); editor.run(previewWrapper); editor.undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop); // Hide default buttons $(".wmd-button-row").addClass("btn-group").find("li:not(.wmd-spacer)").addClass("btn").css("left", 0).find("span").hide(); // Add customized buttons $("#wmd-bold-button").append($("").addClass("icon-bold")); $("#wmd-italic-button").append($("").addClass("icon-italic")); $("#wmd-link-button").append($("").addClass("icon-globe")); $("#wmd-quote-button").append($("").addClass("icon-indent-left")); $("#wmd-code-button").append($("").addClass("icon-code")); $("#wmd-image-button").append($("").addClass("icon-picture")); $("#wmd-olist-button").append($("").addClass("icon-numbered-list")); $("#wmd-ulist-button").append($("").addClass("icon-list")); $("#wmd-heading-button").append($("").addClass("icon-text-height")); $("#wmd-hr-button").append($("").addClass("icon-hr")); // Create additional undo/redo button for real time synchronization var realtimeUndoButton = $('