Changed how files are removed from localStorage

This commit is contained in:
benweet 2014-04-11 00:22:30 +01:00
parent 14ec21101b
commit 3b30813e3d
17 changed files with 152 additions and 174 deletions

View File

@ -12,12 +12,10 @@
"ejs": "~0.8.4" "ejs": "~0.8.4"
}, },
"devDependencies": { "devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-requirejs": "~0.4.1", "grunt-contrib-requirejs": "~0.4.1",
"grunt-contrib-less": "~0.7.0", "grunt-contrib-less": "~0.7.0",
"grunt-string-replace": "~0.2.4", "grunt-string-replace": "~0.2.4",
"grunt-contrib-copy": "~0.4.1", "grunt-contrib-copy": "~0.4.1",
"bower": "~1.2.5",
"grunt-bower-requirejs": "~0.7.1", "grunt-bower-requirejs": "~0.7.1",
"grunt-bower-task": "~0.3.1", "grunt-bower-task": "~0.3.1",
"grunt-bump": "0.0.11", "grunt-bump": "0.0.11",

View File

@ -106,7 +106,6 @@ define([
FileDescriptor.prototype.removeSyncLocation = function(syncAttributes) { FileDescriptor.prototype.removeSyncLocation = function(syncAttributes) {
utils.removeIndexFromArray(this.fileIndex + ".sync", syncAttributes.syncIndex); utils.removeIndexFromArray(this.fileIndex + ".sync", syncAttributes.syncIndex);
delete this.syncLocations[syncAttributes.syncIndex]; delete this.syncLocations[syncAttributes.syncIndex];
storage.removeItem(syncAttributes.syncIndex);
}; };
FileDescriptor.prototype.addPublishLocation = function(publishAttributes) { FileDescriptor.prototype.addPublishLocation = function(publishAttributes) {
@ -118,7 +117,6 @@ define([
FileDescriptor.prototype.removePublishLocation = function(publishAttributes) { FileDescriptor.prototype.removePublishLocation = function(publishAttributes) {
utils.removeIndexFromArray(this.fileIndex + ".publish", publishAttributes.publishIndex); utils.removeIndexFromArray(this.fileIndex + ".publish", publishAttributes.publishIndex);
delete this.publishLocations[publishAttributes.publishIndex]; delete this.publishLocations[publishAttributes.publishIndex];
storage.removeItem(publishAttributes.publishIndex);
}; };
FileDescriptor.prototype.composeTitle = function() { FileDescriptor.prototype.composeTitle = function() {

View File

@ -49,15 +49,25 @@ define([
return content; return content;
}; };
Provider.prototype.parseSerializedContent = function(content) { Provider.prototype.parseContent = function(content) {
if(!_.isString(content)) {
// Real time content is already an object
return {
content: content.content,
discussionList: content.discussionList,
discussionListJSON: JSON.stringify(content.discussionList)
};
}
var discussionList;
var discussionListJSON = '{}'; var discussionListJSON = '{}';
var discussionExtractor = /<!--se_discussion_list:([\s\S]+)-->$/.exec(content); var discussionExtractor = /<!--se_discussion_list:([\s\S]+)-->$/.exec(content);
if(discussionExtractor && this.parseDiscussionList(discussionExtractor[1])) { if(discussionExtractor && (discussionList = this.parseDiscussionList(discussionExtractor[1]))) {
content = content.substring(0, discussionExtractor.index); content = content.substring(0, discussionExtractor.index);
discussionListJSON = discussionExtractor[1]; discussionListJSON = discussionExtractor[1];
} }
return { return {
content: content, content: content,
discussionList: discussionList || {},
discussionListJSON: discussionListJSON discussionListJSON: discussionListJSON
}; };
}; };

View File

@ -376,7 +376,7 @@ define([
// Create discussion index // Create discussion index
var discussionIndex; var discussionIndex;
do { do {
discussionIndex = utils.randomString() + utils.randomString(); // Increased size to prevent collision discussionIndex = utils.randomString();
} while(_.has(discussionList, discussionIndex)); } while(_.has(discussionList, discussionIndex));
discussion.discussionIndex = discussionIndex; discussion.discussionIndex = discussionIndex;
discussionList[discussionIndex] = discussion; discussionList[discussionIndex] = discussion;

View File

@ -106,8 +106,6 @@ define([
// Delete folders // Delete folders
_.each(selectedFolderList, function(folderDesc) { _.each(selectedFolderList, function(folderDesc) {
utils.removeIndexFromArray("folder.list", folderDesc.folderIndex); utils.removeIndexFromArray("folder.list", folderDesc.folderIndex);
storage.removeItem(folderDesc.folderIndex + ".name");
storage.removeItem(folderDesc.folderIndex + ".files");
delete folderList[folderDesc.folderIndex]; delete folderList[folderDesc.folderIndex];
}); });
eventMgr.onFoldersChanged(); eventMgr.onFoldersChanged();

View File

@ -110,6 +110,8 @@ define([
utils.removeIndexFromArray("file.list", fileDesc.fileIndex); utils.removeIndexFromArray("file.list", fileDesc.fileIndex);
delete fileSystem[fileDesc.fileIndex]; delete fileSystem[fileDesc.fileIndex];
// Don't bother with fields in localStorage, they will be removed on next page load
if(fileMgr.currentFile === fileDesc) { if(fileMgr.currentFile === fileDesc) {
// Unset the current fileDesc // Unset the current fileDesc
fileMgr.currentFile = undefined; fileMgr.currentFile = undefined;
@ -117,27 +119,6 @@ define([
fileMgr.selectFile(); fileMgr.selectFile();
} }
// Remove synchronized locations from storage
_.each(fileDesc.syncLocations, function(syncAttributes) {
storage.removeItem(syncAttributes.syncIndex);
});
// Remove publish locations from storage
_.each(fileDesc.publishLocations, function(publishAttributes) {
storage.removeItem(publishAttributes.publishIndex);
});
storage.removeItem(fileDesc.fileIndex + ".title");
storage.removeItem(fileDesc.fileIndex + ".content");
storage.removeItem(fileDesc.fileIndex + ".sync");
storage.removeItem(fileDesc.fileIndex + ".publish");
storage.removeItem(fileDesc.fileIndex + ".selectTime");
storage.removeItem(fileDesc.fileIndex + ".editorStart");
storage.removeItem(fileDesc.fileIndex + ".editorEnd");
storage.removeItem(fileDesc.fileIndex + ".editorScrollTop");
storage.removeItem(fileDesc.fileIndex + ".previewScrollTop");
storage.removeItem(fileDesc.fileIndex + ".discussionList");
eventMgr.onFileDeleted(fileDesc); eventMgr.onFileDeleted(fileDesc);
}; };
@ -148,12 +129,6 @@ define([
}); });
}; };
// Get syncAttributes from syncIndex
fileMgr.getSyncAttributes = function(syncIndex) {
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
return fileDesc && fileDesc.syncLocations[syncIndex];
};
// Get the file descriptor associated to a publishIndex // Get the file descriptor associated to a publishIndex
fileMgr.getFileFromPublishIndex = function(publishIndex) { fileMgr.getFileFromPublishIndex = function(publishIndex) {
return _.find(fileSystem, function(fileDesc) { return _.find(fileSystem, function(fileDesc) {

View File

@ -3,13 +3,21 @@ define([
"utils", "utils",
"classes/FileDescriptor", "classes/FileDescriptor",
"storage", "storage",
], function(_, utils, FileDescriptor) { ], function(_, utils, FileDescriptor, storage) {
var fileSystem = {}; var fileSystem = {};
// Retrieve file descriptors from localStorage // Retrieve file descriptors from localStorage
_.each(utils.retrieveIndexArray("file.list"), function(fileIndex) { utils.retrieveIndexArray("file.list").forEach(function(fileIndex) {
fileSystem[fileIndex] = new FileDescriptor(fileIndex); fileSystem[fileIndex] = new FileDescriptor(fileIndex);
}); });
// Clean fields from deleted files in local storage
Object.keys(storage).forEach(function(key) {
var match = key.match(/(file\.\S+?)\.\S+/);
if(match && !fileSystem.hasOwnProperty(match[1])) {
storage.removeItem(key);
}
});
return fileSystem; return fileSystem;
}); });

View File

@ -1,15 +1,24 @@
define([ define([
"underscore", "underscore",
"utils", "utils",
"storage",
"classes/FolderDescriptor", "classes/FolderDescriptor",
"storage", "storage",
], function(_, utils, FolderDescriptor) { ], function(_, utils, storage, FolderDescriptor) {
var folderList = {}; var folderList = {};
// Retrieve folder descriptors from localStorage // Retrieve folder descriptors from localStorage
_.each(utils.retrieveIndexArray("folder.list"), function(folderIndex) { utils.retrieveIndexArray("folder.list").forEach(function(folderIndex) {
folderList[folderIndex] = new FolderDescriptor(folderIndex); folderList[folderIndex] = new FolderDescriptor(folderIndex);
}); });
// Clean fields from deleted folders in local storage
Object.keys(storage).forEach(function(key) {
var match = key.match(/(folder\.\S+?)\.\S+/);
if(match && !folderList.hasOwnProperty(match[1])) {
storage.removeItem(key);
}
});
return folderList; return folderList;
}); });

View File

@ -542,13 +542,11 @@ define([
task.chain(recursiveDownloadContent); task.chain(recursiveDownloadContent);
return; return;
} }
var url = file.downloadUrl;
// if file is a real time document // if file is a real time document
if(file.mimeType.indexOf("application/vnd.google-apps.drive-sdk") === 0) { if(file.mimeType.indexOf("application/vnd.google-apps.drive-sdk") === 0) {
file.content = "";
file.isRealtime = true; file.isRealtime = true;
objects.shift(); url = 'https://www.googleapis.com/drive/v2/files/' + file.id + '/realtime';
task.chain(recursiveDownloadContent);
return;
} }
var headers = {}; var headers = {};
var authorizationMgr = authorizationMgrMap[accountId]; var authorizationMgr = authorizationMgrMap[accountId];
@ -556,12 +554,12 @@ define([
headers.Authorization = "Bearer " + authorizationMgr.token.access_token; headers.Authorization = "Bearer " + authorizationMgr.token.access_token;
} }
$.ajax({ $.ajax({
url: file.downloadUrl, url: url,
headers: headers, headers: headers,
data: { data: {
key: constants.GOOGLE_API_KEY key: constants.GOOGLE_API_KEY
}, },
dataType: "text", dataType: file.isRealtime ? 'json' : 'text',
timeout: constants.AJAX_TIMEOUT timeout: constants.AJAX_TIMEOUT
}).done(function(data) { }).done(function(data) {
file.content = data; file.content = data;

View File

@ -43,7 +43,7 @@ requirejs.config({
'bootstrap-tour': 'bower-libs/bootstrap-tour/build/js/bootstrap-tour', 'bootstrap-tour': 'bower-libs/bootstrap-tour/build/js/bootstrap-tour',
css_browser_selector: 'bower-libs/css_browser_selector/css_browser_selector', css_browser_selector: 'bower-libs/css_browser_selector/css_browser_selector',
'pagedown-extra': 'bower-libs/pagedown-extra/Markdown.Extra', 'pagedown-extra': 'bower-libs/pagedown-extra/Markdown.Extra',
pagedown: 'bower-libs/stackedit-pagedown/Markdown.Editor', pagedown: 'libs/Markdown.Editor',
'require-css': 'bower-libs/require-css/css', 'require-css': 'bower-libs/require-css/css',
xregexp: 'bower-libs/xregexp/xregexp-all', xregexp: 'bower-libs/xregexp/xregexp-all',
yaml: 'bower-libs/yaml.js', yaml: 'bower-libs/yaml.js',
@ -161,10 +161,10 @@ requirejs.config({
'jquery' 'jquery'
], ],
pagedown: [ pagedown: [
'bower-libs/stackedit-pagedown/Markdown.Converter' 'libs/Markdown.Converter'
], ],
'pagedown-extra': [ 'pagedown-extra': [
'bower-libs/stackedit-pagedown/Markdown.Converter' 'libs/Markdown.Converter'
] ]
} }
}); });

View File

@ -61,7 +61,7 @@ define([
} }
var fileDescList = []; var fileDescList = [];
_.each(result, function(file) { _.each(result, function(file) {
var parsedContent = dropboxProvider.parseSerializedContent(file.content); var parsedContent = dropboxProvider.parseContent(file.content);
var syncAttributes = createSyncAttributes(file.path, file.versionTag, parsedContent.content, parsedContent.discussionListJSON); var syncAttributes = createSyncAttributes(file.path, file.versionTag, parsedContent.content, parsedContent.discussionListJSON);
var syncLocations = {}; var syncLocations = {};
syncLocations[syncAttributes.syncIndex] = syncAttributes; syncLocations[syncAttributes.syncIndex] = syncAttributes;
@ -152,11 +152,13 @@ define([
var interestingChanges = []; var interestingChanges = [];
_.each(changes, function(change) { _.each(changes, function(change) {
var syncIndex = createSyncIndex(change.path); var syncIndex = createSyncIndex(change.path);
var syncAttributes = fileMgr.getSyncAttributes(syncIndex); var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
if(syncAttributes === undefined) { var syncAttributes = fileDesc && fileDesc.syncLocations[syncIndex];
if(!syncAttributes) {
return; return;
} }
// Store syncAttributes to avoid 2 times searching // Store fileDesc and syncAttributes references to avoid 2 times search
change.fileDesc = fileDesc;
change.syncAttributes = syncAttributes; change.syncAttributes = syncAttributes;
// Delete // Delete
if(change.wasRemoved === true) { if(change.wasRemoved === true) {
@ -179,13 +181,8 @@ define([
return callback(); return callback();
} }
var change = changes.pop(); var change = changes.pop();
var fileDesc = change.fileDesc;
var syncAttributes = change.syncAttributes; var syncAttributes = change.syncAttributes;
var syncIndex = syncAttributes.syncIndex;
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
// No file corresponding (file may have been deleted locally)
if(fileDesc === undefined) {
return;
}
// File deleted // File deleted
if(change.wasRemoved === true) { if(change.wasRemoved === true) {
eventMgr.onError('"' + fileDesc.title + '" has been removed from Dropbox.'); eventMgr.onError('"' + fileDesc.title + '" has been removed from Dropbox.');
@ -193,10 +190,10 @@ define([
return eventMgr.onSyncRemoved(fileDesc, syncAttributes); return eventMgr.onSyncRemoved(fileDesc, syncAttributes);
} }
var file = change.stat; var file = change.stat;
var parsedContent = dropboxProvider.parseSerializedContent(file.content); var parsedContent = dropboxProvider.parseContent(file.content);
var remoteContent = parsedContent.content; var remoteContent = parsedContent.content;
var remoteDiscussionListJSON = parsedContent.discussionListJSON; var remoteDiscussionListJSON = parsedContent.discussionListJSON;
var remoteDiscussionList = JSON.parse(remoteDiscussionListJSON); var remoteDiscussionList = parsedContent.discussionList;
var remoteCRC = dropboxProvider.syncMerge(fileDesc, syncAttributes, remoteContent, fileDesc.title, remoteDiscussionList, remoteDiscussionListJSON); var remoteCRC = dropboxProvider.syncMerge(fileDesc, syncAttributes, remoteContent, fileDesc.title, remoteDiscussionList, remoteDiscussionListJSON);
// Update syncAttributes // Update syncAttributes
syncAttributes.version = file.versionTag; syncAttributes.version = file.versionTag;

View File

@ -62,7 +62,7 @@ define([
var fileDescList = []; var fileDescList = [];
var fileDesc; var fileDesc;
_.each(result, function(file) { _.each(result, function(file) {
var parsedContent = gdriveProvider.parseSerializedContent(file.content); var parsedContent = gdriveProvider.parseContent(file.content);
var syncAttributes = createSyncAttributes(file.id, file.etag, parsedContent.content, file.title, parsedContent.discussionListJSON); var syncAttributes = createSyncAttributes(file.id, file.etag, parsedContent.content, file.title, parsedContent.discussionListJSON);
syncAttributes.isRealtime = file.isRealtime; syncAttributes.isRealtime = file.isRealtime;
var syncLocations = {}; var syncLocations = {};
@ -188,11 +188,13 @@ define([
var interestingChanges = []; var interestingChanges = [];
_.each(changes, function(change) { _.each(changes, function(change) {
var syncIndex = createSyncIndex(change.fileId); var syncIndex = createSyncIndex(change.fileId);
var syncAttributes = fileMgr.getSyncAttributes(syncIndex); var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
if(syncAttributes === undefined) { var syncAttributes = fileDesc && fileDesc.syncLocations[syncIndex];
if(!syncAttributes) {
return; return;
} }
// Store syncAttributes to avoid 2 times searching // Store fileDesc and syncAttributes references to avoid 2 times search
change.fileDesc = fileDesc;
change.syncAttributes = syncAttributes; change.syncAttributes = syncAttributes;
// Delete // Delete
if(change.deleted === true) { if(change.deleted === true) {
@ -215,13 +217,8 @@ define([
return callback(); return callback();
} }
var change = changes.pop(); var change = changes.pop();
var fileDesc = change.fileDesc;
var syncAttributes = change.syncAttributes; var syncAttributes = change.syncAttributes;
var syncIndex = syncAttributes.syncIndex;
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
// No file corresponding (file may have been deleted locally)
if(fileDesc === undefined) {
return;
}
// File deleted // File deleted
if(change.deleted === true) { if(change.deleted === true) {
eventMgr.onError('"' + fileDesc.title + '" has been removed from ' + providerName + '.'); eventMgr.onError('"' + fileDesc.title + '" has been removed from ' + providerName + '.');
@ -233,11 +230,11 @@ define([
return; return;
} }
var file = change.file; var file = change.file;
var parsedContent = gdriveProvider.parseSerializedContent(file.content); var parsedContent = gdriveProvider.parseContent(file.content);
var remoteContent = parsedContent.content; var remoteContent = parsedContent.content;
var remoteTitle = file.title; var remoteTitle = file.title;
var remoteDiscussionListJSON = parsedContent.discussionListJSON; var remoteDiscussionListJSON = parsedContent.discussionListJSON;
var remoteDiscussionList = JSON.parse(remoteDiscussionListJSON); var remoteDiscussionList = parsedContent.discussionList;
var remoteCRC = gdriveProvider.syncMerge(fileDesc, syncAttributes, remoteContent, remoteTitle, remoteDiscussionList, remoteDiscussionListJSON); var remoteCRC = gdriveProvider.syncMerge(fileDesc, syncAttributes, remoteContent, remoteTitle, remoteDiscussionList, remoteDiscussionListJSON);
// Update syncAttributes // Update syncAttributes
@ -291,8 +288,8 @@ define([
}); });
// Realtime closure // Realtime closure
var realtimeContext;
(function() { (function() {
var realtimeContext;
function toRealtimeDiscussion(context, discussion) { function toRealtimeDiscussion(context, discussion) {
var realtimeCommentList = context.model.createList(); var realtimeCommentList = context.model.createList();
@ -430,7 +427,7 @@ define([
} }
} }
function updateCRCs() { function updateStatus() {
var context = realtimeContext; var context = realtimeContext;
if(!context) { if(!context) {
return; return;
@ -487,7 +484,7 @@ define([
// For local changes, CRCs are updated on "save success" event // For local changes, CRCs are updated on "save success" event
if(context.isServerChange) { if(context.isServerChange) {
updateCRCs(); updateStatus();
} }
else { else {
context.model.endCompoundOperation(); context.model.endCompoundOperation();
@ -570,7 +567,7 @@ define([
// Also listen to "save success" event // Also listen to "save success" event
doc.addEventListener(gapi.drive.realtime.EventType.DOCUMENT_SAVE_STATE_CHANGED, function(evt) { doc.addEventListener(gapi.drive.realtime.EventType.DOCUMENT_SAVE_STATE_CHANGED, function(evt) {
if(evt.isPending === false && evt.isSaving === false) { if(evt.isPending === false && evt.isSaving === false) {
updateCRCs(); updateStatus();
} }
}); });

View File

@ -35,29 +35,40 @@ define([
}).compact().object().value(); }).compact().object().value();
// Retrieve publish locations from storage // Retrieve publish locations from storage
_.each(fileSystem, function(fileDesc) { (function() {
_.each(utils.retrieveIndexArray(fileDesc.fileIndex + ".publish"), function(publishIndex) { var publishIndexMap = {};
try { _.each(fileSystem, function(fileDesc) {
var publishAttributes = JSON.parse(storage[publishIndex]); utils.retrieveIndexArray(fileDesc.fileIndex + ".publish").forEach(function(publishIndex) {
// Store publishIndex try {
publishAttributes.publishIndex = publishIndex; var publishAttributes = JSON.parse(storage[publishIndex]);
// Replace provider ID by provider module in attributes // Store publishIndex
var provider = providerMap[publishAttributes.provider]; publishAttributes.publishIndex = publishIndex;
if(!provider) { // Replace provider ID by provider module in attributes
throw new Error("Invalid provider ID: " + publishAttributes.provider); var provider = providerMap[publishAttributes.provider];
if(!provider) {
throw new Error("Invalid provider ID: " + publishAttributes.provider);
}
publishAttributes.provider = provider;
fileDesc.publishLocations[publishIndex] = publishAttributes;
publishIndexMap[publishIndex] = publishAttributes;
} }
publishAttributes.provider = provider; catch(e) {
fileDesc.publishLocations[publishIndex] = publishAttributes; // storage can be corrupted
} eventMgr.onError(e);
catch(e) { // Remove publish location
// storage can be corrupted utils.removeIndexFromArray(fileDesc.fileIndex + ".publish", publishIndex);
eventMgr.onError(e); }
// Remove publish location });
utils.removeIndexFromArray(fileDesc.fileIndex + ".publish", publishIndex); });
storage.removeItem(publishIndex);
// Clean fields from deleted files in local storage
Object.keys(storage).forEach(function(key) {
var match = key.match(/(publish\.\S+?)\.\S+/);
if(match && !publishIndexMap.hasOwnProperty(match[1])) {
storage.removeItem(key);
} }
}); });
}); })();
// Apply template to the current document // Apply template to the current document
publisher.applyTemplate = function(fileDesc, publishAttributes, html) { publisher.applyTemplate = function(fileDesc, publishAttributes, html) {

View File

@ -134,29 +134,7 @@ define([
version = "v7"; version = "v7";
} }
if(version == "v7") { if(version == "v7" || version == "v8" || version == "v9") {
_.each(_.keys(localStorage), function(key) {
var matchResult = key.match(/(file\.\S+\.)\S+/);
if(matchResult) {
if(!_.has(localStorage, matchResult[1] + 'title')) {
localStorage.removeItem(key);
}
}
});
version = "v8";
}
if(version == "v8") {
_.each(_.keys(localStorage), function(key) {
var matchResult = key.match(/file\.\S+\.(editorEnd|editorStart)/);
if(matchResult) {
localStorage.removeItem(key);
}
});
version = "v9";
}
if(version == "v9") {
if(_.has(localStorage, 'settings')) { if(_.has(localStorage, 'settings')) {
settings = JSON.parse(localStorage.settings); settings = JSON.parse(localStorage.settings);
delete settings.editorFontFamily; delete settings.editorFontFamily;
@ -235,26 +213,9 @@ define([
version = "v16"; version = "v16";
} }
if(version == "v16") { if(version == "v16" || version == "v17") {
_.each(_.keys(localStorage), function(key) {
var matchResult = key.match(/(file\.\S+\.)\S+/);
if(matchResult) {
if(!_.has(localStorage, matchResult[1] + 'title')) {
localStorage.removeItem(key);
}
}
});
version = "v17";
}
if(version == "v17") {
localStorage.removeItem('focusMode'); localStorage.removeItem('focusMode');
localStorage.removeItem('mode'); localStorage.removeItem('mode');
_.each(_.keys(localStorage), function(key) {
if(key.match(/file\.\S+\.editorSelectRange/)) {
localStorage.removeItem(key);
}
});
version = "v18"; version = "v18";
} }

View File

@ -24,29 +24,40 @@ define([
}).compact().object().value(); }).compact().object().value();
// Retrieve sync locations from storage // Retrieve sync locations from storage
_.each(fileSystem, function(fileDesc) { (function() {
_.each(utils.retrieveIndexArray(fileDesc.fileIndex + ".sync"), function(syncIndex) { var syncIndexMap = {};
try { _.each(fileSystem, function(fileDesc) {
var syncAttributes = JSON.parse(storage[syncIndex]); utils.retrieveIndexArray(fileDesc.fileIndex + ".sync").forEach(function(syncIndex) {
// Store syncIndex try {
syncAttributes.syncIndex = syncIndex; var syncAttributes = JSON.parse(storage[syncIndex]);
// Replace provider ID by provider module in attributes // Store syncIndex
var provider = providerMap[syncAttributes.provider]; syncAttributes.syncIndex = syncIndex;
if(!provider) { // Replace provider ID by provider module in attributes
throw new Error("Invalid provider ID: " + syncAttributes.provider); var provider = providerMap[syncAttributes.provider];
if(!provider) {
throw new Error("Invalid provider ID: " + syncAttributes.provider);
}
syncAttributes.provider = provider;
fileDesc.syncLocations[syncIndex] = syncAttributes;
syncIndexMap[syncIndex] = syncAttributes;
} }
syncAttributes.provider = provider; catch(e) {
fileDesc.syncLocations[syncIndex] = syncAttributes; // storage can be corrupted
} eventMgr.onError(e);
catch(e) { // Remove sync location
// storage can be corrupted utils.removeIndexFromArray(fileDesc.fileIndex + ".sync", syncIndex);
eventMgr.onError(e); }
// Remove sync location });
utils.removeIndexFromArray(fileDesc.fileIndex + ".sync", syncIndex); });
storage.removeItem(syncIndex);
// Clean fields from deleted files in local storage
Object.keys(storage).forEach(function(key) {
var match = key.match(/(sync\.\S+?)\.\S+/);
if(match && !syncIndexMap.hasOwnProperty(match[1])) {
storage.removeItem(key);
} }
}); });
}); })();
// AutoSync configuration // AutoSync configuration
_.each(providerMap, function(provider) { _.each(providerMap, function(provider) {

View File

@ -44,6 +44,18 @@ define([
}; };
}; };
// Generates a 24 chars length random string (should be enough to prevent collisions)
utils.randomString = (function() {
var max = Math.pow(36, 6);
function s6() {
// Linear [0-9a-z]{6} random string
return ('000000' + (Math.random() * max | 0).toString(36)).slice(-6);
}
return function() {
return [s6(), s6(), s6(), s6()].join('');
};
})();
// Return a parameter from the URL // Return a parameter from the URL
utils.getURLParameter = function(name) { utils.getURLParameter = function(name) {
// Parameter can be either a search parameter (&name=...) or a hash fragment parameter (#!name=...) // Parameter can be either a search parameter (&name=...) or a hash fragment parameter (#!name=...)
@ -326,14 +338,9 @@ define([
} }
}; };
// Generates a random string
utils.randomString = function() {
return _.random(4294967296).toString(36);
};
// Time shared by others modules // Time shared by others modules
utils.updateCurrentTime = function() { utils.updateCurrentTime = function() {
utils.currentTime = new Date().getTime(); utils.currentTime = Date.now();
}; };
utils.updateCurrentTime(); utils.updateCurrentTime();