New synchronize pattern

This commit is contained in:
benweet 2013-04-21 01:07:27 +01:00
parent 2f1471af05
commit 425a7f0528
20 changed files with 5860 additions and 263 deletions

View File

@ -1 +1 @@
CACHE MANIFEST # v41 CACHE: index.html css/bootstrap.css css/jgrowl.css css/main.css css/prettify.css js/main-min.js js/require.js img/ajax-loader.gif img/glyphicons-halflings.png img/glyphicons-halflings-white.png img/icons.png img/stackedit-32.ico img/stackedit-promo.png NETWORK: * CACHE MANIFEST # v1 CACHE: index.html css/main-css.css js/main-min.js js/require.js img/ajax-loader.gif img/glyphicons-halflings.png img/glyphicons-halflings-white.png img/icons.png img/stackedit-32.ico img/stackedit-promo.png NETWORK: *

5647
css/main-min.css vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,7 @@ var redirectUrl = location.href.substring(0, location.href.indexOf("gdrive-actio
var state = decodeURI((/state=(.+?)(&|$)/ var state = decodeURI((/state=(.+?)(&|$)/
.exec(location.search) || [ , null ])[1]); .exec(location.search) || [ , null ])[1]);
if(state) { if(state) {
localStorage["sync.gdrive.state"] = state; localStorage["gdrive.state"] = state;
} }
window.location.replace(redirectUrl); window.location.replace(redirectUrl);

View File

@ -11,8 +11,9 @@
content="StackEdit is a free, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites."> content="StackEdit is a free, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites.">
<meta name="author" content="Benoit Schweblin"> <meta name="author" content="Benoit Schweblin">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/main.css" rel="stylesheet" media="screen"> <link href="css/main-min.css" rel="stylesheet" media="screen">
<script> <script>
// http://.../?debug to serve original JavaScript files for debug
var dep = "main-min"; var dep = "main-min";
if (location.search.indexOf("debug") !== -1) { if (location.search.indexOf("debug") !== -1) {
dep = "main"; dep = "main";
@ -184,13 +185,13 @@
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" <button type="button" class="close" data-dismiss="modal"
aria-hidden="true">&times;</button> aria-hidden="true">&times;</button>
<h3>Google Drive export</h3> <h3>Export to Google Drive</h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p>This will upload the current document into your Google Drive <p>This will upload the current document into your Google Drive
root folder and keep it synchronized.</p> root folder and keep it synchronized.</p>
<p class="muted"><b>NOTE:</b> You can move or rename the file <p class="muted"><b>NOTE:</b> You can move or rename the file
within Google Drive afterwards.</p> afterwards within Google Drive.</p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#" <a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
@ -203,7 +204,7 @@
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" <button type="button" class="close" data-dismiss="modal"
aria-hidden="true">&times;</button> aria-hidden="true">&times;</button>
<h3>Dropbox export</h3> <h3>Export to Dropbox</h3>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<p>This will upload the current document to your Dropbox account <p>This will upload the current document to your Dropbox account
@ -225,7 +226,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#" <a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
data-dismiss="modal" class="btn btn-primary action-sync-export-dropbox">OK</a> data-dismiss="modal"
class="btn btn-primary action-sync-export-dropbox">OK</a>
</div> </div>
</div> </div>
@ -260,9 +262,8 @@
class="btn action-sync-manual-dropbox" title="Add location" class="btn action-sync-manual-dropbox" title="Add location"
data-dismiss="modal"><i class="icon-ok"></i></a> data-dismiss="modal"><i class="icon-ok"></i></a>
</div> </div>
<p class="muted"><b>NOTE:</b> Adding a synchronized location will <p class="muted"><b>NOTE:</b> This will upload the local document
upload the local document firstly and overwrite the existing file on firstly and overwrite the existing file on the server.</p>
the server.</p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a> <a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
@ -335,9 +336,21 @@
</div> </div>
<div class="control-group modal-publish-gdrive"> <div class="control-group modal-publish-gdrive">
<div class="controls muted"> <div class="controls muted">
<b>NOTE:</b> If no file ID If no file ID is supplied, the file will be created
is supplied, the file will be created into your Google Drive root into your Google Drive root folder. You can move the file afterwards within
folder. You can move the file within Google Drive afterwards. Google Drive.
</div>
</div>
<div class="control-group modal-publish-gdrive">
<label class="control-label" for="input-publish-gdrive-filename">Force file name (optional)</label>
<div class="controls">
<input type="text" id="input-publish-gdrive-filename"
placeholder="File name">
</div>
</div>
<div class="control-group modal-publish-gdrive">
<div class="controls muted">
If no filename is supplied, the document title will be used.
</div> </div>
</div> </div>

View File

@ -1,14 +1,11 @@
/** /**
* Used to run asynchronous tasks sequentially (ajax mainly) An asynchronous * Used to run asynchronous tasks sequentially (ajax mainly). An asynchronous
* task is composed of different callback types: onRun, onSuccess, onError * task is composed of different callback types: onRun, onSuccess, onError
*/ */
define([ "underscore" ], function() { define([ "core", "underscore" ], function(core) {
var asyncRunner = {}; var asyncRunner = {};
// Dependencies
var core = undefined;
var taskQueue = []; var taskQueue = [];
var currentTask = undefined; var currentTask = undefined;
var currentTaskRunning = false; var currentTaskRunning = false;
@ -21,8 +18,8 @@ define([ "underscore" ], function() {
task.retryCounter = 0; task.retryCounter = 0;
/** /**
* onRun callbacks are called by chain(). These callbacks have to call * onRun callbacks are called by chain(). These callbacks have to call
* chain() themselves to chain with next callback or to finish the task * chain() themselves to chain with next onRun callback or error() to
* and call onSuccess callbacks. * throw an exception or retry() to restart the task.
*/ */
// Run callbacks // Run callbacks
task.runCallbacks = []; task.runCallbacks = [];
@ -75,7 +72,8 @@ define([ "underscore" ], function() {
runCallback(); runCallback();
}; };
/** /**
* error() calls the onError callbacks. * error() calls the onError callbacks with the error parameter and ends
* the task by throwing an exception.
*/ */
task.error = function(error) { task.error = function(error) {
if (task.finished === true) { if (task.finished === true) {
@ -177,9 +175,5 @@ define([ "underscore" ], function() {
} }
}; };
asyncRunner.init = function(coreModule) {
core = coreModule;
};
return asyncRunner; return asyncRunner;
}); });

View File

@ -1,7 +1,4 @@
define(["jquery", "google-helper"], function($, googleHelper) { define(["jquery", "core", "google-helper"], function($, core, googleHelper) {
// Dependencies
var core = undefined;
var bloggerProvider = { var bloggerProvider = {
providerId: PROVIDER_BLOGGER, providerId: PROVIDER_BLOGGER,
@ -33,9 +30,5 @@ define(["jquery", "google-helper"], function($, googleHelper) {
return publishAttributes; return publishAttributes;
}; };
bloggerProvider.init = function(coreModule) {
core = coreModule;
};
return bloggerProvider; return bloggerProvider;
}); });

View File

@ -1,16 +1,10 @@
define( define(
[ "jquery", "file-manager", "google-helper", "dropbox-helper", [ "jquery", "bootstrap", "jgrowl", "layout", "Markdown.Editor", "config",
"github-helper", "synchronizer", "publisher", "async-runner",
"bootstrap", "jgrowl", "layout", "Markdown.Editor", "config",
"underscore" ], "underscore" ],
function($, fileManager, googleHelper, dropboxHelper, githubHelper, function($) {
synchronizer, publisher, asyncRunner) {
var core = {}; var core = {};
// The interval Id for periodic tasks
var intervalId = undefined;
// Usage: callback = callback || core.doNothing; // Usage: callback = callback || core.doNothing;
core.doNothing = function() {}; core.doNothing = function() {};
@ -20,6 +14,13 @@ define(
core.currentTime = new Date().getTime(); core.currentTime = new Date().getTime();
} }
// Used for periodic tasks
var intervalId = undefined;
var periodicCallbacks = [];
core.addPeriodicCallback = function(callback) {
periodicCallbacks.push(callback);
};
// Used to detect user activity // Used to detect user activity
var userReal = false; var userReal = false;
var userActive = false; var userActive = false;
@ -118,6 +119,10 @@ define(
if(!msg) { if(!msg) {
return; return;
} }
var endOfMsg = msg.indexOf("|");
if(endOfMsg !== -1) {
msg = msg.substring(0, endOfMsg);
}
options = options || {}; options = options || {};
iconClass = iconClass || "icon-info-sign"; iconClass = iconClass || "icon-info-sign";
$.jGrowl("<i class='icon-white " + iconClass + "'></i> " + _.escape(msg), options); $.jGrowl("<i class='icon-white " + iconClass + "'></i> " + _.escape(msg), options);
@ -132,7 +137,9 @@ define(
core.isOffline = false; core.isOffline = false;
var offlineTime = core.currentTime; var offlineTime = core.currentTime;
var offlineListeners = []; var offlineListeners = [];
core.addOfflineListener = function(callback) {
offlineListeners.push(callback);
};
core.setOffline = function() { core.setOffline = function() {
offlineTime = core.currentTime; offlineTime = core.currentTime;
if(core.isOffline === false) { if(core.isOffline === false) {
@ -148,7 +155,6 @@ define(
} }
} }
}; };
core.setOnline = function() { core.setOnline = function() {
if(core.isOffline === true) { if(core.isOffline === true) {
$(".msg-offline").parents(".jGrowl-notification").trigger( $(".msg-offline").parents(".jGrowl-notification").trigger(
@ -159,7 +165,6 @@ define(
} }
} }
}; };
function checkOnline() { function checkOnline() {
// Try to reconnect if we are offline but we have some network // Try to reconnect if we are offline but we have some network
if (core.isOffline === true && navigator.onLine === true if (core.isOffline === true && navigator.onLine === true
@ -469,7 +474,6 @@ define(
function setupLocalStorage() { function setupLocalStorage() {
if (localStorage["file.list"] === undefined) { if (localStorage["file.list"] === undefined) {
localStorage["file.list"] = ";"; localStorage["file.list"] = ";";
localStorage["version"] = "v2";
} }
} }
@ -488,12 +492,12 @@ define(
var fileIndexList = _.compact(localStorage["file.list"].split(";")); var fileIndexList = _.compact(localStorage["file.list"].split(";"));
_.each(fileIndexList, function(fileIndex) { _.each(fileIndexList, function(fileIndex) {
localStorage[fileIndex + ".publish"] = ";"; localStorage[fileIndex + ".publish"] = ";";
var fileSyncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";")); var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";"));
_.each(fileSyncIndexList, function(fileSyncIndex) { _.each(syncIndexList, function(syncIndex) {
localStorage[fileSyncIndex + ".contentCRC"] = "0"; localStorage[syncIndex + ".contentCRC"] = "0";
// We store title CRC only for Google Drive synchronization // We store title CRC only for Google Drive synchronization
if(localStorage[fileSyncIndex + ".etag"] !== undefined) { if(localStorage[syncIndex + ".etag"] !== undefined) {
localStorage[fileSyncIndex + ".titleCRC"] = "0"; localStorage[syncIndex + ".titleCRC"] = "0";
} }
}); });
}); });
@ -503,37 +507,41 @@ define(
// from v1 to v2 // from v1 to v2
if(version == "v1") { if(version == "v1") {
var gdriveLastChangeId = localStorage["sync.gdrive.lastChangeId"]; var gdriveLastChangeId = localStorage["sync.gdrive.lastChangeId"];
if(gdriveLastChangeId) {
localStorage["gdrive.lastChangeId"] = gdriveLastChangeId; localStorage["gdrive.lastChangeId"] = gdriveLastChangeId;
localStorage.removeItem("sync.gdrive.lastChangeId"); localStorage.removeItem("sync.gdrive.lastChangeId");
}
var dropboxLastChangeId = localStorage["sync.dropbox.lastChangeId"]; var dropboxLastChangeId = localStorage["sync.dropbox.lastChangeId"];
if(dropboxLastChangeId) {
localStorage["dropbox.lastChangeId"] = dropboxLastChangeId; localStorage["dropbox.lastChangeId"] = dropboxLastChangeId;
localStorage.removeItem("sync.dropbox.lastChangeId"); localStorage.removeItem("sync.dropbox.lastChangeId");
}
var SYNC_PROVIDER_GDRIVE = "sync." + PROVIDER_GDRIVE + "."; var SYNC_PROVIDER_GDRIVE = "sync." + PROVIDER_GDRIVE + ".";
var SYNC_PROVIDER_DROPBOX = "sync." + PROVIDER_DROPBOX + "."; var SYNC_PROVIDER_DROPBOX = "sync." + PROVIDER_DROPBOX + ".";
var fileIndexList = _.compact(localStorage["file.list"].split(";")); var fileIndexList = _.compact(localStorage["file.list"].split(";"));
_.each(fileIndexList, function(fileIndex) { _.each(fileIndexList, function(fileIndex) {
var fileSyncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";")); var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";"));
_.each(fileSyncIndexList, function(fileSyncIndex) { _.each(syncIndexList, function(syncIndex) {
var syncAttributes = {}; var syncAttributes = {};
if (fileSyncIndex.indexOf(SYNC_PROVIDER_GDRIVE) === 0) { if (syncIndex.indexOf(SYNC_PROVIDER_GDRIVE) === 0) {
syncAttributes.provider = PROVIDER_GDRIVE; syncAttributes.provider = PROVIDER_GDRIVE;
syncAttributes.id = fileSyncIndex.substring(SYNC_PROVIDER_GDRIVE.length); syncAttributes.id = syncIndex.substring(SYNC_PROVIDER_GDRIVE.length);
syncAttributes.etag = localStorage[fileSyncIndex + ".etag"]; syncAttributes.etag = localStorage[syncIndex + ".etag"];
syncAttributes.contentCRC = localStorage[fileSyncIndex + ".contentCRC"]; syncAttributes.contentCRC = localStorage[syncIndex + ".contentCRC"];
syncAttributes.titleCRC = localStorage[fileSyncIndex + ".titleCRC"]; syncAttributes.titleCRC = localStorage[syncIndex + ".titleCRC"];
} }
else if (fileSyncIndex.indexOf(SYNC_PROVIDER_DROPBOX) === 0) { else if (syncIndex.indexOf(SYNC_PROVIDER_DROPBOX) === 0) {
syncAttributes.provider = PROVIDER_DROPBOX; syncAttributes.provider = PROVIDER_DROPBOX;
syncAttributes.path = decodeURIComponent(fileSyncIndex.substring(SYNC_PROVIDER_DROPBOX.length)); syncAttributes.path = decodeURIComponent(syncIndex.substring(SYNC_PROVIDER_DROPBOX.length));
syncAttributes.version = localStorage[fileSyncIndex + ".version"]; syncAttributes.version = localStorage[syncIndex + ".version"];
syncAttributes.contentCRC = localStorage[fileSyncIndex + ".contentCRC"]; syncAttributes.contentCRC = localStorage[syncIndex + ".contentCRC"];
} }
localStorage[fileSyncIndex] = JSON.stringify(syncAttributes); localStorage[syncIndex] = JSON.stringify(syncAttributes);
localStorage.remoteItem(fileSyncIndex + ".etag"); localStorage.removeItem(syncIndex + ".etag");
localStorage.remoteItem(fileSyncIndex + ".version"); localStorage.removeItem(syncIndex + ".version");
localStorage.remoteItem(fileSyncIndex + ".contentCRC"); localStorage.removeItem(syncIndex + ".contentCRC");
localStorage.remoteItem(fileSyncIndex + ".titleCRC"); localStorage.removeItem(syncIndex + ".titleCRC");
}); });
}); });
version = "v2"; version = "v2";
@ -559,7 +567,7 @@ define(
+ left); + left);
}; };
core.init = function() { $(function() {
setupLocalStorage(); setupLocalStorage();
upgradeLocalStorage(); upgradeLocalStorage();
@ -626,38 +634,18 @@ define(
core.resetModalInputs(); core.resetModalInputs();
}); });
// Init asyncRunner
asyncRunner.init(core);
// Init helpers
googleHelper.init(core);
dropboxHelper.init(core);
githubHelper.init(core);
// Init synchronizer
synchronizer.init(core, fileManager);
// Init publisher
publisher.init(core, fileManager);
offlineListeners.push(synchronizer.updateSyncButton);
offlineListeners.push(publisher.updatePublishButton);
// Init file manager
fileManager.init(core);
// Do periodic tasks // Do periodic tasks
intervalId = window.setInterval(function() { intervalId = window.setInterval(function() {
updateCurrentTime(); updateCurrentTime();
core.checkWindowUnique(); core.checkWindowUnique();
if(isUserActive() === false) { if(isUserActive() === true) {
return; _.each(periodicCallbacks, function(callback) {
} callback();
synchronizer.sync(); });
asyncRunner.runTask();
checkOnline(); checkOnline();
}
}, 1000); }, 1000);
}; });
return core; return core;
}); });

View File

@ -1,7 +1,4 @@
define(["jquery", "async-runner"], function($, asyncRunner) { define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
// Dependencies
var core = undefined;
var client = undefined; var client = undefined;
var authenticated = false; var authenticated = false;
@ -317,9 +314,5 @@ define(["jquery", "async-runner"], function($, asyncRunner) {
asyncRunner.addTask(task); asyncRunner.addTask(task);
}; };
dropboxHelper.init = function(coreModule) {
core = coreModule;
};
return dropboxHelper; return dropboxHelper;
}); });

View File

@ -1,8 +1,4 @@
define(["jquery", "dropbox-helper"], function($, dropboxHelper) { define(["jquery", "core", "dropbox-helper"], function($, core, dropboxHelper) {
// Dependencies
var core = undefined;
var fileManager = undefined;
var dropboxProvider = { var dropboxProvider = {
providerId: PROVIDER_DROPBOX, providerId: PROVIDER_DROPBOX,
@ -31,7 +27,7 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
syncAttributes.path = path; syncAttributes.path = path;
syncAttributes.version = versionTag; syncAttributes.version = versionTag;
syncAttributes.contentCRC = core.crc32(content); syncAttributes.contentCRC = core.crc32(content);
var syncIndex = "sync." + PROVIDER_DROPBOX + "." + encodeURIComponent(file.path.toLowerCase()); var syncIndex = "sync." + PROVIDER_DROPBOX + "." + encodeURIComponent(path.toLowerCase());
localStorage[syncIndex] = JSON.stringify(syncAttributes); localStorage[syncIndex] = JSON.stringify(syncAttributes);
return syncIndex; return syncIndex;
} }
@ -47,8 +43,8 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
} }
_.each(result, function(file) { _.each(result, function(file) {
var syncIndex = createSyncAttributes(file.path, file.versionTag, file.content); var syncIndex = createSyncAttributes(file.path, file.versionTag, file.content);
var fileIndex = fileManager.createFile(file.name, file.content, [syncIndex]); var fileIndex = core.fileManager.createFile(file.name, file.content, [syncIndex]);
fileManager.selectFile(fileIndex); core.fileManager.selectFile(fileIndex);
core.showMessage('"' + file.name + '" imported successfully from Dropbox.'); core.showMessage('"' + file.name + '" imported successfully from Dropbox.');
}); });
}); });
@ -63,7 +59,7 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
var importPaths = []; var importPaths = [];
_.each(paths, function(path) { _.each(paths, function(path) {
var syncIndex = "sync." + PROVIDER_DROPBOX + "." + encodeURIComponent(path.toLowerCase()); var syncIndex = "sync." + PROVIDER_DROPBOX + "." + encodeURIComponent(path.toLowerCase());
var fileIndex = fileManager.getFileIndexFromSync(syncIndex); var fileIndex = core.fileManager.getFileIndexFromSync(syncIndex);
if(fileIndex !== undefined) { if(fileIndex !== undefined) {
var title = localStorage[fileIndex + ".title"]; var title = localStorage[fileIndex + ".title"];
core.showError('"' + title + '" was already imported'); core.showError('"' + title + '" was already imported');
@ -71,19 +67,19 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
} }
importPaths.push(path); importPaths.push(path);
}); });
dropboxHelper.importFiles(importPaths); importFilesFromPaths(importPaths);
}); });
}; };
function exportFileToPath(path, title, content, callback) { function exportFileToPath(path, title, content, callback) {
path = dropboxHelper.checkPath(path); path = checkPath(path);
if(path === undefined) { if(path === undefined) {
callback(true); callback(true);
return; return;
} }
// Check that file is not synchronized with an other one // Check that file is not synchronized with an other one
var syncIndex = "sync." + PROVIDER_DROPBOX + "." + encodeURIComponent(path.toLowerCase()); var syncIndex = "sync." + PROVIDER_DROPBOX + "." + encodeURIComponent(path.toLowerCase());
var fileIndex = fileManager.getFileIndexFromSync(syncIndex); var fileIndex = core.fileManager.getFileIndexFromSync(syncIndex);
if(fileIndex !== undefined) { if(fileIndex !== undefined) {
var existingTitle = localStorage[fileIndex + ".title"]; var existingTitle = localStorage[fileIndex + ".title"];
core.showError('File path is already synchronized with "' + existingTitle + '"'); core.showError('File path is already synchronized with "' + existingTitle + '"');
@ -102,12 +98,12 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
dropboxProvider.exportFile = function(event, title, content, callback) { dropboxProvider.exportFile = function(event, title, content, callback) {
var path = core.getInputValue($("#input-sync-export-dropbox-path"), event); var path = core.getInputValue($("#input-sync-export-dropbox-path"), event);
exportFileToPath(path); exportFileToPath(path, title, content, callback);
}; };
dropboxProvider.exportManual = function(event, title, content, callback) { dropboxProvider.exportManual = function(event, title, content, callback) {
var path = core.getInputValue($("#input-sync-manual-dropbox-path"), event); var path = core.getInputValue($("#input-sync-manual-dropbox-path"), event);
exportFileToPath(path); exportFileToPath(path, title, content, callback);
}; };
dropboxProvider.syncUp = function(uploadContent, uploadContentCRC, uploadTitle, uploadTitleCRC, syncAttributes, callback) { dropboxProvider.syncUp = function(uploadContent, uploadContentCRC, uploadTitle, uploadTitleCRC, syncAttributes, callback) {
@ -128,12 +124,12 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
}); });
}; };
function syncDown(callback) { dropboxProvider.syncDown = function(callback) {
if (dropboxProvider.useSync === false) { if (dropboxProvider.useSync === false) {
callback(); callback();
return; return;
} }
var lastChangeId = parseInt(localStorage[PROVIDER_DROPBOX + ".lastChangeId"]); var lastChangeId = localStorage[PROVIDER_DROPBOX + ".lastChangeId"];
dropboxHelper.checkChanges(lastChangeId, function(error, changes, newChangeId) { dropboxHelper.checkChanges(lastChangeId, function(error, changes, newChangeId) {
if (error) { if (error) {
callback(error); callback(error);
@ -141,7 +137,7 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
} }
var interestingChanges = []; var interestingChanges = [];
_.each(changes, function(change) { _.each(changes, function(change) {
var syncIndex = "sync." + PROVIDER_DROPBOX + "." + encodeURIComponent(file.path.toLowerCase()); var syncIndex = "sync." + PROVIDER_DROPBOX + "." + encodeURIComponent(change.path.toLowerCase());
var serializedAttributes = localStorage[syncIndex]; var serializedAttributes = localStorage[syncIndex];
if(serializedAttributes === undefined) { if(serializedAttributes === undefined) {
return; return;
@ -161,7 +157,7 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
change.syncAttributes = syncAttributes; change.syncAttributes = syncAttributes;
} }
}); });
dropboxHelper.downloadContent(changes, function(error, changes) { dropboxHelper.downloadContent(interestingChanges, function(error, changes) {
if (error) { if (error) {
callback(error); callback(error);
return; return;
@ -169,16 +165,16 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
var updateFileTitles = false; var updateFileTitles = false;
_.each(changes, function(change) { _.each(changes, function(change) {
var syncIndex = change.syncIndex; var syncIndex = change.syncIndex;
var fileIndex = fileManager.getFileIndexFromSync(syncIndex); var fileIndex = core.fileManager.getFileIndexFromSync(syncIndex);
// No file corresponding (file may have been deleted locally) // No file corresponding (file may have been deleted locally)
if(fileIndex === undefined) { if(fileIndex === undefined) {
fileManager.removeSync(syncIndex); core.fileManager.removeSync(syncIndex);
return; return;
} }
var localTitle = localStorage[fileIndex + ".title"]; var localTitle = localStorage[fileIndex + ".title"];
// File deleted // File deleted
if (change.wasRemoved === true) { if (change.wasRemoved === true) {
fileManager.removeSync(syncIndex); core.fileManager.removeSync(syncIndex);
updateFileTitles = true; updateFileTitles = true;
core.showMessage('"' + localTitle + '" has been removed from Dropbox.'); core.showMessage('"' + localTitle + '" has been removed from Dropbox.');
return; return;
@ -190,7 +186,7 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
var fileContentChanged = localContent != file.content; var fileContentChanged = localContent != file.content;
// Conflict detection // Conflict detection
if (fileContentChanged === true && localContentChanged === true) { if (fileContentChanged === true && localContentChanged === true) {
fileManager.createFile(localTitle + " (backup)", localContent); core.fileManager.createFile(localTitle + " (backup)", localContent);
updateFileTitles = true; updateFileTitles = true;
core.showMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.'); core.showMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.');
} }
@ -198,9 +194,9 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
if(fileContentChanged) { if(fileContentChanged) {
localStorage[fileIndex + ".content"] = file.content; localStorage[fileIndex + ".content"] = file.content;
core.showMessage('"' + localTitle + '" has been updated from Dropbox.'); core.showMessage('"' + localTitle + '" has been updated from Dropbox.');
if(fileManager.isCurrentFileIndex(fileIndex)) { if(core.fileManager.isCurrentFileIndex(fileIndex)) {
updateFileTitles = false; // Done by next function updateFileTitles = false; // Done by next function
fileManager.selectFile(); // Refresh editor core.fileManager.selectFile(); // Refresh editor
} }
} }
// Update syncAttributes // Update syncAttributes
@ -209,13 +205,13 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
localStorage[syncIndex] = JSON.stringify(syncAttributes); localStorage[syncIndex] = JSON.stringify(syncAttributes);
}); });
if(updateFileTitles) { if(updateFileTitles) {
fileManager.updateFileTitles(); core.fileManager.updateFileTitles();
} }
localStorage[PROVIDER_DROPBOX + ".lastChangeId"] = newChangeId; localStorage[PROVIDER_DROPBOX + ".lastChangeId"] = newChangeId;
callback(); callback();
}); });
}); });
} };
dropboxProvider.publish = function(publishAttributes, title, content, callback) { dropboxProvider.publish = function(publishAttributes, title, content, callback) {
var path = checkPath(publishAttributes.path); var path = checkPath(publishAttributes.path);
@ -235,10 +231,5 @@ define(["jquery", "dropbox-helper"], function($, dropboxHelper) {
return publishAttributes; return publishAttributes;
}; };
dropboxProvider.init = function(coreModule, fileManagerModule) {
core = coreModule;
fileManager = fileManagerModule;
};
return dropboxProvider; return dropboxProvider;
}); });

View File

@ -1,10 +1,9 @@
define(["jquery", "google-helper", "dropbox-helper", "github-helper", "synchronizer", "publisher", "underscore"], define(["jquery", "core", "synchronizer", "publisher", "underscore"],
function($, googleHelper, dropboxHelper, githubHelper, synchronizer, publisher) { function($, core, synchronizer, publisher) {
var fileManager = {}; var fileManager = {};
// To avoid circle inclusion
// Dependencies core.fileManager = fileManager;
var core = undefined;
// Defines the current file // Defines the current file
var currentFileIndex = localStorage["file.current"]; var currentFileIndex = localStorage["file.current"];
@ -141,7 +140,7 @@ define(["jquery", "google-helper", "dropbox-helper", "github-helper", "synchroni
var result = " " + localStorage[fileIndex + ".title"]; var result = " " + localStorage[fileIndex + ".title"];
var providerIdList = synchronizer.getSyncProvidersFromFile(fileIndex); var providerIdList = synchronizer.getSyncProvidersFromFile(fileIndex);
_.each(providerIdList, function(providerId) { _.each(providerIdList, function(providerId) {
result = '<i class="icon-' + providerId '"></i>' + result; result = '<i class="icon-' + providerId + '"></i>' + result;
}); });
return result; return result;
} }
@ -217,9 +216,7 @@ define(["jquery", "google-helper", "dropbox-helper", "github-helper", "synchroni
}).value(); }).value();
}; };
fileManager.init = function(coreModule) { $(function() {
core = coreModule;
fileManager.selectFile(); fileManager.selectFile();
$(".action-create-file").click(function() { $(".action-create-file").click(function() {
@ -280,7 +277,7 @@ define(["jquery", "google-helper", "dropbox-helper", "github-helper", "synchroni
+ core.encodeBase64(content); + core.encodeBase64(content);
window.open(uriContent, 'file'); window.open(uriContent, 'file');
}); });
}; });
return fileManager; return fileManager;
}); });

View File

@ -1,12 +1,8 @@
define(["jquery", "google-helper", "underscore"], function($, googleHelper) { define(["jquery", "core", "google-helper", "underscore"], function($, core, googleHelper) {
// Dependencies
var core = undefined;
var fileManager = undefined;
var gdriveProvider = { var gdriveProvider = {
providerId: PROVIDER_GDRIVE, providerId: PROVIDER_GDRIVE,
providerName: "Gdrive", providerName: "Google Drive",
defaultPublishFormat: "template", defaultPublishFormat: "template",
useSync: false useSync: false
}; };
@ -18,7 +14,7 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
syncAttributes.etag = etag; syncAttributes.etag = etag;
syncAttributes.contentCRC = core.crc32(content); syncAttributes.contentCRC = core.crc32(content);
syncAttributes.titleCRC = core.crc32(title); syncAttributes.titleCRC = core.crc32(title);
var syncIndex = "sync." + PROVIDER_GDRIVE + "." + file.id; var syncIndex = "sync." + PROVIDER_GDRIVE + "." + id;
localStorage[syncIndex] = JSON.stringify(syncAttributes); localStorage[syncIndex] = JSON.stringify(syncAttributes);
return syncIndex; return syncIndex;
} }
@ -34,8 +30,8 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
} }
_.each(result, function(file) { _.each(result, function(file) {
var syncIndex = createSyncAttributes(file.id, file.etag, file.content, file.title); var syncIndex = createSyncAttributes(file.id, file.etag, file.content, file.title);
var fileIndex = fileManager.createFile(file.title, file.content, [syncIndex]); var fileIndex = core.fileManager.createFile(file.title, file.content, [syncIndex]);
fileManager.selectFile(fileIndex); core.fileManager.selectFile(fileIndex);
core.showMessage('"' + file.title + '" imported successfully from Google Drive.'); core.showMessage('"' + file.title + '" imported successfully from Google Drive.');
}); });
}); });
@ -50,7 +46,7 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
var importIds = []; var importIds = [];
_.each(ids, function(id) { _.each(ids, function(id) {
var syncIndex = "sync." + PROVIDER_GDRIVE + "." + id; var syncIndex = "sync." + PROVIDER_GDRIVE + "." + id;
var fileIndex = fileManager.getFileIndexFromSync(syncIndex); var fileIndex = core.fileManager.getFileIndexFromSync(syncIndex);
if(fileIndex !== undefined) { if(fileIndex !== undefined) {
var title = localStorage[fileIndex + ".title"]; var title = localStorage[fileIndex + ".title"];
core.showError('"' + title + '" was already imported'); core.showError('"' + title + '" was already imported');
@ -80,7 +76,7 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
} }
// Check that file is not synchronized with an other one // Check that file is not synchronized with an other one
var syncIndex = "sync." + PROVIDER_GDRIVE + "." + id; var syncIndex = "sync." + PROVIDER_GDRIVE + "." + id;
var fileIndex = fileManager.getFileIndexFromSync(syncIndex); var fileIndex = core.fileManager.getFileIndexFromSync(syncIndex);
if(fileIndex !== undefined) { if(fileIndex !== undefined) {
var existingTitle = localStorage[fileIndex + ".title"]; var existingTitle = localStorage[fileIndex + ".title"];
core.showError('File ID is already synchronized with "' + existingTitle + '"'); core.showError('File ID is already synchronized with "' + existingTitle + '"');
@ -117,7 +113,7 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
}); });
}; };
function syncDown(callback) { gdriveProvider.syncDown = function(callback) {
if (gdriveProvider.useSync === false) { if (gdriveProvider.useSync === false) {
callback(); callback();
return; return;
@ -130,7 +126,7 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
} }
var interestingChanges = []; var interestingChanges = [];
_.each(changes, function(change) { _.each(changes, function(change) {
var syncIndex = "sync." + PROVIDER_GDRIVE + "." + file.id; var syncIndex = "sync." + PROVIDER_GDRIVE + "." + change.fileId;
var serializedAttributes = localStorage[syncIndex]; var serializedAttributes = localStorage[syncIndex];
if(serializedAttributes === undefined) { if(serializedAttributes === undefined) {
return; return;
@ -150,7 +146,7 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
change.syncAttributes = syncAttributes; change.syncAttributes = syncAttributes;
} }
}); });
googleHelper.downloadContent(changes, function(error, changes) { googleHelper.downloadContent(interestingChanges, function(error, changes) {
if (error) { if (error) {
callback(error); callback(error);
return; return;
@ -158,16 +154,16 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
var updateFileTitles = false; var updateFileTitles = false;
_.each(changes, function(change) { _.each(changes, function(change) {
var syncIndex = change.syncIndex; var syncIndex = change.syncIndex;
var fileIndex = fileManager.getFileIndexFromSync(syncIndex); var fileIndex = core.fileManager.getFileIndexFromSync(syncIndex);
// No file corresponding (file may have been deleted locally) // No file corresponding (file may have been deleted locally)
if(fileIndex === undefined) { if(fileIndex === undefined) {
fileManager.removeSync(syncIndex); core.fileManager.removeSync(syncIndex);
return; return;
} }
var localTitle = localStorage[fileIndex + ".title"]; var localTitle = localStorage[fileIndex + ".title"];
// File deleted // File deleted
if (change.deleted === true) { if (change.deleted === true) {
fileManager.removeSync(syncIndex); core.fileManager.removeSync(syncIndex);
updateFileTitles = true; updateFileTitles = true;
core.showMessage('"' + localTitle + '" has been removed from Google Drive.'); core.showMessage('"' + localTitle + '" has been removed from Google Drive.');
return; return;
@ -182,7 +178,7 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
// Conflict detection // Conflict detection
if ((fileTitleChanged === true && localTitleChanged === true) if ((fileTitleChanged === true && localTitleChanged === true)
|| (fileContentChanged === true && localContentChanged === true)) { || (fileContentChanged === true && localContentChanged === true)) {
fileManager.createFile(localTitle + " (backup)", localContent); core.fileManager.createFile(localTitle + " (backup)", localContent);
updateFileTitles = true; updateFileTitles = true;
core.showMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.'); core.showMessage('Conflict detected on "' + localTitle + '". A backup has been created locally.');
} }
@ -196,9 +192,9 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
if(fileContentChanged) { if(fileContentChanged) {
localStorage[fileIndex + ".content"] = file.content; localStorage[fileIndex + ".content"] = file.content;
core.showMessage('"' + file.title + '" has been updated from Google Drive.'); core.showMessage('"' + file.title + '" has been updated from Google Drive.');
if(fileManager.isCurrentFileIndex(fileIndex)) { if(core.fileManager.isCurrentFileIndex(fileIndex)) {
updateFileTitles = false; // Done by next function updateFileTitles = false; // Done by next function
fileManager.selectFile(); // Refresh editor core.fileManager.selectFile(); // Refresh editor
} }
} }
// Update syncAttributes // Update syncAttributes
@ -208,36 +204,48 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
localStorage[syncIndex] = JSON.stringify(syncAttributes); localStorage[syncIndex] = JSON.stringify(syncAttributes);
}); });
if(updateFileTitles) { if(updateFileTitles) {
fileManager.updateFileTitles(); core.fileManager.updateFileTitles();
} }
localStorage[PROVIDER_GDRIVE + ".lastChangeId"] = newChangeId; localStorage[PROVIDER_GDRIVE + ".lastChangeId"] = newChangeId;
callback(); callback();
}); });
}); });
} };
gdriveProvider.publish = function(publishAttributes, title, content, callback) { gdriveProvider.publish = function(publishAttributes, title, content, callback) {
googleHelper.upload(publishAttributes.fileId, undefined, title, content, undefined, callback); googleHelper.upload(
publishAttributes.fileId,
undefined,
publishAttributes.fileName || title,
content,
undefined,
function(error, result) {
if(error) {
callback(error);
return;
}
publishAttributes.fileId = result.id;
callback();
}
);
}; };
gdriveProvider.newPublishAttributes = function(event) { gdriveProvider.newPublishAttributes = function(event) {
var publishAttributes = {}; var publishAttributes = {};
publishAttributes.fileId = $("#input-publish-gdrive-fileid").val() || undefined; publishAttributes.fileId = $("#input-publish-gdrive-fileid").val() || undefined;
publishAttributes.fileName = $("#input-publish-gdrive-filename").val() || undefined;
if(event.isPropagationStopped()) { if(event.isPropagationStopped()) {
return undefined; return undefined;
} }
return publishAttributes; return publishAttributes;
}; };
gdriveProvider.init = function(coreModule, fileManagerModule) { $(function() {
core = coreModule; var state = localStorage[PROVIDER_GDRIVE + ".state"];
fileManager = fileManagerModule;
var state = localStorage["sync.gdrive.state"];
if(state === undefined) { if(state === undefined) {
return; return;
} }
localStorage.removeItem("sync.gdrive.state"); localStorage.removeItem(PROVIDER_GDRIVE + ".state");
state = JSON.parse(state); state = JSON.parse(state);
if (state.action == "create") { if (state.action == "create") {
googleHelper.upload(undefined, state.folderId, GDRIVE_DEFAULT_FILE_TITLE, googleHelper.upload(undefined, state.folderId, GDRIVE_DEFAULT_FILE_TITLE,
@ -265,7 +273,7 @@ define(["jquery", "google-helper", "underscore"], function($, googleHelper) {
}); });
importFilesFromIds(importIds); importFilesFromIds(importIds);
} }
}; });
return gdriveProvider; return gdriveProvider;
}); });

View File

@ -1,7 +1,4 @@
define(["jquery", "async-runner"], function($, asyncRunner) { define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
// Dependencies
var core = undefined;
var connected = undefined; var connected = undefined;
var github = undefined; var github = undefined;
@ -10,7 +7,6 @@ define(["jquery", "async-runner"], function($, asyncRunner) {
// Try to connect github by downloading js file // Try to connect github by downloading js file
function connect(task) { function connect(task) {
callback = callback || core.doNothing;
task.onRun(function() { task.onRun(function() {
if(core.isOffline === true) { if(core.isOffline === true) {
connected = false; connected = false;
@ -161,9 +157,5 @@ define(["jquery", "async-runner"], function($, asyncRunner) {
asyncRunner.addTask(task); asyncRunner.addTask(task);
}; };
githubHelper.init = function(coreModule) {
core = coreModule;
};
return githubHelper; return githubHelper;
}); });

View File

@ -1,7 +1,4 @@
define(["jquery", "github-helper"], function($, githubHelper) { define(["jquery", "core", "github-helper"], function($, core, githubHelper) {
// Dependencies
var core = undefined;
var githubProvider = { var githubProvider = {
providerId: PROVIDER_GITHUB, providerId: PROVIDER_GITHUB,
@ -25,9 +22,5 @@ define(["jquery", "github-helper"], function($, githubHelper) {
return publishAttributes; return publishAttributes;
}; };
githubProvider.init = function(coreModule) {
core = coreModule;
};
return githubProvider; return githubProvider;
}); });

View File

@ -1,7 +1,4 @@
define(["jquery", "async-runner"], function($, asyncRunner) { define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
// Dependencies
var core = undefined;
var connected = false; var connected = false;
var authenticated = false; var authenticated = false;
@ -132,7 +129,7 @@ define(["jquery", "async-runner"], function($, asyncRunner) {
// Handle error // Handle error
if(error !== undefined && fileId !== undefined) { if(error !== undefined && fileId !== undefined) {
if(error.code === 404) { if(error.code === 404) {
error = 'File ID "' + fileId + '" does not exist on Google Drive.'; error = 'File ID "' + fileId + '" not found on Google Drive.|removePublish';
} }
else if(error.code === 412) { else if(error.code === 412) {
// We may have missed a file update // We may have missed a file update
@ -235,7 +232,7 @@ define(["jquery", "async-runner"], function($, asyncRunner) {
}; };
// Handle error // Handle error
if(error.code === 404) { if(error.code === 404) {
error = 'File ID "' + id + '" does not exist on Google Drive.'; error = 'File ID "' + id + '" not found on Google Drive.';
} }
handleError(error, task, callback); handleError(error, task, callback);
}); });
@ -458,7 +455,7 @@ define(["jquery", "async-runner"], function($, asyncRunner) {
}; };
// Handle error // Handle error
if(error.code === 404 && postId !== undefined) { if(error.code === 404 && postId !== undefined) {
error = 'Post ' + postId + ' not found on Blogger.'; error = 'Post ' + postId + ' not found on Blogger.|removePublish';
} }
handleError(error, task, callback); handleError(error, task, callback);
}); });
@ -483,25 +480,21 @@ define(["jquery", "async-runner"], function($, asyncRunner) {
}; };
// Handle error // Handle error
if(error.code === 404) { if(error.code === 404) {
error = 'Blog "' + blogUrl + '" not found on Blogger.'; error = 'Blog "' + blogUrl + '" not found on Blogger.|removePublish';
} }
handleError(error, task, callback); handleError(error, task, callback);
}); });
} }
task.chain(getBlogId); task.chain(getBlogId);
}); });
task.onSuccess = function() { task.onSuccess(function() {
callback(undefined, blogId, postId); callback(undefined, blogId, postId);
}; });
task.onError = function(error) { task.onError(function(error) {
callback(error); callback(error);
}; });
asyncRunner.addTask(task); asyncRunner.addTask(task);
}; };
googleHelper.init = function(coreModule) {
core = coreModule;
};
return googleHelper; return googleHelper;
}); });

10
js/main-min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -12,9 +12,8 @@ requirejs.config({
} }
}); });
require(["jquery", "core"], function($, core) { require(["jquery", "file-manager", "synchronizer", "publisher"], function($) {
$(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) {
@ -24,7 +23,5 @@ require(["jquery", "core"], function($, core) {
} }
}, false); }, false);
} }
core.init();
}); });
}); });

View File

@ -1,12 +1,8 @@
define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gdrive-provider", "underscore"], function($) { define(["jquery", "core", "github-provider", "blogger-provider", "dropbox-provider", "gdrive-provider", "underscore"], function($, core) {
// Dependencies
var core = undefined;
var fileManager = undefined;
var publisher = {}; var publisher = {};
// Create a map with providerName: providerObject // Create a map with providerId: providerObject
var providerMap = _.chain(arguments) var providerMap = _.chain(arguments)
.map(function(argument) { .map(function(argument) {
return argument && argument.providerId && [argument.providerId, argument]; return argument && argument.providerId && [argument.providerId, argument];
@ -17,7 +13,7 @@ define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gd
// Allows external modules to update hasPublications flag // Allows external modules to update hasPublications flag
publisher.notifyPublish = function() { publisher.notifyPublish = function() {
var fileIndex = fileManager.getCurrentFileIndex(); var fileIndex = core.fileManager.getCurrentFileIndex();
// Check that file has publications // Check that file has publications
if(localStorage[fileIndex + ".publish"].length === 1) { if(localStorage[fileIndex + ".publish"].length === 1) {
@ -42,7 +38,7 @@ define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gd
// Apply template to the current document // Apply template to the current document
publisher.applyTemplate = function(publishAttributes) { publisher.applyTemplate = function(publishAttributes) {
var fileIndex = fileManager.getCurrentFileIndex(); var fileIndex = core.fileManager.getCurrentFileIndex();
try { try {
return _.template(core.settings.template, { return _.template(core.settings.template, {
documentTitle: localStorage[fileIndex + ".title"], documentTitle: localStorage[fileIndex + ".title"],
@ -91,6 +87,10 @@ define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gd
// Call the provider // Call the provider
var provider = providerMap[publishAttributes.provider]; var provider = providerMap[publishAttributes.provider];
provider.publish(publishAttributes, publishTitle, content, function(error) { provider.publish(publishAttributes, publishTitle, content, function(error) {
if(error !== undefined && error.toString().indexOf("|removePublish") !== -1) {
core.fileManager.removePublish(publishIndex);
core.showMessage(provider.providerName + " publish location has been removed.");
}
publishLocation(callback, errorFlag || error ); publishLocation(callback, errorFlag || error );
}); });
} }
@ -104,7 +104,7 @@ define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gd
publishRunning = true; publishRunning = true;
publisher.updatePublishButton(); publisher.updatePublishButton();
var fileIndex = fileManager.getCurrentFileIndex(); var fileIndex = core.fileManager.getCurrentFileIndex();
publishTitle = localStorage[fileIndex + ".title"]; publishTitle = localStorage[fileIndex + ".title"];
publishIndexList = _.compact(localStorage[fileIndex + ".publish"].split(";")); publishIndexList = _.compact(localStorage[fileIndex + ".publish"].split(";"));
publishLocation(function(errorFlag) { publishLocation(function(errorFlag) {
@ -151,7 +151,7 @@ define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gd
if(publishAttributes === undefined) { if(publishAttributes === undefined) {
return; return;
} }
var fileIndex = fileManager.getCurrentFileIndex(); var fileIndex = core.fileManager.getCurrentFileIndex();
var title = localStorage[fileIndex + ".title"]; var title = localStorage[fileIndex + ".title"];
var content = getPublishContent(publishAttributes); var content = getPublishContent(publishAttributes);
provider.publish(publishAttributes, title, content, function(error) { provider.publish(publishAttributes, title, content, function(error) {
@ -173,7 +173,7 @@ define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gd
'</div>'].join(""); '</div>'].join("");
var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>'; var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>';
publisher.refreshManagePublish = function() { publisher.refreshManagePublish = function() {
var fileIndex = fileManager.getCurrentFileIndex(); var fileIndex = core.fileManager.getCurrentFileIndex();
var publishIndexList = _.compact(localStorage[fileIndex + ".publish"].split(";")); var publishIndexList = _.compact(localStorage[fileIndex + ".publish"].split(";"));
$(".msg-no-publish, .msg-publish-list").addClass("hide"); $(".msg-no-publish, .msg-publish-list").addClass("hide");
$("#manage-publish-list .input-append").remove(); $("#manage-publish-list .input-append").remove();
@ -190,19 +190,17 @@ define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gd
publishDesc: publishDesc publishDesc: publishDesc
})); }));
lineElement.append($(removeButtonTemplate).click(function() { lineElement.append($(removeButtonTemplate).click(function() {
fileManager.removePublish(publishIndex); core.fileManager.removePublish(publishIndex);
})); }));
$("#manage-publish-list").append(lineElement); $("#manage-publish-list").append(lineElement);
}); });
}; };
publisher.init = function(coreModule, fileManagerModule) { $(function() {
core = coreModule; core.addOfflineListener(publisher.updatePublishButton);
fileManager = fileManagerModule;
// Init each provider // Init each provider
_.each(providerMap, function(provider) { _.each(providerMap, function(provider) {
provider.init(core, fileManager);
// Publish provider button // Publish provider button
$(".action-publish-" + provider.providerId).click(function() { $(".action-publish-" + provider.providerId).click(function() {
initNewLocation(provider); initNewLocation(provider);
@ -243,7 +241,7 @@ define(["jquery", "github-provider", "blogger-provider", "dropbox-provider", "gd
$(document).click(function(e) { $(document).click(function(e) {
$(".tooltip-template").tooltip('hide'); $(".tooltip-template").tooltip('hide');
}); });
}; });
return publisher; return publisher;
}); });

View File

@ -1,20 +1,12 @@
define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive-provider"], function($, googleHelper, dropboxHelper) { define(["jquery", "core", "dropbox-provider", "gdrive-provider", "underscore"], function($, core) {
var synchronizer = {}; var synchronizer = {};
// Dependencies // Create a map with providerId: providerObject
var core = undefined;
var fileManager = undefined;
// Create a map with providerName: providerObject
var providerMap = _.chain(arguments) var providerMap = _.chain(arguments)
.map(function(argument) { .map(function(argument) {
return argument && argument.providerId && [argument.providerId, argument]; return argument && argument.providerId && [argument.providerId, argument];
}).compact().object().value(); }).compact().object().value();
// Used to know the providers we are connected to
synchronizer.useGoogleDrive = false;
synchronizer.useDropbox = false;
// Used to know if user can force synchronization // Used to know if user can force synchronization
var uploadPending = false; var uploadPending = false;
@ -116,7 +108,7 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
locationUp(callback); locationUp(callback);
} }
// Used to upload document changes from local storage // Entry point for up synchronization (upload changes)
var uploadCycle = false; var uploadCycle = false;
function syncUp(callback) { function syncUp(callback) {
if(uploadCycle === true) { if(uploadCycle === true) {
@ -135,6 +127,7 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
function providerDown(callback) { function providerDown(callback) {
if(providerList.length === 0) { if(providerList.length === 0) {
callback(); callback();
return;
} }
var provider = providerList.pop(); var provider = providerList.pop();
provider.syncDown(function(error) { provider.syncDown(function(error) {
@ -146,11 +139,13 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
}); });
} }
// Entry point for down synchronization (download changes)
function syncDown(callback) { function syncDown(callback) {
providerList = _.values(providerMap); providerList = _.values(providerMap);
providerDown(callback); providerDown(callback);
}; };
// Main entry point for synchronization
var syncRunning = false; var syncRunning = false;
var lastSync = 0; var lastSync = 0;
synchronizer.sync = function() { synchronizer.sync = function() {
@ -195,7 +190,7 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
'</div>'].join(""); '</div>'].join("");
var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>'; var removeButtonTemplate = '<a class="btn" title="Remove this location"><i class="icon-trash"></i></a>';
synchronizer.refreshManageSync = function() { synchronizer.refreshManageSync = function() {
var fileIndex = fileManager.getCurrentFileIndex(); var fileIndex = core.fileManager.getCurrentFileIndex();
var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";")); var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";"));
$(".msg-no-sync, .msg-sync-list").addClass("hide"); $(".msg-no-sync, .msg-sync-list").addClass("hide");
$("#manage-sync-list .input-append").remove(); $("#manage-sync-list .input-append").remove();
@ -212,19 +207,19 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
syncDesc: syncDesc syncDesc: syncDesc
})); }));
lineElement.append($(removeButtonTemplate).click(function() { lineElement.append($(removeButtonTemplate).click(function() {
fileManager.removeSync(syncIndex); core.fileManager.removeSync(syncIndex);
fileManager.updateFileTitles(); core.fileManager.updateFileTitles();
})); }));
$("#manage-sync-list").append(lineElement); $("#manage-sync-list").append(lineElement);
}); });
}; };
// Used to enable/disable providers' synchronization
synchronizer.resetSyncFlags = function() { synchronizer.resetSyncFlags = function() {
_.each(providerMap, function(provider) { _.each(providerMap, function(provider) {
provider.useSync = false; provider.useSync = false;
}); });
}; };
synchronizer.getSyncProvidersFromFile = function(fileIndex) { synchronizer.getSyncProvidersFromFile = function(fileIndex) {
var sync = localStorage[fileIndex + ".sync"]; var sync = localStorage[fileIndex + ".sync"];
var providerIdList = []; var providerIdList = [];
@ -237,20 +232,19 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
return providerIdList; return providerIdList;
}; };
synchronizer.init = function(coreModule, fileManagerModule) { $(function() {
core = coreModule; core.addOfflineListener(synchronizer.updateSyncButton);
fileManager = fileManagerModule; core.addPeriodicCallback(synchronizer.sync);
// Init each provider // Init each provider
_.each(providerMap, function(provider) { _.each(providerMap, function(provider) {
provider.init(core, fileManager);
// Provider's import button // Provider's import button
$(".action-sync-import-" + provider.providerId).click(function(event) { $(".action-sync-import-" + provider.providerId).click(function(event) {
provider.importFiles(event); provider.importFiles(event);
}); });
// Provider's export button // Provider's export button
$(".action-sync-export-" + provider.providerId).click(function(event) { $(".action-sync-export-" + provider.providerId).click(function(event) {
var fileIndex = fileManager.getCurrentFileIndex(); var fileIndex = core.fileManager.getCurrentFileIndex();
var title = localStorage[fileIndex + ".title"]; var title = localStorage[fileIndex + ".title"];
var content = localStorage[fileIndex + ".content"]; var content = localStorage[fileIndex + ".content"];
provider.exportFile(event, title, content, function(error, syncIndex) { provider.exportFile(event, title, content, function(error, syncIndex) {
@ -259,14 +253,14 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
} }
localStorage[fileIndex + ".sync"] += syncIndex + ";"; localStorage[fileIndex + ".sync"] += syncIndex + ";";
synchronizer.refreshManageSync(); synchronizer.refreshManageSync();
fileManager.updateFileTitles(); core.fileManager.updateFileTitles();
core.showMessage('"' + title core.showMessage('"' + title
+ '" will now be synchronized on ' + provider.providerName + '.'); + '" will now be synchronized on ' + provider.providerName + '.');
}); });
}); });
// Provider's manual sync button // Provider's manual sync button
$(".action-sync-manual-" + provider.providerId).click(function(event) { $(".action-sync-manual-" + provider.providerId).click(function(event) {
var fileIndex = fileManager.getCurrentFileIndex(); var fileIndex = core.fileManager.getCurrentFileIndex();
var title = localStorage[fileIndex + ".title"]; var title = localStorage[fileIndex + ".title"];
var content = localStorage[fileIndex + ".content"]; var content = localStorage[fileIndex + ".content"];
provider.exportManual(event, title, content, function(error, syncIndex) { provider.exportManual(event, title, content, function(error, syncIndex) {
@ -275,7 +269,7 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
} }
localStorage[fileIndex + ".sync"] += syncIndex + ";"; localStorage[fileIndex + ".sync"] += syncIndex + ";";
synchronizer.refreshManageSync(); synchronizer.refreshManageSync();
fileManager.updateFileTitles(); core.fileManager.updateFileTitles();
core.showMessage('"' + title core.showMessage('"' + title
+ '" will now be synchronized on ' + provider.providerName + '.'); + '" will now be synchronized on ' + provider.providerName + '.');
}); });
@ -288,7 +282,7 @@ define(["jquery", "google-helper", "dropbox-helper", "dropbox-provider", "gdrive
synchronizer.forceSync(); synchronizer.forceSync();
} }
}); });
}; });
return synchronizer; return synchronizer;
}); });

6
optimize-css.json Normal file
View File

@ -0,0 +1,6 @@
// RequireJS optimizer configuration file
// Usage: node r.js -o optimize-css.json
({
cssIn: "css/main.css",
out: "css/main-min.css"
})

View File

@ -1,8 +1,8 @@
// RequireJS optimizer configuration file // RequireJS optimizer configuration file
// Usage: node r.js -o optimize.json // Usage: node r.js -o optimize-js.json
({ ({
baseUrl: "js", baseUrl: "js",
name: "main", name: "main",
out: "js/main-min.js", out: "js/main-min.js",
mainConfigFile: 'js/main.js' mainConfigFile: 'js/main.js',
}) })