Import files from disk
This commit is contained in:
parent
b3edbdd0c2
commit
d334dfe2f8
676
css/default.css
676
css/default.css
File diff suppressed because it is too large
Load Diff
194
index.html
194
index.html
@ -11,18 +11,23 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="msvalidate.01" content="5E47EE6F67B069C17E3CDD418351A612" />
|
||||
<script>
|
||||
// Use http://.../?debug to serve original CSS/JavaScript files instead of minified
|
||||
var suffix = "";
|
||||
if (!location.search.match(/(\?|&)debug/)) {
|
||||
suffix = "-min";
|
||||
}
|
||||
document.write('<link href="css/main' + suffix + '.css" rel="stylesheet">');
|
||||
var theme = localStorage.theme;
|
||||
if (theme) {
|
||||
document.write('<link href="themes/' + theme + '/' + theme + '.css" rel="stylesheet">');
|
||||
}
|
||||
var require = { baseUrl : "js", deps : [ "main" + suffix ] };
|
||||
var viewerMode = false;
|
||||
// Use http://.../?debug to serve original CSS/JavaScript files instead of minified
|
||||
var suffix = "";
|
||||
if(!location.search.match(/(\?|&)debug/)) {
|
||||
suffix = "-min";
|
||||
}
|
||||
document.write('<link href="css/main' + suffix + '.css" rel="stylesheet">');
|
||||
var theme = localStorage.theme;
|
||||
if(theme) {
|
||||
document.write('<link href="themes/' + theme + '/' + theme + '.css" rel="stylesheet">');
|
||||
}
|
||||
var require = {
|
||||
baseUrl: "js",
|
||||
deps: [
|
||||
"main" + suffix
|
||||
]
|
||||
};
|
||||
var viewerMode = false;
|
||||
</script>
|
||||
<script src="js/libs/require.js"></script>
|
||||
</head>
|
||||
@ -34,8 +39,7 @@
|
||||
<li><div id="wmd-button-bar"></div></li>
|
||||
</ul>
|
||||
<ul class="nav pull-right hide" id="menu-bar">
|
||||
<li id="extension-buttons">
|
||||
</li>
|
||||
<li id="extension-buttons"></li>
|
||||
<li class="btn-group"><button class="btn action-create-file"
|
||||
title="New local document">
|
||||
<i class="icon-file"></i>
|
||||
@ -62,13 +66,27 @@
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="viewer.html" title="StackEdit Viewer"><i
|
||||
class="icon-fullscreen"></i> Open viewer</a></li>
|
||||
<li><a class="action-download-md" href="#"><i
|
||||
class="icon-download-alt"></i> Save as Markdown</a></li>
|
||||
<li><a class="action-download-html" href="#"><i
|
||||
class="icon-download-alt"></i> Save as HTML</a></li>
|
||||
<li><a class="action-download-template" href="#"><i
|
||||
class="icon-download-alt"></i> Save using template</a></li>
|
||||
class="icon-fullscreen"></i> StackEdit Viewer</a></li>
|
||||
<li class="dropdown-submenu"><a href="#"><i
|
||||
class="icon-hdd"></i> Open from...</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a data-toggle="modal"
|
||||
data-target="#modal-import-harddrive-markdown" class="action-reset-input"
|
||||
href="#">Import from hard drive</a></li>
|
||||
<li><a data-toggle="modal"
|
||||
data-target="#modal-import-harddrive-html" class="action-reset-input"
|
||||
href="#">Convert HTML to Markdown</a></li>
|
||||
</ul></li>
|
||||
<li class="dropdown-submenu"><a href="#"><i
|
||||
class="icon-hdd"></i> Save as...</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a class="action-download-md" href="#">Save as
|
||||
Markdown</a></li>
|
||||
<li><a class="action-download-html" href="#">Save as
|
||||
HTML</a></li>
|
||||
<li><a class="action-download-template" href="#">Save
|
||||
using template</a></li>
|
||||
</ul></li>
|
||||
<li class="divider with-text">synchronize</li>
|
||||
<li class="dropdown-submenu"><a href="#"><i
|
||||
class="icon-gdrive"></i> Google Drive</a>
|
||||
@ -134,9 +152,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a>
|
||||
<a href="#" class="btn btn-primary action-insert-link"
|
||||
data-dismiss="modal">OK</a>
|
||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
|
||||
class="btn btn-primary action-insert-link" data-dismiss="modal">OK</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -155,9 +172,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn action-import-image-gplus" data-dismiss="modal"><i class="icon-gplus"></i> Import from Google+</a>
|
||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a>
|
||||
<a href="#" class="btn btn-primary action-insert-image"
|
||||
<a href="#" class="btn action-import-image-gplus"
|
||||
data-dismiss="modal"><i class="icon-gplus"></i> Import from
|
||||
Google+</a> <a href="#" class="btn" data-dismiss="modal">Cancel</a> <a
|
||||
href="#" class="btn btn-primary action-insert-image"
|
||||
data-dismiss="modal">OK</a>
|
||||
</div>
|
||||
</div>
|
||||
@ -169,32 +187,33 @@
|
||||
<h3>Import image</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<img>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-import-image-title">Title (optional)</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-import-image-title"
|
||||
placeholder="Image title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-import-image-size">Size limit
|
||||
(optional)</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-import-image-size" placeholder="345" class="input-mini"><span class="help-inline">px</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<img>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-import-image-title">Title
|
||||
(optional)</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-import-image-title"
|
||||
placeholder="Image title">
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="input-import-image-size">Size
|
||||
limit (optional)</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-import-image-size" placeholder="345"
|
||||
class="input-mini"><span class="help-inline">px</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a>
|
||||
<a href="#" class="btn btn-primary action-import-image"
|
||||
data-dismiss="modal">OK</a>
|
||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
|
||||
class="btn btn-primary action-import-image" data-dismiss="modal">OK</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -218,6 +237,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-import-harddrive-markdown" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-hidden="true">×</button>
|
||||
<h3>Import from hard drive</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Please select the Markdown files to import:</p>
|
||||
<p><input type="file" id="input-file-import-harddrive-markdown" multiple /></p>
|
||||
<p>Or drag and drop the Markdown files here:</p>
|
||||
<div id="dropzone-import-harddrive-markdown" class="drop-zone">Drop zone</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-import-harddrive-html" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-hidden="true">×</button>
|
||||
<h3>Import from hard drive</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>Please select the HTML files to import:</p>
|
||||
<p><input type="file" id="input-file-import-harddrive-html" multiple /></p>
|
||||
<p>Or drag and drop the HTML files here:</p>
|
||||
<div id="dropzone-import-harddrive-html" class="drop-zone">Drop zone</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-upload-gdrive" class="modal hide">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
@ -442,7 +495,11 @@
|
||||
site</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="input-publish-wordpress-site"
|
||||
placeholder="exemple.wordpress.com">
|
||||
placeholder="exemple.wordpress.com"> <span
|
||||
class="help-block"> <a target="_blank"
|
||||
href="http://jetpack.me/">Jetpack plugin</a> is required for
|
||||
self-hosted sites.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@ -547,16 +604,16 @@
|
||||
<button type="button" class="close" data-dismiss="modal"
|
||||
aria-hidden="true">×</button>
|
||||
<h3>Settings</h3>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a class="action-load-settings"
|
||||
href="#tabpane-settings-editor" data-toggle="tab">Editor</a></li>
|
||||
<li><a class="action-load-settings"
|
||||
href="#tabpane-settings-publish" data-toggle="tab">Publish</a></li>
|
||||
<li><a class="action-load-settings"
|
||||
href="#tabpane-settings-extensions" data-toggle="tab">Extensions</a></li>
|
||||
<li><a class="action-load-settings"
|
||||
href="#tabpane-settings-utils" data-toggle="tab">Utils</a></li>
|
||||
</ul>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a class="action-load-settings"
|
||||
href="#tabpane-settings-editor" data-toggle="tab">Editor</a></li>
|
||||
<li><a class="action-load-settings"
|
||||
href="#tabpane-settings-publish" data-toggle="tab">Publish</a></li>
|
||||
<li><a class="action-load-settings"
|
||||
href="#tabpane-settings-extensions" data-toggle="tab">Extensions</a></li>
|
||||
<li><a class="action-load-settings"
|
||||
href="#tabpane-settings-utils" data-toggle="tab">Utils</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
@ -647,12 +704,14 @@
|
||||
<div class="tab-pane" id="tabpane-settings-utils">
|
||||
<div class="tab-pane-button-container">
|
||||
<a href="#" class="btn btn-block btn-primary action-welcome-file"
|
||||
data-dismiss="modal"><i class="icon-info-sign icon-white"></i> Welcome document</a> <a href="#"
|
||||
data-dismiss="modal"><i class="icon-info-sign icon-white"></i>
|
||||
Welcome document</a> <a href="#"
|
||||
class="btn btn-block btn-primary action-default-settings"
|
||||
data-dismiss="modal"><i class="icon-wrench icon-white"></i> Load default settings</a> <a href="#"
|
||||
data-dismiss="modal"><i class="icon-wrench icon-white"></i>
|
||||
Load default settings</a> <a href="#"
|
||||
class="btn btn-block btn-primary" data-dismiss="modal"
|
||||
data-toggle="modal" data-target="#modal-app-reset"><i class="icon-fire icon-white"></i> Reset
|
||||
application</a>
|
||||
data-toggle="modal" data-target="#modal-app-reset"><i
|
||||
class="icon-fire icon-white"></i> Reset application</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -670,8 +729,7 @@
|
||||
aria-hidden="true">×</button>
|
||||
<img src="img/stackedit-promo.png" />
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
</div>
|
||||
<div class="modal-body"></div>
|
||||
<div class="modal-footer">
|
||||
<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
|
||||
</div>
|
||||
|
@ -1,198 +0,0 @@
|
||||
/**
|
||||
* Used to run asynchronous tasks sequentially (ajax mainly). An asynchronous
|
||||
* task is composed of different callback types: onRun, onSuccess, onError
|
||||
*/
|
||||
define([
|
||||
"underscore",
|
||||
"core",
|
||||
"utils",
|
||||
"extensionMgr",
|
||||
"libs/stacktrace",
|
||||
], function(_, core, utils, extensionMgr) {
|
||||
|
||||
var asyncRunner = {};
|
||||
|
||||
var taskQueue = [];
|
||||
var asyncRunning = false;
|
||||
var currentTask = undefined;
|
||||
var currentTaskRunning = false;
|
||||
var currentTaskStartTime = 0;
|
||||
|
||||
asyncRunner.createTask = function() {
|
||||
var task = {};
|
||||
task.finished = false;
|
||||
task.timeout = ASYNC_TASK_DEFAULT_TIMEOUT;
|
||||
task.retryCounter = 0;
|
||||
task.callPath = [];
|
||||
/**
|
||||
* onRun callbacks are called by chain(). These callbacks have to call
|
||||
* chain() themselves to chain with next onRun callback or error() to
|
||||
* throw an exception or retry() to restart the task.
|
||||
*/
|
||||
// Run callbacks
|
||||
task.runCallbacks = [];
|
||||
task.onRun = function(callback) {
|
||||
task.runCallbacks.push(callback);
|
||||
};
|
||||
/**
|
||||
* onSuccess callbacks are called when every onRun callbacks have
|
||||
* succeed.
|
||||
*/
|
||||
task.successCallbacks = [];
|
||||
task.onSuccess = function(callback) {
|
||||
task.successCallbacks.push(callback);
|
||||
};
|
||||
/**
|
||||
* onError callbacks are called when error() is called in a onRun
|
||||
* callback.
|
||||
*/
|
||||
task.errorCallbacks = [];
|
||||
task.onError = function(callback) {
|
||||
task.errorCallbacks.push(callback);
|
||||
};
|
||||
/**
|
||||
* chain() calls the next onRun callback or the onSuccess callbacks when
|
||||
* finished. The optional callback parameter can be used to pass an
|
||||
* onRun callback during execution.
|
||||
*/
|
||||
task.chain = function(callback) {
|
||||
task.callPath.unshift(printStackTrace()[5]);
|
||||
if(task.finished === true) {
|
||||
return;
|
||||
}
|
||||
// If first execution
|
||||
if(task.queue === undefined) {
|
||||
// Create a copy of the onRun callbacks
|
||||
task.queue = task.runCallbacks.slice();
|
||||
}
|
||||
// If a callback is passed as a parameter
|
||||
if(callback !== undefined) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
// If all callbacks have been run
|
||||
if(task.queue.length === 0) {
|
||||
// Run the onSuccess callbacks
|
||||
runSafe(task, task.successCallbacks);
|
||||
return;
|
||||
}
|
||||
// Run the next callback
|
||||
var runCallback = task.queue.shift();
|
||||
runCallback();
|
||||
};
|
||||
/**
|
||||
* error() calls the onError callbacks passing the error parameter and
|
||||
* ends the task by throwing an exception.
|
||||
*/
|
||||
task.error = function(error) {
|
||||
task.callPath.unshift(printStackTrace()[5]);
|
||||
if(task.finished === true) {
|
||||
return;
|
||||
}
|
||||
error = error || new Error("Unknown error|\n" + task.callPath.join("\n"));
|
||||
if(error.message) {
|
||||
extensionMgr.onError(error);
|
||||
}
|
||||
runSafe(task, task.errorCallbacks, error);
|
||||
// Exit the current call stack
|
||||
throw error;
|
||||
};
|
||||
/**
|
||||
* retry() can be called in an onRun callback to restart the task
|
||||
*/
|
||||
task.retry = function(error, maxRetryCounter) {
|
||||
if(task.finished === true) {
|
||||
return;
|
||||
}
|
||||
maxRetryCounter = maxRetryCounter || 5;
|
||||
task.queue = undefined;
|
||||
if(task.retryCounter >= maxRetryCounter) {
|
||||
task.error(error);
|
||||
return;
|
||||
}
|
||||
// Implement an exponential backoff
|
||||
var delay = Math.pow(2, task.retryCounter++) * 1000;
|
||||
currentTaskStartTime = utils.currentTime + delay;
|
||||
currentTaskRunning = false;
|
||||
task.callPath = [];
|
||||
asyncRunner.runTask();
|
||||
};
|
||||
return task;
|
||||
};
|
||||
|
||||
// Run the next task in the queue if any and no other running
|
||||
asyncRunner.runTask = function() {
|
||||
// Use defer to avoid stack overflow
|
||||
_.defer(function() {
|
||||
|
||||
// If there is a task currently running
|
||||
if(currentTaskRunning === true) {
|
||||
// If the current task takes too long
|
||||
if(currentTaskStartTime + currentTask.timeout < utils.currentTime) {
|
||||
currentTask.error(new Error("A timeout occurred.|\n" + currentTask.callPath.join("\n")));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(currentTask === undefined) {
|
||||
// If no task in the queue
|
||||
if(taskQueue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Dequeue an enqueued task
|
||||
currentTask = taskQueue.shift();
|
||||
currentTaskStartTime = utils.currentTime;
|
||||
if(asyncRunning === false) {
|
||||
asyncRunning = true;
|
||||
extensionMgr.onAsyncRunning(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Run the task
|
||||
if(currentTaskStartTime <= utils.currentTime) {
|
||||
currentTaskRunning = true;
|
||||
currentTask.chain();
|
||||
}
|
||||
});
|
||||
};
|
||||
// Run runTask function periodically
|
||||
core.addPeriodicCallback(asyncRunner.runTask);
|
||||
|
||||
function runSafe(task, callbacks, param) {
|
||||
try {
|
||||
_.each(callbacks, function(callback) {
|
||||
callback(param);
|
||||
});
|
||||
}
|
||||
finally {
|
||||
task.finished = true;
|
||||
if(currentTask === task) {
|
||||
currentTask = undefined;
|
||||
currentTaskRunning = false;
|
||||
}
|
||||
if(taskQueue.length === 0) {
|
||||
asyncRunning = false;
|
||||
extensionMgr.onAsyncRunning(false);
|
||||
}
|
||||
else {
|
||||
asyncRunner.runTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add a task to the queue
|
||||
asyncRunner.addTask = function(task) {
|
||||
taskQueue.push(task);
|
||||
asyncRunner.runTask();
|
||||
};
|
||||
|
||||
// Change current task timeout
|
||||
asyncRunner.setCurrentTaskTimeout = function(timeout) {
|
||||
if(currentTask !== undefined) {
|
||||
currentTask.timeout = timeout;
|
||||
}
|
||||
};
|
||||
|
||||
return asyncRunner;
|
||||
});
|
@ -18,6 +18,7 @@ var ASYNC_TASK_DEFAULT_TIMEOUT = 60000;
|
||||
var ASYNC_TASK_LONG_TIMEOUT = 180000;
|
||||
var SYNC_PERIOD = 180000;
|
||||
var USER_IDLE_THRESHOLD = 300000;
|
||||
var IMPORT_FILE_MAX_CONTENT_SIZE = 100000;
|
||||
var TEMPORARY_FILE_INDEX = "file.tempIndex";
|
||||
var WELCOME_DOCUMENT_TITLE = "Welcome document";
|
||||
var DOWNLOAD_PROXY_URL = "http://stackedit-download-proxy.herokuapp.com/";
|
||||
|
@ -261,6 +261,7 @@ define([
|
||||
var newDocumentContent = editorElt.val();
|
||||
if(documentContent !== undefined && documentContent != newDocumentContent) {
|
||||
fileDesc.content = newDocumentContent;
|
||||
extensionMgr.onContentChanged(fileDesc);
|
||||
}
|
||||
documentContent = newDocumentContent;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ define([
|
||||
"extensions/dialogAbout",
|
||||
"extensions/dialogManagePublication",
|
||||
"extensions/dialogManageSynchronization",
|
||||
"extensions/dialogOpenHarddrive",
|
||||
"extensions/documentSelector",
|
||||
"extensions/documentTitle",
|
||||
"extensions/workingIndicator",
|
||||
|
@ -10,9 +10,9 @@ define([
|
||||
settingsBloc: '<p>Populates the "Manage publication" dialog box.</p>'
|
||||
};
|
||||
|
||||
var fileMgr = undefined;
|
||||
dialogManagePublication.onFileMgrCreated = function(fileMgrParameter) {
|
||||
fileMgr = fileMgrParameter;
|
||||
var extensionMgr = undefined;
|
||||
dialogManagePublication.onExtensionMgrCreated = function(extensionMgrParameter) {
|
||||
extensionMgr = extensionMgrParameter;
|
||||
};
|
||||
|
||||
var fileDesc = undefined;
|
||||
@ -42,7 +42,8 @@ define([
|
||||
publishDesc: publishDesc
|
||||
}));
|
||||
lineElement.append($(removeButtonTemplate).click(function() {
|
||||
fileMgr.removePublish(publishAttributes);
|
||||
fileDesc.removePublishLocation(publishAttributes);
|
||||
extensionMgr.onPublishRemoved(publishFileDesc, publishAttributes);
|
||||
}));
|
||||
publishList.append(lineElement);
|
||||
});
|
||||
|
@ -10,9 +10,9 @@ define([
|
||||
settingsBloc: '<p>Populates the "Manage synchronization" dialog box.</p>'
|
||||
};
|
||||
|
||||
var fileMgr = undefined;
|
||||
dialogManageSynchronization.onFileMgrCreated = function(fileMgrParameter) {
|
||||
fileMgr = fileMgrParameter;
|
||||
var extensionMgr = undefined;
|
||||
dialogManageSynchronization.onExtensionMgrCreated = function(extensionMgrParameter) {
|
||||
extensionMgr = extensionMgrParameter;
|
||||
};
|
||||
|
||||
var fileDesc = undefined;
|
||||
@ -38,7 +38,8 @@ define([
|
||||
syncDesc: syncDesc
|
||||
}));
|
||||
lineElement.append($(removeButtonTemplate).click(function() {
|
||||
fileMgr.removeSync(syncAttributes);
|
||||
fileDesc.removeSyncLocation(syncAttributes);
|
||||
extensionMgr.onSyncRemoved(fileDesc, syncAttributes);
|
||||
}));
|
||||
syncList.append(lineElement);
|
||||
});
|
||||
|
@ -38,6 +38,7 @@ define([
|
||||
var liMap = undefined;
|
||||
var liArray = undefined;
|
||||
var sortFunction = undefined;
|
||||
var selectFileDesc = undefined;
|
||||
var buildSelector = function() {
|
||||
|
||||
function composeTitle(fileDesc) {
|
||||
@ -68,23 +69,17 @@ define([
|
||||
});
|
||||
var li = $("<li>").append(a);
|
||||
liMap[fileDesc.fileIndex] = li;
|
||||
if(fileDesc === selectFileDesc) {
|
||||
li.addClass("disabled");
|
||||
}
|
||||
$("#file-selector").append(li);
|
||||
});
|
||||
liArray = _.values(liMap);
|
||||
};
|
||||
|
||||
var selectFileDesc = undefined;
|
||||
documentSelector.onFileSelected = function(fileDesc) {
|
||||
selectFileDesc = fileDesc;
|
||||
buildSelector();
|
||||
$("#file-selector li:not(.stick)").removeClass("disabled");
|
||||
var li = liMap[fileDesc.fileIndex];
|
||||
if(li === undefined) {
|
||||
// It means that we are showing a temporary file (not in the
|
||||
// selector)
|
||||
return;
|
||||
}
|
||||
li.addClass("disabled");
|
||||
};
|
||||
|
||||
documentSelector.onFileCreated = buildSelector;
|
||||
|
154
js/fileMgr.js
154
js/fileMgr.js
@ -6,93 +6,12 @@ define([
|
||||
"settings",
|
||||
"extensionMgr",
|
||||
"fileSystem",
|
||||
"classes/FileDescriptor",
|
||||
"text!../WELCOME.md"
|
||||
], function($, _, core, utils, settings, extensionMgr, fileSystem, welcomeContent) {
|
||||
], function($, _, core, utils, settings, extensionMgr, fileSystem, FileDescriptor, welcomeContent) {
|
||||
|
||||
var fileMgr = {};
|
||||
|
||||
// Defines a file descriptor (fileDesc objects)
|
||||
function FileDescriptor(fileIndex, title, syncLocations, publishLocations) {
|
||||
this.fileIndex = fileIndex;
|
||||
this._title = title;
|
||||
this._editorScrollTop = parseInt(localStorage[fileIndex + ".editorScrollTop"]) || 0;
|
||||
this._editorStart = parseInt(localStorage[fileIndex + ".editorStart"]) || 0;
|
||||
this._editorEnd = parseInt(localStorage[fileIndex + ".editorEnd"]) || 0;
|
||||
this._previewScrollTop = parseInt(localStorage[fileIndex + ".previewScrollTop"]) || 0;
|
||||
this._selectTime = parseInt(localStorage[fileIndex + ".selectTime"]) || 0;
|
||||
this.syncLocations = syncLocations || {};
|
||||
this.publishLocations = publishLocations || {};
|
||||
Object.defineProperty(this, 'title', {
|
||||
get: function() {
|
||||
return this._title;
|
||||
},
|
||||
set: function(title) {
|
||||
this._title = title;
|
||||
localStorage[this.fileIndex + ".title"] = title;
|
||||
extensionMgr.onTitleChanged(this);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, 'content', {
|
||||
get: function() {
|
||||
return localStorage[this.fileIndex + ".content"];
|
||||
},
|
||||
set: function(content) {
|
||||
localStorage[this.fileIndex + ".content"] = content;
|
||||
extensionMgr.onContentChanged(this);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, 'editorScrollTop', {
|
||||
get: function() {
|
||||
return this._editorScrollTop;
|
||||
},
|
||||
set: function(editorScrollTop) {
|
||||
this._editorScrollTop = editorScrollTop;
|
||||
localStorage[this.fileIndex + ".editorScrollTop"] = editorScrollTop;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, 'editorStart', {
|
||||
get: function() {
|
||||
return this._editorStart;
|
||||
},
|
||||
set: function(editorStart) {
|
||||
this._editorStart = editorStart;
|
||||
localStorage[this.fileIndex + ".editorStart"] = editorStart;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, 'editorEnd', {
|
||||
get: function() {
|
||||
return this._editorEnd;
|
||||
},
|
||||
set: function(editorEnd) {
|
||||
this._editorEnd = editorEnd;
|
||||
localStorage[this.fileIndex + ".editorEnd"] = editorEnd;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, 'previewScrollTop', {
|
||||
get: function() {
|
||||
return this._previewScrollTop;
|
||||
},
|
||||
set: function(previewScrollTop) {
|
||||
this._previewScrollTop = previewScrollTop;
|
||||
localStorage[this.fileIndex + ".previewScrollTop"] = previewScrollTop;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, 'selectTime', {
|
||||
get: function() {
|
||||
return this._selectTime;
|
||||
},
|
||||
set: function(selectTime) {
|
||||
this._selectTime = selectTime;
|
||||
localStorage[this.fileIndex + ".selectTime"] = selectTime;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Retrieve file descriptors from localStorage and populate fileSystem
|
||||
_.each(utils.retrieveIndexArray("file.list"), function(fileIndex) {
|
||||
fileSystem[fileIndex] = new FileDescriptor(fileIndex, localStorage[fileIndex + ".title"]);
|
||||
});
|
||||
|
||||
// Defines the current file
|
||||
var currentFile = undefined;
|
||||
fileMgr.getCurrentFile = function() {
|
||||
@ -103,12 +22,6 @@ define([
|
||||
};
|
||||
fileMgr.setCurrentFile = function(fileDesc) {
|
||||
currentFile = fileDesc;
|
||||
if(fileDesc === undefined) {
|
||||
localStorage.removeItem("file.current");
|
||||
}
|
||||
else if(fileDesc.fileIndex != TEMPORARY_FILE_INDEX) {
|
||||
localStorage["file.current"] = fileDesc.fileIndex;
|
||||
}
|
||||
};
|
||||
|
||||
fileMgr.selectFile = function(fileDesc) {
|
||||
@ -116,17 +29,15 @@ define([
|
||||
|
||||
if(fileDesc === undefined) {
|
||||
var fileSystemSize = _.size(fileSystem);
|
||||
// If fileSystem empty create one file
|
||||
if(fileSystemSize === 0) {
|
||||
// If fileSystem empty create one file
|
||||
fileDesc = fileMgr.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
|
||||
}
|
||||
else {
|
||||
var fileIndex = localStorage["file.current"];
|
||||
// If no file is selected take the last created
|
||||
if(fileIndex === undefined) {
|
||||
fileIndex = _.keys(fileSystem)[fileSystemSize - 1];
|
||||
}
|
||||
fileDesc = fileSystem[fileIndex];
|
||||
// Select the last selected file
|
||||
fileDesc = _.max(fileSystem, function(fileDesc) {
|
||||
return fileDesc.selectTime || 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,6 +85,7 @@ define([
|
||||
// syncIndex associations
|
||||
syncLocations = syncLocations || {};
|
||||
var sync = _.reduce(syncLocations, function(sync, syncAttributes) {
|
||||
utils.storeAttributes(syncAttributes);
|
||||
return sync + syncAttributes.syncIndex + ";";
|
||||
}, ";");
|
||||
|
||||
@ -204,18 +116,18 @@ define([
|
||||
if(fileMgr.isCurrentFile(fileDesc) === true) {
|
||||
// Unset the current fileDesc
|
||||
fileMgr.setCurrentFile();
|
||||
// Refresh the editor with an other file
|
||||
// Refresh the editor with another file
|
||||
fileMgr.selectFile();
|
||||
}
|
||||
|
||||
// Remove synchronized locations
|
||||
// Remove synchronized locations from localStorage
|
||||
_.each(fileDesc.syncLocations, function(syncAttributes) {
|
||||
fileMgr.removeSync(syncAttributes);
|
||||
localStorage.removeItem(syncAttributes.syncIndex);
|
||||
});
|
||||
|
||||
// Remove publish locations
|
||||
// Remove publish locations from localStorage
|
||||
_.each(fileDesc.publishLocations, function(publishAttributes) {
|
||||
fileMgr.removePublish(publishAttributes);
|
||||
localStorage.removeItem(publishAttributes.publishIndex);
|
||||
});
|
||||
|
||||
localStorage.removeItem(fileDesc.fileIndex + ".title");
|
||||
@ -226,26 +138,6 @@ define([
|
||||
extensionMgr.onFileDeleted(fileDesc);
|
||||
};
|
||||
|
||||
// Add a synchronized location to a file
|
||||
fileMgr.addSync = function(fileDesc, syncAttributes) {
|
||||
utils.appendIndexToArray(fileDesc.fileIndex + ".sync", syncAttributes.syncIndex);
|
||||
fileDesc.syncLocations[syncAttributes.syncIndex] = syncAttributes;
|
||||
// addSync is only used for export, not for import
|
||||
extensionMgr.onSyncExportSuccess(fileDesc, syncAttributes);
|
||||
};
|
||||
|
||||
// Remove a synchronized location
|
||||
fileMgr.removeSync = function(syncAttributes) {
|
||||
var fileDesc = fileMgr.getFileFromSyncIndex(syncAttributes.syncIndex);
|
||||
if(fileDesc !== undefined) {
|
||||
utils.removeIndexFromArray(fileDesc.fileIndex + ".sync", syncAttributes.syncIndex);
|
||||
delete fileDesc.syncLocations[syncAttributes.syncIndex];
|
||||
extensionMgr.onSyncRemoved(fileDesc, syncAttributes);
|
||||
}
|
||||
// Remove sync attributes from localStorage
|
||||
localStorage.removeItem(syncAttributes.syncIndex);
|
||||
};
|
||||
|
||||
// Get the file descriptor associated to a syncIndex
|
||||
fileMgr.getFileFromSyncIndex = function(syncIndex) {
|
||||
return _.find(fileSystem, function(fileDesc) {
|
||||
@ -268,25 +160,6 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
// Add a publishIndex (publish location) to a file
|
||||
fileMgr.addPublish = function(fileDesc, publishAttributes) {
|
||||
utils.appendIndexToArray(fileDesc.fileIndex + ".publish", publishAttributes.publishIndex);
|
||||
fileDesc.publishLocations[publishAttributes.publishIndex] = publishAttributes;
|
||||
extensionMgr.onNewPublishSuccess(fileDesc, publishAttributes);
|
||||
};
|
||||
|
||||
// Remove a publishIndex (publish location)
|
||||
fileMgr.removePublish = function(publishAttributes) {
|
||||
var fileDesc = fileMgr.getFileFromPublishIndex(publishAttributes.publishIndex);
|
||||
if(fileDesc !== undefined) {
|
||||
utils.removeIndexFromArray(fileDesc.fileIndex + ".publish", publishAttributes.publishIndex);
|
||||
delete fileDesc.publishLocations[publishAttributes.publishIndex];
|
||||
extensionMgr.onPublishRemoved(fileDesc, publishAttributes);
|
||||
}
|
||||
// Remove publish attributes from localStorage
|
||||
localStorage.removeItem(publishAttributes.publishIndex);
|
||||
};
|
||||
|
||||
// Get the file descriptor associated to a publishIndex
|
||||
fileMgr.getFileFromPublishIndex = function(publishIndex) {
|
||||
return _.find(fileSystem, function(fileDesc) {
|
||||
@ -327,6 +200,7 @@ define([
|
||||
var fileDesc = fileMgr.getCurrentFile();
|
||||
if(title && title != fileDesc.title) {
|
||||
fileDesc.title = title;
|
||||
extensionMgr.onTitleChanged(fileDesc);
|
||||
}
|
||||
input.val(fileDesc.title);
|
||||
$("#wmd-input").focus();
|
||||
|
@ -1,3 +1,16 @@
|
||||
// The fileSystem module is empty when created. It's filled by fileMgr when loading.
|
||||
// syncLocations and publishLocations are respectively loaded by synchronizer and publisher.
|
||||
define({});
|
||||
define([
|
||||
"utils",
|
||||
"classes/FileDescriptor",
|
||||
"storage",
|
||||
], function(utils, FileDescriptor) {
|
||||
var fileSystem = {};
|
||||
|
||||
// Retrieve file descriptors from localStorage and populate fileSystem
|
||||
_.each(utils.retrieveIndexArray("file.list"), function(fileIndex) {
|
||||
fileSystem[fileIndex] = new FileDescriptor(fileIndex, localStorage[fileIndex + ".title"]);
|
||||
});
|
||||
|
||||
return fileSystem;
|
||||
});
|
@ -3,8 +3,8 @@ define([
|
||||
"underscore",
|
||||
"core",
|
||||
"extensionMgr",
|
||||
"asyncRunner"
|
||||
], function($, _, core, extensionMgr, asyncRunner) {
|
||||
"classes/AsyncTask"
|
||||
], function($, _, core, extensionMgr, AsyncTask) {
|
||||
|
||||
var client = undefined;
|
||||
var authenticated = false;
|
||||
@ -88,7 +88,7 @@ define([
|
||||
|
||||
dropboxHelper.upload = function(path, content, callback) {
|
||||
var result = undefined;
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -111,13 +111,13 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
dropboxHelper.checkChanges = function(lastChangeId, callback) {
|
||||
var changes = [];
|
||||
var newChangeId = lastChangeId || 0;
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -148,12 +148,12 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
dropboxHelper.downloadMetadata = function(paths, callback) {
|
||||
var result = [];
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -181,12 +181,12 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
dropboxHelper.downloadContent = function(objects, callback) {
|
||||
var result = [];
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -229,7 +229,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
function handleError(error, task) {
|
||||
@ -299,7 +299,7 @@ define([
|
||||
|
||||
dropboxHelper.picker = function(callback) {
|
||||
var paths = [];
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
// Add some time for user to choose his files
|
||||
task.timeout = ASYNC_TASK_LONG_TIMEOUT;
|
||||
connect(task);
|
||||
@ -328,7 +328,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
return dropboxHelper;
|
||||
|
@ -3,8 +3,8 @@ define([
|
||||
"core",
|
||||
"utils",
|
||||
"extensionMgr",
|
||||
"asyncRunner"
|
||||
], function($, core, utils, extensionMgr, asyncRunner) {
|
||||
"classes/AsyncTask"
|
||||
], function($, core, utils, extensionMgr, AsyncTask) {
|
||||
|
||||
var connected = undefined;
|
||||
var github = undefined;
|
||||
@ -111,7 +111,7 @@ define([
|
||||
}
|
||||
|
||||
githubHelper.upload = function(reponame, branch, path, content, commitMsg, callback) {
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -145,11 +145,11 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
githubHelper.uploadGist = function(gistId, filename, isPublic, title, content, callback) {
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -185,11 +185,11 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
githubHelper.downloadGist = function(gistId, filename, callback) {
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
// No need for authentication
|
||||
var title = undefined;
|
||||
@ -219,7 +219,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
function handleError(error, task) {
|
||||
|
@ -3,8 +3,8 @@ define([
|
||||
"core",
|
||||
"utils",
|
||||
"extensionMgr",
|
||||
"asyncRunner"
|
||||
], function($, core, utils, extensionMgr, asyncRunner) {
|
||||
"classes/AsyncTask"
|
||||
], function($, core, utils, extensionMgr, AsyncTask) {
|
||||
|
||||
var connected = false;
|
||||
var authenticated = false;
|
||||
@ -86,7 +86,7 @@ define([
|
||||
|
||||
googleHelper.upload = function(fileId, parentId, title, content, etag, callback) {
|
||||
var result = undefined;
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -164,13 +164,13 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
googleHelper.checkChanges = function(lastChangeId, callback) {
|
||||
var changes = [];
|
||||
var newChangeId = lastChangeId || 0;
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -216,12 +216,12 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
googleHelper.downloadMetadata = function(ids, callback, skipAuth) {
|
||||
var result = [];
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
if(!skipAuth) {
|
||||
authenticate(task);
|
||||
@ -270,12 +270,12 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
googleHelper.downloadContent = function(objects, callback, skipAuth) {
|
||||
var result = [];
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
// Add some time for user to choose his files
|
||||
task.timeout = ASYNC_TASK_LONG_TIMEOUT;
|
||||
connect(task);
|
||||
@ -338,7 +338,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
function handleError(error, task) {
|
||||
@ -389,7 +389,9 @@ define([
|
||||
timeout: AJAX_TIMEOUT
|
||||
}).done(function() {
|
||||
google.load('picker', '1', {
|
||||
callback: task.chain
|
||||
callback: function() {
|
||||
task.chain();
|
||||
}
|
||||
});
|
||||
pickerLoaded = true;
|
||||
}).fail(function(jqXHR) {
|
||||
@ -411,7 +413,7 @@ define([
|
||||
$(".modal-backdrop, .picker").remove();
|
||||
}
|
||||
}
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
loadPicker(task);
|
||||
task.onRun(function() {
|
||||
@ -451,11 +453,11 @@ define([
|
||||
hidePicker();
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
googleHelper.uploadBlogger = function(blogUrl, blogId, postId, labelList, title, content, callback) {
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -541,7 +543,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
return googleHelper;
|
||||
|
@ -1,8 +1,8 @@
|
||||
define([
|
||||
"jquery",
|
||||
"core",
|
||||
"asyncRunner"
|
||||
], function($, core, asyncRunner) {
|
||||
"classes/AsyncTask"
|
||||
], function($, core, AsyncTask) {
|
||||
|
||||
var sshHelper = {};
|
||||
|
||||
@ -18,7 +18,7 @@ define([
|
||||
}
|
||||
|
||||
sshHelper.upload = function(host, port, username, password, path, title, content, callback) {
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
task.onRun(function() {
|
||||
var url = SSH_PROXY_URL + "upload";
|
||||
@ -57,7 +57,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
function handleError(error, task) {
|
||||
|
@ -3,8 +3,8 @@ define([
|
||||
"core",
|
||||
"utils",
|
||||
"extensionMgr",
|
||||
"asyncRunner"
|
||||
], function($, core, utils, extensionMgr, asyncRunner) {
|
||||
"classes/AsyncTask"
|
||||
], function($, core, utils, extensionMgr, AsyncTask) {
|
||||
|
||||
var oauthParams = undefined;
|
||||
|
||||
@ -96,7 +96,7 @@ define([
|
||||
}
|
||||
|
||||
tumblrHelper.upload = function(blogHostname, postId, tags, format, title, content, callback) {
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -135,7 +135,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
function handleError(error, task) {
|
||||
|
@ -3,8 +3,8 @@ define([
|
||||
"core",
|
||||
"utils",
|
||||
"extensionMgr",
|
||||
"asyncRunner"
|
||||
], function($, core, utils, extensionMgr, asyncRunner) {
|
||||
"classes/AsyncTask"
|
||||
], function($, core, utils, extensionMgr, AsyncTask) {
|
||||
|
||||
var token = undefined;
|
||||
|
||||
@ -80,7 +80,7 @@ define([
|
||||
}
|
||||
|
||||
wordpressHelper.upload = function(site, postId, tags, title, content, callback) {
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
connect(task);
|
||||
authenticate(task);
|
||||
task.onRun(function() {
|
||||
@ -133,7 +133,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
function handleError(error, task) {
|
||||
|
@ -1,53 +1,43 @@
|
||||
<blockquote>StackEdit is a free, open-source Markdown
|
||||
editor based on PageDown, the Markdown library used by Stack Overflow
|
||||
and the other Stack Exchange sites.</blockquote>
|
||||
|
||||
<dl>
|
||||
<dt>About:</dt>
|
||||
<dd>
|
||||
<a target="_blank" href="https://github.com/benweet/stackedit/">GitHub
|
||||
project</a> / <a target="_blank"
|
||||
href="https://github.com/benweet/stackedit/issues">issue tracker</a>
|
||||
</dd>
|
||||
<dd>
|
||||
href="https://github.com/benweet/stackedit/issues">issue tracker</a><br />
|
||||
<a target="_blank"
|
||||
href="https://chrome.google.com/webstore/detail/stackedit/iiooodelglhkcpgbajoejffhijaclcdg">Chrome
|
||||
app</a> (thanks for your review!)
|
||||
</dd>
|
||||
<dd>
|
||||
<a target="_blank" href="https://twitter.com/stackedit/">Follow on
|
||||
Twitter</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a target="_blank" href="https://www.facebook.com/stackedit/">Follow
|
||||
on Facebook</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a target="_blank"
|
||||
app</a> (thanks for your review!)<br /> <a target="_blank"
|
||||
href="https://twitter.com/stackedit/">Follow on Twitter</a><br /> <a
|
||||
target="_blank" href="https://www.facebook.com/stackedit/">Follow
|
||||
on Facebook</a><br /> <a target="_blank"
|
||||
href="https://plus.google.com/110816046787593496375" rel="publisher">Follow
|
||||
on Google+</a>
|
||||
on Google+</a><br />
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Developers:</dt>
|
||||
<dd>
|
||||
<a target="_blank" href="http://www.benoitschweblin.com">Benoit
|
||||
Schweblin</a><br />
|
||||
Schweblin</a><br /> Pete Eigel (contributor)
|
||||
</dd>
|
||||
<dd>Pete Eigel (contributor)</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Credit:</dt>
|
||||
<% _.each(libraries, function(url, name) { %>
|
||||
<dd>
|
||||
<a target="_blank" href="<%= url %>"><%= name %></a>
|
||||
<% _.each(libraries, function(url, name) { %> <a target="_blank"
|
||||
href="<%= url %>"><%= name %></a><br /> <% }); %>
|
||||
</dd>
|
||||
<% }); %>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>Related projects:</dt>
|
||||
<% _.each(projects, function(url, name) { %>
|
||||
<dd>
|
||||
<a target="_blank" href="<%= url %>"><%= name %></a>
|
||||
<% _.each(projects, function(url, name) { %> <a target="_blank"
|
||||
href="<%= url %>"><%= name %></a><br /> <% }); %>
|
||||
</dd>
|
||||
<% }); %>
|
||||
</dl>
|
||||
<p>Copyright 2013 <a target="_blank"
|
||||
href="http://www.benoitschweblin.com">Benoit Schweblin</a><br />
|
||||
|
@ -6,6 +6,7 @@ requirejs.config({
|
||||
"underscore": "libs/underscore",
|
||||
"jgrowl": "libs/jgrowl",
|
||||
"mousetrap": "libs/mousetrap",
|
||||
"toMarkdown": "libs/to-markdown",
|
||||
"text": "libs/text",
|
||||
"libs/MathJax": '../lib/MathJax/MathJax.js?config=TeX-AMS_HTML'
|
||||
},
|
||||
@ -22,6 +23,12 @@ requirejs.config({
|
||||
'mousetrap': {
|
||||
exports: 'Mousetrap'
|
||||
},
|
||||
'toMarkdown': {
|
||||
deps: [
|
||||
'jquery'
|
||||
],
|
||||
exports: 'toMarkdown'
|
||||
},
|
||||
'libs/jquery-ui': [
|
||||
'jquery'
|
||||
],
|
||||
|
@ -1,8 +1,8 @@
|
||||
define([
|
||||
"jquery",
|
||||
"core",
|
||||
"asyncRunner"
|
||||
], function($, core, asyncRunner) {
|
||||
"classes/AsyncTask"
|
||||
], function($, core, AsyncTask) {
|
||||
|
||||
var PROVIDER_DOWNLOAD = "download";
|
||||
|
||||
@ -14,9 +14,9 @@ define([
|
||||
};
|
||||
|
||||
downloadProvider.importPublic = function(importParameters, callback) {
|
||||
var task = asyncRunner.createTask();
|
||||
var title = undefined;
|
||||
var content = undefined;
|
||||
var task = new AsyncTask();
|
||||
task.onRun(function() {
|
||||
var url = importParameters.url;
|
||||
var slashUrl = url.lastIndexOf("/");
|
||||
@ -43,7 +43,7 @@ define([
|
||||
task.onError(function(error) {
|
||||
callback(error);
|
||||
});
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
return downloadProvider;
|
||||
|
@ -39,7 +39,6 @@ define([
|
||||
syncAttributes.version = versionTag;
|
||||
syncAttributes.contentCRC = utils.crc32(content);
|
||||
syncAttributes.syncIndex = createSyncIndex(path);
|
||||
utils.storeAttributes(syncAttributes);
|
||||
return syncAttributes;
|
||||
}
|
||||
|
||||
@ -184,7 +183,8 @@ define([
|
||||
// File deleted
|
||||
if(change.wasRemoved === true) {
|
||||
extensionMgr.onError('"' + localTitle + '" has been removed from Dropbox.');
|
||||
fileMgr.removeSync(syncAttributes);
|
||||
fileDesc.removeSyncLocation(syncAttributes);
|
||||
extensionMgr.onSyncRemoved(fileDesc, syncAttributes);
|
||||
return;
|
||||
}
|
||||
var localContent = fileDesc.content;
|
||||
@ -201,6 +201,7 @@ define([
|
||||
// If file content changed
|
||||
if(fileContentChanged && remoteContentChanged === true) {
|
||||
fileDesc.content = file.content;
|
||||
extensionMgr.onContentChanged(fileDesc);
|
||||
extensionMgr.onMessage('"' + localTitle + '" has been updated from Dropbox.');
|
||||
if(fileMgr.isCurrentFile(fileDesc)) {
|
||||
fileMgr.selectFile(); // Refresh editor
|
||||
|
@ -31,7 +31,6 @@ define([
|
||||
syncAttributes.contentCRC = utils.crc32(content);
|
||||
syncAttributes.titleCRC = utils.crc32(title);
|
||||
syncAttributes.syncIndex = createSyncIndex(id);
|
||||
utils.storeAttributes(syncAttributes);
|
||||
return syncAttributes;
|
||||
}
|
||||
|
||||
@ -179,7 +178,8 @@ define([
|
||||
// File deleted
|
||||
if(change.deleted === true) {
|
||||
extensionMgr.onError('"' + localTitle + '" has been removed from Google Drive.');
|
||||
fileMgr.removeSync(syncAttributes);
|
||||
fileDesc.removeSyncLocation(syncAttributes);
|
||||
extensionMgr.onSyncRemoved(fileDesc, syncAttributes);
|
||||
return;
|
||||
}
|
||||
var localTitleChanged = syncAttributes.titleCRC != utils.crc32(localTitle);
|
||||
@ -200,11 +200,13 @@ define([
|
||||
// If file title changed
|
||||
if(fileTitleChanged && remoteTitleChanged === true) {
|
||||
fileDesc.title = file.title;
|
||||
extensionMgr.onTitleChanged(fileDesc);
|
||||
extensionMgr.onMessage('"' + localTitle + '" has been renamed to "' + file.title + '" on Google Drive.');
|
||||
}
|
||||
// If file content changed
|
||||
if(fileContentChanged && remoteContentChanged === true) {
|
||||
fileDesc.content = file.content;
|
||||
extensionMgr.onContentChanged(fileDesc);
|
||||
extensionMgr.onMessage('"' + file.title + '" has been updated from Google Drive.');
|
||||
if(fileMgr.isCurrentFile(fileDesc)) {
|
||||
fileMgr.selectFile(); // Refresh editor
|
||||
|
@ -54,41 +54,41 @@ define([
|
||||
});
|
||||
|
||||
// Apply template to the current document
|
||||
publisher.applyTemplate = function(publishAttributes) {
|
||||
var fileDesc = fileMgr.getCurrentFile();
|
||||
publisher.applyTemplate = function(fileDesc, publishAttributes, html) {
|
||||
try {
|
||||
return _.template(settings.template, {
|
||||
documentTitle: fileDesc.title,
|
||||
documentMarkdown: $("#wmd-input").val(),
|
||||
documentHTML: $("#wmd-preview").html(),
|
||||
documentMarkdown: fileDesc.content,
|
||||
documentHTML: html,
|
||||
publishAttributes: publishAttributes
|
||||
});
|
||||
}
|
||||
catch(e) {
|
||||
extensionMgr.onError(e);
|
||||
throw e;
|
||||
return e.message;
|
||||
}
|
||||
};
|
||||
|
||||
// Used to get content to publish
|
||||
function getPublishContent(publishAttributes) {
|
||||
function getPublishContent(fileDesc, publishAttributes, html) {
|
||||
if(publishAttributes.format === undefined) {
|
||||
publishAttributes.format = $("input:radio[name=radio-publish-format]:checked").prop("value");
|
||||
}
|
||||
if(publishAttributes.format == "markdown") {
|
||||
return $("#wmd-input").val();
|
||||
return fileDesc.content;
|
||||
}
|
||||
else if(publishAttributes.format == "html") {
|
||||
return $("#wmd-preview").html();
|
||||
return html;
|
||||
}
|
||||
else {
|
||||
return publisher.applyTemplate(publishAttributes);
|
||||
return publisher.applyTemplate(fileDesc, publishAttributes, html);
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive function to publish a file on multiple locations
|
||||
var publishAttributesList = [];
|
||||
var publishTitle = undefined;
|
||||
var publishFileDesc = undefined;
|
||||
var publishHTML = undefined;
|
||||
function publishLocation(callback, errorFlag) {
|
||||
|
||||
// No more publish location for this document
|
||||
@ -99,14 +99,17 @@ define([
|
||||
|
||||
// Dequeue a synchronized location
|
||||
var publishAttributes = publishAttributesList.pop();
|
||||
var content = getPublishContent(publishAttributes);
|
||||
|
||||
// Format the content
|
||||
var content = getPublishContent(publishFileDesc, publishAttributes, publishHTML);
|
||||
|
||||
// Call the provider
|
||||
publishAttributes.provider.publish(publishAttributes, publishTitle, content, function(error) {
|
||||
publishAttributes.provider.publish(publishAttributes, publishFileDesc.title, content, function(error) {
|
||||
if(error !== undefined) {
|
||||
var errorMsg = error.toString();
|
||||
if(errorMsg.indexOf("|removePublish") !== -1) {
|
||||
fileMgr.removePublish(publishAttributes);
|
||||
publishFileDesc.removePublishLocation(publishAttributes);
|
||||
extensionMgr.onPublishRemoved(publishFileDesc, publishAttributes);
|
||||
}
|
||||
if(errorMsg.indexOf("|stopPublish") !== -1) {
|
||||
callback(error);
|
||||
@ -126,14 +129,14 @@ define([
|
||||
|
||||
publishRunning = true;
|
||||
extensionMgr.onPublishRunning(true);
|
||||
var fileDesc = fileMgr.getCurrentFile();
|
||||
publishTitle = fileDesc.title;
|
||||
publishAttributesList = _.values(fileDesc.publishLocations);
|
||||
publishFileDesc = fileMgr.getCurrentFile();
|
||||
publishHTML = $("#wmd-preview").html();
|
||||
publishAttributesList = _.values(publishFileDesc.publishLocations);
|
||||
publishLocation(function(errorFlag) {
|
||||
publishRunning = false;
|
||||
extensionMgr.onPublishRunning(false);
|
||||
if(errorFlag === undefined) {
|
||||
extensionMgr.onPublishSuccess(fileDesc);
|
||||
extensionMgr.onPublishSuccess(publishFileDesc);
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -145,8 +148,8 @@ define([
|
||||
publishIndex = "publish." + utils.randomString();
|
||||
} while (_.has(localStorage, publishIndex));
|
||||
publishAttributes.publishIndex = publishIndex;
|
||||
utils.storeAttributes(publishAttributes);
|
||||
fileMgr.addPublish(fileDesc, publishAttributes);
|
||||
fileDesc.addPublishLocation(publishAttributes);
|
||||
extensionMgr.onNewPublishSuccess(fileDesc, publishAttributes);
|
||||
}
|
||||
|
||||
// Initialize the "New publication" dialog
|
||||
@ -186,9 +189,9 @@ define([
|
||||
|
||||
// Perform provider's publishing
|
||||
var fileDesc = fileMgr.getCurrentFile();
|
||||
var title = fileDesc.title;
|
||||
var content = getPublishContent(publishAttributes);
|
||||
provider.publish(publishAttributes, title, content, function(error) {
|
||||
var html = $("#wmd-preview").html();
|
||||
var content = getPublishContent(fileDesc, publishAttributes, html);
|
||||
provider.publish(publishAttributes, fileDesc.title, content, function(error) {
|
||||
if(error === undefined) {
|
||||
publishAttributes.provider = provider;
|
||||
sharing.createLink(publishAttributes, function() {
|
||||
@ -235,9 +238,10 @@ define([
|
||||
utils.saveAs(content, title + ".html");
|
||||
});
|
||||
$(".action-download-template").click(function() {
|
||||
var content = publisher.applyTemplate();
|
||||
var title = fileMgr.getCurrentFile().title;
|
||||
utils.saveAs(content, title + (settings.template.indexOf("documentHTML") === -1 ? ".md" : ".html"));
|
||||
var fileDesc = fileMgr.getCurrentFile();
|
||||
var html = $("#wmd-preview").html();
|
||||
var content = publisher.applyTemplate(fileDesc, undefined, html);
|
||||
utils.saveAs(content, fileDesc.title + (settings.template.indexOf("documentHTML") === -1 ? ".md" : ".html"));
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -5,10 +5,10 @@ define([
|
||||
"utils",
|
||||
"extensionMgr",
|
||||
"fileMgr",
|
||||
"asyncRunner",
|
||||
"classes/AsyncTask",
|
||||
"providers/downloadProvider",
|
||||
"providers/gistProvider"
|
||||
], function($, _, core, utils, extensionMgr, fileMgr, asyncRunner) {
|
||||
], function($, _, core, utils, extensionMgr, fileMgr, AsyncTask) {
|
||||
|
||||
var sharing = {};
|
||||
|
||||
@ -30,7 +30,7 @@ define([
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
var task = asyncRunner.createTask();
|
||||
var task = new AsyncTask();
|
||||
var shortUrl = undefined;
|
||||
task.onRun(function() {
|
||||
if(core.isOffline === true) {
|
||||
@ -69,7 +69,7 @@ define([
|
||||
}
|
||||
task.onSuccess(onFinish);
|
||||
task.onError(onFinish);
|
||||
asyncRunner.addTask(task);
|
||||
task.enqueue();
|
||||
};
|
||||
|
||||
core.onReady(function() {
|
||||
|
@ -120,6 +120,16 @@ define([
|
||||
});
|
||||
version = "v6";
|
||||
}
|
||||
|
||||
// Upgrade from v6 to v7
|
||||
if(version == "v6") {
|
||||
var currentFileIndex = localStorage["file.current"];
|
||||
if(currentFileIndex !== undefined) {
|
||||
localStorage[currentFileIndex + ".selectTime"] = new Date().getTime();
|
||||
localStorage.removeItem("file.current");
|
||||
}
|
||||
version = "v7";
|
||||
}
|
||||
|
||||
localStorage["version"] = version;
|
||||
});
|
@ -223,7 +223,8 @@ define([
|
||||
if(error) {
|
||||
return;
|
||||
}
|
||||
fileMgr.addSync(fileDesc, syncAttributes);
|
||||
fileDesc.addSyncLocation(syncAttributes);
|
||||
extensionMgr.onSyncExportSuccess(fileDesc, syncAttributes);
|
||||
});
|
||||
|
||||
// Store input values as preferences for next time we open the
|
||||
@ -241,7 +242,8 @@ define([
|
||||
if(error) {
|
||||
return;
|
||||
}
|
||||
fileMgr.addSync(fileDesc, syncAttributes);
|
||||
fileDesc.addSyncLocation(syncAttributes);
|
||||
extensionMgr.onSyncExportSuccess(fileDesc, syncAttributes);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user