Stackedit/js/file-manager.js

355 lines
11 KiB
JavaScript
Raw Normal View History

2013-05-26 22:59:03 +00:00
define([
"jquery",
2013-05-27 19:45:33 +00:00
"underscore",
2013-05-26 22:59:03 +00:00
"core",
"utils",
2013-05-27 19:45:33 +00:00
"settings",
2013-05-26 22:59:03 +00:00
"extension-manager",
2013-05-27 19:45:33 +00:00
"file-system",
"lib/text!../WELCOME.md"
], function($, _, core, utils, settings, extensionMgr, fileSystem, welcomeContent) {
2013-05-04 00:05:58 +00:00
2013-05-27 19:45:33 +00:00
var fileMgr = {};
2013-05-28 23:41:09 +00:00
// 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);
};
2013-05-26 22:59:03 +00:00
2013-05-28 23:41:09 +00:00
// Load file descriptors from localStorage
_.chain(
localStorage["file.list"].split(";")
).compact().each(function(fileIndex) {
fileSystem[fileIndex] = new FileDescriptor(fileIndex, localStorage[fileIndex + ".title"]);
});
2013-04-13 18:11:54 +00:00
// Defines the current file
2013-05-28 23:41:09 +00:00
var currentFile = undefined;
2013-05-27 19:45:33 +00:00
fileMgr.getCurrentFile = function() {
2013-05-26 22:59:03 +00:00
return currentFile;
2013-04-13 18:11:54 +00:00
};
2013-05-27 19:45:33 +00:00
fileMgr.isCurrentFile = function(fileDesc) {
2013-05-26 22:59:03 +00:00
return fileDesc === currentFile;
2013-04-13 18:11:54 +00:00
};
2013-05-27 19:45:33 +00:00
fileMgr.setCurrentFile = function(fileDesc) {
2013-05-26 22:59:03 +00:00
currentFile = fileDesc;
if(fileDesc === undefined) {
2013-04-13 18:11:54 +00:00
localStorage.removeItem("file.current");
}
2013-05-26 23:38:13 +00:00
else if(fileDesc.fileIndex != TEMPORARY_FILE_INDEX) {
localStorage["file.current"] = fileDesc.fileIndex;
2013-04-13 18:11:54 +00:00
}
};
2013-05-28 23:41:09 +00:00
// Caution: this function recreates the editor (reset undo operations)
2013-05-27 19:45:33 +00:00
fileMgr.selectFile = function(fileDesc) {
2013-05-27 23:27:38 +00:00
fileDesc = fileDesc || fileMgr.getCurrentFile();
2013-04-02 18:42:47 +00:00
2013-05-26 22:59:03 +00:00
if(fileDesc === undefined) {
2013-05-27 23:27:38 +00:00
var fileSystemSize = _.size(fileSystem);
// If fileSystem empty create one file
if (fileSystemSize === 0) {
fileDesc = fileMgr.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
}
else {
2013-05-28 23:41:09 +00:00
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];
2013-05-27 23:27:38 +00:00
}
2013-04-02 18:42:47 +00:00
}
2013-05-26 22:59:03 +00:00
2013-05-28 23:41:09 +00:00
if(fileMgr.isCurrentFile(fileDesc) === false) {
fileMgr.setCurrentFile(fileDesc);
// Notify extensions
extensionMgr.onFileSelected(fileDesc);
// Hide the viewer pencil button
if(fileDesc.fileIndex == TEMPORARY_FILE_INDEX) {
$(".action-edit-document").removeClass("hide");
}
else {
$(".action-edit-document").addClass("hide");
}
2013-05-04 00:05:58 +00:00
}
2013-04-02 18:42:47 +00:00
// Recreate the editor
2013-05-28 23:41:09 +00:00
$("#wmd-input").val(fileDesc.getContent());
2013-04-02 18:42:47 +00:00
core.createEditor(function() {
2013-05-18 13:40:16 +00:00
// Callback to save content when textarea changes
2013-05-27 19:45:33 +00:00
fileMgr.saveFile();
2013-04-02 18:42:47 +00:00
});
};
2013-05-26 22:59:03 +00:00
2013-05-27 19:45:33 +00:00
fileMgr.createFile = function(title, content, syncLocations, isTemporary) {
content = content !== undefined ? content : settings.defaultContent;
2013-04-02 18:42:47 +00:00
if (!title) {
// Create a file title
title = DEFAULT_FILE_TITLE;
var indicator = 2;
2013-05-27 19:45:33 +00:00
while(_.some(fileSystem, function(fileDesc) {
2013-04-13 18:11:54 +00:00
return fileDesc.title == title;
})) {
2013-04-02 18:42:47 +00:00
title = DEFAULT_FILE_TITLE + indicator++;
}
}
2013-04-11 22:38:41 +00:00
// Generate a unique fileIndex
2013-05-04 00:05:58 +00:00
var fileIndex = TEMPORARY_FILE_INDEX;
if(!isTemporary) {
do {
2013-05-25 18:13:59 +00:00
fileIndex = "file." + utils.randomString();
2013-05-27 19:45:33 +00:00
} while(_.has(fileSystem, fileIndex));
2013-05-04 00:05:58 +00:00
}
2013-04-11 22:38:41 +00:00
2013-05-28 23:41:09 +00:00
// syncIndex associations
syncLocations = syncLocations || {};
2013-05-26 22:59:03 +00:00
var sync = _.reduce(syncLocations, function(sync, syncAttributes, syncIndex) {
2013-04-13 18:11:54 +00:00
return sync + syncIndex + ";";
}, ";");
2013-05-28 23:41:09 +00:00
localStorage[fileIndex + ".title"] = title;
localStorage[fileIndex + ".content"] = content;
2013-04-02 18:42:47 +00:00
localStorage[fileIndex + ".sync"] = sync;
2013-04-09 07:58:06 +00:00
localStorage[fileIndex + ".publish"] = ";";
2013-05-26 22:59:03 +00:00
// Create the file descriptor
2013-05-28 23:41:09 +00:00
var fileDesc = new FileDescriptor(fileIndex, title, syncLocations);
2013-05-26 22:59:03 +00:00
2013-05-18 13:40:16 +00:00
// Add the index to the file list
2013-05-04 00:05:58 +00:00
if(!isTemporary) {
localStorage["file.list"] += fileIndex + ";";
2013-05-27 19:45:33 +00:00
fileSystem[fileIndex] = fileDesc;
extensionMgr.onFileCreated(fileDesc);
2013-05-04 00:05:58 +00:00
}
2013-05-26 22:59:03 +00:00
return fileDesc;
2013-04-02 18:42:47 +00:00
};
2013-05-27 19:45:33 +00:00
fileMgr.deleteFile = function(fileDesc) {
fileDesc = fileDesc || fileMgr.getCurrentFile();
2013-05-28 23:41:09 +00:00
if(fileMgr.isCurrentFile(fileDesc) === true) {
2013-05-26 22:59:03 +00:00
// Unset the current fileDesc
2013-05-27 19:45:33 +00:00
fileMgr.setCurrentFile();
2013-05-28 23:41:09 +00:00
// Refresh the editor with an other file
fileMgr.selectFile();
2013-04-02 18:42:47 +00:00
}
// Remove synchronized locations
2013-05-26 23:38:13 +00:00
_.each(fileDesc.syncLocations, function(syncAttributes) {
2013-05-27 19:45:33 +00:00
fileMgr.removeSync(syncAttributes, true);
2013-04-13 18:11:54 +00:00
});
2013-04-11 22:38:41 +00:00
// Remove publish locations
2013-05-26 23:38:13 +00:00
_.each(fileDesc.publishLocations, function(publishAttributes) {
2013-05-27 19:45:33 +00:00
fileMgr.removePublish(publishAttributes, true);
2013-04-13 18:11:54 +00:00
});
2013-04-02 18:42:47 +00:00
2013-05-18 13:40:16 +00:00
// Remove the index from the file list
2013-05-26 23:38:13 +00:00
var fileIndex = fileDesc.fileIndex;
2013-04-02 18:42:47 +00:00
localStorage["file.list"] = localStorage["file.list"].replace(";"
+ fileIndex + ";", ";");
2013-05-28 23:41:09 +00:00
2013-04-02 18:42:47 +00:00
localStorage.removeItem(fileIndex + ".title");
localStorage.removeItem(fileIndex + ".content");
2013-05-18 13:40:16 +00:00
localStorage.removeItem(fileIndex + ".sync");
localStorage.removeItem(fileIndex + ".publish");
2013-05-28 23:41:09 +00:00
2013-05-27 19:45:33 +00:00
fileSystem.removeItem(fileIndex);
extensionMgr.onFileDeleted(fileDesc);
2013-04-02 18:42:47 +00:00
};
2013-05-18 13:40:16 +00:00
// Save current file in localStorage
2013-05-27 19:45:33 +00:00
fileMgr.saveFile = function() {
2013-04-02 18:42:47 +00:00
var content = $("#wmd-input").val();
2013-05-27 19:45:33 +00:00
var fileDesc = fileMgr.getCurrentFile();
2013-05-28 23:41:09 +00:00
fileDesc.setContent(content);
2013-04-02 18:42:47 +00:00
};
2013-05-26 23:38:13 +00:00
// Add a synchronized location to a file
2013-05-27 19:45:33 +00:00
fileMgr.addSync = function(fileDesc, syncAttributes) {
2013-05-26 23:38:13 +00:00
localStorage[fileDesc.fileIndex + ".sync"] += syncAttributes.syncIndex + ";";
fileDesc.syncLocations[syncAttributes.syncIndex] = syncAttributes;
2013-05-26 22:59:03 +00:00
// addSync is only used for export, not for import
2013-05-27 19:45:33 +00:00
extensionMgr.onSyncExportSuccess(fileDesc, syncAttributes);
2013-04-02 18:42:47 +00:00
};
2013-05-26 22:59:03 +00:00
2013-05-26 23:38:13 +00:00
// Remove a synchronized location
2013-05-27 19:45:33 +00:00
fileMgr.removeSync = function(syncAttributes, skipExtensions) {
var fileDesc = fileMgr.getFileFromSyncIndex(syncAttributes.syncIndex);
2013-05-26 22:59:03 +00:00
if(fileDesc !== undefined) {
2013-05-26 23:38:13 +00:00
localStorage[fileDesc.fileIndex + ".sync"] = localStorage[fileDesc.fileIndex + ".sync"].replace(";"
+ syncAttributes.syncIndex + ";", ";");
2013-04-02 18:42:47 +00:00
}
2013-04-20 00:14:20 +00:00
// Remove sync attributes
2013-05-26 23:38:13 +00:00
localStorage.removeItem(syncAttributes.syncIndex);
2013-05-27 23:39:07 +00:00
fileDesc.syncLocations.removeItem(syncAttributes.syncIndex);
2013-05-26 22:59:03 +00:00
if(!skipExtensions) {
2013-05-27 19:45:33 +00:00
extensionMgr.onSyncRemoved(fileDesc, syncAttributes);
2013-05-26 22:59:03 +00:00
}
2013-04-02 18:42:47 +00:00
};
2013-05-26 22:59:03 +00:00
// Get the file descriptor associated to a syncIndex
2013-05-27 19:45:33 +00:00
fileMgr.getFileFromSyncIndex = function(syncIndex) {
return _.find(fileSystem, function(fileDesc) {
2013-05-26 22:59:03 +00:00
return _.has(fileDesc.syncLocations, syncIndex);
});
};
// Get syncAttributes from syncIndex
2013-05-27 19:45:33 +00:00
fileMgr.getSyncAttributes = function(syncIndex) {
var fileDesc = fileMgr.getFileFromSyncIndex(syncIndex);
2013-05-26 22:59:03 +00:00
return fileDesc && fileDesc.syncLocations[syncIndex];
};
// Returns true if provider has locations to synchronize
2013-05-27 19:45:33 +00:00
fileMgr.hasSync = function(provider) {
return _.some(fileSystem, function(fileDesc) {
2013-05-26 22:59:03 +00:00
return _.some(fileDesc.syncLocations, function(syncAttributes) {
2013-05-27 22:13:41 +00:00
return syncAttributes.provider === provider;
2013-05-26 22:59:03 +00:00
});
});
2013-04-02 18:42:47 +00:00
};
2013-05-26 22:59:03 +00:00
// Add a publishIndex (publish location) to a file
2013-05-27 19:45:33 +00:00
fileMgr.addPublish = function(fileDesc, publishAttributes) {
2013-05-26 23:38:13 +00:00
localStorage[fileDesc.fileIndex + ".publish"] += publishAttributes.publishIndex + ";";
fileDesc.publishLocations[publishAttributes.publishIndex] = publishAttributes;
2013-05-27 19:45:33 +00:00
extensionMgr.onNewPublishSuccess(fileDesc, publishAttributes);
2013-05-26 22:59:03 +00:00
};
2013-04-14 13:24:29 +00:00
// Remove a publishIndex (publish location)
2013-05-27 19:45:33 +00:00
fileMgr.removePublish = function(publishAttributes, skipExtensions) {
2013-05-28 23:41:09 +00:00
var fileDesc = fileMgr.getFileFromPublishIndex(publishAttributes.publishIndex);
2013-05-26 22:59:03 +00:00
if(fileDesc !== undefined) {
2013-05-26 23:38:13 +00:00
localStorage[fileDesc.fileIndex + ".publish"] = localStorage[fileDesc.fileIndex + ".publish"].replace(";"
+ publishAttributes.publishIndex + ";", ";");
2013-04-11 22:38:41 +00:00
}
2013-04-20 00:14:20 +00:00
// Remove publish attributes
2013-05-26 23:38:13 +00:00
localStorage.removeItem(publishAttributes.publishIndex);
2013-05-27 23:39:07 +00:00
fileDesc.publishLocations.removeItem(publishAttributes.publishIndex);
2013-05-26 22:59:03 +00:00
if(!skipExtensions) {
2013-05-27 19:45:33 +00:00
extensionMgr.onPublishRemoved(fileDesc, publishAttributes);
2013-05-26 22:59:03 +00:00
}
2013-04-11 22:38:41 +00:00
};
2013-05-26 22:59:03 +00:00
// Get the file descriptor associated to a publishIndex
2013-05-28 23:41:09 +00:00
fileMgr.getFileFromPublishIndex = function(publishIndex) {
2013-05-27 19:45:33 +00:00
return _.find(fileSystem, function(fileDesc) {
2013-05-26 22:59:03 +00:00
return _.has(fileDesc.publishLocations, publishIndex);
});
2013-04-11 22:38:41 +00:00
};
2013-05-19 23:26:05 +00:00
// Filter for search input in file selector
function filterFileSelector(filter) {
var liList = $("#file-selector li:not(.stick)");
liList.show();
if(filter) {
var words = filter.toLowerCase().split(/\s+/);
liList.each(function() {
var fileTitle = $(this).text().toLowerCase();
if(_.some(words, function(word) {
return fileTitle.indexOf(word) === -1;
})) {
$(this).hide();
}
});
}
}
2013-04-22 01:04:12 +00:00
core.onReady(function() {
2013-05-27 19:45:33 +00:00
fileMgr.selectFile();
2013-04-10 18:14:59 +00:00
$(".action-create-file").click(function() {
2013-05-27 19:45:33 +00:00
var fileDesc = fileMgr.createFile();
fileMgr.selectFile(fileDesc);
var wmdInput = $("#wmd-input").focus().get(0);
if(wmdInput.setSelectionRange) {
wmdInput.setSelectionRange(0, 0);
}
2013-04-10 18:14:59 +00:00
$("#file-title").click();
});
$(".action-remove-file").click(function() {
2013-05-27 19:45:33 +00:00
fileMgr.deleteFile();
2013-04-10 18:14:59 +00:00
});
$("#file-title").click(function() {
2013-04-30 23:02:19 +00:00
if(viewerMode === true) {
return;
}
2013-04-10 18:14:59 +00:00
$(this).hide();
var fileTitleInput = $("#file-title-input").show();
_.defer(function() {
fileTitleInput.focus().get(0).select();
});
2013-04-10 18:14:59 +00:00
});
2013-04-20 00:14:20 +00:00
function applyTitle(input) {
2013-05-26 22:59:03 +00:00
input.hide();
$("#file-title").show();
2013-04-20 00:14:20 +00:00
var title = $.trim(input.val());
2013-05-27 19:45:33 +00:00
var fileDesc = fileMgr.getCurrentFile();
2013-05-28 23:41:09 +00:00
if (title && title != fileDesc.title) {
fileDesc.setTitle(title);
2013-04-10 18:14:59 +00:00
}
2013-05-28 23:41:09 +00:00
input.val(fileDesc.title);
$("#wmd-input").focus();
2013-04-20 00:14:20 +00:00
}
$("#file-title-input").blur(function() {
applyTitle($(this));
}).keyup(function(e) {
if (e.keyCode == 13) {
applyTitle($(this));
}
if (e.keyCode == 27) {
$(this).val("");
applyTitle($(this));
}
2013-04-10 18:14:59 +00:00
});
2013-05-19 23:26:05 +00:00
$(".action-open-file").click(function() {
filterFileSelector();
_.defer(function() {
$("#file-search").val("").focus();
});
});
$("#file-search").keyup(function() {
filterFileSelector($(this).val());
}).click(function(event) {
event.stopPropagation();
});
2013-05-04 00:05:58 +00:00
$(".action-open-stackedit").click(function() {
window.location.href = ".";
});
$(".action-edit-document").click(function() {
var content = $("#wmd-input").val();
2013-05-27 19:45:33 +00:00
var title = fileMgr.getCurrentFile().title;
var fileDesc = fileMgr.createFile(title, content);
fileMgr.selectFile(fileDesc);
2013-05-04 00:05:58 +00:00
window.location.href = ".";
});
2013-04-27 23:16:38 +00:00
$(".action-welcome-file").click(function() {
2013-05-27 19:45:33 +00:00
var fileDesc = fileMgr.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
fileMgr.selectFile(fileDesc);
2013-04-27 23:16:38 +00:00
});
2013-04-21 00:07:27 +00:00
});
2013-04-10 18:14:59 +00:00
2013-05-27 19:45:33 +00:00
extensionMgr.onFileMgrCreated(fileMgr);
return fileMgr;
2013-04-02 18:42:47 +00:00
});