Publish support
This commit is contained in:
parent
85528c92a9
commit
c2461c3af0
@ -1 +1 @@
|
|||||||
CACHE MANIFEST
# v33
CACHE:
index.html
css/bootstrap.css
css/jgrowl.css
css/main.css
js/async-runner.js
js/bootstrap.js
js/config.js
js/custo.github.js
js/dropbox-helper.js
js/github.js
js/google-helper.js
js/jgrowl.js
js/jquery.js
js/jquery-ui.js
js/layout.js
js/main.js
js/Markdown.Converter.js
js/Markdown.Editor.js
js/Markdown.Sanitizer.js
js/publisher.js
js/require.js
js/synchronizer.js
js/underscore-min.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
# v33
CACHE:
index.html
css/bootstrap.css
css/jgrowl.css
css/main.css
js/async-runner.js
js/bootstrap.js
js/config.js
js/custo.github.js
js/dropbox-helper.js
js/github-helper.js
js/google-helper.js
js/jgrowl.js
js/jquery.js
js/jquery-ui.js
js/layout.js
js/main.js
js/Markdown.Converter.js
js/Markdown.Editor.js
js/Markdown.Sanitizer.js
js/publisher.js
js/require.js
js/synchronizer.js
js/underscore-min.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:
*
|
||||||
|
BIN
img/icons.png
BIN
img/icons.png
Binary file not shown.
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.4 KiB |
47
index.html
47
index.html
@ -26,7 +26,7 @@
|
|||||||
title="Synchronize">
|
title="Synchronize">
|
||||||
<i class="icon-refresh"></i>
|
<i class="icon-refresh"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn action-publish" title="Publish">
|
<button class="btn action-force-publish" title="Publish">
|
||||||
<i class="icon-share"></i>
|
<i class="icon-share"></i>
|
||||||
</button></li>
|
</button></li>
|
||||||
<li class="btn-group"><button class="btn action-create-file"
|
<li class="btn-group"><button class="btn action-create-file"
|
||||||
@ -58,7 +58,8 @@
|
|||||||
<li><a href="#" class="action-download-gdrive">Import
|
<li><a href="#" class="action-download-gdrive">Import
|
||||||
from Google Drive</a></li>
|
from Google Drive</a></li>
|
||||||
<li><a href="#" data-toggle="modal"
|
<li><a href="#" data-toggle="modal"
|
||||||
data-target="#modal-upload-gdrive">Export to Google Drive</a></li>
|
data-target="#modal-upload-gdrive" class="action-reset-input">Export
|
||||||
|
to Google Drive</a></li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li class="dropdown-submenu"><a href="#"><i
|
<li class="dropdown-submenu"><a href="#"><i
|
||||||
class="icon-dropbox"></i> Dropbox</a>
|
class="icon-dropbox"></i> Dropbox</a>
|
||||||
@ -66,11 +67,12 @@
|
|||||||
<li><a class="action-download-dropbox" href="#">Import
|
<li><a class="action-download-dropbox" href="#">Import
|
||||||
from Dropbox</a></li>
|
from Dropbox</a></li>
|
||||||
<li><a href="#" data-toggle="modal"
|
<li><a href="#" data-toggle="modal"
|
||||||
data-target="#modal-upload-dropbox">Export to Dropbox</a></li>
|
data-target="#modal-upload-dropbox" class="action-reset-input">Export
|
||||||
|
to Dropbox</a></li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><a href="#" data-toggle="modal"
|
<li><a href="#" data-toggle="modal"
|
||||||
data-target="#modal-manage-sync"><i class="icon-refresh"></i>
|
data-target="#modal-manage-sync" class="action-reset-input"><i
|
||||||
Manage synchronization</a></li>
|
class="icon-refresh"></i> Manage synchronization</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li class="dropdown-submenu"><a href="#"><i
|
<li class="dropdown-submenu"><a href="#"><i
|
||||||
class="icon-share"></i> Publish on</a>
|
class="icon-share"></i> Publish on</a>
|
||||||
@ -79,17 +81,15 @@
|
|||||||
class="icon-github"></i> GitHub</a></li>
|
class="icon-github"></i> GitHub</a></li>
|
||||||
<li><a href="#" class="action-publish-blogger"><i
|
<li><a href="#" class="action-publish-blogger"><i
|
||||||
class="icon-blogger"></i> Blogger</a></li>
|
class="icon-blogger"></i> Blogger</a></li>
|
||||||
<li><a href="#" class="action-publish-wordpress"><i
|
|
||||||
class="icon-wordpress"></i> WordPress</a></li>
|
|
||||||
<li><a href="#" class="action-publish-tumblr"><i
|
|
||||||
class="icon-tumblr"></i> Tumblr</a></li>
|
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><a href="#" data-toggle="modal"
|
<li><a href="#" data-toggle="modal"
|
||||||
data-target="#modal-manage-publication"><i class="icon-share"></i>
|
data-target="#modal-manage-publication"
|
||||||
Manage publication</a></li>
|
class="action-reset-input"><i class="icon-share"></i> Manage
|
||||||
|
publishing</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="#" data-toggle="modal"
|
<li><a href="#" data-toggle="modal"
|
||||||
data-target="#modal-settings" class="action-load-settings"><i
|
data-target="#modal-settings"
|
||||||
|
class="action-load-settings action-reset-input"><i
|
||||||
class="icon-cog"></i> Settings</a></li>
|
class="icon-cog"></i> Settings</a></li>
|
||||||
<li><a href="#" data-toggle="modal"
|
<li><a href="#" data-toggle="modal"
|
||||||
data-target="#modal-about"><i class="icon-question-sign"></i>
|
data-target="#modal-about"><i class="icon-question-sign"></i>
|
||||||
@ -226,7 +226,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p class="msg-sync-list hide">"<span class="file-title"></span>"
|
<p class="msg-sync-list hide">"<span class="file-title"></span>"
|
||||||
is synchronized with these locations:
|
is synchronized with the following location(s):
|
||||||
</p>
|
</p>
|
||||||
<div id="manage-sync-list"></div>
|
<div id="manage-sync-list"></div>
|
||||||
<p class="msg-sync-list hide muted"><b>NOTE:</b> Removing a
|
<p class="msg-sync-list hide muted"><b>NOTE:</b> Removing a
|
||||||
@ -267,14 +267,16 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
<div class="control-group control-publish-blogger">
|
<div class="control-group control-publish-blogger">
|
||||||
<label class="control-label" for="input-publish-blogger-url">Blog URL</label>
|
<label class="control-label" for="input-publish-blogger-url">Blog
|
||||||
|
URL</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" id="input-publish-blogger-url"
|
<input type="text" id="input-publish-blogger-url"
|
||||||
placeholder="http://exemple.blogger.com/">
|
placeholder="http://exemple.blogger.com/">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group control-publish-blogger">
|
<div class="control-group control-publish-blogger">
|
||||||
<label class="control-label" for="input-publish-blogger-postid">Update existing post ID (optional)</label>
|
<label class="control-label" for="input-publish-blogger-postid">Update
|
||||||
|
existing post ID (optional)</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<input type="text" id="input-publish-blogger-postid"
|
<input type="text" id="input-publish-blogger-postid"
|
||||||
placeholder="Post ID">
|
placeholder="Post ID">
|
||||||
@ -294,9 +296,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a>
|
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
|
||||||
<a href="#" data-dismiss="modal"
|
data-dismiss="modal" class="btn btn-primary action-process-publish">OK</a>
|
||||||
class="btn btn-primary action-publish-ok">OK</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -320,6 +321,14 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="input-editor-font-size">Editor
|
||||||
|
font size</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="input-editor-font-size" class="input-mini"><span
|
||||||
|
class="help-inline">px</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
@ -407,7 +416,7 @@
|
|||||||
<h3>Stopped...</h3>
|
<h3>Stopped...</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>StackEdit has stopped because another instance was running on
|
<p>StackEdit has stopped because another instance was running in
|
||||||
the same browser.</p>
|
the same browser.</p>
|
||||||
<p class="muted">If you want to reopen StackEdit, click on
|
<p class="muted">If you want to reopen StackEdit, click on
|
||||||
"Reload".</p>
|
"Reload".</p>
|
||||||
|
126
js/core.js
126
js/core.js
@ -1,9 +1,9 @@
|
|||||||
define(
|
define(
|
||||||
[ "jquery", "file-manager", "google-helper", "dropbox-helper",
|
[ "jquery", "file-manager", "google-helper", "dropbox-helper",
|
||||||
"synchronizer", "publisher", "async-runner", "bootstrap", "jgrowl",
|
"github-helper", "synchronizer", "publisher", "async-runner",
|
||||||
"layout", "Markdown.Editor", "config", "custo" ],
|
"bootstrap", "jgrowl", "layout", "Markdown.Editor", "config", "custo" ],
|
||||||
function($, fileManager, googleHelper, dropboxHelper, synchronizer,
|
function($, fileManager, googleHelper, dropboxHelper, githubHelper,
|
||||||
publisher, asyncTaskRunner) {
|
synchronizer, publisher, asyncTaskRunner) {
|
||||||
|
|
||||||
var core = {};
|
var core = {};
|
||||||
|
|
||||||
@ -47,6 +47,7 @@ define(
|
|||||||
var frontWindowId = localStorage["frontWindowId"];
|
var frontWindowId = localStorage["frontWindowId"];
|
||||||
if(frontWindowId != windowId) {
|
if(frontWindowId != windowId) {
|
||||||
windowUnique = false;
|
windowUnique = false;
|
||||||
|
$(".modal").modal("hide");
|
||||||
$('#modal-non-unique').modal({
|
$('#modal-non-unique').modal({
|
||||||
backdrop: "static",
|
backdrop: "static",
|
||||||
keyboard: false
|
keyboard: false
|
||||||
@ -54,23 +55,45 @@ define(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Useful function
|
// Useful function for input control
|
||||||
core.getInputValue = function(element, event) {
|
function inputError(element, event) {
|
||||||
var value = element.val();
|
element.stop(true, true).addClass("error").delay(400).switchClass("error");
|
||||||
if (value !== undefined) {
|
if(event !== undefined) {
|
||||||
value = value.replace(/^\s+|\s+$/g, '');
|
event.stopPropagation();
|
||||||
element.val(undefined);
|
|
||||||
}
|
}
|
||||||
if (value === undefined || value.length === 0) {
|
}
|
||||||
element.stop(true, true).addClass("error").delay(400)
|
core.getInputValue = function(element, event, validationRegex) {
|
||||||
.switchClass("error");
|
var value = element.val();
|
||||||
if(event !== undefined) {
|
if (value === undefined) {
|
||||||
event.stopPropagation();
|
inputError(element, event);
|
||||||
}
|
return undefined;
|
||||||
|
}
|
||||||
|
// trim
|
||||||
|
value = value.replace(/^\s+|\s+$/g, '');
|
||||||
|
if((value.length === 0)
|
||||||
|
|| (validationRegex !== undefined && !value.match(validationRegex))) {
|
||||||
|
inputError(element, event);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
core.getInputIntValue = function(element, event, min, max) {
|
||||||
|
var value = core.getInputValue(element, event);
|
||||||
|
if(value === undefined) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
value = parseInt(value);
|
||||||
|
if((value === NaN)
|
||||||
|
|| (min !== undefined && value < min)
|
||||||
|
|| (max !== undefined && value > max)) {
|
||||||
|
inputError(element, event);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
core.resetModalInputs = function() {
|
||||||
|
$(".modal input[type=text]:not([disabled])").val("");
|
||||||
|
};
|
||||||
|
|
||||||
// Used by asyncTaskRunner
|
// Used by asyncTaskRunner
|
||||||
core.showWorkingIndicator = function(show) {
|
core.showWorkingIndicator = function(show) {
|
||||||
@ -143,7 +166,11 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setting management
|
// Setting management
|
||||||
var settings = { layoutOrientation : "horizontal" };
|
var settings = {
|
||||||
|
layoutOrientation : "horizontal",
|
||||||
|
editorFontSize : 14
|
||||||
|
};
|
||||||
|
|
||||||
core.loadSettings = function() {
|
core.loadSettings = function() {
|
||||||
if (localStorage.settings) {
|
if (localStorage.settings) {
|
||||||
$.extend(settings, JSON.parse(localStorage.settings));
|
$.extend(settings, JSON.parse(localStorage.settings));
|
||||||
@ -152,15 +179,25 @@ define(
|
|||||||
// Layout orientation
|
// Layout orientation
|
||||||
$("input:radio[name=radio-layout-orientation][value="
|
$("input:radio[name=radio-layout-orientation][value="
|
||||||
+ settings.layoutOrientation + "]").prop("checked", true);
|
+ settings.layoutOrientation + "]").prop("checked", true);
|
||||||
|
|
||||||
|
// Editor font size
|
||||||
|
$("#input-editor-font-size").val(settings.editorFontSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
core.saveSettings = function() {
|
core.saveSettings = function(event) {
|
||||||
|
var newSettings = {};
|
||||||
|
|
||||||
// Layout orientation
|
// Layout orientation
|
||||||
settings.layoutOrientation = $(
|
newSettings.layoutOrientation = $(
|
||||||
"input:radio[name=radio-layout-orientation]:checked").prop("value");
|
"input:radio[name=radio-layout-orientation]:checked").prop("value");
|
||||||
|
|
||||||
localStorage.settings = JSON.stringify(settings);
|
// Editor font size
|
||||||
|
newSettings.editorFontSize = core.getInputIntValue($("#input-editor-font-size"), event, 1, 99);
|
||||||
|
|
||||||
|
if(!event.isPropagationStopped()) {
|
||||||
|
settings = newSettings;
|
||||||
|
localStorage.settings = JSON.stringify(newSettings);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create the layout
|
// Create the layout
|
||||||
@ -225,12 +262,14 @@ define(
|
|||||||
var editor = new Markdown.Editor(converter);
|
var editor = new Markdown.Editor(converter);
|
||||||
editor.hooks.set("insertLinkDialog", function (callback) {
|
editor.hooks.set("insertLinkDialog", function (callback) {
|
||||||
insertLinkCallback = callback;
|
insertLinkCallback = callback;
|
||||||
$("#modal-insert-link").modal('show');
|
core.resetModalInputs();
|
||||||
|
$("#modal-insert-link").modal();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
editor.hooks.set("insertImageDialog", function (callback) {
|
editor.hooks.set("insertImageDialog", function (callback) {
|
||||||
insertLinkCallback = callback;
|
insertLinkCallback = callback;
|
||||||
$("#modal-insert-image").modal('show');
|
core.resetModalInputs();
|
||||||
|
$("#modal-insert-image").modal();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -413,6 +452,24 @@ define(
|
|||||||
localStorage["version"] = version;
|
localStorage["version"] = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
core.popupWindow = function(url, title, w, h) {
|
||||||
|
var left = (screen.width / 2) - (w / 2);
|
||||||
|
var top = (screen.height / 2) - (h / 2);
|
||||||
|
return window
|
||||||
|
.open(
|
||||||
|
url,
|
||||||
|
title,
|
||||||
|
'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='
|
||||||
|
+ w
|
||||||
|
+ ', height='
|
||||||
|
+ h
|
||||||
|
+ ', top='
|
||||||
|
+ top
|
||||||
|
+ ', left='
|
||||||
|
+ left);
|
||||||
|
};
|
||||||
|
|
||||||
core.init = function() {
|
core.init = function() {
|
||||||
setupLocalStorage();
|
setupLocalStorage();
|
||||||
upgradeLocalStorage();
|
upgradeLocalStorage();
|
||||||
@ -459,13 +516,25 @@ define(
|
|||||||
this.loadSettings();
|
this.loadSettings();
|
||||||
this.createLayout();
|
this.createLayout();
|
||||||
|
|
||||||
|
// Apply editor font size
|
||||||
|
$("#wmd-input").css({
|
||||||
|
"font-size": settings.editorFontSize + "px",
|
||||||
|
"line-height": Math.round(settings.editorFontSize * (20/14)) + "px"
|
||||||
|
});
|
||||||
|
|
||||||
$(".action-load-settings").click(function() {
|
$(".action-load-settings").click(function() {
|
||||||
core.loadSettings();
|
core.loadSettings();
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".action-apply-settings").click(function() {
|
$(".action-apply-settings").click(function(e) {
|
||||||
core.saveSettings();
|
core.saveSettings(e);
|
||||||
window.location.reload();
|
if(!e.isPropagationStopped()) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".action-reset-input").click(function() {
|
||||||
|
core.resetModalInputs();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Init asyncTaskRunner
|
// Init asyncTaskRunner
|
||||||
@ -474,13 +543,16 @@ define(
|
|||||||
// Init helpers
|
// Init helpers
|
||||||
googleHelper.init(core, fileManager);
|
googleHelper.init(core, fileManager);
|
||||||
dropboxHelper.init(core, fileManager);
|
dropboxHelper.init(core, fileManager);
|
||||||
|
githubHelper.init(core, fileManager);
|
||||||
|
|
||||||
|
// Init synchronizer
|
||||||
|
synchronizer.init(core, fileManager);
|
||||||
|
|
||||||
// Init publisher
|
// Init publisher
|
||||||
publisher.init(core, fileManager);
|
publisher.init(core, fileManager);
|
||||||
|
|
||||||
// Init synchronizer
|
|
||||||
synchronizer.init(core, fileManager);
|
|
||||||
offlineListeners.push(synchronizer.updateSyncButton);
|
offlineListeners.push(synchronizer.updateSyncButton);
|
||||||
|
offlineListeners.push(publisher.updatePublishButton);
|
||||||
|
|
||||||
// Init file manager
|
// Init file manager
|
||||||
fileManager.init(core);
|
fileManager.init(core);
|
||||||
|
@ -21,8 +21,9 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the file titles
|
// Update the file titles
|
||||||
this.updateFileTitles();
|
fileManager.updateFileTitles();
|
||||||
refreshManageSync();
|
refreshManageSync();
|
||||||
|
publisher.notifyCurrentFile(localStorage["file.current"]);
|
||||||
|
|
||||||
// Recreate the editor
|
// Recreate the editor
|
||||||
fileIndex = localStorage["file.current"];
|
fileIndex = localStorage["file.current"];
|
||||||
@ -348,6 +349,37 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize the "New publication" dialog
|
||||||
|
var newPublishProvider = undefined;
|
||||||
|
function initNewPublish(provider, defaultPublishFormat) {
|
||||||
|
defaultPublishFormat = defaultPublishFormat || "markdown";
|
||||||
|
newPublishProvider = provider;
|
||||||
|
|
||||||
|
// Show/hide controls depending on provider
|
||||||
|
$('div[class*=" control-publish-"]').hide().filter(".control-publish-" + provider).show();
|
||||||
|
|
||||||
|
// Reset fields
|
||||||
|
core.resetModalInputs();
|
||||||
|
$("input:radio[name=radio-publish-format][value=" + defaultPublishFormat + "]").prop("checked", true);
|
||||||
|
|
||||||
|
// Open dialog box
|
||||||
|
$("#modal-publish").modal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new publication
|
||||||
|
function newPublishBlogger(event) {
|
||||||
|
var blogUrl = core.getInputValue($("#input-publish-blogger-url"), event);
|
||||||
|
if(event.isPropagationStopped()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
googleHelper.getBlogByUrl(blogUrl, function(blog) {
|
||||||
|
console.log(blog);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fileManager.init = function(coreModule) {
|
fileManager.init = function(coreModule) {
|
||||||
core = coreModule;
|
core = coreModule;
|
||||||
|
|
||||||
@ -393,6 +425,8 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
+ core.encodeBase64(content);
|
+ core.encodeBase64(content);
|
||||||
window.open(uriContent, 'file');
|
window.open(uriContent, 'file');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Synchronize actions
|
||||||
$(".action-upload-gdrive-root").click(function() {
|
$(".action-upload-gdrive-root").click(function() {
|
||||||
uploadGdrive();
|
uploadGdrive();
|
||||||
});
|
});
|
||||||
@ -423,6 +457,19 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
var path = core.getInputValue($("#manual-dropbox-path"), event);
|
var path = core.getInputValue($("#manual-dropbox-path"), event);
|
||||||
manualDropbox(path);
|
manualDropbox(path);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Publish actions
|
||||||
|
$(".action-publish-github").click(function() {
|
||||||
|
initNewPublish("github");
|
||||||
|
});
|
||||||
|
$(".action-publish-blogger").click(function() {
|
||||||
|
initNewPublish("blogger", "html");
|
||||||
|
});
|
||||||
|
$(".action-process-publish").click(function(e) {
|
||||||
|
if(newPublishProvider == "blogger") {
|
||||||
|
newPublishBlogger(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return fileManager;
|
return fileManager;
|
||||||
|
283
js/github-helper.js
Normal file
283
js/github-helper.js
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
||||||
|
|
||||||
|
// Dependencies
|
||||||
|
var core = undefined;
|
||||||
|
var fileManager = undefined;
|
||||||
|
|
||||||
|
var connected = undefined;
|
||||||
|
var client = undefined;
|
||||||
|
|
||||||
|
var githubHelper = {};
|
||||||
|
|
||||||
|
// Try to connect github by downloading js file
|
||||||
|
function connect(callback) {
|
||||||
|
callback = callback || core.doNothing;
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
if(core.isOffline === true) {
|
||||||
|
connected = false;
|
||||||
|
core.showMessage("Operation not available in offline mode.");
|
||||||
|
asyncTask.error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (connected === true) {
|
||||||
|
asyncTask.success();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.ajax({
|
||||||
|
url : "lib/github.js",
|
||||||
|
dataType : "script", timeout : AJAX_TIMEOUT
|
||||||
|
}).done(function() {
|
||||||
|
connected = true;
|
||||||
|
asyncTask.success();
|
||||||
|
}).fail(function() {
|
||||||
|
asyncTask.error();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
core.setOffline();
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to authenticate with Oauth
|
||||||
|
function authenticate(callback, immediate) {
|
||||||
|
callback = callback || core.doNothing;
|
||||||
|
if (immediate === undefined) {
|
||||||
|
immediate = true;
|
||||||
|
}
|
||||||
|
connect(function() {
|
||||||
|
if (connected === false) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
if (client !== undefined) {
|
||||||
|
asyncTask.success();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (immediate !== false) {
|
||||||
|
}
|
||||||
|
core.showMessage("Please make sure the Github authorization popup is not blocked by your browser.");
|
||||||
|
myWindow=core.popupWindow('github-oauth-client.html?client_id=test','stackedit-github-oauth',500,400);
|
||||||
|
myWindow.focus();
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
// If immediate did not work retry without immediate flag
|
||||||
|
if (connected === true && immediate === true) {
|
||||||
|
authenticate(callback, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
githubHelper.upload = function(path, content, callback) {
|
||||||
|
callback = callback || core.doNothing;
|
||||||
|
authenticate(function() {
|
||||||
|
if (client === undefined) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileSyncIndex = undefined;
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
client.writeFile(path, content, function(error, stat) {
|
||||||
|
if (!error) {
|
||||||
|
fileSyncIndex = SYNC_PROVIDER_GITHUB + encodeURIComponent(stat.path.toLowerCase());
|
||||||
|
localStorage[fileSyncIndex + ".version"] = stat.versionTag;
|
||||||
|
asyncTask.success();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle error
|
||||||
|
if(error.status === Github.ApiError.INVALID_PARAM) {
|
||||||
|
error = 'Could not upload document into path "' + path + '".';
|
||||||
|
}
|
||||||
|
handleError(error, asyncTask, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
callback(fileSyncIndex);
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
githubHelper.checkUpdates = function(lastChangeId, callback) {
|
||||||
|
callback = callback || core.doNothing;
|
||||||
|
authenticate(function() {
|
||||||
|
if (client === undefined) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var changes = [];
|
||||||
|
var newChangeId = lastChangeId || 0;
|
||||||
|
function retrievePageOfChanges(changeId) {
|
||||||
|
var shouldPullAgain = false;
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
client.pullChanges(changeId, function(error, pullChanges) {
|
||||||
|
if (pullChanges && pullChanges.cursorTag) {
|
||||||
|
// Retrieve success
|
||||||
|
newChangeId = pullChanges.cursor();
|
||||||
|
shouldPullAgain = pullChanges.shouldPullAgain;
|
||||||
|
if(pullChanges.changes !== undefined) {
|
||||||
|
for(var i=0; i<pullChanges.changes.length; i++) {
|
||||||
|
var item = pullChanges.changes[i];
|
||||||
|
var version = localStorage[SYNC_PROVIDER_GITHUB
|
||||||
|
+ encodeURIComponent(item.path.toLowerCase()) + ".version"];
|
||||||
|
if(version && (item.wasRemoved || item.stat.versionTag != version)) {
|
||||||
|
changes.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asyncTask.success();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Handle error
|
||||||
|
handleError(error, asyncTask, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
if (shouldPullAgain === true) {
|
||||||
|
retrievePageOfChanges(newChangeId);
|
||||||
|
} else {
|
||||||
|
callback(changes, newChangeId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
}
|
||||||
|
retrievePageOfChanges(newChangeId);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
githubHelper.downloadMetadata = function(paths, callback, result) {
|
||||||
|
callback = callback || core.doNothing;
|
||||||
|
result = result || [];
|
||||||
|
if(paths.length === 0) {
|
||||||
|
callback(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticate(function() {
|
||||||
|
if (client === undefined) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var path = paths.pop();
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
client.stat(path, function(error, stat) {
|
||||||
|
if(stat) {
|
||||||
|
result.push(stat);
|
||||||
|
asyncTask.success();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleError(error, asyncTask, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
githubHelper.downloadMetadata(paths, callback, result);
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
githubHelper.downloadContent = function(objects, callback, result) {
|
||||||
|
callback = callback || core.doNothing;
|
||||||
|
result = result || [];
|
||||||
|
if(objects.length === 0) {
|
||||||
|
callback(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var object = objects.pop();
|
||||||
|
result.push(object);
|
||||||
|
var file = undefined;
|
||||||
|
// object may be a file
|
||||||
|
if(object.isFile === true) {
|
||||||
|
file = object;
|
||||||
|
}
|
||||||
|
// object may be a change
|
||||||
|
else if(object.wasRemoved !== undefined) {
|
||||||
|
file = object.stat;
|
||||||
|
}
|
||||||
|
if(!file) {
|
||||||
|
this.downloadContent(objects, callback, result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticate(function() {
|
||||||
|
if (client === undefined) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
client.readFile(file.path, function(error, data) {
|
||||||
|
if(data) {
|
||||||
|
file.content = data;
|
||||||
|
asyncTask.success();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleError(error, asyncTask, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
githubHelper.downloadContent(objects, callback, result);
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function handleError(error, asyncTask, callback) {
|
||||||
|
var errorMsg = undefined;
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
if (errorMsg !== undefined) {
|
||||||
|
core.showError(errorMsg);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
};
|
||||||
|
if (error) {
|
||||||
|
// Try to analyze the error
|
||||||
|
if (typeof error === "string") {
|
||||||
|
errorMsg = error;
|
||||||
|
} else if (error.status === Github.ApiError.INVALID_TOKEN
|
||||||
|
|| error.status === Github.ApiError.OAUTH_ERROR) {
|
||||||
|
client = undefined;
|
||||||
|
errorMsg = "Access to Github is not authorized.";
|
||||||
|
} else if (error.status === Github.ApiError.NETWORK_ERROR) {
|
||||||
|
connected = false;
|
||||||
|
client = undefined;
|
||||||
|
core.setOffline();
|
||||||
|
} else {
|
||||||
|
errorMsg = "Github error ("
|
||||||
|
+ error.status + ").";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
asyncTask.error();
|
||||||
|
}
|
||||||
|
|
||||||
|
githubHelper.init = function(coreModule, fileManagerModule) {
|
||||||
|
core = coreModule;
|
||||||
|
fileManager = fileManagerModule;
|
||||||
|
authenticate();
|
||||||
|
};
|
||||||
|
|
||||||
|
return githubHelper;
|
||||||
|
});
|
10
js/github.js
10
js/github.js
@ -1,10 +0,0 @@
|
|||||||
define(["jquery", "core", "async-runner", "underscore-min"], function($, core, asyncTaskRunner) {
|
|
||||||
|
|
||||||
var client = undefined;
|
|
||||||
var authenticated = false;
|
|
||||||
|
|
||||||
var github = {};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
@ -465,6 +465,84 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
googleHelper.getBlogByUrl = function(url, callback) {
|
||||||
|
authenticate(function() {
|
||||||
|
if (connected === false) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = undefined;
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
var token = gapi.auth.getToken();
|
||||||
|
var headers = {
|
||||||
|
Authorization : token ? "Bearer " + token.access_token: null
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
url : "https://www.googleapis.com/blogger/v3/blogs/byurl",
|
||||||
|
data: { url: url },
|
||||||
|
headers : headers,
|
||||||
|
dataType : "json",
|
||||||
|
timeout : AJAX_TIMEOUT
|
||||||
|
}).done(function(blog, textStatus, jqXHR) {
|
||||||
|
result = blog;
|
||||||
|
asyncTask.success();
|
||||||
|
}).fail(function(jqXHR) {
|
||||||
|
var error = {
|
||||||
|
code: jqXHR.status,
|
||||||
|
message: jqXHR.statusText
|
||||||
|
};
|
||||||
|
// Handle error
|
||||||
|
handleError(error, asyncTask, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
callback(result);
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
googleHelper.getBlogByUrl = function(url, callback) {
|
||||||
|
authenticate(function() {
|
||||||
|
if (connected === false) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = undefined;
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
var token = gapi.auth.getToken();
|
||||||
|
var headers = {
|
||||||
|
Authorization : token ? "Bearer " + token.access_token: null
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
url : "https://www.googleapis.com/blogger/v3/blogs/byurl",
|
||||||
|
data: { url: url },
|
||||||
|
headers : headers,
|
||||||
|
dataType : "json",
|
||||||
|
timeout : AJAX_TIMEOUT
|
||||||
|
}).done(function(blog, textStatus, jqXHR) {
|
||||||
|
result = blog;
|
||||||
|
asyncTask.success();
|
||||||
|
}).fail(function(jqXHR) {
|
||||||
|
var error = {
|
||||||
|
code: jqXHR.status,
|
||||||
|
message: jqXHR.statusText
|
||||||
|
};
|
||||||
|
// Handle error
|
||||||
|
handleError(error, asyncTask, callback);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
callback(result);
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
googleHelper.init = function(coreModule, fileManagerModule) {
|
googleHelper.init = function(coreModule, fileManagerModule) {
|
||||||
core = coreModule;
|
core = coreModule;
|
||||||
fileManager = fileManagerModule;
|
fileManager = fileManagerModule;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
define(["jquery"], function($) {
|
define(["jquery", "google-helper", "github-helper"], function($, googleHelper, githubHelper) {
|
||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
var core = undefined;
|
var core = undefined;
|
||||||
@ -6,38 +6,37 @@ define(["jquery"], function($) {
|
|||||||
|
|
||||||
var publisher = {};
|
var publisher = {};
|
||||||
|
|
||||||
var wizardProvider = undefined;
|
// Used to know if the current file has publications
|
||||||
|
var hasPublications = false;
|
||||||
|
|
||||||
function initWizard(provider, defaultPublishFormat) {
|
// Allows external modules to update hasPublications flag
|
||||||
defaultPublishFormat = defaultPublishFormat || "markdown";
|
publisher.notifyCurrentFile = function(fileIndex) {
|
||||||
wizardProvider = provider;
|
|
||||||
|
|
||||||
// Show/hide controls depending on provider
|
// Check that file has publications
|
||||||
$('div[class*=" control-publish-"]').hide().filter(".control-publish-" + provider).show();
|
if(localStorage[fileIndex + ".publish"].length === 1) {
|
||||||
|
hasPublications = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hasPublications = true;
|
||||||
|
}
|
||||||
|
publisher.updatePublishButton();
|
||||||
|
};
|
||||||
|
|
||||||
// Reset fields
|
// Used to enable/disable the publish button
|
||||||
$("#modal-publish input[type=text]").val("");
|
publisher.updatePublishButton = function() {
|
||||||
$("input:radio[name=radio-publish-format][value=" + defaultPublishFormat + "]").prop("checked", true);
|
if(publishRunning === true || hasPublications === false || core.isOffline) {
|
||||||
|
$(".action-force-publish").addClass("disabled");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(".action-force-publish").removeClass("disabled");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Open dialog box
|
var publishRunning = false;
|
||||||
$("#modal-publish").modal();
|
|
||||||
}
|
|
||||||
|
|
||||||
publisher.init = function(coreModule, fileManagerModule) {
|
publisher.init = function(coreModule, fileManagerModule) {
|
||||||
core = coreModule;
|
core = coreModule;
|
||||||
fileManager = fileManagerModule;
|
fileManager = fileManagerModule;
|
||||||
$(".action-publish-github").click(function() {
|
|
||||||
initWizard("github");
|
|
||||||
});
|
|
||||||
$(".action-publish-blogger").click(function() {
|
|
||||||
initWizard("blogger", "html");
|
|
||||||
});
|
|
||||||
$(".action-publish-wordpress").click(function() {
|
|
||||||
initWizard("wordpress");
|
|
||||||
});
|
|
||||||
$(".action-publish-tumblr").click(function() {
|
|
||||||
initWizard("tumblr");
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return publisher;
|
return publisher;
|
||||||
|
@ -12,14 +12,29 @@ define(["jquery", "google-helper", "dropbox-helper"], function($, googleHelper,
|
|||||||
// Used to know if user can force synchronization
|
// Used to know if user can force synchronization
|
||||||
var uploadPending = false;
|
var uploadPending = false;
|
||||||
|
|
||||||
// Add a file to the synchronization queue
|
// Allows external modules to update uploadPending flag
|
||||||
synchronizer.notifyChange = function(fileIndex) {
|
synchronizer.notifyChange = function(fileIndex) {
|
||||||
// Check that file has synchronized locations
|
// Check that file has synchronized locations
|
||||||
if(localStorage[fileIndex + ".sync"].length === 1) {
|
if(localStorage[fileIndex + ".sync"].length !== 1) {
|
||||||
return;
|
uploadPending = true;
|
||||||
|
synchronizer.updateSyncButton();
|
||||||
}
|
}
|
||||||
uploadPending = true;
|
};
|
||||||
synchronizer.updateSyncButton();
|
|
||||||
|
// Used to enable/disable the synchronization button
|
||||||
|
synchronizer.updateSyncButton = function() {
|
||||||
|
if(syncRunning === true || uploadPending === false || core.isOffline) {
|
||||||
|
$(".action-force-sync").addClass("disabled");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(".action-force-sync").removeClass("disabled");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Force the synchronization
|
||||||
|
synchronizer.forceSync = function() {
|
||||||
|
lastSync = 0;
|
||||||
|
synchronizer.sync();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Recursive function to upload a single file on multiple locations
|
// Recursive function to upload a single file on multiple locations
|
||||||
@ -331,20 +346,6 @@ define(["jquery", "google-helper", "dropbox-helper"], function($, googleHelper,
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
synchronizer.forceSync = function() {
|
|
||||||
lastSync = 0;
|
|
||||||
synchronizer.sync();
|
|
||||||
};
|
|
||||||
|
|
||||||
synchronizer.updateSyncButton = function() {
|
|
||||||
if(syncRunning === true || uploadPending === false || core.isOffline) {
|
|
||||||
$(".action-force-sync").addClass("disabled");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$(".action-force-sync").removeClass("disabled");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
synchronizer.init = function(coreModule, fileManagerModule) {
|
synchronizer.init = function(coreModule, fileManagerModule) {
|
||||||
core = coreModule;
|
core = coreModule;
|
||||||
fileManager = fileManagerModule;
|
fileManager = fileManagerModule;
|
||||||
|
Loading…
Reference in New Issue
Block a user