New extension pattern
This commit is contained in:
parent
569a52ca21
commit
a7a5defbc7
@ -174,6 +174,31 @@ input[readonly], select[readonly], textarea[readonly] {
|
|||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#extension-buttons {
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#extension-buttons > .btn-group {
|
||||||
|
margin: 5px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#extension-buttons > .btn-group > .btn {
|
||||||
|
-webkit-border-radius: 0;
|
||||||
|
-moz-border-radius: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
#extension-buttons > .btn-group:first-child > .btn {
|
||||||
|
-webkit-border-radius: 4px 0 0 4px;
|
||||||
|
-moz-border-radius: 4px 0 0 4px;
|
||||||
|
border-radius: 4px 0 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#extension-buttons > .btn-group:last-child > .btn {
|
||||||
|
-webkit-border-radius: 0 4px 4px 0;
|
||||||
|
-moz-border-radius: 0 4px 4px 0;
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
.btn-group > .btn + .dropdown-toggle {
|
.btn-group > .btn + .dropdown-toggle {
|
||||||
padding-right: 12px;
|
padding-right: 12px;
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
@ -405,7 +430,7 @@ div.dropdown-menu i {
|
|||||||
width: 43px;
|
width: 43px;
|
||||||
height: 11px;
|
height: 11px;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
margin: 14px 15px 0;
|
margin: 16px 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.working-indicator.show {
|
.working-indicator.show {
|
||||||
|
26
index.html
26
index.html
@ -34,31 +34,7 @@
|
|||||||
<li><div id="wmd-button-bar"></div></li>
|
<li><div id="wmd-button-bar"></div></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav pull-right hide" id="menu-bar">
|
<ul class="nav pull-right hide" id="menu-bar">
|
||||||
<li class="btn-group">
|
<li id="extension-buttons">
|
||||||
<button class="btn action-force-sync"
|
|
||||||
title="Synchronize all documents">
|
|
||||||
<i class="icon-refresh"></i>
|
|
||||||
</button>
|
|
||||||
<button class="btn action-force-publish"
|
|
||||||
title="Publish this document">
|
|
||||||
<i class="icon-share"></i>
|
|
||||||
</button>
|
|
||||||
<button class="btn dropdown-toggle" data-toggle="dropdown"
|
|
||||||
title="Share this document">
|
|
||||||
<i class="icon-link"></i>
|
|
||||||
</button>
|
|
||||||
<div id="link-container" class="dropdown-menu">
|
|
||||||
<div class="link-list"></div>
|
|
||||||
<p class="no-link">To share this document you need first to <a
|
|
||||||
href="#" class="action-publish-gist">publish it as a Gist</a> in
|
|
||||||
Markdown format.
|
|
||||||
</p>
|
|
||||||
<blockquote class="muted">
|
|
||||||
<b>NOTE:</b> You can open any URL within StackEdit using <a
|
|
||||||
href="viewer.html?url=https://raw.github.com/benweet/stackedit/master/README.md"
|
|
||||||
title="Sharing example">viewer.html?url=...</a>
|
|
||||||
</blockquote>
|
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
<li class="btn-group"><button class="btn action-create-file"
|
<li class="btn-group"><button class="btn action-create-file"
|
||||||
title="New local document">
|
title="New local document">
|
||||||
|
@ -12,6 +12,7 @@ define([
|
|||||||
var asyncRunner = {};
|
var asyncRunner = {};
|
||||||
|
|
||||||
var taskQueue = [];
|
var taskQueue = [];
|
||||||
|
var asyncRunning = false;
|
||||||
var currentTask = undefined;
|
var currentTask = undefined;
|
||||||
var currentTaskRunning = false;
|
var currentTaskRunning = false;
|
||||||
var currentTaskStartTime = 0;
|
var currentTaskStartTime = 0;
|
||||||
@ -137,7 +138,10 @@ define([
|
|||||||
// Dequeue an enqueued task
|
// Dequeue an enqueued task
|
||||||
currentTask = taskQueue.shift();
|
currentTask = taskQueue.shift();
|
||||||
currentTaskStartTime = utils.currentTime;
|
currentTaskStartTime = utils.currentTime;
|
||||||
extensionMgr.onAsyncRunning(true);
|
if(asyncRunning === false) {
|
||||||
|
asyncRunning = true;
|
||||||
|
extensionMgr.onAsyncRunning(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the task
|
// Run the task
|
||||||
@ -155,13 +159,15 @@ define([
|
|||||||
_.each(callbacks, function(callback) {
|
_.each(callbacks, function(callback) {
|
||||||
callback(param);
|
callback(param);
|
||||||
});
|
});
|
||||||
} finally {
|
}
|
||||||
|
finally {
|
||||||
task.finished = true;
|
task.finished = true;
|
||||||
if (currentTask === task) {
|
if (currentTask === task) {
|
||||||
currentTask = undefined;
|
currentTask = undefined;
|
||||||
currentTaskRunning = false;
|
currentTaskRunning = false;
|
||||||
}
|
}
|
||||||
if (taskQueue.length === 0) {
|
if (taskQueue.length === 0) {
|
||||||
|
asyncRunning = false;
|
||||||
extensionMgr.onAsyncRunning(false);
|
extensionMgr.onAsyncRunning(false);
|
||||||
} else {
|
} else {
|
||||||
asyncRunner.runTask();
|
asyncRunner.runTask();
|
||||||
|
@ -261,8 +261,8 @@ define([
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
extensionMgr.onEditorConfigure(editor);
|
|
||||||
editor.hooks.chain("onPreviewRefresh", extensionMgr.onAsyncPreview);
|
editor.hooks.chain("onPreviewRefresh", extensionMgr.onAsyncPreview);
|
||||||
|
extensionMgr.onEditorConfigure(editor);
|
||||||
|
|
||||||
$("#wmd-input, #wmd-preview").scrollTop(0);
|
$("#wmd-input, #wmd-preview").scrollTop(0);
|
||||||
$("#wmd-button-bar").empty();
|
$("#wmd-button-bar").empty();
|
||||||
|
@ -230,7 +230,7 @@ define([
|
|||||||
function handleError(error, task) {
|
function handleError(error, task) {
|
||||||
var errorMsg = true;
|
var errorMsg = true;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
// Try to analyze the error
|
// Try to analyze the error
|
||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
errorMsg = error;
|
errorMsg = error;
|
||||||
|
@ -39,6 +39,7 @@ define([
|
|||||||
syncAttributes.version = versionTag;
|
syncAttributes.version = versionTag;
|
||||||
syncAttributes.contentCRC = utils.crc32(content);
|
syncAttributes.contentCRC = utils.crc32(content);
|
||||||
syncAttributes.syncIndex = createSyncIndex(path);
|
syncAttributes.syncIndex = createSyncIndex(path);
|
||||||
|
utils.storeAttributes(syncAttributes);
|
||||||
return syncAttributes;
|
return syncAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +55,6 @@ define([
|
|||||||
var fileDescList = [];
|
var fileDescList = [];
|
||||||
_.each(result, function(file) {
|
_.each(result, function(file) {
|
||||||
var syncAttributes = createSyncAttributes(file.path, file.versionTag, file.content);
|
var syncAttributes = createSyncAttributes(file.path, file.versionTag, file.content);
|
||||||
localStorage[syncAttributes.syncIndex] = utils.serializeAttributes(syncAttributes);
|
|
||||||
var syncLocations = {};
|
var syncLocations = {};
|
||||||
syncLocations[syncAttributes.syncIndex] = syncAttributes;
|
syncLocations[syncAttributes.syncIndex] = syncAttributes;
|
||||||
var fileDesc = fileMgr.createFile(file.name, file.content, syncLocations);
|
var fileDesc = fileMgr.createFile(file.name, file.content, syncLocations);
|
||||||
@ -106,7 +106,6 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var syncAttributes = createSyncAttributes(result.path, result.versionTag, content);
|
var syncAttributes = createSyncAttributes(result.path, result.versionTag, content);
|
||||||
localStorage[syncAttributes.syncIndex] = utils.serializeAttributes(syncAttributes);
|
|
||||||
callback(undefined, syncAttributes);
|
callback(undefined, syncAttributes);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -185,7 +184,7 @@ define([
|
|||||||
fileMgr.removeSync(syncAttributes);
|
fileMgr.removeSync(syncAttributes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var localContent = localStorage[fileDesc.fileIndex + ".content"];
|
var localContent = fileDesc.getContent();
|
||||||
var localContentChanged = syncAttributes.contentCRC != utils.crc32(localContent);
|
var localContentChanged = syncAttributes.contentCRC != utils.crc32(localContent);
|
||||||
var file = change.stat;
|
var file = change.stat;
|
||||||
var remoteContentCRC = utils.crc32(file.content);
|
var remoteContentCRC = utils.crc32(file.content);
|
||||||
@ -193,13 +192,12 @@ define([
|
|||||||
var fileContentChanged = localContent != file.content;
|
var fileContentChanged = localContent != file.content;
|
||||||
// Conflict detection
|
// Conflict detection
|
||||||
if (fileContentChanged === true && localContentChanged === true && remoteContentChanged === true) {
|
if (fileContentChanged === true && localContentChanged === true && remoteContentChanged === true) {
|
||||||
var backupFileDesc = fileMgr.createFile(localTitle + " (backup)", localContent);
|
fileMgr.createFile(localTitle + " (backup)", localContent);
|
||||||
extensionMgr.onTitleChanged(backupFileDesc);
|
|
||||||
extensionMgr.onMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.');
|
extensionMgr.onMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.');
|
||||||
}
|
}
|
||||||
// If file content changed
|
// If file content changed
|
||||||
if(fileContentChanged && remoteContentChanged === true) {
|
if(fileContentChanged && remoteContentChanged === true) {
|
||||||
localStorage[fileDesc.fileIndex + ".content"] = file.content;
|
fileDesc.setContent(file.content);
|
||||||
extensionMgr.onMessage('"' + localTitle + '" has been updated from Dropbox.');
|
extensionMgr.onMessage('"' + localTitle + '" has been updated from Dropbox.');
|
||||||
if(fileMgr.isCurrentFile(fileDesc)) {
|
if(fileMgr.isCurrentFile(fileDesc)) {
|
||||||
fileMgr.selectFile(); // Refresh editor
|
fileMgr.selectFile(); // Refresh editor
|
||||||
@ -208,7 +206,7 @@ define([
|
|||||||
// Update syncAttributes
|
// Update syncAttributes
|
||||||
syncAttributes.version = file.versionTag;
|
syncAttributes.version = file.versionTag;
|
||||||
syncAttributes.contentCRC = remoteContentCRC;
|
syncAttributes.contentCRC = remoteContentCRC;
|
||||||
localStorage[syncIndex] = utils.serializeAttributes(syncAttributes);
|
utils.storeAttributes(syncAttributes);
|
||||||
});
|
});
|
||||||
localStorage[PROVIDER_DROPBOX + ".lastChangeId"] = newChangeId;
|
localStorage[PROVIDER_DROPBOX + ".lastChangeId"] = newChangeId;
|
||||||
callback();
|
callback();
|
||||||
|
@ -3,9 +3,9 @@ define( [
|
|||||||
"underscore",
|
"underscore",
|
||||||
"utils",
|
"utils",
|
||||||
"settings",
|
"settings",
|
||||||
|
"extensions/button-sync",
|
||||||
"extensions/button-publish",
|
"extensions/button-publish",
|
||||||
"extensions/button-share",
|
"extensions/button-share",
|
||||||
"extensions/button-sync",
|
|
||||||
"extensions/document-selector",
|
"extensions/document-selector",
|
||||||
"extensions/document-title",
|
"extensions/document-title",
|
||||||
"extensions/manage-publication",
|
"extensions/manage-publication",
|
||||||
@ -42,7 +42,7 @@ define( [
|
|||||||
function createHook(hookName) {
|
function createHook(hookName) {
|
||||||
var callbackList = getExtensionCallbackList(hookName);
|
var callbackList = getExtensionCallbackList(hookName);
|
||||||
return function() {
|
return function() {
|
||||||
console.debug(hookName);
|
logger.debug(hookName, arguments);
|
||||||
var callbackArguments = arguments;
|
var callbackArguments = arguments;
|
||||||
_.each(callbackList, function(callback) {
|
_.each(callbackList, function(callback) {
|
||||||
callback.apply(null, callbackArguments);
|
callback.apply(null, callbackArguments);
|
||||||
@ -64,7 +64,7 @@ define( [
|
|||||||
|
|
||||||
// Load/Save extension config from/to settings
|
// Load/Save extension config from/to settings
|
||||||
extensionMgr["onLoadSettings"] = function() {
|
extensionMgr["onLoadSettings"] = function() {
|
||||||
console.debug("onLoadSettings");
|
logger.debug("onLoadSettings");
|
||||||
_.each(extensionList, function(extension) {
|
_.each(extensionList, function(extension) {
|
||||||
utils.setInputChecked("#input-enable-extension-" + extension.extensionId, extension.config.enabled);
|
utils.setInputChecked("#input-enable-extension-" + extension.extensionId, extension.config.enabled);
|
||||||
var onLoadSettingsCallback = extension.onLoadSettings;
|
var onLoadSettingsCallback = extension.onLoadSettings;
|
||||||
@ -72,7 +72,7 @@ define( [
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
extensionMgr["onSaveSettings"] = function(newExtensionSettings, event) {
|
extensionMgr["onSaveSettings"] = function(newExtensionSettings, event) {
|
||||||
console.debug("onSaveSettings");
|
logger.debug("onSaveSettings");
|
||||||
_.each(extensionList, function(extension) {
|
_.each(extensionList, function(extension) {
|
||||||
var newExtensionConfig = extension.defaultConfig || {};
|
var newExtensionConfig = extension.defaultConfig || {};
|
||||||
newExtensionConfig.enabled = utils.getInputChecked("#input-enable-extension-" + extension.extensionId);
|
newExtensionConfig.enabled = utils.getInputChecked("#input-enable-extension-" + extension.extensionId);
|
||||||
@ -88,17 +88,16 @@ define( [
|
|||||||
addHook("onOfflineChanged");
|
addHook("onOfflineChanged");
|
||||||
addHook("onAsyncRunning");
|
addHook("onAsyncRunning");
|
||||||
|
|
||||||
// To store reference to modules that are accessible from extensions
|
// To access modules that are loaded after extensions
|
||||||
addHook("onFileMgrCreated");
|
addHook("onFileMgrCreated");
|
||||||
addHook("onSynchronizerCreated");
|
addHook("onSynchronizerCreated");
|
||||||
addHook("onPublisherCreated");
|
addHook("onPublisherCreated");
|
||||||
|
|
||||||
// Operations on files
|
// Operations on files
|
||||||
addHook("onFileSystemCreated");
|
|
||||||
addHook("onFileCreated");
|
addHook("onFileCreated");
|
||||||
addHook("onFileDeleted");
|
addHook("onFileDeleted");
|
||||||
addHook("onFileChanged");
|
|
||||||
addHook("onFileSelected");
|
addHook("onFileSelected");
|
||||||
|
addHook("onContentChanged");
|
||||||
addHook("onTitleChanged");
|
addHook("onTitleChanged");
|
||||||
|
|
||||||
// Sync events
|
// Sync events
|
||||||
@ -124,7 +123,7 @@ define( [
|
|||||||
var onPreviewFinished = createHook("onPreviewFinished");
|
var onPreviewFinished = createHook("onPreviewFinished");
|
||||||
var onAsyncPreviewCallbackList = getExtensionCallbackList("onAsyncPreview");
|
var onAsyncPreviewCallbackList = getExtensionCallbackList("onAsyncPreview");
|
||||||
extensionMgr["onAsyncPreview"] = function() {
|
extensionMgr["onAsyncPreview"] = function() {
|
||||||
console.debug("onAsyncPreview");
|
logger.debug("onAsyncPreview");
|
||||||
// Call onPreviewFinished callbacks when all async preview are finished
|
// Call onPreviewFinished callbacks when all async preview are finished
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
function tryFinished() {
|
function tryFinished() {
|
||||||
@ -172,6 +171,14 @@ define( [
|
|||||||
).sortBy(function(extension) {
|
).sortBy(function(extension) {
|
||||||
return extension.extensionName.toLowerCase();
|
return extension.extensionName.toLowerCase();
|
||||||
}).each(createSettings);
|
}).each(createSettings);
|
||||||
|
|
||||||
|
// Create extension buttons
|
||||||
|
logger.debug("onCreateButton");
|
||||||
|
var onCreateButtonCallbackList = getExtensionCallbackList("onCreateButton");
|
||||||
|
_.each(onCreateButtonCallbackList, function(callback) {
|
||||||
|
$("#extension-buttons").append($('<div class="btn-group">').append(callback()));
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return extensionMgr;
|
return extensionMgr;
|
||||||
|
@ -9,20 +9,42 @@ define([
|
|||||||
settingsBloc: '<p>Adds a "Publish document" button in the navigation bar.</p>'
|
settingsBloc: '<p>Adds a "Publish document" button in the navigation bar.</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var button = undefined;
|
||||||
var currentFileDesc = undefined;
|
var currentFileDesc = undefined;
|
||||||
var publishRunning = false;
|
var publishRunning = false;
|
||||||
var hasPublications = false;
|
var hasPublications = false;
|
||||||
var isOffline = false;
|
var isOffline = false;
|
||||||
// Enable/disable the button
|
// Enable/disable the button
|
||||||
function updateButtonState() {
|
function updateButtonState() {
|
||||||
|
if(button === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(publishRunning === true || hasPublications === false || isOffline === true) {
|
if(publishRunning === true || hasPublications === false || isOffline === true) {
|
||||||
$(".action-force-publish").addClass("disabled");
|
button.addClass("disabled");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$(".action-force-publish").removeClass("disabled");
|
button.removeClass("disabled");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var publisher = undefined;
|
||||||
|
buttonPublish.onPublisherCreated = function(publisherParameter) {
|
||||||
|
publisher = publisherParameter;
|
||||||
|
};
|
||||||
|
|
||||||
|
buttonPublish.onCreateButton = function() {
|
||||||
|
button = $([
|
||||||
|
'<button class="btn" title="Publish this document">',
|
||||||
|
'<i class="icon-share"></i>',
|
||||||
|
'</button>'].join("")
|
||||||
|
).click(function() {
|
||||||
|
if(!$(this).hasClass("disabled")) {
|
||||||
|
publisher.publish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
};
|
||||||
|
|
||||||
buttonPublish.onPublishRunning = function(isRunning) {
|
buttonPublish.onPublishRunning = function(isRunning) {
|
||||||
publishRunning = isRunning;
|
publishRunning = isRunning;
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
|
@ -10,6 +10,26 @@ define([
|
|||||||
settingsBloc: '<p>Adds a "Share document" button in the navigation bar.</p>'
|
settingsBloc: '<p>Adds a "Share document" button in the navigation bar.</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
buttonShare.onCreateButton = function() {
|
||||||
|
return $([
|
||||||
|
'<button class="btn dropdown-toggle" data-toggle="dropdown" title="Share this document">',
|
||||||
|
'<i class="icon-link"></i>',
|
||||||
|
'</button>',
|
||||||
|
'<div id="link-container" class="dropdown-menu pull-right">',
|
||||||
|
'<div class="link-list"></div>',
|
||||||
|
'<p class="no-link">To share this document you need first to <a',
|
||||||
|
'href="#" class="action-publish-gist">publish it as a Gist</a> in',
|
||||||
|
'Markdown format.',
|
||||||
|
'</p>',
|
||||||
|
'<blockquote class="muted">',
|
||||||
|
'<b>NOTE:</b> You can open any URL within StackEdit using <a',
|
||||||
|
'href="viewer.html?url=https://raw.github.com/benweet/stackedit/master/README.md"',
|
||||||
|
'title="Sharing example">viewer.html?url=...</a>',
|
||||||
|
'</blockquote>',
|
||||||
|
'</div>'].join("")
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
var fileDesc = undefined;
|
var fileDesc = undefined;
|
||||||
var lineTemplate = [
|
var lineTemplate = [
|
||||||
'<div class="input-prepend">',
|
'<div class="input-prepend">',
|
||||||
|
@ -9,19 +9,43 @@ define([
|
|||||||
settingsBloc: '<p>Adds a "Synchronize documents" button in the navigation bar.</p>'
|
settingsBloc: '<p>Adds a "Synchronize documents" button in the navigation bar.</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var button = undefined;
|
||||||
var syncRunning = false;
|
var syncRunning = false;
|
||||||
var uploadPending = false;
|
var uploadPending = false;
|
||||||
var isOffline = false;
|
var isOffline = false;
|
||||||
// Enable/disable the button
|
// Enable/disable the button
|
||||||
var updateButtonState = function() {
|
var updateButtonState = function() {
|
||||||
|
if(button === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(syncRunning === true || uploadPending === false || isOffline) {
|
if(syncRunning === true || uploadPending === false || isOffline) {
|
||||||
$(".action-force-sync").addClass("disabled");
|
button.addClass("disabled");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$(".action-force-sync").removeClass("disabled");
|
button.removeClass("disabled");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var synchronizer = undefined;
|
||||||
|
buttonSync.onSynchronizerCreated = function(synchronizerParameter) {
|
||||||
|
synchronizer = synchronizerParameter;
|
||||||
|
};
|
||||||
|
|
||||||
|
buttonSync.onCreateButton = function() {
|
||||||
|
button = $([
|
||||||
|
'<button class="btn" title="Synchronize all documents">',
|
||||||
|
'<i class="icon-refresh"></i>',
|
||||||
|
'</button>'].join("")
|
||||||
|
).click(function() {
|
||||||
|
if(!$(this).hasClass("disabled")) {
|
||||||
|
synchronizer.forceSync();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return button;
|
||||||
|
};
|
||||||
|
|
||||||
|
buttonSync.onReady = updateButtonState;
|
||||||
|
|
||||||
buttonSync.onSyncRunning = function(isRunning) {
|
buttonSync.onSyncRunning = function(isRunning) {
|
||||||
syncRunning = isRunning;
|
syncRunning = isRunning;
|
||||||
uploadPending = true;
|
uploadPending = true;
|
||||||
@ -38,8 +62,6 @@ define([
|
|||||||
updateButtonState();
|
updateButtonState();
|
||||||
};
|
};
|
||||||
|
|
||||||
buttonSync.onReady = updateButtonState;
|
|
||||||
|
|
||||||
// Check that a file has synchronized locations
|
// Check that a file has synchronized locations
|
||||||
var checkSynchronization = function(fileDesc) {
|
var checkSynchronization = function(fileDesc) {
|
||||||
if(_.size(fileDesc.syncLocations) !== 0) {
|
if(_.size(fileDesc.syncLocations) !== 0) {
|
||||||
@ -48,7 +70,7 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
buttonSync.onFileChanged = checkSynchronization;
|
buttonSync.onContentChanged = checkSynchronization;
|
||||||
buttonSync.onTitleChanged = checkSynchronization;
|
buttonSync.onTitleChanged = checkSynchronization;
|
||||||
|
|
||||||
return buttonSync;
|
return buttonSync;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
define([
|
define([
|
||||||
"jquery",
|
"jquery",
|
||||||
"underscore"
|
"underscore",
|
||||||
], function($, _) {
|
"file-system"
|
||||||
|
], function($, _, fileSystem) {
|
||||||
|
|
||||||
var documentSelector = {
|
var documentSelector = {
|
||||||
extensionId: "documentSelector",
|
extensionId: "documentSelector",
|
||||||
@ -9,11 +10,6 @@ define([
|
|||||||
settingsBloc: '<p>Builds the "Open document" dropdown menu.</p>'
|
settingsBloc: '<p>Builds the "Open document" dropdown menu.</p>'
|
||||||
};
|
};
|
||||||
|
|
||||||
var fileSystem = undefined;
|
|
||||||
documentSelector.onFileSystemCreated = function(fileSystemParameter) {
|
|
||||||
fileSystem = fileSystemParameter;
|
|
||||||
};
|
|
||||||
|
|
||||||
var fileMgr = undefined;
|
var fileMgr = undefined;
|
||||||
documentSelector.onFileMgrCreated = function(fileMgrParameter) {
|
documentSelector.onFileMgrCreated = function(fileMgrParameter) {
|
||||||
fileMgr = fileMgrParameter;
|
fileMgr = fileMgrParameter;
|
||||||
|
@ -37,11 +37,11 @@ define([
|
|||||||
$(".msg-no-publish").removeClass("hide");
|
$(".msg-no-publish").removeClass("hide");
|
||||||
}
|
}
|
||||||
_.each(publishAttributesList, function(publishAttributes) {
|
_.each(publishAttributesList, function(publishAttributes) {
|
||||||
publishAttributes = _.extend({}, publishAttributes);
|
formattedAttributes = _.omit(publishAttributes, "provider", "publishIndex", "sharingLink");
|
||||||
if(publishAttributes.password) {
|
if(formattedAttributes.password) {
|
||||||
publishAttributes.password = "********";
|
formattedAttributes.password = "********";
|
||||||
}
|
}
|
||||||
var publishDesc = JSON.stringify(publishAttributes).replace(/{|}|"/g, "");
|
var publishDesc = JSON.stringify(formattedAttributes).replace(/{|}|"/g, "").replace(/,/g, ", ");
|
||||||
var lineElement = $(_.template(lineTemplate, {
|
var lineElement = $(_.template(lineTemplate, {
|
||||||
provider: publishAttributes.provider,
|
provider: publishAttributes.provider,
|
||||||
publishDesc: publishDesc
|
publishDesc: publishDesc
|
||||||
|
@ -58,12 +58,12 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
notifications.onMessage = function(message) {
|
notifications.onMessage = function(message) {
|
||||||
console.log(message);
|
logger.log(message);
|
||||||
showMessage(message);
|
showMessage(message);
|
||||||
};
|
};
|
||||||
|
|
||||||
notifications.onError = function(error) {
|
notifications.onError = function(error) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
if(_.isString(error)) {
|
if(_.isString(error)) {
|
||||||
showMessage(error, "icon-warning-sign");
|
showMessage(error, "icon-warning-sign");
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,36 @@ define([
|
|||||||
], function($, _, core, utils, settings, extensionMgr, fileSystem, welcomeContent) {
|
], function($, _, core, utils, settings, extensionMgr, fileSystem, welcomeContent) {
|
||||||
|
|
||||||
var fileMgr = {};
|
var fileMgr = {};
|
||||||
|
|
||||||
|
// Defines a file descriptor in the file system (fileDesc objects)
|
||||||
|
function FileDescriptor(fileIndex, title, syncLocations, publishLocations) {
|
||||||
|
this.fileIndex = fileIndex;
|
||||||
|
this.title = title;
|
||||||
|
this.syncLocations = syncLocations || {};
|
||||||
|
this.publishLocations = publishLocations || {};
|
||||||
|
}
|
||||||
|
FileDescriptor.prototype.getContent = function() {
|
||||||
|
return localStorage[this.fileIndex + ".content"];
|
||||||
|
};
|
||||||
|
FileDescriptor.prototype.setContent = function(content) {
|
||||||
|
localStorage[this.fileIndex + ".content"] = content;
|
||||||
|
extensionMgr.onContentChanged(this);
|
||||||
|
};
|
||||||
|
FileDescriptor.prototype.setTitle = function(title) {
|
||||||
|
this.title = title;
|
||||||
|
localStorage[this.fileIndex + ".title"] = title;
|
||||||
|
extensionMgr.onTitleChanged(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Load file descriptors from localStorage
|
||||||
|
_.chain(
|
||||||
|
localStorage["file.list"].split(";")
|
||||||
|
).compact().each(function(fileIndex) {
|
||||||
|
fileSystem[fileIndex] = new FileDescriptor(fileIndex, localStorage[fileIndex + ".title"]);
|
||||||
|
});
|
||||||
|
|
||||||
// Defines the current file
|
// Defines the current file
|
||||||
var currentFile = (function() {
|
var currentFile = undefined;
|
||||||
var fileIndex = localStorage["file.current"];
|
|
||||||
if(fileIndex !== undefined) {
|
|
||||||
return fileSystem[fileIndex];
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
fileMgr.getCurrentFile = function() {
|
fileMgr.getCurrentFile = function() {
|
||||||
return currentFile;
|
return currentFile;
|
||||||
};
|
};
|
||||||
@ -34,7 +56,7 @@ define([
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Caution: this function recreate the editor (reset undo operations)
|
// Caution: this function recreates the editor (reset undo operations)
|
||||||
fileMgr.selectFile = function(fileDesc) {
|
fileMgr.selectFile = function(fileDesc) {
|
||||||
fileDesc = fileDesc || fileMgr.getCurrentFile();
|
fileDesc = fileDesc || fileMgr.getCurrentFile();
|
||||||
|
|
||||||
@ -44,26 +66,33 @@ define([
|
|||||||
if (fileSystemSize === 0) {
|
if (fileSystemSize === 0) {
|
||||||
fileDesc = fileMgr.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
|
fileDesc = fileMgr.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
|
||||||
}
|
}
|
||||||
// If no file is selected take the last created
|
|
||||||
else {
|
else {
|
||||||
fileDesc = fileSystem[_.keys(fileSystem)[fileSystemSize - 1]];
|
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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fileMgr.setCurrentFile(fileDesc);
|
|
||||||
|
|
||||||
// Notify extensions
|
|
||||||
extensionMgr.onFileSelected(fileDesc);
|
|
||||||
|
|
||||||
// Hide the viewer pencil button
|
if(fileMgr.isCurrentFile(fileDesc) === false) {
|
||||||
if(fileDesc.fileIndex == TEMPORARY_FILE_INDEX) {
|
fileMgr.setCurrentFile(fileDesc);
|
||||||
$(".action-edit-document").removeClass("hide");
|
|
||||||
}
|
// Notify extensions
|
||||||
else {
|
extensionMgr.onFileSelected(fileDesc);
|
||||||
$(".action-edit-document").addClass("hide");
|
|
||||||
|
// Hide the viewer pencil button
|
||||||
|
if(fileDesc.fileIndex == TEMPORARY_FILE_INDEX) {
|
||||||
|
$(".action-edit-document").removeClass("hide");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(".action-edit-document").addClass("hide");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recreate the editor
|
// Recreate the editor
|
||||||
$("#wmd-input").val(localStorage[fileDesc.fileIndex + ".content"]);
|
$("#wmd-input").val(fileDesc.getContent());
|
||||||
core.createEditor(function() {
|
core.createEditor(function() {
|
||||||
// Callback to save content when textarea changes
|
// Callback to save content when textarea changes
|
||||||
fileMgr.saveFile();
|
fileMgr.saveFile();
|
||||||
@ -72,7 +101,6 @@ define([
|
|||||||
|
|
||||||
fileMgr.createFile = function(title, content, syncLocations, isTemporary) {
|
fileMgr.createFile = function(title, content, syncLocations, isTemporary) {
|
||||||
content = content !== undefined ? content : settings.defaultContent;
|
content = content !== undefined ? content : settings.defaultContent;
|
||||||
syncLocations = syncLocations || {};
|
|
||||||
if (!title) {
|
if (!title) {
|
||||||
// Create a file title
|
// Create a file title
|
||||||
title = DEFAULT_FILE_TITLE;
|
title = DEFAULT_FILE_TITLE;
|
||||||
@ -92,24 +120,19 @@ define([
|
|||||||
} while(_.has(fileSystem, fileIndex));
|
} while(_.has(fileSystem, fileIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the file in the localStorage
|
// syncIndex associations
|
||||||
localStorage[fileIndex + ".content"] = content;
|
syncLocations = syncLocations || {};
|
||||||
localStorage[fileIndex + ".title"] = title;
|
|
||||||
// Store syncIndexes associated to the file
|
|
||||||
var sync = _.reduce(syncLocations, function(sync, syncAttributes, syncIndex) {
|
var sync = _.reduce(syncLocations, function(sync, syncAttributes, syncIndex) {
|
||||||
return sync + syncIndex + ";";
|
return sync + syncIndex + ";";
|
||||||
}, ";");
|
}, ";");
|
||||||
|
|
||||||
|
localStorage[fileIndex + ".title"] = title;
|
||||||
|
localStorage[fileIndex + ".content"] = content;
|
||||||
localStorage[fileIndex + ".sync"] = sync;
|
localStorage[fileIndex + ".sync"] = sync;
|
||||||
// Store publishIndexes associated to the file
|
|
||||||
localStorage[fileIndex + ".publish"] = ";";
|
localStorage[fileIndex + ".publish"] = ";";
|
||||||
|
|
||||||
// Create the file descriptor
|
// Create the file descriptor
|
||||||
var fileDesc = {
|
var fileDesc = new FileDescriptor(fileIndex, title, syncLocations);
|
||||||
fileIndex : fileIndex,
|
|
||||||
title : title,
|
|
||||||
syncLocations: syncLocations,
|
|
||||||
publishLocations: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add the index to the file list
|
// Add the index to the file list
|
||||||
if(!isTemporary) {
|
if(!isTemporary) {
|
||||||
@ -122,9 +145,11 @@ define([
|
|||||||
|
|
||||||
fileMgr.deleteFile = function(fileDesc) {
|
fileMgr.deleteFile = function(fileDesc) {
|
||||||
fileDesc = fileDesc || fileMgr.getCurrentFile();
|
fileDesc = fileDesc || fileMgr.getCurrentFile();
|
||||||
if(fileMgr.isCurrentFile(fileDesc)) {
|
if(fileMgr.isCurrentFile(fileDesc) === true) {
|
||||||
// Unset the current fileDesc
|
// Unset the current fileDesc
|
||||||
fileMgr.setCurrentFile();
|
fileMgr.setCurrentFile();
|
||||||
|
// Refresh the editor with an other file
|
||||||
|
fileMgr.selectFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove synchronized locations
|
// Remove synchronized locations
|
||||||
@ -141,10 +166,12 @@ define([
|
|||||||
var fileIndex = fileDesc.fileIndex;
|
var fileIndex = fileDesc.fileIndex;
|
||||||
localStorage["file.list"] = localStorage["file.list"].replace(";"
|
localStorage["file.list"] = localStorage["file.list"].replace(";"
|
||||||
+ fileIndex + ";", ";");
|
+ fileIndex + ";", ";");
|
||||||
|
|
||||||
localStorage.removeItem(fileIndex + ".title");
|
localStorage.removeItem(fileIndex + ".title");
|
||||||
localStorage.removeItem(fileIndex + ".content");
|
localStorage.removeItem(fileIndex + ".content");
|
||||||
localStorage.removeItem(fileIndex + ".sync");
|
localStorage.removeItem(fileIndex + ".sync");
|
||||||
localStorage.removeItem(fileIndex + ".publish");
|
localStorage.removeItem(fileIndex + ".publish");
|
||||||
|
|
||||||
fileSystem.removeItem(fileIndex);
|
fileSystem.removeItem(fileIndex);
|
||||||
extensionMgr.onFileDeleted(fileDesc);
|
extensionMgr.onFileDeleted(fileDesc);
|
||||||
};
|
};
|
||||||
@ -153,8 +180,7 @@ define([
|
|||||||
fileMgr.saveFile = function() {
|
fileMgr.saveFile = function() {
|
||||||
var content = $("#wmd-input").val();
|
var content = $("#wmd-input").val();
|
||||||
var fileDesc = fileMgr.getCurrentFile();
|
var fileDesc = fileMgr.getCurrentFile();
|
||||||
localStorage[fileDesc.fileIndex + ".content"] = content;
|
fileDesc.setContent(content);
|
||||||
extensionMgr.onFileChanged(fileDesc);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add a synchronized location to a file
|
// Add a synchronized location to a file
|
||||||
@ -211,7 +237,7 @@ define([
|
|||||||
|
|
||||||
// Remove a publishIndex (publish location)
|
// Remove a publishIndex (publish location)
|
||||||
fileMgr.removePublish = function(publishAttributes, skipExtensions) {
|
fileMgr.removePublish = function(publishAttributes, skipExtensions) {
|
||||||
var fileDesc = fileMgr.getFileFromPublish(publishAttributes.publishIndex);
|
var fileDesc = fileMgr.getFileFromPublishIndex(publishAttributes.publishIndex);
|
||||||
if(fileDesc !== undefined) {
|
if(fileDesc !== undefined) {
|
||||||
localStorage[fileDesc.fileIndex + ".publish"] = localStorage[fileDesc.fileIndex + ".publish"].replace(";"
|
localStorage[fileDesc.fileIndex + ".publish"] = localStorage[fileDesc.fileIndex + ".publish"].replace(";"
|
||||||
+ publishAttributes.publishIndex + ";", ";");
|
+ publishAttributes.publishIndex + ";", ";");
|
||||||
@ -225,7 +251,7 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Get the file descriptor associated to a publishIndex
|
// Get the file descriptor associated to a publishIndex
|
||||||
fileMgr.getFileFromPublish = function(publishIndex) {
|
fileMgr.getFileFromPublishIndex = function(publishIndex) {
|
||||||
return _.find(fileSystem, function(fileDesc) {
|
return _.find(fileSystem, function(fileDesc) {
|
||||||
return _.has(fileDesc.publishLocations, publishIndex);
|
return _.has(fileDesc.publishLocations, publishIndex);
|
||||||
});
|
});
|
||||||
@ -263,7 +289,6 @@ define([
|
|||||||
});
|
});
|
||||||
$(".action-remove-file").click(function() {
|
$(".action-remove-file").click(function() {
|
||||||
fileMgr.deleteFile();
|
fileMgr.deleteFile();
|
||||||
fileMgr.selectFile();
|
|
||||||
});
|
});
|
||||||
$("#file-title").click(function() {
|
$("#file-title").click(function() {
|
||||||
if(viewerMode === true) {
|
if(viewerMode === true) {
|
||||||
@ -280,15 +305,10 @@ define([
|
|||||||
$("#file-title").show();
|
$("#file-title").show();
|
||||||
var title = $.trim(input.val());
|
var title = $.trim(input.val());
|
||||||
var fileDesc = fileMgr.getCurrentFile();
|
var fileDesc = fileMgr.getCurrentFile();
|
||||||
var fileIndexTitle = fileDesc.fileIndex + ".title";
|
if (title && title != fileDesc.title) {
|
||||||
if (title) {
|
fileDesc.setTitle(title);
|
||||||
if (title != localStorage[fileIndexTitle]) {
|
|
||||||
localStorage[fileIndexTitle] = title;
|
|
||||||
fileDesc.title = title;
|
|
||||||
extensionMgr.onTitleChanged(fileDesc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
input.val(localStorage[fileIndexTitle]);
|
input.val(fileDesc.title);
|
||||||
$("#wmd-input").focus();
|
$("#wmd-input").focus();
|
||||||
}
|
}
|
||||||
$("#file-title-input").blur(function() {
|
$("#file-title-input").blur(function() {
|
||||||
|
@ -1,22 +1,3 @@
|
|||||||
define([
|
// The fileSystem module is empty when created. It's filled by fileMgr when loading.
|
||||||
"underscore",
|
// syncLocations and publishLocations are respectively loaded by synchronizer and publisher.
|
||||||
"extension-manager"
|
define({});
|
||||||
], function(_, extensionMgr) {
|
|
||||||
|
|
||||||
var fileSystem = {};
|
|
||||||
|
|
||||||
// Load file descriptors from localStorage
|
|
||||||
_.chain(
|
|
||||||
localStorage["file.list"].split(";")
|
|
||||||
).compact().each(function(fileIndex) {
|
|
||||||
fileSystem[fileIndex] = {
|
|
||||||
fileIndex : fileIndex,
|
|
||||||
title : localStorage[fileIndex + ".title"],
|
|
||||||
syncLocations: {},
|
|
||||||
publishLocations: {}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
extensionMgr.onFileSystemCreated(fileSystem);
|
|
||||||
|
|
||||||
return fileSystem;
|
|
||||||
});
|
|
@ -28,6 +28,7 @@ define([
|
|||||||
syncAttributes.contentCRC = utils.crc32(content);
|
syncAttributes.contentCRC = utils.crc32(content);
|
||||||
syncAttributes.titleCRC = utils.crc32(title);
|
syncAttributes.titleCRC = utils.crc32(title);
|
||||||
syncAttributes.syncIndex = createSyncIndex(id);
|
syncAttributes.syncIndex = createSyncIndex(id);
|
||||||
|
utils.storeAttributes(syncAttributes);
|
||||||
return syncAttributes;
|
return syncAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +44,6 @@ define([
|
|||||||
var fileDescList = [];
|
var fileDescList = [];
|
||||||
_.each(result, function(file) {
|
_.each(result, function(file) {
|
||||||
var syncAttributes = createSyncAttributes(file.id, file.etag, file.content, file.title);
|
var syncAttributes = createSyncAttributes(file.id, file.etag, file.content, file.title);
|
||||||
localStorage[syncAttributes.syncIndex] = utils.serializeAttributes(syncAttributes);
|
|
||||||
var syncLocations = {};
|
var syncLocations = {};
|
||||||
syncLocations[syncAttributes.syncIndex] = syncAttributes;
|
syncLocations[syncAttributes.syncIndex] = syncAttributes;
|
||||||
var fileDesc = fileMgr.createFile(file.title, file.content, syncLocations);
|
var fileDesc = fileMgr.createFile(file.title, file.content, syncLocations);
|
||||||
@ -82,7 +82,6 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var syncAttributes = createSyncAttributes(result.id, result.etag, content, title);
|
var syncAttributes = createSyncAttributes(result.id, result.etag, content, title);
|
||||||
localStorage[syncAttributes.syncIndex] = utils.serializeAttributes(syncAttributes);
|
|
||||||
callback(undefined, syncAttributes);
|
callback(undefined, syncAttributes);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -92,7 +91,7 @@ define([
|
|||||||
if(!id) {
|
if(!id) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Check that file is not synchronized with an other one
|
// Check that file is not synchronized with another an existing document
|
||||||
var syncIndex = createSyncIndex(id);
|
var syncIndex = createSyncIndex(id);
|
||||||
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
|
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
|
||||||
if(fileDesc !== undefined) {
|
if(fileDesc !== undefined) {
|
||||||
@ -106,7 +105,6 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var syncAttributes = createSyncAttributes(result.id, result.etag, content, title);
|
var syncAttributes = createSyncAttributes(result.id, result.etag, content, title);
|
||||||
localStorage[syncAttributes.syncIndex] = utils.serializeAttributes(syncAttributes);
|
|
||||||
callback(undefined, syncAttributes);
|
callback(undefined, syncAttributes);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -178,7 +176,7 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var localTitleChanged = syncAttributes.titleCRC != utils.crc32(localTitle);
|
var localTitleChanged = syncAttributes.titleCRC != utils.crc32(localTitle);
|
||||||
var localContent = localStorage[fileDesc.fileIndex + ".content"];
|
var localContent = fileDesc.getContent();
|
||||||
var localContentChanged = syncAttributes.contentCRC != utils.crc32(localContent);
|
var localContentChanged = syncAttributes.contentCRC != utils.crc32(localContent);
|
||||||
var file = change.file;
|
var file = change.file;
|
||||||
var remoteTitleCRC = utils.crc32(file.title);
|
var remoteTitleCRC = utils.crc32(file.title);
|
||||||
@ -190,20 +188,17 @@ define([
|
|||||||
// Conflict detection
|
// Conflict detection
|
||||||
if ((fileTitleChanged === true && localTitleChanged === true && remoteTitleChanged === true)
|
if ((fileTitleChanged === true && localTitleChanged === true && remoteTitleChanged === true)
|
||||||
|| (fileContentChanged === true && localContentChanged === true && remoteContentChanged === true)) {
|
|| (fileContentChanged === true && localContentChanged === true && remoteContentChanged === true)) {
|
||||||
var backupFileDesc = fileMgr.createFile(localTitle + " (backup)", localContent);
|
fileMgr.createFile(localTitle + " (backup)", localContent);
|
||||||
extensionMgr.onTitleChanged(backupFileDesc);
|
|
||||||
extensionMgr.onMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.');
|
extensionMgr.onMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.');
|
||||||
}
|
}
|
||||||
// If file title changed
|
// If file title changed
|
||||||
if(fileTitleChanged && remoteTitleChanged === true) {
|
if(fileTitleChanged && remoteTitleChanged === true) {
|
||||||
localStorage[fileDesc.fileIndex + ".title"] = file.title;
|
fileDesc.setTitle(file.title);
|
||||||
fileDesc.title = file.title;
|
|
||||||
extensionMgr.onTitleChanged(fileDesc);
|
|
||||||
extensionMgr.onMessage('"' + localTitle + '" has been renamed to "' + file.title + '" on Google Drive.');
|
extensionMgr.onMessage('"' + localTitle + '" has been renamed to "' + file.title + '" on Google Drive.');
|
||||||
}
|
}
|
||||||
// If file content changed
|
// If file content changed
|
||||||
if(fileContentChanged && remoteContentChanged === true) {
|
if(fileContentChanged && remoteContentChanged === true) {
|
||||||
localStorage[fileDesc.fileIndex + ".content"] = file.content;
|
fileDesc.setContent(file.content);
|
||||||
extensionMgr.onMessage('"' + file.title + '" has been updated from Google Drive.');
|
extensionMgr.onMessage('"' + file.title + '" has been updated from Google Drive.');
|
||||||
if(fileMgr.isCurrentFile(fileDesc)) {
|
if(fileMgr.isCurrentFile(fileDesc)) {
|
||||||
fileMgr.selectFile(); // Refresh editor
|
fileMgr.selectFile(); // Refresh editor
|
||||||
@ -213,7 +208,7 @@ define([
|
|||||||
syncAttributes.etag = file.etag;
|
syncAttributes.etag = file.etag;
|
||||||
syncAttributes.contentCRC = remoteContentCRC;
|
syncAttributes.contentCRC = remoteContentCRC;
|
||||||
syncAttributes.titleCRC = remoteTitleCRC;
|
syncAttributes.titleCRC = remoteTitleCRC;
|
||||||
localStorage[syncIndex] = utils.serializeAttributes(syncAttributes);
|
utils.storeAttributes(syncAttributes);
|
||||||
});
|
});
|
||||||
localStorage[PROVIDER_GDRIVE + ".lastChangeId"] = newChangeId;
|
localStorage[PROVIDER_GDRIVE + ".lastChangeId"] = newChangeId;
|
||||||
callback();
|
callback();
|
||||||
@ -263,7 +258,6 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var syncAttributes = createSyncAttributes(file.id, file.etag, file.content, file.title);
|
var syncAttributes = createSyncAttributes(file.id, file.etag, file.content, file.title);
|
||||||
localStorage[syncAttributes.syncIndex] = utils.serializeAttributes(syncAttributes);
|
|
||||||
var syncLocations = {};
|
var syncLocations = {};
|
||||||
syncLocations[syncAttributes.syncIndex] = syncAttributes;
|
syncLocations[syncAttributes.syncIndex] = syncAttributes;
|
||||||
var fileDesc = fileMgr.createFile(file.title, file.content, syncAttributes);
|
var fileDesc = fileMgr.createFile(file.title, file.content, syncAttributes);
|
||||||
|
@ -224,7 +224,7 @@ define([
|
|||||||
function handleError(error, task) {
|
function handleError(error, task) {
|
||||||
var errorMsg = undefined;
|
var errorMsg = undefined;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
// Try to analyze the error
|
// Try to analyze the error
|
||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
errorMsg = error;
|
errorMsg = error;
|
||||||
|
@ -326,7 +326,7 @@ define([
|
|||||||
function handleError(error, task) {
|
function handleError(error, task) {
|
||||||
var errorMsg = undefined;
|
var errorMsg = undefined;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
// Try to analyze the error
|
// Try to analyze the error
|
||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
errorMsg = error;
|
errorMsg = error;
|
||||||
|
16
js/main.js
16
js/main.js
@ -23,6 +23,20 @@ requirejs.config({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Defines the logger object
|
||||||
|
var logger = {
|
||||||
|
debug: function() {},
|
||||||
|
log: function() {},
|
||||||
|
info: function() {},
|
||||||
|
warn: function() {},
|
||||||
|
error: function() {}
|
||||||
|
};
|
||||||
|
// Use http://.../?console to print logs in the console
|
||||||
|
if (location.search.indexOf("console") !== -1) {
|
||||||
|
logger = console;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequireJS entry point. By requiring synchronizer and publisher, we are actually loading all the modules
|
||||||
require([
|
require([
|
||||||
"jquery",
|
"jquery",
|
||||||
"core",
|
"core",
|
||||||
@ -31,6 +45,7 @@ require([
|
|||||||
], function($, core) {
|
], function($, core) {
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
// If browser has detected a new application cache.
|
// If browser has detected a new application cache.
|
||||||
if (window.applicationCache) {
|
if (window.applicationCache) {
|
||||||
window.applicationCache.addEventListener('updateready', function(e) {
|
window.applicationCache.addEventListener('updateready', function(e) {
|
||||||
@ -41,6 +56,7 @@ require([
|
|||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Here, all the modules are loaded and the DOM is ready
|
||||||
core.setReady();
|
core.setReady();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ define([
|
|||||||
publishIndex = "publish." + utils.randomString();
|
publishIndex = "publish." + utils.randomString();
|
||||||
} while(_.has(localStorage, publishIndex));
|
} while(_.has(localStorage, publishIndex));
|
||||||
publishAttributes.publishIndex = publishIndex;
|
publishAttributes.publishIndex = publishIndex;
|
||||||
localStorage[publishIndex] = utils.serializeAttributes(publishAttributes);
|
utils.storeAttributes(publishAttributes);
|
||||||
fileMgr.addPublish(fileDesc, publishAttributes);
|
fileMgr.addPublish(fileDesc, publishAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,12 +230,6 @@ define([
|
|||||||
|
|
||||||
$(".action-process-publish").click(performNewLocation);
|
$(".action-process-publish").click(performNewLocation);
|
||||||
|
|
||||||
$(".action-force-publish").click(function() {
|
|
||||||
if(!$(this).hasClass("disabled")) {
|
|
||||||
publisher.publish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Save As menu items
|
// Save As menu items
|
||||||
$(".action-download-md").click(function() {
|
$(".action-download-md").click(function() {
|
||||||
var content = $("#wmd-input").val();
|
var content = $("#wmd-input").val();
|
||||||
|
@ -63,7 +63,7 @@ define([
|
|||||||
function handleError(error, task) {
|
function handleError(error, task) {
|
||||||
var errorMsg = undefined;
|
var errorMsg = undefined;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
// Try to analyze the error
|
// Try to analyze the error
|
||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
errorMsg = "SSH error: " + error + ".";
|
errorMsg = "SSH error: " + error + ".";
|
||||||
|
@ -73,7 +73,7 @@ define([
|
|||||||
}
|
}
|
||||||
if(uploadFlag) {
|
if(uploadFlag) {
|
||||||
// Update syncAttributes in localStorage
|
// Update syncAttributes in localStorage
|
||||||
localStorage[syncAttributes.syncIndex] = utils.serializeAttributes(syncAttributes);
|
utils.storeAttributes(syncAttributes);
|
||||||
}
|
}
|
||||||
locationUp(callback);
|
locationUp(callback);
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ define([
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dequeue a fileDesc
|
// Dequeue a fileDesc to synchronize
|
||||||
var fileDesc = uploadFileList.pop();
|
var fileDesc = uploadFileList.pop();
|
||||||
uploadSyncAttributesList = _.values(fileDesc.syncLocations);
|
uploadSyncAttributesList = _.values(fileDesc.syncLocations);
|
||||||
if(uploadSyncAttributesList.length === 0) {
|
if(uploadSyncAttributesList.length === 0) {
|
||||||
@ -99,7 +99,7 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get document title/content
|
// Get document title/content
|
||||||
uploadContent = localStorage[fileDesc.fileIndex + ".content"];
|
uploadContent = fileDesc.getContent();
|
||||||
uploadContentCRC = utils.crc32(uploadContent);
|
uploadContentCRC = utils.crc32(uploadContent);
|
||||||
uploadTitle = fileDesc.title;
|
uploadTitle = fileDesc.title;
|
||||||
uploadTitleCRC = utils.crc32(uploadTitle);
|
uploadTitleCRC = utils.crc32(uploadTitle);
|
||||||
@ -226,9 +226,7 @@ define([
|
|||||||
|
|
||||||
// Perform the provider's export
|
// Perform the provider's export
|
||||||
var fileDesc = fileMgr.getCurrentFile();
|
var fileDesc = fileMgr.getCurrentFile();
|
||||||
var title = fileDesc.title;
|
provider.exportFile(event, fileDesc.title, fileDesc.getContent(), function(error, syncAttributes) {
|
||||||
var content = localStorage[fileDesc.fileIndex + ".content"];
|
|
||||||
provider.exportFile(event, title, content, function(error, syncAttributes) {
|
|
||||||
if(error) {
|
if(error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -245,9 +243,7 @@ define([
|
|||||||
// Provider's manual export button
|
// Provider's manual export button
|
||||||
$(".action-sync-manual-" + provider.providerId).click(function(event) {
|
$(".action-sync-manual-" + provider.providerId).click(function(event) {
|
||||||
var fileDesc = fileMgr.getCurrentFile();
|
var fileDesc = fileMgr.getCurrentFile();
|
||||||
var title = fileDesc.title;
|
provider.exportManual(event, fileDesc.title, fileDesc.getContent(), function(error, syncAttributes) {
|
||||||
var content = localStorage[fileDesc.fileIndex + ".content"];
|
|
||||||
provider.exportManual(event, title, content, function(error, syncAttributes) {
|
|
||||||
if(error) {
|
if(error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -255,12 +251,6 @@ define([
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".action-force-sync").click(function() {
|
|
||||||
if(!$(this).hasClass("disabled")) {
|
|
||||||
synchronizer.forceSync();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
extensionMgr.onSynchronizerCreated(synchronizer);
|
extensionMgr.onSynchronizerCreated(synchronizer);
|
||||||
|
@ -143,7 +143,7 @@ define([
|
|||||||
function handleError(error, task) {
|
function handleError(error, task) {
|
||||||
var errorMsg = undefined;
|
var errorMsg = undefined;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
// Try to analyze the error
|
// Try to analyze the error
|
||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
errorMsg = error;
|
errorMsg = error;
|
||||||
|
@ -298,13 +298,14 @@ define([
|
|||||||
utils.updateCurrentTime();
|
utils.updateCurrentTime();
|
||||||
|
|
||||||
|
|
||||||
// Serialize sync/publish attributes
|
// Serialize sync/publish attributes and store it in the fileStorage
|
||||||
utils.serializeAttributes = function(attributes) {
|
utils.storeAttributes = function(attributes) {
|
||||||
|
var storeIndex = attributes.syncIndex || attributes.publishIndex;
|
||||||
// Don't store sync/publish index
|
// Don't store sync/publish index
|
||||||
attributes = _.omit(attributes, "syncIndex", "publishIndex");
|
attributes = _.omit(attributes, "syncIndex", "publishIndex");
|
||||||
// Store providerId instead of provider
|
// Store providerId instead of provider
|
||||||
attributes.provider = attributes.provider.providerId;
|
attributes.provider = attributes.provider.providerId;
|
||||||
return JSON.stringify(attributes);
|
localStorage[storeIndex] = JSON.stringify(attributes);
|
||||||
};
|
};
|
||||||
|
|
||||||
return utils;
|
return utils;
|
||||||
|
@ -141,7 +141,7 @@ define([
|
|||||||
function handleError(error, task) {
|
function handleError(error, task) {
|
||||||
var errorMsg = undefined;
|
var errorMsg = undefined;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
logger.error(error);
|
||||||
// Try to analyze the error
|
// Try to analyze the error
|
||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
errorMsg = error;
|
errorMsg = error;
|
||||||
|
Loading…
Reference in New Issue
Block a user