Better error management
This commit is contained in:
parent
df2109206a
commit
0adeb3a349
@ -1 +1 @@
|
|||||||
CACHE MANIFEST
# v14
CACHE:
index.html
css/main-min.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
# v15
CACHE:
index.html
css/main-min.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:
*
|
||||||
|
7
css/main-min.css
vendored
7
css/main-min.css
vendored
@ -5565,13 +5565,16 @@ hr {
|
|||||||
height: 16px;
|
height: 16px;
|
||||||
background-position: -109px 0;
|
background-position: -109px 0;
|
||||||
}
|
}
|
||||||
.icon-spinner {
|
.working-indicator {
|
||||||
background-image: url("../img/ajax-loader.gif");
|
background-image: none;
|
||||||
width: 43px;
|
width: 43px;
|
||||||
height: 11px;
|
height: 11px;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
margin: 14px 15px 0;
|
margin: 14px 15px 0;
|
||||||
}
|
}
|
||||||
|
.working-indicator.show {
|
||||||
|
background-image: url("../img/ajax-loader.gif");
|
||||||
|
}
|
||||||
.ui-layout-toggler-north .caret, .ui-layout-toggler-south .caret {
|
.ui-layout-toggler-north .caret, .ui-layout-toggler-south .caret {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
@ -274,14 +274,18 @@ hr {
|
|||||||
background-position: -109px 0;
|
background-position: -109px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-spinner {
|
.working-indicator {
|
||||||
background-image: url("../img/ajax-loader.gif");
|
background-image: none;
|
||||||
width: 43px;
|
width: 43px;
|
||||||
height: 11px;
|
height: 11px;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
margin: 14px 15px 0;
|
margin: 14px 15px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.working-indicator.show {
|
||||||
|
background-image: url("../img/ajax-loader.gif");
|
||||||
|
}
|
||||||
|
|
||||||
.ui-layout-toggler-north .caret, .ui-layout-toggler-south .caret {
|
.ui-layout-toggler-north .caret, .ui-layout-toggler-south .caret {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
35
index.html
35
index.html
@ -111,7 +111,7 @@
|
|||||||
</ul></li>
|
</ul></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav pull-right">
|
<ul class="nav pull-right">
|
||||||
<li><i class="working-indicator icon-spinner hide"></i></li>
|
<li><i class="working-indicator icon-none"></i></li>
|
||||||
<li><a class="brand" id="file-title" href="#"
|
<li><a class="brand" id="file-title" href="#"
|
||||||
title="Rename current document"> </a></li>
|
title="Rename current document"> </a></li>
|
||||||
<li class="navbar-form"><input id="file-title-input"
|
<li class="navbar-form"><input id="file-title-input"
|
||||||
@ -321,7 +321,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group modal-publish-blogger">
|
<div class="control-group modal-publish-blogger">
|
||||||
<label class="control-label" for="input-publish-blogger-labels">Labels (comma separated)</label>
|
<label class="control-label" for="input-publish-blogger-labels">Labels
|
||||||
|
(comma separated)</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" id="input-publish-blogger-labels"
|
<input type="text" id="input-publish-blogger-labels"
|
||||||
placeholder="Label1, Label2">
|
placeholder="Label1, Label2">
|
||||||
@ -344,23 +345,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group modal-publish-gdrive">
|
<div class="control-group modal-publish-gdrive">
|
||||||
<div class="controls muted">
|
<div class="controls muted">If no file ID is supplied, the
|
||||||
If no file ID is supplied, the file will be created
|
file will be created into your Google Drive root folder. You can
|
||||||
into your Google Drive root folder. You can move the file afterwards within
|
move the file afterwards within Google Drive.</div>
|
||||||
Google Drive.
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group modal-publish-gdrive">
|
<div class="control-group modal-publish-gdrive">
|
||||||
<label class="control-label" for="input-publish-gdrive-filename">Force file name (optional)</label>
|
<label class="control-label" for="input-publish-gdrive-filename">Force
|
||||||
|
file name (optional)</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" id="input-publish-gdrive-filename"
|
<input type="text" id="input-publish-gdrive-filename"
|
||||||
placeholder="File name">
|
placeholder="File name">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group modal-publish-gdrive">
|
<div class="control-group modal-publish-gdrive">
|
||||||
<div class="controls muted">
|
<div class="controls muted">If no file name is supplied, the
|
||||||
If no file name is supplied, the document title will be used.
|
document title will be used.</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
@ -435,8 +434,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label class="control-label" for="input-settings-scroll-link">Scroll Link <a
|
<label class="control-label" for="input-settings-scroll-link">Scroll
|
||||||
href="#" class="tooltip-scroll-link">(?)</a></label>
|
Link <a href="#" class="tooltip-scroll-link">(?)</a>
|
||||||
|
</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="checkbox" id="input-settings-scroll-link" />
|
<input type="checkbox" id="input-settings-scroll-link" />
|
||||||
</div>
|
</div>
|
||||||
@ -540,7 +540,9 @@
|
|||||||
<a target="_blank" href="http://twitter.github.io/bootstrap/">Bootstrap</a>
|
<a target="_blank" href="http://twitter.github.io/bootstrap/">Bootstrap</a>
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a target="_blank" href="https://github.com/rafaelp/css_browser_selector/">CSS Browser Selector</a>
|
<a target="_blank"
|
||||||
|
href="https://github.com/rafaelp/css_browser_selector/">CSS
|
||||||
|
Browser Selector</a>
|
||||||
</dd>
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a target="_blank" href="https://github.com/dropbox/dropbox-js">Dropbox-js</a>
|
<a target="_blank" href="https://github.com/dropbox/dropbox-js">Dropbox-js</a>
|
||||||
@ -587,13 +589,14 @@
|
|||||||
href="http://www.apache.org/licenses/LICENSE-2.0">Apache License</a></p>
|
href="http://www.apache.org/licenses/LICENSE-2.0">Apache License</a></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 action-welcome-file" data-dismiss="modal">Welcome
|
||||||
|
document</a> <a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="modal-non-unique" class="modal hide">
|
<div id="modal-non-unique" class="modal hide">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3>Stopped...</h3>
|
<h3>Whoops...</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>StackEdit has stopped because another instance was running in
|
<p>StackEdit has stopped because another instance was running in
|
||||||
|
@ -470,6 +470,7 @@
|
|||||||
Markdown.Extra.prototype.all = function(text) {
|
Markdown.Extra.prototype.all = function(text) {
|
||||||
text = this.tables(text);
|
text = this.tables(text);
|
||||||
text = this.fencedCodeBlocks(text);
|
text = this.fencedCodeBlocks(text);
|
||||||
|
text = this.definitionLists(text);
|
||||||
return text;
|
return text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,7 +79,10 @@ define([ "core", "underscore" ], function(core) {
|
|||||||
if (task.finished === true) {
|
if (task.finished === true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
error = error || "Unknown error";
|
error = error || new Error("Unknown error");
|
||||||
|
if(error.message) {
|
||||||
|
core.showError(error.message);
|
||||||
|
}
|
||||||
runSafe(task, task.errorCallbacks, error);
|
runSafe(task, task.errorCallbacks, error);
|
||||||
// Exit the current call stack
|
// Exit the current call stack
|
||||||
throw error;
|
throw error;
|
||||||
@ -87,13 +90,14 @@ define([ "core", "underscore" ], function(core) {
|
|||||||
/**
|
/**
|
||||||
* retry() can be called in an onRun callback to restart the task
|
* retry() can be called in an onRun callback to restart the task
|
||||||
*/
|
*/
|
||||||
task.retry = function() {
|
task.retry = function(error, maxRetryCounter) {
|
||||||
if (task.finished === true) {
|
if (task.finished === true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
maxRetryCounter = maxRetryCounter || 5;
|
||||||
task.queue = undefined;
|
task.queue = undefined;
|
||||||
if (task.retryCounter === 5) {
|
if (task.retryCounter >= maxRetryCounter) {
|
||||||
task.error(new Error("Maximum retry number reached"));
|
task.error(error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Implement an exponential backoff
|
// Implement an exponential backoff
|
||||||
@ -112,9 +116,7 @@ define([ "core", "underscore" ], function(core) {
|
|||||||
if (currentTaskRunning === true) {
|
if (currentTaskRunning === true) {
|
||||||
// If the current task takes too long
|
// If the current task takes too long
|
||||||
if (currentTaskStartTime + currentTask.timeout < core.currentTime) {
|
if (currentTaskStartTime + currentTask.timeout < core.currentTime) {
|
||||||
var errorMsg = "A timeout occurred.";
|
currentTask.error(new Error("A timeout occurred."));
|
||||||
core.showError(errorMsg);
|
|
||||||
currentTask.error(new Error(errorMsg));
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ var PROVIDER_BLOGGER = "blogger";
|
|||||||
var PROVIDER_DROPBOX = "dropbox";
|
var PROVIDER_DROPBOX = "dropbox";
|
||||||
var PROVIDER_GDRIVE = "gdrive";
|
var PROVIDER_GDRIVE = "gdrive";
|
||||||
var PROVIDER_GITHUB = "github";
|
var PROVIDER_GITHUB = "github";
|
||||||
|
var WELCOME_DOCUMENT_TITLE = "Welcome document";
|
||||||
|
|
||||||
// Use by Google's client.js
|
// Use by Google's client.js
|
||||||
var delayedFunction = undefined;
|
var delayedFunction = undefined;
|
||||||
|
25
js/core.js
25
js/core.js
@ -127,10 +127,10 @@ define(
|
|||||||
// Used by asyncRunner
|
// Used by asyncRunner
|
||||||
core.showWorkingIndicator = function(show) {
|
core.showWorkingIndicator = function(show) {
|
||||||
if (show === false) {
|
if (show === false) {
|
||||||
$(".working-indicator").addClass("hide");
|
$(".working-indicator").removeClass("show");
|
||||||
$("body").removeClass("working");
|
$("body").removeClass("working");
|
||||||
} else {
|
} else {
|
||||||
$(".working-indicator").removeClass("hide");
|
$(".working-indicator").addClass("show");
|
||||||
$("body").addClass("working");
|
$("body").addClass("working");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -293,7 +293,7 @@ define(
|
|||||||
var offset = 0, mdSectionOffset = 0;
|
var offset = 0, mdSectionOffset = 0;
|
||||||
function addMdSection(sectionText) {
|
function addMdSection(sectionText) {
|
||||||
var sectionHeight = padding;
|
var sectionHeight = padding;
|
||||||
if(sectionText) {
|
if(sectionText !== undefined) {
|
||||||
textareaElt.val(sectionText);
|
textareaElt.val(sectionText);
|
||||||
sectionHeight += textareaElt.prop('scrollHeight');
|
sectionHeight += textareaElt.prop('scrollHeight');
|
||||||
}
|
}
|
||||||
@ -313,7 +313,11 @@ define(
|
|||||||
if(title) {
|
if(title) {
|
||||||
// We just found a title which means end of the previous section
|
// We just found a title which means end of the previous section
|
||||||
// Exclude last \n of the section
|
// Exclude last \n of the section
|
||||||
addMdSection(text.substring(offset, matchOffset-1));
|
var sectionText = undefined;
|
||||||
|
if(matchOffset > offset) {
|
||||||
|
sectionText = text.substring(offset, matchOffset-1);
|
||||||
|
}
|
||||||
|
addMdSection(sectionText);
|
||||||
offset = matchOffset;
|
offset = matchOffset;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@ -358,8 +362,9 @@ define(
|
|||||||
lastEditorScrollTop = -9;
|
lastEditorScrollTop = -9;
|
||||||
lastPreviewScrollTop = -9;
|
lastPreviewScrollTop = -9;
|
||||||
scrollLink();
|
scrollLink();
|
||||||
}, 800);
|
}, 500);
|
||||||
|
|
||||||
|
// -9 is less than -5
|
||||||
var lastEditorScrollTop = -9;
|
var lastEditorScrollTop = -9;
|
||||||
var lastPreviewScrollTop = -9;
|
var lastPreviewScrollTop = -9;
|
||||||
var scrollLink = _.debounce(function() {
|
var scrollLink = _.debounce(function() {
|
||||||
@ -379,11 +384,12 @@ define(
|
|||||||
});
|
});
|
||||||
if(srcSection === undefined) {
|
if(srcSection === undefined) {
|
||||||
// Something wrong in the algorithm...
|
// Something wrong in the algorithm...
|
||||||
return 0;
|
return -9;
|
||||||
}
|
}
|
||||||
var posInSection = (srcScrollTop - srcSection.startOffset) / srcSection.height;
|
var posInSection = (srcScrollTop - srcSection.startOffset) / srcSection.height;
|
||||||
var destSection = destSectionList[sectionIndex];
|
var destSection = destSectionList[sectionIndex];
|
||||||
var destScrollTop = destSection.startOffset + destSection.height * posInSection;
|
var destScrollTop = destSection.startOffset + destSection.height * posInSection;
|
||||||
|
destScrollTop = _.min([destScrollTop, destElt.prop('scrollHeight') - destElt.outerHeight()]);
|
||||||
destElt.animate({scrollTop: destScrollTop}, 800, function() {
|
destElt.animate({scrollTop: destScrollTop}, 800, function() {
|
||||||
lastEditorScrollTop = editorElt.scrollTop();
|
lastEditorScrollTop = editorElt.scrollTop();
|
||||||
lastPreviewScrollTop = previewElt.scrollTop();
|
lastPreviewScrollTop = previewElt.scrollTop();
|
||||||
@ -396,7 +402,7 @@ define(
|
|||||||
else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) {
|
else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 5) {
|
||||||
editorScrollTop = animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList);
|
editorScrollTop = animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList);
|
||||||
}
|
}
|
||||||
}, 1200);
|
}, 1000);
|
||||||
|
|
||||||
// Create the layout
|
// Create the layout
|
||||||
var layout = undefined;
|
var layout = undefined;
|
||||||
@ -486,6 +492,11 @@ define(
|
|||||||
// Modify scroll position of the preview not the editor
|
// Modify scroll position of the preview not the editor
|
||||||
lastEditorScrollTop = -9;
|
lastEditorScrollTop = -9;
|
||||||
buildSections();
|
buildSections();
|
||||||
|
// Preview may change if images are loading
|
||||||
|
$("#wmd-preview img").load(function() {
|
||||||
|
lastEditorScrollTop = -9;
|
||||||
|
buildSections();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Custom insert link dialog
|
// Custom insert link dialog
|
||||||
|
@ -10,8 +10,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
task.onRun(function() {
|
task.onRun(function() {
|
||||||
if(core.isOffline === true) {
|
if(core.isOffline === true) {
|
||||||
client = undefined;
|
client = undefined;
|
||||||
core.showMessage("Operation not available in offline mode.");
|
task.error(new Error("Operation not available in offline mode."));
|
||||||
task.error();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (client !== undefined) {
|
if (client !== undefined) {
|
||||||
@ -31,9 +30,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
rememberUser: true
|
rememberUser: true
|
||||||
}));
|
}));
|
||||||
task.chain();
|
task.chain();
|
||||||
}).fail(function() {
|
}).fail(function(jqXHR) {
|
||||||
core.setOffline();
|
var error = {
|
||||||
task.error(new Error("Network timeout|stopPublish"));
|
status: jqXHR.status,
|
||||||
|
responseText: jqXHR.statusText
|
||||||
|
};
|
||||||
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -67,9 +69,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Error
|
// Error
|
||||||
var errorMsg = "Access to Dropbox account is not authorized.";
|
task.error(new Error("Access to Dropbox account is not authorized."));
|
||||||
core.showError(errorMsg);
|
|
||||||
task.error(new Error(errorMsg));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
task.chain(localAuthenticate);
|
task.chain(localAuthenticate);
|
||||||
@ -93,7 +93,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
if(error.status === Dropbox.ApiError.INVALID_PARAM) {
|
if(error.status === Dropbox.ApiError.INVALID_PARAM) {
|
||||||
error = 'Could not upload document into path "' + path + '".';
|
error = 'Could not upload document into path "' + path + '".';
|
||||||
}
|
}
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
task.onSuccess(function() {
|
task.onSuccess(function() {
|
||||||
@ -116,7 +116,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
function retrievePageOfChanges() {
|
function retrievePageOfChanges() {
|
||||||
client.pullChanges(newChangeId, function(error, pullChanges) {
|
client.pullChanges(newChangeId, function(error, pullChanges) {
|
||||||
if (error) {
|
if (error) {
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Retrieve success
|
// Retrieve success
|
||||||
@ -161,7 +161,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
task.chain(recursiveDownloadMetadata);
|
task.chain(recursiveDownloadMetadata);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
task.chain(recursiveDownloadMetadata);
|
task.chain(recursiveDownloadMetadata);
|
||||||
@ -208,7 +208,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
recursiveDownloadContent();
|
recursiveDownloadContent();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
task.chain(recursiveDownloadContent);
|
task.chain(recursiveDownloadContent);
|
||||||
@ -222,17 +222,23 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
asyncRunner.addTask(task);
|
asyncRunner.addTask(task);
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleError(error, task, callback) {
|
function handleError(error, task) {
|
||||||
var errorMsg = true;
|
var errorMsg = true;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
// Try to analyze the error
|
// Try to analyze the error
|
||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
errorMsg = error;
|
errorMsg = error;
|
||||||
} else if (error.status === Dropbox.ApiError.INVALID_TOKEN
|
}
|
||||||
|
else {
|
||||||
|
errorMsg = "Dropbox error ("
|
||||||
|
+ error.status + ": " + error.responseText + ").";
|
||||||
|
|
||||||
|
if (error.status === Dropbox.ApiError.INVALID_TOKEN
|
||||||
|| error.status === Dropbox.ApiError.OAUTH_ERROR) {
|
|| error.status === Dropbox.ApiError.OAUTH_ERROR) {
|
||||||
authenticated = false;
|
authenticated = false;
|
||||||
task.retry();
|
errorMsg = "Access to Dropbox account is not authorized.";
|
||||||
|
task.retry(new Error(errorMsg), 1);
|
||||||
return;
|
return;
|
||||||
} else if(error.status === Dropbox.ApiError.INVALID_PARAM && error.responseText
|
} else if(error.status === Dropbox.ApiError.INVALID_PARAM && error.responseText
|
||||||
.indexOf("oauth_nonce") !== -1) {
|
.indexOf("oauth_nonce") !== -1) {
|
||||||
@ -244,18 +250,15 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
authenticated = false;
|
authenticated = false;
|
||||||
task.retry();
|
task.retry(new Error(errorMsg), 1);
|
||||||
return;
|
return;
|
||||||
} else if (error.status === Dropbox.ApiError.NETWORK_ERROR) {
|
} else if (error.status === Dropbox.ApiError.NETWORK_ERROR || error.status < 0) {
|
||||||
client = undefined;
|
client = undefined;
|
||||||
authenticated = false;
|
authenticated = false;
|
||||||
core.setOffline();
|
core.setOffline();
|
||||||
errorMsg = "|stopPublish";
|
errorMsg = "|stopPublish";
|
||||||
} else {
|
|
||||||
errorMsg = "Dropbox error ("
|
|
||||||
+ error.status + ").";
|
|
||||||
}
|
}
|
||||||
core.showError(errorMsg);
|
}
|
||||||
}
|
}
|
||||||
task.error(new Error(errorMsg));
|
task.error(new Error(errorMsg));
|
||||||
}
|
}
|
||||||
@ -273,9 +276,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
}).done(function() {
|
}).done(function() {
|
||||||
pickerLoaded = true;
|
pickerLoaded = true;
|
||||||
task.chain();
|
task.chain();
|
||||||
}).fail(function() {
|
}).fail(function(jqXHR) {
|
||||||
core.setOffline();
|
var error = {
|
||||||
task.error();
|
status: jqXHR.status,
|
||||||
|
responseText: jqXHR.statusText
|
||||||
|
};
|
||||||
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
define(["jquery", "core", "synchronizer", "publisher", "underscore"],
|
define(["jquery", "core", "synchronizer", "publisher", "text!../WELCOME.md", "underscore"],
|
||||||
function($, core, synchronizer, publisher) {
|
function($, core, synchronizer, publisher, welcomeContent) {
|
||||||
|
|
||||||
var fileManager = {};
|
var fileManager = {};
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ define(["jquery", "core", "synchronizer", "publisher", "underscore"],
|
|||||||
fileManager.selectFile = function(fileIndex) {
|
fileManager.selectFile = function(fileIndex) {
|
||||||
// If no file create one
|
// If no file create one
|
||||||
if (localStorage["file.list"].length === 1) {
|
if (localStorage["file.list"].length === 1) {
|
||||||
fileIndex = this.createFile();
|
fileIndex = fileManager.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fileIndex !== undefined) {
|
if(fileIndex !== undefined) {
|
||||||
@ -272,6 +272,10 @@ define(["jquery", "core", "synchronizer", "publisher", "underscore"],
|
|||||||
var title = localStorage[fileManager.getCurrentFileIndex() + ".title"];
|
var title = localStorage[fileManager.getCurrentFileIndex() + ".title"];
|
||||||
core.saveFile(content, title + ".txt");
|
core.saveFile(content, title + ".txt");
|
||||||
});
|
});
|
||||||
|
$(".action-welcome-file").click(function() {
|
||||||
|
var fileIndex = fileManager.createFile(WELCOME_DOCUMENT_TITLE, welcomeContent);
|
||||||
|
fileManager.selectFile(fileIndex);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
core.setFileManager(fileManager);
|
core.setFileManager(fileManager);
|
||||||
|
@ -10,8 +10,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
task.onRun(function() {
|
task.onRun(function() {
|
||||||
if(core.isOffline === true) {
|
if(core.isOffline === true) {
|
||||||
connected = false;
|
connected = false;
|
||||||
core.showMessage("Operation not available in offline mode.");
|
task.error(new Error("Operation not available in offline mode."));
|
||||||
task.error();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (connected === true) {
|
if (connected === true) {
|
||||||
@ -24,9 +23,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
}).done(function() {
|
}).done(function() {
|
||||||
connected = true;
|
connected = true;
|
||||||
task.chain();
|
task.chain();
|
||||||
}).fail(function() {
|
}).fail(function(jqXHR) {
|
||||||
core.setOffline();
|
var error = {
|
||||||
task.error(new Error("Network timeout|stopPublish"));
|
error: jqXHR.status,
|
||||||
|
message: jqXHR.statusText
|
||||||
|
};
|
||||||
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -50,6 +52,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
core.showMessage("Please make sure the Github authorization popup is not blocked by your browser.");
|
core.showMessage("Please make sure the Github authorization popup is not blocked by your browser.");
|
||||||
|
var errorMsg = "Failed to retrieve a token from GitHub.";
|
||||||
// We add time for user to enter his credentials
|
// We add time for user to enter his credentials
|
||||||
task.timeout = ASYNC_TASK_LONG_TIMEOUT;
|
task.timeout = ASYNC_TASK_LONG_TIMEOUT;
|
||||||
var code = undefined;
|
var code = undefined;
|
||||||
@ -66,7 +69,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
intervalId = undefined;
|
intervalId = undefined;
|
||||||
code = localStorage["githubCode"];
|
code = localStorage["githubCode"];
|
||||||
if(code === undefined) {
|
if(code === undefined) {
|
||||||
task.error();
|
task.error(new Error(errorMsg));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
localStorage.removeItem("githubCode");
|
localStorage.removeItem("githubCode");
|
||||||
@ -86,7 +89,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
task.chain();
|
task.chain();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
task.error();
|
task.error(new Error(errorMsg));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -113,7 +116,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
var user = github.getUser();
|
var user = github.getUser();
|
||||||
user.show(undefined, function(err, result) {
|
user.show(undefined, function(err, result) {
|
||||||
if(err) {
|
if(err) {
|
||||||
task.error(err);
|
handleError(err, task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
userLogin = result.login;
|
userLogin = result.login;
|
||||||
@ -124,7 +127,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
var repo = github.getRepo(userLogin, reponame);
|
var repo = github.getRepo(userLogin, reponame);
|
||||||
repo.write(branch, path, content, commitMsg, function(err) {
|
repo.write(branch, path, content, commitMsg, function(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
task.error(err);
|
handleError(err, task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
task.chain();
|
task.chain();
|
||||||
@ -135,27 +138,37 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
task.onSuccess(function() {
|
task.onSuccess(function() {
|
||||||
callback();
|
callback();
|
||||||
});
|
});
|
||||||
task.onError(function(err) {
|
task.onError(function(error) {
|
||||||
var errorMsg = "Could not publish on GitHub.";
|
callback(error);
|
||||||
if(err !== undefined) {
|
|
||||||
console.error(err);
|
|
||||||
if(err.error === 401 || err.error === 403) {
|
|
||||||
github = undefined;
|
|
||||||
// Token must be renewed
|
|
||||||
localStorage.removeItem("githubToken");
|
|
||||||
errorMsg = "Access to GitHub is not authorized.";
|
|
||||||
}
|
|
||||||
else if(err.error === 0) {
|
|
||||||
connected = false;
|
|
||||||
github = undefined;
|
|
||||||
core.setOffline();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
core.showError(errorMsg);
|
|
||||||
callback(errorMsg);
|
|
||||||
});
|
});
|
||||||
asyncRunner.addTask(task);
|
asyncRunner.addTask(task);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function handleError(error, task) {
|
||||||
|
var errorMsg = undefined;
|
||||||
|
if (error) {
|
||||||
|
console.error(error);
|
||||||
|
// Try to analyze the error
|
||||||
|
if (typeof error === "string") {
|
||||||
|
errorMsg = error;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errorMsg = "Could not publish on GitHub.";
|
||||||
|
if (error.error === 401 || error.error === 403) {
|
||||||
|
github = undefined;
|
||||||
|
errorMsg = "Access to GitHub account is not authorized.";
|
||||||
|
task.retry(new Error(errorMsg), 1);
|
||||||
|
return;
|
||||||
|
} else if (error.error <= 0) {
|
||||||
|
connected = false;
|
||||||
|
github = undefined;
|
||||||
|
core.setOffline();
|
||||||
|
errorMsg = "|stopPublish";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
task.error(new Error(errorMsg));
|
||||||
|
}
|
||||||
|
|
||||||
return githubHelper;
|
return githubHelper;
|
||||||
});
|
});
|
||||||
|
@ -10,8 +10,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
task.onRun(function() {
|
task.onRun(function() {
|
||||||
if(core.isOffline === true) {
|
if(core.isOffline === true) {
|
||||||
connected = false;
|
connected = false;
|
||||||
core.showMessage("Operation not available in offline mode.");
|
task.error(new Error("Operation not available in offline mode."));
|
||||||
task.error();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (connected === true) {
|
if (connected === true) {
|
||||||
@ -25,9 +24,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url : "https://apis.google.com/js/client.js?onload=runDelayedFunction",
|
url : "https://apis.google.com/js/client.js?onload=runDelayedFunction",
|
||||||
dataType : "script", timeout : AJAX_TIMEOUT
|
dataType : "script", timeout : AJAX_TIMEOUT
|
||||||
}).fail(function() {
|
}).fail(function(jqXHR) {
|
||||||
core.setOffline();
|
var error = {
|
||||||
task.error(new Error("Network timeout|stopPublish"));
|
code: jqXHR.status,
|
||||||
|
message: jqXHR.statusText
|
||||||
|
};
|
||||||
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -58,9 +60,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Error
|
// Error
|
||||||
var errorMsg = "Access to Google account is not authorized.";
|
task.error(new Error("Access to Google account is not authorized."));
|
||||||
core.showError(errorMsg);
|
|
||||||
task.error(new Error(errorMsg));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Success
|
// Success
|
||||||
@ -137,7 +137,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
error = 'Conflict on file ID "' + fileId + '". Please restart the synchronization.';
|
error = 'Conflict on file ID "' + fileId + '". Please restart the synchronization.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
task.onSuccess(function() {
|
task.onSuccess(function() {
|
||||||
@ -172,7 +172,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
request.execute(function(response) {
|
request.execute(function(response) {
|
||||||
if (!response || !response.largestChangeId) {
|
if (!response || !response.largestChangeId) {
|
||||||
// Handle error
|
// Handle error
|
||||||
handleError(response.error, task, callback);
|
handleError(response.error, task);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Retrieve success
|
// Retrieve success
|
||||||
@ -234,7 +234,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
if(error.code === 404) {
|
if(error.code === 404) {
|
||||||
error = 'File ID "' + id + '" not found on Google Drive.';
|
error = 'File ID "' + id + '" not found on Google Drive.';
|
||||||
}
|
}
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
task.chain(recursiveDownloadMetadata);
|
task.chain(recursiveDownloadMetadata);
|
||||||
@ -295,7 +295,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
message: jqXHR.statusText
|
message: jqXHR.statusText
|
||||||
};
|
};
|
||||||
// Handle error
|
// Handle error
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
task.chain(recursiveDownloadContent);
|
task.chain(recursiveDownloadContent);
|
||||||
@ -309,7 +309,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
asyncRunner.addTask(task);
|
asyncRunner.addTask(task);
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleError(error, task, callback) {
|
function handleError(error, task) {
|
||||||
var errorMsg = undefined;
|
var errorMsg = undefined;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -317,24 +317,25 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
if (typeof error === "string") {
|
if (typeof error === "string") {
|
||||||
errorMsg = error;
|
errorMsg = error;
|
||||||
}
|
}
|
||||||
else if (error.code >= 500 && error.code < 600) {
|
else {
|
||||||
|
errorMsg = "Google error (" + error.code + ": "
|
||||||
|
+ error.message + ").";
|
||||||
|
if (error.code >= 500 && error.code < 600) {
|
||||||
// Retry as described in Google's best practices
|
// Retry as described in Google's best practices
|
||||||
task.retry();
|
task.retry(new Error(errorMsg));
|
||||||
return;
|
return;
|
||||||
} else if (error.code === 401 || error.code === 403) {
|
} else if (error.code === 401 || error.code === 403) {
|
||||||
authenticated = false;
|
authenticated = false;
|
||||||
task.retry();
|
errorMsg = "Access to Google account is not authorized.";
|
||||||
|
task.retry(new Error(errorMsg), 1);
|
||||||
return;
|
return;
|
||||||
} else if (error.code <= 0) {
|
} else if (error.code <= 0) {
|
||||||
connected = false;
|
connected = false;
|
||||||
authenticated = false;
|
authenticated = false;
|
||||||
core.setOffline();
|
core.setOffline();
|
||||||
errorMsg = "|stopPublish";
|
errorMsg = "|stopPublish";
|
||||||
} else {
|
|
||||||
errorMsg = "Google error (" + error.code + ": "
|
|
||||||
+ error.message + ").";
|
|
||||||
}
|
}
|
||||||
core.showError(errorMsg);
|
}
|
||||||
}
|
}
|
||||||
task.error(new Error(errorMsg));
|
task.error(new Error(errorMsg));
|
||||||
}
|
}
|
||||||
@ -353,9 +354,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
}).done(function() {
|
}).done(function() {
|
||||||
google.load('picker', '1', {callback: task.chain});
|
google.load('picker', '1', {callback: task.chain});
|
||||||
pickerLoaded = true;
|
pickerLoaded = true;
|
||||||
}).fail(function() {
|
}).fail(function(jqXHR) {
|
||||||
core.setOffline();
|
var error = {
|
||||||
task.error(new Error("Network timeout"));
|
code: jqXHR.status,
|
||||||
|
message: jqXHR.statusText
|
||||||
|
};
|
||||||
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -364,6 +368,12 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
callback = callback || core.doNothing;
|
callback = callback || core.doNothing;
|
||||||
var ids = [];
|
var ids = [];
|
||||||
var picker = undefined;
|
var picker = undefined;
|
||||||
|
function hidePicker() {
|
||||||
|
if(picker !== undefined) {
|
||||||
|
picker.setVisible(false);
|
||||||
|
$(".modal-backdrop, .picker").remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
var task = asyncRunner.createTask();
|
var task = asyncRunner.createTask();
|
||||||
connect(task);
|
connect(task);
|
||||||
loadPicker(task);
|
loadPicker(task);
|
||||||
@ -388,14 +398,13 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
ids.push(data.docs[i].id);
|
ids.push(data.docs[i].id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$(".modal-backdrop, .picker").remove();
|
hidePicker();
|
||||||
task.chain();
|
task.chain();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
picker = pickerBuilder.build();
|
picker = pickerBuilder.build();
|
||||||
$("body").append($("<div>").addClass("modal-backdrop").click(function() {
|
$("body").append($("<div>").addClass("modal-backdrop").click(function() {
|
||||||
picker.setVisible(false);
|
hidePicker();
|
||||||
$(".modal-backdrop, .picker").remove();
|
|
||||||
task.chain();
|
task.chain();
|
||||||
}));
|
}));
|
||||||
picker.setVisible(true);
|
picker.setVisible(true);
|
||||||
@ -404,11 +413,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
callback(undefined, ids);
|
callback(undefined, ids);
|
||||||
});
|
});
|
||||||
task.onError(function(error) {
|
task.onError(function(error) {
|
||||||
if(picker !== undefined) {
|
hidePicker();
|
||||||
picker.setVisible(false);
|
|
||||||
$(".modal-backdrop, .picker").remove();
|
|
||||||
task.chain();
|
|
||||||
}
|
|
||||||
callback(error);
|
callback(error);
|
||||||
});
|
});
|
||||||
asyncRunner.addTask(task);
|
asyncRunner.addTask(task);
|
||||||
@ -459,7 +464,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
if(error.code === 404 && postId !== undefined) {
|
if(error.code === 404 && postId !== undefined) {
|
||||||
error = 'Post ' + postId + ' not found on Blogger.|removePublish';
|
error = 'Post ' + postId + ' not found on Blogger.|removePublish';
|
||||||
}
|
}
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function getBlogId() {
|
function getBlogId() {
|
||||||
@ -485,7 +490,7 @@ define(["jquery", "core", "async-runner"], function($, core, asyncRunner) {
|
|||||||
if(error.code === 404) {
|
if(error.code === 404) {
|
||||||
error = 'Blog "' + blogUrl + '" not found on Blogger.|removePublish';
|
error = 'Blog "' + blogUrl + '" not found on Blogger.|removePublish';
|
||||||
}
|
}
|
||||||
handleError(error, task, callback);
|
handleError(error, task);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
task.chain(getBlogId);
|
task.chain(getBlogId);
|
||||||
|
8
js/main-min.js
vendored
8
js/main-min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user