Implement remember document position
This commit is contained in:
parent
693072218e
commit
c99f927205
@ -736,6 +736,9 @@
|
||||
<dd>
|
||||
<a target="_blank" href="http://jquery.com/">jQuery</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a target="_blank" href="https://github.com/brandonaaron/jquery-mousewheel">jQuery Mouse Wheel Plugin</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a target="_blank" href="https://code.google.com/p/pagedown/">PageDown</a>
|
||||
/ <a target="_blank"
|
||||
|
45
js/core.js
45
js/core.js
@ -200,15 +200,31 @@ define([
|
||||
|
||||
// Create the PageDown editor
|
||||
var editor = undefined;
|
||||
var fileDesc = undefined;
|
||||
var documentContent = undefined;
|
||||
core.createEditor = function(onTextChange) {
|
||||
var undoManager = undefined;
|
||||
core.createEditor = function(fileDescParam) {
|
||||
fileDesc = fileDescParam;
|
||||
documentContent = undefined;
|
||||
$("#wmd-input, .preview-container").scrollTop(0);
|
||||
var initDocumentContent = fileDesc.content;
|
||||
$("#wmd-input").val(initDocumentContent);
|
||||
if(editor !== undefined) {
|
||||
// Only restart if the editor is already created
|
||||
editor.restart();
|
||||
// If the editor is already created
|
||||
undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop);
|
||||
editor.refreshPreview();
|
||||
return;
|
||||
}
|
||||
// Store scrollTop on scroll event
|
||||
$("#wmd-input").scroll(function() {
|
||||
if(documentContent !== undefined) {
|
||||
fileDesc.editorScrollTop = $(this).scrollTop();
|
||||
}
|
||||
});
|
||||
$(".preview-container").scroll(function() {
|
||||
if(documentContent !== undefined) {
|
||||
fileDesc.previewScrollTop = $(this).scrollTop();
|
||||
}
|
||||
});
|
||||
var converter = new Markdown.Converter();
|
||||
editor = new Markdown.Editor(converter);
|
||||
// Custom insert link dialog
|
||||
@ -229,7 +245,7 @@ define([
|
||||
function checkDocumentChanges() {
|
||||
var newDocumentContent = $("#wmd-input").val();
|
||||
if(documentContent !== undefined && documentContent != newDocumentContent) {
|
||||
onTextChange();
|
||||
fileDesc.content = newDocumentContent;
|
||||
}
|
||||
documentContent = newDocumentContent;
|
||||
}
|
||||
@ -240,6 +256,8 @@ define([
|
||||
return function() {
|
||||
if(documentContent === undefined) {
|
||||
makePreview();
|
||||
$("#wmd-input").scrollTop(fileDesc.editorScrollTop);
|
||||
$(".preview-container").scrollTop(fileDesc.previewScrollTop);
|
||||
}
|
||||
else {
|
||||
debouncedMakePreview();
|
||||
@ -251,14 +269,22 @@ define([
|
||||
else {
|
||||
previewWrapper = function(makePreview) {
|
||||
return function() {
|
||||
checkDocumentChanges();
|
||||
makePreview();
|
||||
if(documentContent === undefined) {
|
||||
$(".preview-container").scrollTop(fileDesc.previewScrollTop);
|
||||
}
|
||||
checkDocumentChanges();
|
||||
};
|
||||
};
|
||||
}
|
||||
extensionMgr.onEditorConfigure(editor);
|
||||
editor.hooks.chain("onPreviewRefresh", extensionMgr.onAsyncPreview);
|
||||
editor.run(previewWrapper);
|
||||
undoManager = editor.run(previewWrapper);
|
||||
undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop);
|
||||
$("#wmd-input").bind("keydown click focus", function(event) {
|
||||
fileDesc.editorStart = this.selectionStart;
|
||||
fileDesc.editorEnd = this.selectionEnd;
|
||||
});
|
||||
|
||||
// Hide default buttons
|
||||
$(".wmd-button-row").addClass("btn-group").find("li:not(.wmd-spacer)").addClass("btn").css("left", 0).find("span").hide();
|
||||
@ -482,11 +508,6 @@ define([
|
||||
checkOnline();
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Focus on the editor at startup
|
||||
_.defer(function() {
|
||||
$("#wmd-input").focus();
|
||||
});
|
||||
});
|
||||
|
||||
return core;
|
||||
|
@ -7,6 +7,11 @@ define([
|
||||
var documentSelector = {
|
||||
extensionId: "documentSelector",
|
||||
extensionName: "Document selector",
|
||||
/*
|
||||
defaultConfig: {
|
||||
keyShortcut: 223
|
||||
},
|
||||
*/
|
||||
settingsBloc: '<p>Builds the "Open document" dropdown menu.</p>'
|
||||
};
|
||||
|
||||
@ -56,7 +61,8 @@ define([
|
||||
$("#file-selector li:not(.stick)").removeClass("disabled");
|
||||
var li = liMap[fileDesc.fileIndex];
|
||||
if(li === undefined) {
|
||||
// It means that we are showing a temporary file (not in the selector)
|
||||
// It means that we are showing a temporary file (not in the
|
||||
// selector)
|
||||
return;
|
||||
}
|
||||
liMap[fileDesc.fileIndex].addClass("disabled");
|
||||
@ -104,6 +110,12 @@ define([
|
||||
}).click(function(event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
/*
|
||||
$("#wmd-input").keydown(function(event) {
|
||||
if(event.ctrlKey && event.keyCode == documentSelector.config.keyShortcut) {
|
||||
console.log(event.keyCode);
|
||||
}
|
||||
});*/
|
||||
};
|
||||
|
||||
return documentSelector;
|
||||
|
@ -1,7 +1,8 @@
|
||||
define([
|
||||
"jquery",
|
||||
"underscore",
|
||||
"libs/css_browser_selector"
|
||||
"libs/css_browser_selector",
|
||||
"libs/jquery.mousewheel"
|
||||
], function($, _) {
|
||||
|
||||
var scrollLink = {
|
||||
@ -95,13 +96,14 @@ define([
|
||||
|
||||
// apply Scroll Link
|
||||
lastEditorScrollTop = -10;
|
||||
isScrollPreview = false;
|
||||
lastPreviewScrollTop = -10;
|
||||
runScrollLink();
|
||||
}, 500);
|
||||
|
||||
// -10 to be sure the gap is > 9
|
||||
// -10 to be sure the gap is more than 9px
|
||||
var lastEditorScrollTop = -10;
|
||||
var lastPreviewScrollTop = -10;
|
||||
var isScrollEditor = false;
|
||||
var isScrollPreview = false;
|
||||
var runScrollLink = _.debounce(function() {
|
||||
if(mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) {
|
||||
@ -120,7 +122,8 @@ define([
|
||||
});
|
||||
if(srcSection === undefined) {
|
||||
// Something wrong in the algorithm...
|
||||
return -10;
|
||||
callback(-10);
|
||||
return;
|
||||
}
|
||||
var posInSection = (srcScrollTop - srcSection.startOffset) / srcSection.height;
|
||||
var destSection = destSectionList[sectionIndex];
|
||||
@ -131,50 +134,58 @@ define([
|
||||
]);
|
||||
if(Math.abs(destScrollTop - lastDestScrollTop) < 9) {
|
||||
// Skip the animation in case it's not necessary
|
||||
callback(lastDestScrollTop);
|
||||
return;
|
||||
}
|
||||
destElt.animate({
|
||||
scrollTop: destScrollTop
|
||||
}, 600, function() {
|
||||
}, 500, function() {
|
||||
callback(destScrollTop);
|
||||
});
|
||||
}
|
||||
// Perform the animation if diff > 9px
|
||||
if(isScrollPreview === false && Math.abs(editorScrollTop - lastEditorScrollTop) > 9) {
|
||||
if(isScrollEditor === true && Math.abs(editorScrollTop - lastEditorScrollTop) > 9) {
|
||||
isScrollEditor = false;
|
||||
// Animate the preview
|
||||
lastEditorScrollTop = editorScrollTop;
|
||||
animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList, lastPreviewScrollTop, function(destScrollTop) {
|
||||
lastPreviewScrollTop = destScrollTop;
|
||||
});
|
||||
}
|
||||
else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 9) {
|
||||
else if(isScrollPreview === true && Math.abs(previewScrollTop - lastPreviewScrollTop) > 9) {
|
||||
isScrollPreview = false;
|
||||
// Animate the editor
|
||||
lastPreviewScrollTop = previewScrollTop;
|
||||
animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList, lastEditorScrollTop, function(destScrollTop) {
|
||||
lastEditorScrollTop = destScrollTop;
|
||||
});
|
||||
}
|
||||
}, 600);
|
||||
}, 500);
|
||||
|
||||
scrollLink.onLayoutConfigure = function(layoutConfig) {
|
||||
layoutConfig.onresize = buildSections;
|
||||
layoutConfig.onresize = function() {
|
||||
isScrollEditor = true;
|
||||
buildSections();
|
||||
};
|
||||
};
|
||||
|
||||
scrollLink.onLayoutCreated = function() {
|
||||
$(".preview-container").scroll(function() {
|
||||
$(".preview-container").bind("keydown click focus mousewheel", function() {
|
||||
isScrollPreview = true;
|
||||
isScrollEditor = false;
|
||||
runScrollLink();
|
||||
});
|
||||
$("#wmd-input").scroll(function() {
|
||||
$("#wmd-input").bind("keydown click focus mousewheel", function() {
|
||||
isScrollEditor = true;
|
||||
isScrollPreview = false;
|
||||
runScrollLink();
|
||||
});
|
||||
};
|
||||
|
||||
scrollLink.onEditorConfigure = function(editor) {
|
||||
lastPreviewScrollTop = 0;
|
||||
editor.getConverter().hooks.chain("postConversion", function(text) {
|
||||
// To avoid losing scrolling position before elements are fully loaded
|
||||
// To avoid losing scrolling position before elements are fully
|
||||
// loaded
|
||||
$("#wmd-preview").height($("#wmd-preview").height());
|
||||
return text;
|
||||
});
|
||||
@ -183,11 +194,8 @@ define([
|
||||
scrollLink.onPreviewFinished = function() {
|
||||
// Now set the correct height
|
||||
$("#wmd-preview").height("auto");
|
||||
_.defer(function() {
|
||||
// Modify scroll position of the preview not the editor
|
||||
lastEditorScrollTop = -10;
|
||||
isScrollEditor = true;
|
||||
buildSections();
|
||||
});
|
||||
};
|
||||
|
||||
return scrollLink;
|
||||
|
@ -11,10 +11,16 @@ define([
|
||||
|
||||
var fileMgr = {};
|
||||
|
||||
// Defines a file descriptor in the file system (fileDesc objects)
|
||||
// Defines a file descriptor (fileDesc objects)
|
||||
function FileDescriptor(fileIndex, title, syncLocations, publishLocations) {
|
||||
this.fileIndex = fileIndex;
|
||||
this._title = title;
|
||||
this._editorScrollTop = parseInt(localStorage[fileIndex + ".editorScrollTop"]) || 0;
|
||||
this._editorStart = parseInt(localStorage[fileIndex + ".editorStart"]) || 0;
|
||||
this._editorEnd = parseInt(localStorage[fileIndex + ".editorEnd"]) || 0;
|
||||
this._previewScrollTop = parseInt(localStorage[fileIndex + ".previewScrollTop"]) || 0;
|
||||
this.syncLocations = syncLocations || {};
|
||||
this.publishLocations = publishLocations || {};
|
||||
this.__defineGetter__("title", function() {
|
||||
return this._title;
|
||||
});
|
||||
@ -30,12 +36,38 @@ define([
|
||||
localStorage[this.fileIndex + ".content"] = content;
|
||||
extensionMgr.onContentChanged(this);
|
||||
});
|
||||
this.syncLocations = syncLocations || {};
|
||||
this.publishLocations = publishLocations || {};
|
||||
this.__defineGetter__("editorScrollTop", function() {
|
||||
return this._editorScrollTop;
|
||||
});
|
||||
this.__defineSetter__("editorScrollTop", function(editorScrollTop) {
|
||||
this._editorScrollTop = editorScrollTop;
|
||||
localStorage[this.fileIndex + ".editorScrollTop"] = editorScrollTop;
|
||||
});
|
||||
this.__defineGetter__("editorStart", function() {
|
||||
return this._editorStart;
|
||||
});
|
||||
this.__defineSetter__("editorStart", function(editorStart) {
|
||||
this._editorStart = editorStart;
|
||||
localStorage[this.fileIndex + ".editorStart"] = editorStart;
|
||||
});
|
||||
this.__defineGetter__("editorEnd", function() {
|
||||
return this._editorEnd;
|
||||
});
|
||||
this.__defineSetter__("editorEnd", function(editorEnd) {
|
||||
this._editorEnd = editorEnd;
|
||||
localStorage[this.fileIndex + ".editorEnd"] = editorEnd;
|
||||
});
|
||||
this.__defineGetter__("previewScrollTop", function() {
|
||||
return this._previewScrollTop;
|
||||
});
|
||||
this.__defineSetter__("previewScrollTop", function(previewScrollTop) {
|
||||
this._previewScrollTop = previewScrollTop;
|
||||
localStorage[this.fileIndex + ".previewScrollTop"] = previewScrollTop;
|
||||
});
|
||||
}
|
||||
|
||||
// Load file descriptors from localStorage
|
||||
_.chain(localStorage["file.list"].split(";")).compact().each(function(fileIndex) {
|
||||
// Retrieve file descriptors from localStorage and populate fileSystem
|
||||
_.each(utils.retrieveIndexArray("file.list"), function(fileIndex) {
|
||||
fileSystem[fileIndex] = new FileDescriptor(fileIndex, localStorage[fileIndex + ".title"]);
|
||||
});
|
||||
|
||||
@ -57,7 +89,6 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
// Caution: this function recreates the editor (reset undo operations)
|
||||
fileMgr.selectFile = function(fileDesc) {
|
||||
fileDesc = fileDesc || fileMgr.getCurrentFile();
|
||||
|
||||
@ -92,12 +123,8 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
// Recreate the editor
|
||||
$("#wmd-input").val(fileDesc.content);
|
||||
core.createEditor(function() {
|
||||
// Callback to save content when textarea changes
|
||||
fileMgr.saveFile();
|
||||
});
|
||||
// Refresh the editor
|
||||
core.createEditor(fileDesc);
|
||||
};
|
||||
|
||||
fileMgr.createFile = function(title, content, syncLocations, isTemporary) {
|
||||
@ -137,7 +164,7 @@ define([
|
||||
|
||||
// Add the index to the file list
|
||||
if(!isTemporary) {
|
||||
localStorage["file.list"] += fileIndex + ";";
|
||||
utils.appendIndexToArray("file.list", fileIndex);
|
||||
fileSystem[fileIndex] = fileDesc;
|
||||
extensionMgr.onFileCreated(fileDesc);
|
||||
}
|
||||
@ -148,7 +175,7 @@ define([
|
||||
fileDesc = fileDesc || fileMgr.getCurrentFile();
|
||||
|
||||
// Remove the index from the file list
|
||||
localStorage["file.list"] = localStorage["file.list"].replace(";" + fileDesc.fileIndex + ";", ";");
|
||||
utils.removeIndexFromArray("file.list", fileDesc.fileIndex);
|
||||
delete fileSystem[fileDesc.fileIndex];
|
||||
|
||||
if(fileMgr.isCurrentFile(fileDesc) === true) {
|
||||
@ -160,12 +187,12 @@ define([
|
||||
|
||||
// Remove synchronized locations
|
||||
_.each(fileDesc.syncLocations, function(syncAttributes) {
|
||||
fileMgr.removeSync(syncAttributes, true);
|
||||
fileMgr.removeSync(syncAttributes);
|
||||
});
|
||||
|
||||
// Remove publish locations
|
||||
_.each(fileDesc.publishLocations, function(publishAttributes) {
|
||||
fileMgr.removePublish(publishAttributes, true);
|
||||
fileMgr.removePublish(publishAttributes);
|
||||
});
|
||||
|
||||
localStorage.removeItem(fileDesc.fileIndex + ".title");
|
||||
@ -176,32 +203,24 @@ define([
|
||||
extensionMgr.onFileDeleted(fileDesc);
|
||||
};
|
||||
|
||||
// Save current file in localStorage
|
||||
fileMgr.saveFile = function() {
|
||||
var fileDesc = fileMgr.getCurrentFile();
|
||||
fileDesc.content = $("#wmd-input").val();
|
||||
};
|
||||
|
||||
// Add a synchronized location to a file
|
||||
fileMgr.addSync = function(fileDesc, syncAttributes) {
|
||||
localStorage[fileDesc.fileIndex + ".sync"] += syncAttributes.syncIndex + ";";
|
||||
utils.appendIndexToArray(fileDesc.fileIndex + ".sync", syncAttributes.syncIndex);
|
||||
fileDesc.syncLocations[syncAttributes.syncIndex] = syncAttributes;
|
||||
// addSync is only used for export, not for import
|
||||
extensionMgr.onSyncExportSuccess(fileDesc, syncAttributes);
|
||||
};
|
||||
|
||||
// Remove a synchronized location
|
||||
fileMgr.removeSync = function(syncAttributes, skipExtensions) {
|
||||
fileMgr.removeSync = function(syncAttributes) {
|
||||
var fileDesc = fileMgr.getFileFromSyncIndex(syncAttributes.syncIndex);
|
||||
if(fileDesc !== undefined) {
|
||||
localStorage[fileDesc.fileIndex + ".sync"] = localStorage[fileDesc.fileIndex + ".sync"].replace(";" + syncAttributes.syncIndex + ";", ";");
|
||||
}
|
||||
// Remove sync attributes
|
||||
localStorage.removeItem(syncAttributes.syncIndex);
|
||||
utils.removeIndexFromArray(fileDesc.fileIndex + ".sync", syncAttributes.syncIndex);
|
||||
delete fileDesc.syncLocations[syncAttributes.syncIndex];
|
||||
if(!skipExtensions) {
|
||||
extensionMgr.onSyncRemoved(fileDesc, syncAttributes);
|
||||
}
|
||||
// Remove sync attributes from localStorage
|
||||
localStorage.removeItem(syncAttributes.syncIndex);
|
||||
};
|
||||
|
||||
// Get the file descriptor associated to a syncIndex
|
||||
@ -228,23 +247,21 @@ define([
|
||||
|
||||
// Add a publishIndex (publish location) to a file
|
||||
fileMgr.addPublish = function(fileDesc, publishAttributes) {
|
||||
localStorage[fileDesc.fileIndex + ".publish"] += publishAttributes.publishIndex + ";";
|
||||
utils.appendIndexToArray(fileDesc.fileIndex + ".publish", publishAttributes.publishIndex);
|
||||
fileDesc.publishLocations[publishAttributes.publishIndex] = publishAttributes;
|
||||
extensionMgr.onNewPublishSuccess(fileDesc, publishAttributes);
|
||||
};
|
||||
|
||||
// Remove a publishIndex (publish location)
|
||||
fileMgr.removePublish = function(publishAttributes, skipExtensions) {
|
||||
fileMgr.removePublish = function(publishAttributes) {
|
||||
var fileDesc = fileMgr.getFileFromPublishIndex(publishAttributes.publishIndex);
|
||||
if(fileDesc !== undefined) {
|
||||
localStorage[fileDesc.fileIndex + ".publish"] = localStorage[fileDesc.fileIndex + ".publish"].replace(";" + publishAttributes.publishIndex + ";", ";");
|
||||
}
|
||||
// Remove publish attributes
|
||||
localStorage.removeItem(publishAttributes.publishIndex);
|
||||
utils.removeIndexFromArray(fileDesc.fileIndex + ".publish", publishAttributes.publishIndex);
|
||||
delete fileDesc.publishLocations[publishAttributes.publishIndex];
|
||||
if(!skipExtensions) {
|
||||
extensionMgr.onPublishRemoved(fileDesc, publishAttributes);
|
||||
}
|
||||
// Remove publish attributes from localStorage
|
||||
localStorage.removeItem(publishAttributes.publishIndex);
|
||||
};
|
||||
|
||||
// Get the file descriptor associated to a publishIndex
|
||||
|
@ -362,7 +362,7 @@ define([
|
||||
task.retry(new Error(errorMsg), 1);
|
||||
return;
|
||||
}
|
||||
else if(error.code <= 0) {
|
||||
else if(error.code === 0 || error.code === -1) {
|
||||
connected = false;
|
||||
authenticated = false;
|
||||
core.setOffline();
|
||||
|
@ -111,14 +111,13 @@
|
||||
* its own image insertion dialog, this hook should return true, and the callback should be called with the chosen
|
||||
* image url (or null if the user cancelled). If this hook returns false, the default dialog will be used.
|
||||
*/
|
||||
hooks.addFalse("insertLinkDialog"); // benweet
|
||||
hooks.addFalse("insertLinkDialog");
|
||||
|
||||
this.getConverter = function () { return markdownConverter; }
|
||||
|
||||
var that = this,
|
||||
panels;
|
||||
|
||||
// benweet
|
||||
var undoManager;
|
||||
this.run = function (previewWrapper) {
|
||||
if (panels)
|
||||
@ -126,7 +125,7 @@
|
||||
|
||||
panels = new PanelCollection(idPostfix);
|
||||
var commandManager = new CommandManager(hooks, getString);
|
||||
var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }, previewWrapper); // benweet
|
||||
var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }, previewWrapper);
|
||||
var uiManager;
|
||||
|
||||
if (!/\?noundo/.test(doc.location.href)) {
|
||||
@ -147,13 +146,9 @@
|
||||
|
||||
var forceRefresh = that.refreshPreview = function () { previewManager.refresh(true); };
|
||||
|
||||
forceRefresh();
|
||||
};
|
||||
|
||||
// benweet
|
||||
this.restart = function() {
|
||||
undoManager.reinit();
|
||||
that.refreshPreview();
|
||||
//Not necessary
|
||||
//forceRefresh();
|
||||
return undoManager;
|
||||
};
|
||||
|
||||
}
|
||||
@ -681,18 +676,21 @@
|
||||
var init = function () {
|
||||
setEventHandlers();
|
||||
refreshState(true);
|
||||
saveState();
|
||||
//Not necessary
|
||||
//saveState();
|
||||
};
|
||||
|
||||
// benweet
|
||||
this.reinit = function() {
|
||||
this.reinit = function(content, start, end, scrollTop) {
|
||||
undoStack = [];
|
||||
stackPtr = 0;
|
||||
mode = "none";
|
||||
lastState = undefined;
|
||||
timer = undefined;
|
||||
inputStateObj = undefined;
|
||||
refreshState();
|
||||
inputStateObj.text = content;
|
||||
inputStateObj.start = start;
|
||||
inputStateObj.end = end;
|
||||
inputStateObj.scrollTop = scrollTop;
|
||||
inputStateObj.setInputAreaSelection();
|
||||
saveState();
|
||||
};
|
||||
@ -842,7 +840,7 @@
|
||||
this.init();
|
||||
};
|
||||
|
||||
function PreviewManager(converter, panels, previewRefreshCallback, previewWrapper) { // benweet
|
||||
function PreviewManager(converter, panels, previewRefreshCallback, previewWrapper) {
|
||||
|
||||
var managerObj = this;
|
||||
var timeout;
|
||||
@ -908,7 +906,7 @@
|
||||
|
||||
pushPreviewHtml(text);
|
||||
};
|
||||
if(previewWrapper !== undefined) { // benweet
|
||||
if(previewWrapper !== undefined) {
|
||||
makePreviewHtml = previewWrapper(makePreviewHtml);
|
||||
}
|
||||
|
||||
@ -1030,7 +1028,8 @@
|
||||
var init = function () {
|
||||
|
||||
setupEvents(panels.input, applyTimeout);
|
||||
makePreviewHtml();
|
||||
//Not necessary
|
||||
//makePreviewHtml();
|
||||
|
||||
if (panels.preview) {
|
||||
panels.preview.scrollTop = 0;
|
||||
@ -1437,12 +1436,12 @@
|
||||
return false;
|
||||
}
|
||||
}
|
||||
button.className = button.className.replace(/ disabled/g, ""); // benweet
|
||||
button.className = button.className.replace(/ disabled/g, "");
|
||||
}
|
||||
else {
|
||||
image.style.backgroundPosition = button.XShift + " " + disabledYShift;
|
||||
button.onmouseover = button.onmouseout = button.onclick = function () { };
|
||||
button.className += " disabled"; // benweet
|
||||
button.className += " disabled";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1807,7 +1806,7 @@
|
||||
ui.prompt(this.getString("imagedialog"), imageDefaultText, linkEnteredCallback);
|
||||
}
|
||||
else {
|
||||
if (!this.hooks.insertLinkDialog(linkEnteredCallback)) // benweet
|
||||
if (!this.hooks.insertLinkDialog(linkEnteredCallback))
|
||||
ui.prompt(this.getString("linkdialog"), linkDefaultText, linkEnteredCallback);
|
||||
}
|
||||
return true;
|
||||
|
@ -24,7 +24,7 @@
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function trim(str) {
|
||||
@ -113,21 +113,17 @@
|
||||
|
||||
// Duplicated from PageDown converter
|
||||
function unescapeSpecialChars(text) {
|
||||
//
|
||||
// Swap back in all the special characters we've hidden.
|
||||
//
|
||||
text = text.replace(/~E(\d+)E/g,
|
||||
function (wholeMatch, m1) {
|
||||
text = text.replace(/~E(\d+)E/g, function(wholeMatch, m1) {
|
||||
var charCodeToReplace = parseInt(m1);
|
||||
return String.fromCharCode(charCodeToReplace);
|
||||
}
|
||||
);
|
||||
});
|
||||
return text;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
/*****************************************************************************
|
||||
* Markdown.Extra *
|
||||
*****************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
Markdown.Extra = function() {
|
||||
// For converting internal markdown (in tables for instance).
|
||||
@ -159,36 +155,47 @@
|
||||
var extra = new Markdown.Extra();
|
||||
var postNormalizationTransformations = [];
|
||||
var preBlockGamutTransformations = [];
|
||||
var postConversionTransformations = ["unHashExtraBlocks"];
|
||||
|
||||
options = options || {};
|
||||
options.extensions = options.extensions || ["all"];
|
||||
if (contains(options.extensions, "all"))
|
||||
if (contains(options.extensions, "all")) {
|
||||
options.extensions = ["tables", "fenced_code_gfm", "def_list", "attr_list"];
|
||||
if (contains(options.extensions, "tables"))
|
||||
preBlockGamutTransformations.push("tables");
|
||||
if (contains(options.extensions, "fenced_code_gfm"))
|
||||
postNormalizationTransformations.push("fencedCodeBlocks");
|
||||
if (contains(options.extensions, "def_list"))
|
||||
preBlockGamutTransformations.push("definitionLists");
|
||||
if (contains(options.extensions, "attr_list"))
|
||||
}
|
||||
if (contains(options.extensions, "attr_list")) {
|
||||
postNormalizationTransformations.push("hashFcbAttributeBlocks");
|
||||
preBlockGamutTransformations.push("hashHeaderAttributeBlocks");
|
||||
postConversionTransformations.push("applyAttributeBlocks");
|
||||
extra.attributeBlocks = true;
|
||||
|
||||
}
|
||||
if (contains(options.extensions, "tables")) {
|
||||
preBlockGamutTransformations.push("tables");
|
||||
}
|
||||
if (contains(options.extensions, "fenced_code_gfm")) {
|
||||
postNormalizationTransformations.push("fencedCodeBlocks");
|
||||
}
|
||||
if (contains(options.extensions, "def_list")) {
|
||||
preBlockGamutTransformations.push("definitionLists");
|
||||
}
|
||||
|
||||
converter.hooks.chain("postNormalization", function(text) {
|
||||
return extra.doTransform(postNormalizationTransformations, text);
|
||||
return extra.doTransform(postNormalizationTransformations, text) + '\n';
|
||||
});
|
||||
|
||||
// preBlockGamut also gives us access to a hook so we can run the
|
||||
// block gamut recursively, however we don't need it at this point
|
||||
converter.hooks.chain("preBlockGamut", function(text, blockGamutHookCallback) {
|
||||
// Keep a reference to the block gamut callback to run recursively
|
||||
extra.blockGamutHookCallback = blockGamutHookCallback;
|
||||
return extra.doConversion(preBlockGamutTransformations, text);
|
||||
text = processEscapes(text);
|
||||
return extra.doTransform(preBlockGamutTransformations, text) + '\n';
|
||||
});
|
||||
|
||||
// Keep a reference to the hook chain running before finishConversion to apply on hashed extra blocks
|
||||
// Keep a reference to the hook chain running before doPostConversion to apply on hashed extra blocks
|
||||
extra.previousPostConversion = converter.hooks.postConversion;
|
||||
converter.hooks.chain("postConversion", function(text) {
|
||||
return extra.finishConversion(text);
|
||||
text = extra.doTransform(postConversionTransformations, text);
|
||||
// Clear state vars that may use unnecessary memory
|
||||
this.hashBlocks = [];
|
||||
return text;
|
||||
});
|
||||
|
||||
if ("highlighter" in options) {
|
||||
@ -208,34 +215,8 @@
|
||||
|
||||
// Do transformations
|
||||
Markdown.Extra.prototype.doTransform = function(transformations, text) {
|
||||
if (this.attributeBlocks)
|
||||
text = this.hashFcbAttributeBlocks(text);
|
||||
|
||||
for(var i = 0; i < transformations.length; i++)
|
||||
text = this[transformations[i]](text);
|
||||
|
||||
return text + '\n';
|
||||
};
|
||||
|
||||
// Setup state vars, do conversion
|
||||
Markdown.Extra.prototype.doConversion = function(transformations, text) {
|
||||
text = processEscapes(text);
|
||||
|
||||
if (this.attributeBlocks)
|
||||
text = this.hashHeaderAttributeBlocks(text);
|
||||
|
||||
return this.doTransform(transformations, text);
|
||||
};
|
||||
|
||||
// Clear state vars that may use unnecessary memory. Unhash blocks we
|
||||
// stored, apply attribute blocks if necessary, and return converted text.
|
||||
Markdown.Extra.prototype.finishConversion = function(text) {
|
||||
text = this.unHashExtraBlocks(text);
|
||||
|
||||
if (this.attributeBlocks)
|
||||
text = this.applyAttributeBlocks(text);
|
||||
|
||||
this.hashBlocks = [];
|
||||
return text;
|
||||
};
|
||||
|
||||
@ -466,6 +447,9 @@
|
||||
code = code.replace(/&/g, "&");
|
||||
code = code.replace(/</g, "<");
|
||||
code = code.replace(/>/g, ">");
|
||||
// These were escaped by PageDown before postNormalization
|
||||
code = code.replace(/~D/g, "$$");
|
||||
code = code.replace(/~T/g, "~");
|
||||
return code;
|
||||
}
|
||||
|
||||
|
117
js/libs/jquery.mousewheel.js
Normal file
117
js/libs/jquery.mousewheel.js
Normal file
@ -0,0 +1,117 @@
|
||||
/*! Copyright (c) 2013 Brandon Aaron (http://brandonaaron.net)
|
||||
* Licensed under the MIT License (LICENSE.txt).
|
||||
*
|
||||
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
||||
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
||||
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
||||
*
|
||||
* Version: 3.1.3
|
||||
*
|
||||
* Requires: 1.2.2+
|
||||
*/
|
||||
|
||||
(function (factory) {
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof exports === 'object') {
|
||||
// Node/CommonJS style for Browserify
|
||||
module.exports = factory;
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
|
||||
var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'];
|
||||
var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'];
|
||||
var lowestDelta, lowestDeltaXY;
|
||||
|
||||
if ( $.event.fixHooks ) {
|
||||
for ( var i = toFix.length; i; ) {
|
||||
$.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
|
||||
}
|
||||
}
|
||||
|
||||
$.event.special.mousewheel = {
|
||||
setup: function() {
|
||||
if ( this.addEventListener ) {
|
||||
for ( var i = toBind.length; i; ) {
|
||||
this.addEventListener( toBind[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = handler;
|
||||
}
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
if ( this.removeEventListener ) {
|
||||
for ( var i = toBind.length; i; ) {
|
||||
this.removeEventListener( toBind[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
mousewheel: function(fn) {
|
||||
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
|
||||
},
|
||||
|
||||
unmousewheel: function(fn) {
|
||||
return this.unbind("mousewheel", fn);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function handler(event) {
|
||||
var orgEvent = event || window.event,
|
||||
args = [].slice.call(arguments, 1),
|
||||
delta = 0,
|
||||
deltaX = 0,
|
||||
deltaY = 0,
|
||||
absDelta = 0,
|
||||
absDeltaXY = 0,
|
||||
fn;
|
||||
event = $.event.fix(orgEvent);
|
||||
event.type = "mousewheel";
|
||||
|
||||
// Old school scrollwheel delta
|
||||
if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; }
|
||||
if ( orgEvent.detail ) { delta = orgEvent.detail * -1; }
|
||||
|
||||
// New school wheel delta (wheel event)
|
||||
if ( orgEvent.deltaY ) {
|
||||
deltaY = orgEvent.deltaY * -1;
|
||||
delta = deltaY;
|
||||
}
|
||||
if ( orgEvent.deltaX ) {
|
||||
deltaX = orgEvent.deltaX;
|
||||
delta = deltaX * -1;
|
||||
}
|
||||
|
||||
// Webkit
|
||||
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; }
|
||||
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX * -1; }
|
||||
|
||||
// Look for lowest delta to normalize the delta values
|
||||
absDelta = Math.abs(delta);
|
||||
if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; }
|
||||
absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX));
|
||||
if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; }
|
||||
|
||||
// Get a whole value for the deltas
|
||||
fn = delta > 0 ? 'floor' : 'ceil';
|
||||
delta = Math[fn](delta / lowestDelta);
|
||||
deltaX = Math[fn](deltaX / lowestDeltaXY);
|
||||
deltaY = Math[fn](deltaY / lowestDeltaXY);
|
||||
|
||||
// Add event and delta to the front of the arguments
|
||||
args.unshift(event, delta, deltaX, deltaY);
|
||||
|
||||
return ($.event.dispatch || $.event.handle).apply(this, args);
|
||||
}
|
||||
|
||||
}));
|
@ -26,6 +26,9 @@ requirejs.config({
|
||||
'libs/jquery.waitforimages': [
|
||||
'jquery'
|
||||
],
|
||||
'libs/jquery.mousewheel': [
|
||||
'jquery'
|
||||
],
|
||||
'libs/layout': [
|
||||
'libs/jquery-ui'
|
||||
],
|
||||
|
@ -244,12 +244,11 @@ define([
|
||||
};
|
||||
|
||||
core.onReady(function() {
|
||||
var state = localStorage[PROVIDER_GDRIVE + ".state"];
|
||||
var state = utils.retrieveIgnoreError(PROVIDER_GDRIVE + ".state");
|
||||
if(state === undefined) {
|
||||
return;
|
||||
}
|
||||
localStorage.removeItem(PROVIDER_GDRIVE + ".state");
|
||||
state = JSON.parse(state);
|
||||
if(state.action == "create") {
|
||||
googleHelper.upload(undefined, state.folderId, GDRIVE_DEFAULT_FILE_TITLE, settings.defaultContent, undefined, function(error, file) {
|
||||
if(error) {
|
||||
|
@ -28,6 +28,7 @@ define([
|
||||
|
||||
var importImageCallback = undefined;
|
||||
var imageDoc = undefined;
|
||||
var importImagePreferences = utils.retrieveIgnoreError(PROVIDER_GPLUS + ".importImagePreferences");
|
||||
gplusProvider.importImage = function(callback) {
|
||||
importImageCallback = callback;
|
||||
googleHelper.picker(function(error, docs) {
|
||||
@ -46,9 +47,7 @@ define([
|
||||
utils.setInputValue("#input-import-image-title", imageDoc.name);
|
||||
|
||||
// Load preferences
|
||||
var serializedPreferences = localStorage[PROVIDER_GPLUS + ".importImagePreferences"];
|
||||
if(serializedPreferences) {
|
||||
var importImagePreferences = JSON.parse(serializedPreferences);
|
||||
if(importImagePreferences) {
|
||||
utils.setInputValue("#input-import-image-size", importImagePreferences.size);
|
||||
}
|
||||
|
||||
@ -67,7 +66,7 @@ define([
|
||||
importImageCallback(undefined, image);
|
||||
|
||||
// Store import preferences for next time
|
||||
var importImagePreferences = {};
|
||||
importImagePreferences = {};
|
||||
if(size) {
|
||||
importImagePreferences.size = size;
|
||||
}
|
||||
|
@ -30,13 +30,22 @@ define([
|
||||
|
||||
// Retrieve publish locations from localStorage
|
||||
_.each(fileSystem, function(fileDesc) {
|
||||
_.chain(localStorage[fileDesc.fileIndex + ".publish"].split(";")).compact().each(function(publishIndex) {
|
||||
_.each(utils.retrieveIndexArray(fileDesc.fileIndex + ".publish"), function(publishIndex) {
|
||||
try {
|
||||
var publishAttributes = JSON.parse(localStorage[publishIndex]);
|
||||
// Store publishIndex
|
||||
publishAttributes.publishIndex = publishIndex;
|
||||
// Replace provider ID by provider module in attributes
|
||||
publishAttributes.provider = providerMap[publishAttributes.provider];
|
||||
fileDesc.publishLocations[publishIndex] = publishAttributes;
|
||||
}
|
||||
catch(e) {
|
||||
// localStorage can be corrupted
|
||||
extensionMgr.onError(e);
|
||||
// Remove publish location
|
||||
utils.removeIndexFromArray(fileDesc.fileIndex + ".publish", publishIndex);
|
||||
localStorage.removeItem(publishIndex);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -151,9 +160,8 @@ define([
|
||||
$("input:radio[name=radio-publish-format][value=" + defaultPublishFormat + "]").prop("checked", true);
|
||||
|
||||
// Load preferences
|
||||
var serializedPreferences = localStorage[provider.providerId + ".publishPreferences"];
|
||||
if(serializedPreferences) {
|
||||
var publishPreferences = JSON.parse(serializedPreferences);
|
||||
var publishPreferences = utils.retrieveIgnoreError(provider.providerId + ".publishPreferences");
|
||||
if(publishPreferences) {
|
||||
_.each(provider.publishPreferencesInputIds, function(inputId) {
|
||||
utils.setInputValue("#input-publish-" + inputId, publishPreferences[inputId]);
|
||||
});
|
||||
@ -195,18 +203,6 @@ define([
|
||||
localStorage[provider.providerId + ".publishPreferences"] = JSON.stringify(publishPreferences);
|
||||
}
|
||||
|
||||
// Retrieve file's publish locations from localStorage
|
||||
publisher.populatePublishLocations = function(fileDesc) {
|
||||
_.chain(localStorage[fileDesc.fileIndex + ".publish"].split(";")).compact().each(function(publishIndex) {
|
||||
var publishAttributes = JSON.parse(localStorage[publishIndex]);
|
||||
// Store publishIndex
|
||||
publishAttributes.publishIndex = publishIndex;
|
||||
// Replace provider ID by provider module in attributes
|
||||
publishAttributes.provider = providerMap[publishAttributes.provider];
|
||||
fileDesc.publishLocations[publishIndex] = publishAttributes;
|
||||
});
|
||||
};
|
||||
|
||||
core.onReady(function() {
|
||||
// Add every provider
|
||||
var publishMenu = $("#publish-menu");
|
||||
|
@ -26,9 +26,12 @@ define([
|
||||
extensionSettings: {}
|
||||
};
|
||||
|
||||
if(_.has(localStorage, "settings")) {
|
||||
try {
|
||||
_.extend(settings, JSON.parse(localStorage.settings));
|
||||
}
|
||||
catch(e) {
|
||||
// Ignore parsing error
|
||||
}
|
||||
|
||||
return settings;
|
||||
});
|
@ -1,13 +1,10 @@
|
||||
// Setup an empty localStorage or upgrade an existing one
|
||||
define([
|
||||
"underscore"
|
||||
], function(_) {
|
||||
"underscore",
|
||||
"utils"
|
||||
], function(_, utils) {
|
||||
|
||||
// Create the file system if not exist
|
||||
if(localStorage["file.list"] === undefined) {
|
||||
localStorage["file.list"] = ";";
|
||||
}
|
||||
var fileIndexList = _.compact(localStorage["file.list"].split(";"));
|
||||
var fileIndexList = utils.retrieveIndexArray("file.list");
|
||||
|
||||
// localStorage versioning
|
||||
var version = localStorage["version"];
|
||||
@ -22,7 +19,7 @@ define([
|
||||
|
||||
_.each(fileIndexList, function(fileIndex) {
|
||||
localStorage[fileIndex + ".publish"] = ";";
|
||||
var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";"));
|
||||
var syncIndexList = utils.retrieveIndexArray(fileIndex + ".sync");
|
||||
_.each(syncIndexList, function(syncIndex) {
|
||||
localStorage[syncIndex + ".contentCRC"] = "0";
|
||||
// We store title CRC only for Google Drive synchronization
|
||||
@ -52,7 +49,7 @@ define([
|
||||
var SYNC_PROVIDER_GDRIVE = "sync." + PROVIDER_GDRIVE + ".";
|
||||
var SYNC_PROVIDER_DROPBOX = "sync." + PROVIDER_DROPBOX + ".";
|
||||
_.each(fileIndexList, function(fileIndex) {
|
||||
var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";"));
|
||||
var syncIndexList = utils.retrieveIndexArray(fileIndex + ".sync");
|
||||
_.each(syncIndexList, function(syncIndex) {
|
||||
var syncAttributes = {};
|
||||
if(syncIndex.indexOf(SYNC_PROVIDER_GDRIVE) === 0) {
|
||||
@ -85,7 +82,7 @@ define([
|
||||
localStorage.removeItem(fileIndex + ".title");
|
||||
localStorage.removeItem(fileIndex + ".publish");
|
||||
localStorage.removeItem(fileIndex + ".content");
|
||||
localStorage["file.list"] = localStorage["file.list"].replace(";" + fileIndex + ";", ";");
|
||||
utils.removeIndexFromArray("file.list", fileIndex);
|
||||
}
|
||||
});
|
||||
version = "v3";
|
||||
@ -110,7 +107,7 @@ define([
|
||||
// Upgrade from v5 to v6
|
||||
if(version == "v5") {
|
||||
_.each(fileIndexList, function(fileIndex) {
|
||||
var publishIndexList = _.compact(localStorage[fileIndex + ".publish"].split(";"));
|
||||
var publishIndexList = utils.retrieveIndexArray(fileIndex + ".publish");
|
||||
_.each(publishIndexList, function(publishIndex) {
|
||||
var publishAttributes = JSON.parse(localStorage[publishIndex]);
|
||||
if(publishAttributes.provider == "gdrive") {
|
||||
|
@ -22,13 +22,22 @@ define([
|
||||
|
||||
// Retrieve sync locations from localStorage
|
||||
_.each(fileSystem, function(fileDesc) {
|
||||
_.chain(localStorage[fileDesc.fileIndex + ".sync"].split(";")).compact().each(function(syncIndex) {
|
||||
_.each(utils.retrieveIndexArray(fileDesc.fileIndex + ".sync"), function(syncIndex) {
|
||||
try {
|
||||
var syncAttributes = JSON.parse(localStorage[syncIndex]);
|
||||
// Store syncIndex
|
||||
syncAttributes.syncIndex = syncIndex;
|
||||
// Replace provider ID by provider module in attributes
|
||||
syncAttributes.provider = providerMap[syncAttributes.provider];
|
||||
fileDesc.syncLocations[syncIndex] = syncAttributes;
|
||||
}
|
||||
catch(e) {
|
||||
// localStorage can be corrupted
|
||||
extensionMgr.onError(e);
|
||||
// Remove sync location
|
||||
utils.removeIndexFromArray(fileDesc.fileIndex + ".sync", syncIndex);
|
||||
localStorage.removeItem(syncIndex);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -191,9 +200,8 @@ define([
|
||||
utils.resetModalInputs();
|
||||
|
||||
// Load preferences
|
||||
var serializedPreferences = localStorage[provider.providerId + ".exportPreferences"];
|
||||
if(serializedPreferences) {
|
||||
var exportPreferences = JSON.parse(serializedPreferences);
|
||||
var exportPreferences = utils.retrieveIgnoreError(provider.providerId + ".exportPreferences");
|
||||
if(exportPreferences) {
|
||||
_.each(provider.exportPreferencesInputIds, function(inputId) {
|
||||
utils.setInputValue("#input-sync-export-" + inputId, exportPreferences[inputId]);
|
||||
});
|
||||
|
33
js/utils.js
33
js/utils.js
@ -196,7 +196,7 @@ define([
|
||||
};
|
||||
utils.updateCurrentTime();
|
||||
|
||||
// Serialize sync/publish attributes and store it in the fileStorage
|
||||
// Serialize sync/publish attributes and store it in the localStorage
|
||||
utils.storeAttributes = function(attributes) {
|
||||
var storeIndex = attributes.syncIndex || attributes.publishIndex;
|
||||
// Don't store sync/publish index
|
||||
@ -206,6 +206,37 @@ define([
|
||||
localStorage[storeIndex] = JSON.stringify(attributes);
|
||||
};
|
||||
|
||||
// Retrieve/parse an index array from localStorage
|
||||
utils.retrieveIndexArray = function(storeIndex) {
|
||||
try {
|
||||
return _.compact(localStorage[storeIndex].split(";"));
|
||||
}
|
||||
catch(e) {
|
||||
localStorage[storeIndex] = ";";
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
// Append an index to an array in localStorage
|
||||
utils.appendIndexToArray = function(storeIndex, index) {
|
||||
localStorage[storeIndex] += index + ";";
|
||||
};
|
||||
|
||||
// Remove an index from an array in localStorage
|
||||
utils.removeIndexFromArray = function(storeIndex, index) {
|
||||
localStorage[storeIndex] = localStorage[storeIndex].replace(";" + index + ";", ";");
|
||||
};
|
||||
|
||||
// Retrieve/parse an object from localStorage. Returns undefined if error.
|
||||
utils.retrieveIgnoreError = function(storeIndex) {
|
||||
try {
|
||||
return JSON.parse(localStorage[storeIndex]);
|
||||
}
|
||||
catch(e) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
// Base64 conversion
|
||||
utils.encodeBase64 = function(str) {
|
||||
if(str.length === 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user