Added GitHub publishing
This commit is contained in:
commit
4ec862928b
@ -1,11 +1,11 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<script src="lib/dropbox.js"></script>
|
<script src="lib/dropbox.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
Dropbox.Drivers.Popup.oauthReceiver();
|
Dropbox.Drivers.Popup.oauthReceiver();
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
24
github-oauth-client.html
Normal file
24
github-oauth-client.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<script type="text/javascript">
|
||||||
|
function getParameter(name) {
|
||||||
|
var regex = new RegExp(name + "=(.+?)(&|$)");
|
||||||
|
try {
|
||||||
|
return decodeURI(regex.exec(location.search)[1]);
|
||||||
|
} catch (e) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var client_id = getParameter("client_id");
|
||||||
|
var code = getParameter("code");
|
||||||
|
if (code) {
|
||||||
|
localStorage["githubCode"] = code;
|
||||||
|
window.close();
|
||||||
|
} else if (client_id) {
|
||||||
|
window.location.href = "https://github.com/login/oauth/authorize?client_id="
|
||||||
|
+ client_id + "&scope=repo";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
</html>
|
136
index.html
136
index.html
@ -79,17 +79,14 @@
|
|||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<li><a href="#" class="action-publish-github"><i
|
<li><a href="#" class="action-publish-github"><i
|
||||||
class="icon-github"></i> GitHub</a></li>
|
class="icon-github"></i> GitHub</a></li>
|
||||||
<li><a href="#" class="action-publish-blogger"><i
|
|
||||||
class="icon-blogger"></i> Blogger</a></li>
|
|
||||||
</ul></li>
|
</ul></li>
|
||||||
<li><a href="#" data-toggle="modal"
|
<li><a href="#" data-toggle="modal"
|
||||||
data-target="#modal-manage-publication"
|
data-target="#modal-manage-publish" class="action-reset-input"><i
|
||||||
class="action-reset-input"><i class="icon-share"></i> Manage
|
class="icon-share"></i> Manage publishing</a></li>
|
||||||
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"
|
data-target="#modal-settings"
|
||||||
class="action-load-settings action-reset-input"><i
|
class="action-load-settings"><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>
|
||||||
@ -236,17 +233,17 @@
|
|||||||
</p>
|
</p>
|
||||||
<p>Add a synchronized location manually:</p>
|
<p>Add a synchronized location manually:</p>
|
||||||
<div class="input-prepend input-append">
|
<div class="input-prepend input-append">
|
||||||
<span class="add-on"><i class="icon-gdrive"></i></span><input
|
<span class="add-on" title="Google Drive"><i
|
||||||
id="manual-gdrive-fileid" type="text" class="span5"
|
class="icon-gdrive"></i></span><input id="manual-gdrive-fileid"
|
||||||
placeholder="Google Drive file ID"></input> <a
|
type="text" class="span5" placeholder="Google Drive file ID"></input>
|
||||||
class="btn action-manual-gdrive" title="Add this location"
|
<a class="btn action-manual-gdrive" title="Add location"
|
||||||
data-dismiss="modal"><i class="icon-ok"></i></a>
|
data-dismiss="modal"><i class="icon-ok"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="input-prepend input-append">
|
<div class="input-prepend input-append">
|
||||||
<span class="add-on"><i class="icon-dropbox"></i></span><input
|
<span class="add-on" title="Dropbox"><i class="icon-dropbox"></i></span><input
|
||||||
id="manual-dropbox-path" type="text" class="span5"
|
id="manual-dropbox-path" type="text" class="span5"
|
||||||
placeholder="Dropbox file path"></input> <a
|
placeholder="Dropbox file path"></input> <a
|
||||||
class="btn action-manual-dropbox" title="Add this location"
|
class="btn action-manual-dropbox" title="Add location"
|
||||||
data-dismiss="modal"><i class="icon-ok"></i></a>
|
data-dismiss="modal"><i class="icon-ok"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<p class="muted"><b>NOTE:</b> Adding a synchronized location will
|
<p class="muted"><b>NOTE:</b> Adding a synchronized location will
|
||||||
@ -266,6 +263,36 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
|
<div class="control-group control-publish-github">
|
||||||
|
<label class="control-label" for="input-publish-github-username">GitHub
|
||||||
|
user</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="input-publish-github-username"
|
||||||
|
placeholder="User name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group control-publish-github">
|
||||||
|
<label class="control-label" for="input-publish-github-reponame">Repository</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="input-publish-github-reponame"
|
||||||
|
placeholder="Repository name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group control-publish-github">
|
||||||
|
<label class="control-label" for="input-publish-github-branch">Branch</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="input-publish-github-branch"
|
||||||
|
placeholder="Branch name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group control-publish-github">
|
||||||
|
<label class="control-label" for="input-publish-github-path">File
|
||||||
|
path</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="input-publish-github-path"
|
||||||
|
placeholder="path/to/file.md">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="control-group control-publish-blogger">
|
<div class="control-group control-publish-blogger">
|
||||||
<label class="control-label" for="input-publish-blogger-url">Blog
|
<label class="control-label" for="input-publish-blogger-url">Blog
|
||||||
URL</label>
|
URL</label>
|
||||||
@ -301,6 +328,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="modal-manage-publish" class="modal hide">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal"
|
||||||
|
aria-hidden="true">×</button>
|
||||||
|
<h3>Publishing</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p class="msg-publish-list hide">"<span class="file-title"></span>"
|
||||||
|
is published on the following location(s):
|
||||||
|
</p>
|
||||||
|
<div id="manage-publish-list"></div>
|
||||||
|
<p class="msg-no-publish hide">"<span class="file-title"></span>"
|
||||||
|
is not published.
|
||||||
|
</p>
|
||||||
|
<p class="muted"><b>NOTE:</b> You can add locations using
|
||||||
|
sub-menu "Publish on".</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<a href="#" class="btn btn-primary" data-dismiss="modal">Close</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="modal-settings" class="modal hide">
|
<div id="modal-settings" class="modal hide">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal"
|
<button type="button" class="close" data-dismiss="modal"
|
||||||
@ -308,28 +357,50 @@
|
|||||||
<h3>Settings</h3>
|
<h3>Settings</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-horizontal">
|
<ul class="nav nav-tabs">
|
||||||
<div class="control-group">
|
<li class="active"><a class="action-load-settings" href="#tabpane-settings-editor"
|
||||||
<div class="control-label">Layout orientation</div>
|
data-toggle="tab">Editor</a></li>
|
||||||
<div class="controls">
|
<li><a class="action-load-settings" href="#tabpane-settings-publish" data-toggle="tab">Publishing</a></li>
|
||||||
<label class="radio"> <input type="radio"
|
</ul>
|
||||||
name="radio-layout-orientation" value="horizontal">
|
|
||||||
Horizontal
|
<div class="tab-content">
|
||||||
</label> <label class="radio"> <input type="radio"
|
<div class="tab-pane active" id="tabpane-settings-editor">
|
||||||
name="radio-layout-orientation" value="vertical">
|
<div class="form-horizontal">
|
||||||
Vertical
|
<div class="control-group">
|
||||||
</label>
|
<div class="control-label">Layout orientation</div>
|
||||||
|
<div class="controls">
|
||||||
|
<label class="radio"> <input type="radio"
|
||||||
|
name="radio-layout-orientation" value="horizontal">
|
||||||
|
Horizontal
|
||||||
|
</label> <label class="radio"> <input type="radio"
|
||||||
|
name="radio-layout-orientation" value="vertical">
|
||||||
|
Vertical
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label"
|
||||||
|
for="input-settings-editor-font-size">Editor font size</label>
|
||||||
|
<div class="controls">
|
||||||
|
<input type="text" id="input-settings-editor-font-size"
|
||||||
|
class="input-mini"><span class="help-inline">px</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="tab-pane" id="tabpane-settings-publish">
|
||||||
<label class="control-label" for="input-editor-font-size">Editor
|
<div class="form-horizontal">
|
||||||
font size</label>
|
<div class="control-group">
|
||||||
<div class="controls">
|
<label class="control-label"
|
||||||
<input type="text" id="input-editor-font-size" class="input-mini"><span
|
for="input-settings-publish-commit-msg">Commit message</label>
|
||||||
class="help-inline">px</span>
|
<div class="controls">
|
||||||
|
<input type="text" id="input-settings-publish-commit-msg">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
|
<a href="#" class="btn" data-dismiss="modal">Cancel</a> <a href="#"
|
||||||
@ -381,6 +452,13 @@
|
|||||||
<dd>
|
<dd>
|
||||||
<a target="_blank" href="http://twitter.github.com/bootstrap/">Bootstrap</a>
|
<a target="_blank" href="http://twitter.github.com/bootstrap/">Bootstrap</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a target="_blank" href="https://github.com/dropbox/dropbox-js">Dropbox-js</a>
|
||||||
|
</dd>
|
||||||
|
<dd>
|
||||||
|
<a target="_blank" href="https://github.com/michael/github">Github.js</a>
|
||||||
|
/ <a target="_blank" href="https://github.com/prose/gatekeeper">Gatekeeper</a>
|
||||||
|
</dd>
|
||||||
<dd>
|
<dd>
|
||||||
<a target="_blank" href="http://glyphicons.com/">Glyphicons</a>
|
<a target="_blank" href="http://glyphicons.com/">Glyphicons</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
@ -14,6 +14,8 @@ var SYNC_PERIOD = 180000;
|
|||||||
var USER_IDLE_THRESHOLD = 300000;
|
var USER_IDLE_THRESHOLD = 300000;
|
||||||
var SYNC_PROVIDER_GDRIVE = "sync.gdrive.";
|
var SYNC_PROVIDER_GDRIVE = "sync.gdrive.";
|
||||||
var SYNC_PROVIDER_DROPBOX = "sync.dropbox.";
|
var SYNC_PROVIDER_DROPBOX = "sync.dropbox.";
|
||||||
|
var PUBLISH_PROVIDER_GITHUB = "github";
|
||||||
|
var PUBLISH_PROVIDER_BLOGGER = "blogger";
|
||||||
|
|
||||||
// Use by Google's client.js
|
// Use by Google's client.js
|
||||||
var delayedFunction = undefined;
|
var delayedFunction = undefined;
|
||||||
|
56
js/core.js
56
js/core.js
@ -7,6 +7,9 @@ define(
|
|||||||
|
|
||||||
var core = {};
|
var core = {};
|
||||||
|
|
||||||
|
// The interval Id for periodic tasks
|
||||||
|
var intervalId = undefined;
|
||||||
|
|
||||||
// Usage: callback = callback || core.doNothing;
|
// Usage: callback = callback || core.doNothing;
|
||||||
core.doNothing = function() {};
|
core.doNothing = function() {};
|
||||||
|
|
||||||
@ -41,12 +44,15 @@ define(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(windowId === undefined) {
|
if(windowId === undefined) {
|
||||||
windowId = Math.random().toString(36);
|
windowId = core.randomString();
|
||||||
localStorage["frontWindowId"] = windowId;
|
localStorage["frontWindowId"] = windowId;
|
||||||
}
|
}
|
||||||
var frontWindowId = localStorage["frontWindowId"];
|
var frontWindowId = localStorage["frontWindowId"];
|
||||||
if(frontWindowId != windowId) {
|
if(frontWindowId != windowId) {
|
||||||
windowUnique = false;
|
windowUnique = false;
|
||||||
|
if(intervalId !== undefined) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
}
|
||||||
$(".modal").modal("hide");
|
$(".modal").modal("hide");
|
||||||
$('#modal-non-unique').modal({
|
$('#modal-non-unique').modal({
|
||||||
backdrop: "static",
|
backdrop: "static",
|
||||||
@ -166,22 +172,26 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setting management
|
// Setting management
|
||||||
var settings = {
|
core.settings = {
|
||||||
layoutOrientation : "horizontal",
|
layoutOrientation : "horizontal",
|
||||||
editorFontSize : 14
|
editorFontSize : 14,
|
||||||
|
commitMsg : "Published by StackEdit."
|
||||||
};
|
};
|
||||||
|
|
||||||
core.loadSettings = function() {
|
core.loadSettings = function() {
|
||||||
if (localStorage.settings) {
|
if (localStorage.settings) {
|
||||||
$.extend(settings, JSON.parse(localStorage.settings));
|
$.extend(core.settings, JSON.parse(localStorage.settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout orientation
|
// Layout orientation
|
||||||
$("input:radio[name=radio-layout-orientation][value="
|
$("input:radio[name=radio-layout-orientation][value="
|
||||||
+ settings.layoutOrientation + "]").prop("checked", true);
|
+ core.settings.layoutOrientation + "]").prop("checked", true);
|
||||||
|
|
||||||
// Editor font size
|
// Editor font size
|
||||||
$("#input-editor-font-size").val(settings.editorFontSize);
|
$("#input-settings-editor-font-size").val(core.settings.editorFontSize);
|
||||||
|
|
||||||
|
// Commit message
|
||||||
|
$("#input-settings-publish-commit-msg").val(core.settings.commitMsg);
|
||||||
};
|
};
|
||||||
|
|
||||||
core.saveSettings = function(event) {
|
core.saveSettings = function(event) {
|
||||||
@ -192,10 +202,13 @@ define(
|
|||||||
"input:radio[name=radio-layout-orientation]:checked").prop("value");
|
"input:radio[name=radio-layout-orientation]:checked").prop("value");
|
||||||
|
|
||||||
// Editor font size
|
// Editor font size
|
||||||
newSettings.editorFontSize = core.getInputIntValue($("#input-editor-font-size"), event, 1, 99);
|
newSettings.editorFontSize = core.getInputIntValue($("#input-settings-editor-font-size"), event, 1, 99);
|
||||||
|
|
||||||
|
// Commit message
|
||||||
|
newSettings.commitMsg = core.getInputValue($("#input-settings-publish-commit-msg"), event);
|
||||||
|
|
||||||
if(!event.isPropagationStopped()) {
|
if(!event.isPropagationStopped()) {
|
||||||
settings = newSettings;
|
core.settings = newSettings;
|
||||||
localStorage.settings = JSON.stringify(newSettings);
|
localStorage.settings = JSON.stringify(newSettings);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -215,7 +228,7 @@ define(
|
|||||||
togglerLength_closed : 90,
|
togglerLength_closed : 90,
|
||||||
stateManagement__enabled : false
|
stateManagement__enabled : false
|
||||||
};
|
};
|
||||||
if (settings.layoutOrientation == "horizontal") {
|
if (core.settings.layoutOrientation == "horizontal") {
|
||||||
$(".ui-layout-south").remove();
|
$(".ui-layout-south").remove();
|
||||||
$(".ui-layout-east").addClass("well").prop("id", "wmd-preview");
|
$(".ui-layout-east").addClass("well").prop("id", "wmd-preview");
|
||||||
layout = $('body').layout(
|
layout = $('body').layout(
|
||||||
@ -225,7 +238,7 @@ define(
|
|||||||
east__minSize : 200
|
east__minSize : 200
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else if (settings.layoutOrientation == "vertical") {
|
} else if (core.settings.layoutOrientation == "vertical") {
|
||||||
$(".ui-layout-east").remove();
|
$(".ui-layout-east").remove();
|
||||||
$(".ui-layout-south").addClass("well").prop("id", "wmd-preview");
|
$(".ui-layout-south").addClass("well").prop("id", "wmd-preview");
|
||||||
layout = $('body').layout(
|
layout = $('body').layout(
|
||||||
@ -413,10 +426,14 @@ define(
|
|||||||
return crc.toString(16);
|
return crc.toString(16);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Generates a random string
|
||||||
|
core.randomString = function() {
|
||||||
|
return Math.ceil(Math.random() * 4294967296).toString(36);
|
||||||
|
};
|
||||||
|
|
||||||
// Used to setup an empty localStorage
|
// Used to setup an empty localStorage
|
||||||
function setupLocalStorage() {
|
function setupLocalStorage() {
|
||||||
if (localStorage["file.counter"] === undefined) {
|
if (localStorage["file.list"] === undefined) {
|
||||||
localStorage["file.counter"] = "0";
|
|
||||||
localStorage["file.list"] = ";";
|
localStorage["file.list"] = ";";
|
||||||
localStorage["version"] = "v1";
|
localStorage["version"] = "v1";
|
||||||
}
|
}
|
||||||
@ -429,9 +446,10 @@ define(
|
|||||||
// from v0 to v1
|
// from v0 to v1
|
||||||
if(version === undefined) {
|
if(version === undefined) {
|
||||||
|
|
||||||
// Synchronization queue not used anymore
|
// Not used anymore
|
||||||
localStorage.removeItem("sync.queue");
|
localStorage.removeItem("sync.queue");
|
||||||
localStorage.removeItem("sync.current");
|
localStorage.removeItem("sync.current");
|
||||||
|
localStorage.removeItem("file.counter");
|
||||||
|
|
||||||
var fileIndexList = localStorage["file.list"].split(";");
|
var fileIndexList = localStorage["file.list"].split(";");
|
||||||
for ( var i = 1; i < fileIndexList.length - 1; i++) {
|
for ( var i = 1; i < fileIndexList.length - 1; i++) {
|
||||||
@ -452,7 +470,7 @@ define(
|
|||||||
localStorage["version"] = version;
|
localStorage["version"] = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create an centered popup window
|
||||||
core.popupWindow = function(url, title, w, h) {
|
core.popupWindow = function(url, title, w, h) {
|
||||||
var left = (screen.width / 2) - (w / 2);
|
var left = (screen.width / 2) - (w / 2);
|
||||||
var top = (screen.height / 2) - (h / 2);
|
var top = (screen.height / 2) - (h / 2);
|
||||||
@ -513,13 +531,13 @@ define(
|
|||||||
});
|
});
|
||||||
|
|
||||||
$("#menu-bar, .ui-layout-center, .ui-layout-east, .ui-layout-south").removeClass("hide");
|
$("#menu-bar, .ui-layout-center, .ui-layout-east, .ui-layout-south").removeClass("hide");
|
||||||
this.loadSettings();
|
core.loadSettings();
|
||||||
this.createLayout();
|
core.createLayout();
|
||||||
|
|
||||||
// Apply editor font size
|
// Apply editor font size
|
||||||
$("#wmd-input").css({
|
$("#wmd-input").css({
|
||||||
"font-size": settings.editorFontSize + "px",
|
"font-size": core.settings.editorFontSize + "px",
|
||||||
"line-height": Math.round(settings.editorFontSize * (20/14)) + "px"
|
"line-height": Math.round(core.settings.editorFontSize * (20/14)) + "px"
|
||||||
});
|
});
|
||||||
|
|
||||||
$(".action-load-settings").click(function() {
|
$(".action-load-settings").click(function() {
|
||||||
@ -558,7 +576,7 @@ define(
|
|||||||
fileManager.init(core);
|
fileManager.init(core);
|
||||||
|
|
||||||
// Do periodic tasks
|
// Do periodic tasks
|
||||||
window.setInterval(function() {
|
intervalId = window.setInterval(function() {
|
||||||
updateCurrentTime();
|
updateCurrentTime();
|
||||||
core.checkWindowUnique();
|
core.checkWindowUnique();
|
||||||
if(isUserActive() === false) {
|
if(isUserActive() === false) {
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
|
var BASE_URL = "http://benweet.github.io/stackedit/";
|
||||||
var GOOGLE_KEY = "AIzaSyB1Bc1wI_YUWkkOR-5Gri5BFuypgZl0Sxc";
|
var GOOGLE_KEY = "AIzaSyB1Bc1wI_YUWkkOR-5Gri5BFuypgZl0Sxc";
|
||||||
var GOOGLE_CLIENT_ID = '241271498917-jpto9lls9fqnem1e4h6ppds9uob8rpvu.apps.googleusercontent.com';
|
var GOOGLE_CLIENT_ID = '241271498917-jpto9lls9fqnem1e4h6ppds9uob8rpvu.apps.googleusercontent.com';
|
||||||
|
var GITHUB_CLIENT_ID = 'fa0d09514da8377ee32e';
|
||||||
|
var GATEKEEPER_URL = "http://stackedit-gatekeeper.herokuapp.com/";
|
5
js/custo.js
Normal file
5
js/custo.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
var BASE_URL = "http://localhost/";
|
||||||
|
var GOOGLE_KEY = "AIzaSyAeCU8CGcSkn0z9js6iocHuPBX4f_mMWkw";
|
||||||
|
var GOOGLE_CLIENT_ID = '241271498917-lev37kef013q85avc91am1gccg5g8lrb.apps.googleusercontent.com';
|
||||||
|
var GITHUB_CLIENT_ID = 'e47fef6055344579799d';
|
||||||
|
var GATEKEEPER_URL = "http://stackedit-gatekeeper-localhost.herokuapp.com/";
|
@ -39,7 +39,7 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
secret: DROPBOX_APP_SECRET
|
secret: DROPBOX_APP_SECRET
|
||||||
});
|
});
|
||||||
client.authDriver(new Dropbox.Drivers.Popup({
|
client.authDriver(new Dropbox.Drivers.Popup({
|
||||||
receiverUrl: "http://localhost/dropbox-oauth-receiver.html",
|
receiverUrl: BASE_URL + "dropbox-oauth-receiver.html",
|
||||||
rememberUser: true
|
rememberUser: true
|
||||||
}));
|
}));
|
||||||
callback();
|
callback();
|
||||||
@ -125,6 +125,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
asyncTask.onSuccess = function() {
|
asyncTask.onSuccess = function() {
|
||||||
callback(fileSyncIndex);
|
callback(fileSyncIndex);
|
||||||
};
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -172,6 +175,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
callback(changes, newChangeId);
|
callback(changes, newChangeId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
}
|
}
|
||||||
retrievePageOfChanges(newChangeId);
|
retrievePageOfChanges(newChangeId);
|
||||||
@ -207,6 +213,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
asyncTask.onSuccess = function() {
|
asyncTask.onSuccess = function() {
|
||||||
dropboxHelper.downloadMetadata(paths, callback, result);
|
dropboxHelper.downloadMetadata(paths, callback, result);
|
||||||
};
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -255,6 +264,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
asyncTask.onSuccess = function() {
|
asyncTask.onSuccess = function() {
|
||||||
dropboxHelper.downloadContent(objects, callback, result);
|
dropboxHelper.downloadContent(objects, callback, result);
|
||||||
};
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"],
|
define(["jquery", "google-helper", "dropbox-helper", "github-helper", "synchronizer", "publisher"],
|
||||||
function($, googleHelper, dropboxHelper, synchronizer, publisher) {
|
function($, googleHelper, dropboxHelper, githubHelper, synchronizer, publisher) {
|
||||||
|
|
||||||
var fileManager = {};
|
var fileManager = {};
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
// Update the file titles
|
// Update the file titles
|
||||||
fileManager.updateFileTitles();
|
fileManager.updateFileTitles();
|
||||||
refreshManageSync();
|
refreshManageSync();
|
||||||
|
refreshManagePublish();
|
||||||
publisher.notifyCurrentFile(localStorage["file.current"]);
|
publisher.notifyCurrentFile(localStorage["file.current"]);
|
||||||
|
|
||||||
// Recreate the editor
|
// Recreate the editor
|
||||||
@ -51,9 +52,13 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
title = DEFAULT_FILE_TITLE + indicator++;
|
title = DEFAULT_FILE_TITLE + indicator++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Create the fileIndex
|
|
||||||
var fileCounter = parseInt(localStorage["file.counter"]);
|
// Generate a unique fileIndex
|
||||||
var fileIndex = "file." + fileCounter;
|
var fileIndex = undefined;
|
||||||
|
do {
|
||||||
|
fileIndex = "file." + core.randomString();
|
||||||
|
} while(localStorage[fileIndex + ".title"] !== undefined);
|
||||||
|
|
||||||
// Create the file in the localStorage
|
// Create the file in the localStorage
|
||||||
localStorage[fileIndex + ".content"] = content;
|
localStorage[fileIndex + ".content"] = content;
|
||||||
localStorage[fileIndex + ".title"] = title;
|
localStorage[fileIndex + ".title"] = title;
|
||||||
@ -63,7 +68,6 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
}
|
}
|
||||||
localStorage[fileIndex + ".sync"] = sync;
|
localStorage[fileIndex + ".sync"] = sync;
|
||||||
localStorage[fileIndex + ".publish"] = ";";
|
localStorage[fileIndex + ".publish"] = ";";
|
||||||
localStorage["file.counter"] = fileCounter + 1;
|
|
||||||
localStorage["file.list"] += fileIndex + ";";
|
localStorage["file.list"] += fileIndex + ";";
|
||||||
return fileIndex;
|
return fileIndex;
|
||||||
};
|
};
|
||||||
@ -85,6 +89,14 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
}
|
}
|
||||||
localStorage.removeItem(fileIndex + ".sync");
|
localStorage.removeItem(fileIndex + ".sync");
|
||||||
|
|
||||||
|
// Remove publish locations
|
||||||
|
var publishIndexList = localStorage[fileIndex + ".publish"].split(";");
|
||||||
|
for ( var i = 1; i < publishIndexList.length - 1; i++) {
|
||||||
|
var publishIndex = publishIndexList[i];
|
||||||
|
fileManager.removePublish(publishIndex);
|
||||||
|
}
|
||||||
|
localStorage.removeItem(fileIndex + ".sync");
|
||||||
|
|
||||||
localStorage["file.list"] = localStorage["file.list"].replace(";"
|
localStorage["file.list"] = localStorage["file.list"].replace(";"
|
||||||
+ fileIndex + ";", ";");
|
+ fileIndex + ";", ";");
|
||||||
localStorage.removeItem(fileIndex + ".title");
|
localStorage.removeItem(fileIndex + ".title");
|
||||||
@ -191,17 +203,44 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
|
|
||||||
// Look for local file associated to a synchronized location
|
// Look for local file associated to a synchronized location
|
||||||
fileManager.getFileIndexFromSync = function(fileSyncIndex) {
|
fileManager.getFileIndexFromSync = function(fileSyncIndex) {
|
||||||
var fileIndex = undefined;
|
|
||||||
var fileIndexList = localStorage["file.list"].split(";");
|
var fileIndexList = localStorage["file.list"].split(";");
|
||||||
for ( var i = 1; i < fileIndexList.length - 1; i++) {
|
for ( var i = 1; i < fileIndexList.length - 1; i++) {
|
||||||
var tempFileIndex = fileIndexList[i];
|
var fileIndex = fileIndexList[i];
|
||||||
var sync = localStorage[tempFileIndex + ".sync"];
|
var sync = localStorage[fileIndex + ".sync"];
|
||||||
if (sync.indexOf(";" + fileSyncIndex + ";") !== -1) {
|
if (sync.indexOf(";" + fileSyncIndex + ";") !== -1) {
|
||||||
fileIndex = tempFileIndex;
|
return fileIndex;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fileIndex;
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Remove a publish location
|
||||||
|
fileManager.removePublish = function(publishIndex) {
|
||||||
|
var fileIndexCurrent = localStorage["file.current"];
|
||||||
|
var fileIndex = this.getFileIndexFromPublish(publishIndex);
|
||||||
|
if(fileIndex !== undefined) {
|
||||||
|
localStorage[fileIndex + ".publish"] = localStorage[fileIndex + ".publish"].replace(";"
|
||||||
|
+ publishIndex + ";", ";");
|
||||||
|
if(fileIndex == fileIndexCurrent) {
|
||||||
|
refreshManagePublish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove publish object
|
||||||
|
localStorage.removeItem(publishIndex);
|
||||||
|
publisher.notifyCurrentFile(localStorage["file.current"]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Look for local file associated to a publish location
|
||||||
|
fileManager.getFileIndexFromPublish = function(publishIndex) {
|
||||||
|
var fileIndexList = localStorage["file.list"].split(";");
|
||||||
|
for ( var i = 1; i < fileIndexList.length - 1; i++) {
|
||||||
|
var fileIndex = fileIndexList[i];
|
||||||
|
var publish = localStorage[fileIndex + ".publish"];
|
||||||
|
if (publish.indexOf(";" + publishIndex + ";") !== -1) {
|
||||||
|
return fileIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
function uploadGdrive(fileId, folderId) {
|
function uploadGdrive(fileId, folderId) {
|
||||||
@ -325,14 +364,14 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
(function(fileSyncIndex) {
|
(function(fileSyncIndex) {
|
||||||
var line = $("<div>").addClass("input-prepend input-append");
|
var line = $("<div>").addClass("input-prepend input-append");
|
||||||
if (fileSyncIndex.indexOf(SYNC_PROVIDER_GDRIVE) === 0) {
|
if (fileSyncIndex.indexOf(SYNC_PROVIDER_GDRIVE) === 0) {
|
||||||
line.append($("<span>").addClass("add-on").html(
|
line.append($("<span>").addClass("add-on").prop("title", "Google Drive").html(
|
||||||
'<i class="icon-gdrive"></i>'));
|
'<i class="icon-gdrive"></i>'));
|
||||||
line.append($("<input>").prop("type", "text").prop(
|
line.append($("<input>").prop("type", "text").prop(
|
||||||
"disabled", true).addClass("span5").val(
|
"disabled", true).addClass("span5").val(
|
||||||
fileSyncIndex.substring(SYNC_PROVIDER_GDRIVE.length)));
|
fileSyncIndex.substring(SYNC_PROVIDER_GDRIVE.length)));
|
||||||
}
|
}
|
||||||
if (fileSyncIndex.indexOf(SYNC_PROVIDER_DROPBOX) === 0) {
|
else if (fileSyncIndex.indexOf(SYNC_PROVIDER_DROPBOX) === 0) {
|
||||||
line.append($("<span>").addClass("add-on").html(
|
line.append($("<span>").addClass("add-on").prop("title", "Dropbox").html(
|
||||||
'<i class="icon-dropbox"></i>'));
|
'<i class="icon-dropbox"></i>'));
|
||||||
line.append($("<input>").prop("type", "text").prop(
|
line.append($("<input>").prop("type", "text").prop(
|
||||||
"disabled", true).addClass("span5").val(
|
"disabled", true).addClass("span5").val(
|
||||||
@ -349,6 +388,44 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function refreshManagePublish() {
|
||||||
|
var fileIndex = localStorage["file.current"];
|
||||||
|
var publishIndexList = localStorage[fileIndex + ".publish"].split(";");
|
||||||
|
$(".msg-no-publish, .msg-publish-list").addClass("hide");
|
||||||
|
$("#manage-publish-list .input-append").remove();
|
||||||
|
if (publishIndexList.length > 2) {
|
||||||
|
$(".msg-publish-list").removeClass("hide");
|
||||||
|
} else {
|
||||||
|
$(".msg-no-publish").removeClass("hide");
|
||||||
|
}
|
||||||
|
for ( var i = 1; i < publishIndexList.length - 1; i++) {
|
||||||
|
var publishIndex = publishIndexList[i];
|
||||||
|
var serializedObject = localStorage[publishIndex];
|
||||||
|
(function(publishIndex, publishObject, serializedObject) {
|
||||||
|
var line = $("<div>").addClass("input-prepend input-append");
|
||||||
|
if (publishObject.provider == PUBLISH_PROVIDER_GITHUB) {
|
||||||
|
line.append($("<span>").addClass("add-on").prop("title", "GitHub").html(
|
||||||
|
'<i class="icon-github"></i>'));
|
||||||
|
line.append($("<input>").prop("type", "text").prop(
|
||||||
|
"disabled", true).addClass("span5").val(
|
||||||
|
serializedObject));
|
||||||
|
}
|
||||||
|
else if (publishObject.provider == PUBLISH_PROVIDER_BLOGGER) {
|
||||||
|
line.append($("<span>").addClass("add-on").prop("title", "Blogger").html(
|
||||||
|
'<i class="icon-blogger"></i>'));
|
||||||
|
line.append($("<input>").prop("type", "text").prop(
|
||||||
|
"disabled", true).addClass("span5").val(
|
||||||
|
serializedObject));
|
||||||
|
}
|
||||||
|
line.append($("<a>").addClass("btn").html(
|
||||||
|
'<i class="icon-trash"></i>').prop("title",
|
||||||
|
"Remove this location").click(function() {
|
||||||
|
fileManager.removePublish(publishIndex);
|
||||||
|
}));
|
||||||
|
$("#manage-publish-list").append(line);
|
||||||
|
})(publishIndex, JSON.parse(serializedObject), serializedObject.replace(/{|}|"/g, ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the "New publication" dialog
|
// Initialize the "New publication" dialog
|
||||||
var newPublishProvider = undefined;
|
var newPublishProvider = undefined;
|
||||||
@ -367,7 +444,46 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
$("#modal-publish").modal();
|
$("#modal-publish").modal();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new publication
|
// Generate a publishIndex, store a publishObject and associate it to a fileIndex
|
||||||
|
function createPublishIndex(publishObject, fileIndex) {
|
||||||
|
var publishIndex = undefined;
|
||||||
|
do {
|
||||||
|
publishIndex = "publish." + core.randomString();
|
||||||
|
} while(localStorage[publishIndex] !== undefined);
|
||||||
|
localStorage[publishIndex] = JSON.stringify(publishObject);
|
||||||
|
localStorage[fileIndex + ".publish"] += publishIndex + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new publication on GitHub
|
||||||
|
function newPublishGithub(event) {
|
||||||
|
var publishObject = {};
|
||||||
|
publishObject.username = core.getInputValue($("#input-publish-github-username"), event);
|
||||||
|
publishObject.repository = core.getInputValue($("#input-publish-github-reponame"), event);
|
||||||
|
publishObject.branch = core.getInputValue($("#input-publish-github-branch"), event);
|
||||||
|
publishObject.path = core.getInputValue($("#input-publish-github-path"), event);
|
||||||
|
publishObject.provider = newPublishProvider;
|
||||||
|
if(event.isPropagationStopped()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileIndex = localStorage["file.current"];
|
||||||
|
var title = localStorage[fileIndex + ".title"];
|
||||||
|
var content = publisher.getPublishContent(publishObject);
|
||||||
|
var commitMsg = core.settings.commitMsg;
|
||||||
|
githubHelper.upload(publishObject.username, publishObject.repository,
|
||||||
|
publishObject.branch, publishObject.path, content, commitMsg,
|
||||||
|
function(error) {
|
||||||
|
if(error === undefined) {
|
||||||
|
createPublishIndex(publishObject, fileIndex);
|
||||||
|
refreshManagePublish();
|
||||||
|
publisher.notifyCurrentFile(localStorage["file.current"]);
|
||||||
|
core.showMessage('"' + title
|
||||||
|
+ '" will now be published on GitHub.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new publication on Blogger
|
||||||
function newPublishBlogger(event) {
|
function newPublishBlogger(event) {
|
||||||
var blogUrl = core.getInputValue($("#input-publish-blogger-url"), event);
|
var blogUrl = core.getInputValue($("#input-publish-blogger-url"), event);
|
||||||
if(event.isPropagationStopped()) {
|
if(event.isPropagationStopped()) {
|
||||||
@ -460,13 +576,16 @@ define(["jquery", "google-helper", "dropbox-helper", "synchronizer", "publisher"
|
|||||||
|
|
||||||
// Publish actions
|
// Publish actions
|
||||||
$(".action-publish-github").click(function() {
|
$(".action-publish-github").click(function() {
|
||||||
initNewPublish("github");
|
initNewPublish(PUBLISH_PROVIDER_GITHUB);
|
||||||
});
|
});
|
||||||
$(".action-publish-blogger").click(function() {
|
$(".action-publish-blogger").click(function() {
|
||||||
initNewPublish("blogger", "html");
|
initNewPublish(PUBLISH_PROVIDER_BLOGGER, "html");
|
||||||
});
|
});
|
||||||
$(".action-process-publish").click(function(e) {
|
$(".action-process-publish").click(function(e) {
|
||||||
if(newPublishProvider == "blogger") {
|
if(newPublishProvider == PUBLISH_PROVIDER_GITHUB) {
|
||||||
|
newPublishGithub(e);
|
||||||
|
}
|
||||||
|
else if(newPublishProvider == PUBLISH_PROVIDER_BLOGGER) {
|
||||||
newPublishBlogger(e);
|
newPublishBlogger(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -2,10 +2,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
|
|
||||||
// Dependencies
|
// Dependencies
|
||||||
var core = undefined;
|
var core = undefined;
|
||||||
var fileManager = undefined;
|
|
||||||
|
|
||||||
var connected = undefined;
|
var connected = undefined;
|
||||||
var client = undefined;
|
var github = undefined;
|
||||||
|
|
||||||
var githubHelper = {};
|
var githubHelper = {};
|
||||||
|
|
||||||
@ -47,236 +46,129 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
// Try to authenticate with Oauth
|
// Try to authenticate with Oauth
|
||||||
function authenticate(callback, immediate) {
|
function authenticate(callback, immediate) {
|
||||||
callback = callback || core.doNothing;
|
callback = callback || core.doNothing;
|
||||||
if (immediate === undefined) {
|
|
||||||
immediate = true;
|
|
||||||
}
|
|
||||||
connect(function() {
|
connect(function() {
|
||||||
if (connected === false) {
|
if (connected === false) {
|
||||||
callback();
|
callback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var intervalId = undefined;
|
||||||
|
var authWindow = undefined;
|
||||||
|
var token = localStorage["githubToken"];
|
||||||
var asyncTask = {};
|
var asyncTask = {};
|
||||||
asyncTask.run = function() {
|
asyncTask.run = function() {
|
||||||
if (client !== undefined) {
|
if (github !== undefined) {
|
||||||
asyncTask.success();
|
asyncTask.success();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (immediate !== false) {
|
|
||||||
|
if (token !== undefined) {
|
||||||
|
github = new Github({
|
||||||
|
token: token,
|
||||||
|
auth: "oauth"
|
||||||
|
});
|
||||||
|
asyncTask.success();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
core.showMessage("Please make sure the Github authorization popup is not blocked by your browser.");
|
if(immediate === true) {
|
||||||
myWindow=core.popupWindow('github-oauth-client.html?client_id=test','stackedit-github-oauth',500,400);
|
core.showError("Unable to perform GitHub authenticate.");
|
||||||
myWindow.focus();
|
asyncTask.error();
|
||||||
};
|
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
callback();
|
// We add time for user to enter his credentials
|
||||||
};
|
asyncTask.timeout = AUTH_POPUP_TIMEOUT;
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
core.showMessage("Please make sure the Github authorization popup is not blocked by your browser.");
|
||||||
});
|
localStorage.removeItem("githubCode");
|
||||||
}
|
authWindow = core.popupWindow(
|
||||||
|
'github-oauth-client.html?client_id=' + GITHUB_CLIENT_ID,
|
||||||
githubHelper.upload = function(path, content, callback) {
|
'stackedit-github-oauth', 960, 600);
|
||||||
callback = callback || core.doNothing;
|
authWindow.focus();
|
||||||
authenticate(function() {
|
intervalId = setInterval(function() {
|
||||||
if (client === undefined) {
|
var code = localStorage["githubCode"];
|
||||||
callback();
|
if(code !== undefined) {
|
||||||
return;
|
localStorage.removeItem("githubCode");
|
||||||
}
|
$.getJSON(GATEKEEPER_URL + "authenticate/" + code, function(data) {
|
||||||
|
if(data.token !== undefined) {
|
||||||
var fileSyncIndex = undefined;
|
localStorage["githubToken"] = data.token;
|
||||||
var asyncTask = {};
|
asyncTask.success();
|
||||||
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();
|
else {
|
||||||
return;
|
core.showError("Error retrieving GitHub Oauth token.");
|
||||||
}
|
asyncTask.error();
|
||||||
// Handle error
|
}
|
||||||
handleError(error, asyncTask, callback);
|
});
|
||||||
});
|
|
||||||
};
|
|
||||||
asyncTask.onSuccess = function() {
|
|
||||||
if (shouldPullAgain === true) {
|
|
||||||
retrievePageOfChanges(newChangeId);
|
|
||||||
} else {
|
|
||||||
callback(changes, newChangeId);
|
|
||||||
}
|
}
|
||||||
};
|
}, 500);
|
||||||
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() {
|
asyncTask.onSuccess = function() {
|
||||||
githubHelper.downloadMetadata(paths, callback, result);
|
if(intervalId !== undefined) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
}
|
||||||
|
if (github !== undefined) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
authenticate(callback, true);
|
||||||
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
if(intervalId !== undefined) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
}
|
||||||
|
if(authWindow !== undefined) {
|
||||||
|
authWindow.close();
|
||||||
|
}
|
||||||
|
callback();
|
||||||
};
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
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) {
|
githubHelper.upload = function(username, reponame, branch, path, content, commitMsg, callback) {
|
||||||
|
callback = callback || core.doNothing;
|
||||||
|
authenticate(function() {
|
||||||
|
if (github === undefined) {
|
||||||
|
callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var error = undefined;
|
||||||
|
var asyncTask = {};
|
||||||
|
asyncTask.run = function() {
|
||||||
|
var repo = github.getRepo(username, reponame);
|
||||||
|
repo.write(branch, path, content, commitMsg, function(err) {
|
||||||
|
if(!err) {
|
||||||
|
asyncTask.success();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
error = err.error;
|
||||||
|
asyncTask.error();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
asyncTask.onSuccess = function() {
|
||||||
|
callback(error);
|
||||||
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
if(error === 401) {
|
||||||
|
github = undefined;
|
||||||
|
// Token must be renewed
|
||||||
|
localStorage.removeItem("githubToken");
|
||||||
|
githubHelper.upload(username, reponame, branch, path, content, commitMsg, callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(error === 0) {
|
||||||
|
connected = false;
|
||||||
|
github = undefined;
|
||||||
|
core.setOffline();
|
||||||
|
}
|
||||||
|
core.showError("Could not publish on GitHub");
|
||||||
|
callback(error);
|
||||||
|
};
|
||||||
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
githubHelper.init = function(coreModule) {
|
||||||
core = coreModule;
|
core = coreModule;
|
||||||
fileManager = fileManagerModule;
|
|
||||||
authenticate();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return githubHelper;
|
return githubHelper;
|
||||||
|
@ -122,10 +122,18 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
}
|
}
|
||||||
var path = '/upload/drive/v2/files';
|
var path = '/upload/drive/v2/files';
|
||||||
var method = 'POST';
|
var method = 'POST';
|
||||||
|
var etag = undefined;
|
||||||
if (fileId !== undefined) {
|
if (fileId !== undefined) {
|
||||||
// If it's an update
|
// If it's an update
|
||||||
path += "/" + fileId;
|
path += "/" + fileId;
|
||||||
method = 'PUT';
|
method = 'PUT';
|
||||||
|
etag = localStorage[SYNC_PROVIDER_GDRIVE
|
||||||
|
+ fileId + ".etag"];
|
||||||
|
}
|
||||||
|
var headers = { 'Content-Type' : 'multipart/mixed; boundary="'
|
||||||
|
+ boundary + '"', };
|
||||||
|
if(etag !== undefined) {
|
||||||
|
headers["If-Match"] = etag;
|
||||||
}
|
}
|
||||||
|
|
||||||
var base64Data = core.encodeBase64(content);
|
var base64Data = core.encodeBase64(content);
|
||||||
@ -141,8 +149,8 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
'path' : path,
|
'path' : path,
|
||||||
'method' : method,
|
'method' : method,
|
||||||
'params' : { 'uploadType' : 'multipart', },
|
'params' : { 'uploadType' : 'multipart', },
|
||||||
'headers' : { 'Content-Type' : 'multipart/mixed; boundary="'
|
'headers' : headers,
|
||||||
+ boundary + '"', }, 'body' : multipartRequestBody, });
|
'body' : multipartRequestBody, });
|
||||||
request.execute(function(response) {
|
request.execute(function(response) {
|
||||||
if (response && response.id) {
|
if (response && response.id) {
|
||||||
// Upload success
|
// Upload success
|
||||||
@ -154,7 +162,12 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
var error = response.error;
|
var error = response.error;
|
||||||
// Handle error
|
// Handle error
|
||||||
if(error !== undefined && fileId !== undefined && error.code === 404) {
|
if(error !== undefined && fileId !== undefined && error.code === 404) {
|
||||||
error = 'File ID "' + fileId + '" does not exist on Google Drive.';
|
if(error.code === 404) {
|
||||||
|
error = 'File ID "' + fileId + '" does not exist on Google Drive.';
|
||||||
|
}
|
||||||
|
else if(error.code === 412) {
|
||||||
|
error = 'Conflict on file ID "' + fileId + '". Please restart the synchronization.';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
handleError(error, asyncTask, callback);
|
handleError(error, asyncTask, callback);
|
||||||
});
|
});
|
||||||
@ -162,6 +175,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
asyncTask.onSuccess = function() {
|
asyncTask.onSuccess = function() {
|
||||||
callback(fileSyncIndex);
|
callback(fileSyncIndex);
|
||||||
};
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -212,6 +228,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
callback(changes, newChangeId);
|
callback(changes, newChangeId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
}
|
}
|
||||||
var initialRequest = gapi.client.drive.changes
|
var initialRequest = gapi.client.drive.changes
|
||||||
@ -264,6 +283,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
asyncTask.onSuccess = function() {
|
asyncTask.onSuccess = function() {
|
||||||
googleHelper.downloadMetadata(ids, callback, result);
|
googleHelper.downloadMetadata(ids, callback, result);
|
||||||
};
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -324,6 +346,9 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
asyncTask.onSuccess = function() {
|
asyncTask.onSuccess = function() {
|
||||||
googleHelper.downloadContent(objects, callback, result);
|
googleHelper.downloadContent(objects, callback, result);
|
||||||
};
|
};
|
||||||
|
asyncTask.onError = function() {
|
||||||
|
callback();
|
||||||
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -500,44 +525,8 @@ define(["jquery", "async-runner"], function($, asyncTaskRunner) {
|
|||||||
asyncTask.onSuccess = function() {
|
asyncTask.onSuccess = function() {
|
||||||
callback(result);
|
callback(result);
|
||||||
};
|
};
|
||||||
asyncTaskRunner.addTask(asyncTask);
|
asyncTask.onError = function() {
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
googleHelper.getBlogByUrl = function(url, callback) {
|
|
||||||
authenticate(function() {
|
|
||||||
if (connected === false) {
|
|
||||||
callback();
|
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);
|
asyncTaskRunner.addTask(asyncTask);
|
||||||
});
|
});
|
||||||
|
@ -32,11 +32,77 @@ define(["jquery", "google-helper", "github-helper"], function($, googleHelper, g
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Used to get content to publish
|
||||||
|
publisher.getPublishContent = function(publishObject) {
|
||||||
|
if(publishObject.format === undefined) {
|
||||||
|
publishObject.format = $("input:radio[name=radio-publish-format]:checked").prop("value");
|
||||||
|
}
|
||||||
|
if(publishObject.format == "markdown") {
|
||||||
|
return $("#wmd-input").val();
|
||||||
|
}
|
||||||
|
return $("#wmd-preview").html();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Recursive function to publish a file on multiple locations
|
||||||
|
var publishIndexList = [];
|
||||||
|
function publishLocation(callback, error) {
|
||||||
|
|
||||||
|
// No more publish location for this document
|
||||||
|
if (publishIndexList.length === 0) {
|
||||||
|
callback(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dequeue a synchronized location
|
||||||
|
var publishIndex = publishIndexList.pop();
|
||||||
|
if(!publishIndex) {
|
||||||
|
publishLocation(callback, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var publishObject = JSON.parse(localStorage[publishIndex]);
|
||||||
|
var content = publisher.getPublishContent(publishObject);
|
||||||
|
var commitMsg = core.settings.commitMsg;
|
||||||
|
|
||||||
|
// Try to find the provider
|
||||||
|
if(publishObject.provider == PUBLISH_PROVIDER_GITHUB) {
|
||||||
|
githubHelper.upload(publishObject.username, publishObject.repository,
|
||||||
|
publishObject.branch, publishObject.path, content, commitMsg,
|
||||||
|
function(error) {
|
||||||
|
publishLocation(callback, error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var publishRunning = false;
|
var publishRunning = false;
|
||||||
|
publisher.publish = function() {
|
||||||
|
// If publish is running or offline
|
||||||
|
if(publishRunning === true || core.isOffline) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
publishRunning = true;
|
||||||
|
publisher.updatePublishButton();
|
||||||
|
var fileIndex = localStorage["file.current"];
|
||||||
|
var title = localStorage[fileIndex + ".title"];
|
||||||
|
publishIndexList = localStorage[fileIndex + ".publish"].split(";");;
|
||||||
|
publishLocation(function(error) {
|
||||||
|
publishRunning = false;
|
||||||
|
publisher.updatePublishButton();
|
||||||
|
if(error === undefined) {
|
||||||
|
core.showMessage('"' + title + '" successfully published.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
publisher.init = function(coreModule, fileManagerModule) {
|
publisher.init = function(coreModule, fileManagerModule) {
|
||||||
core = coreModule;
|
core = coreModule;
|
||||||
fileManager = fileManagerModule;
|
fileManager = fileManagerModule;
|
||||||
|
$(".action-force-publish").click(function() {
|
||||||
|
if(!$(this).hasClass("disabled")) {
|
||||||
|
publisher.publish();
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return publisher;
|
return publisher;
|
||||||
|
@ -187,9 +187,9 @@ define(["jquery", "google-helper", "dropbox-helper"], function($, googleHelper,
|
|||||||
core.showMessage('"' + localTitle + '" has been removed from Google Drive.');
|
core.showMessage('"' + localTitle + '" has been removed from Google Drive.');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var localTitleChanged = localStorage[fileSyncIndex + ".titleCRC"] == core.crc32(localTitle);
|
var localTitleChanged = localStorage[fileSyncIndex + ".titleCRC"] != core.crc32(localTitle);
|
||||||
var localContent = localStorage[fileIndex + ".content"];
|
var localContent = localStorage[fileIndex + ".content"];
|
||||||
var localContentChanged = localStorage[fileSyncIndex + ".contentCRC"] == core.crc32(localContent);
|
var localContentChanged = localStorage[fileSyncIndex + ".contentCRC"] != core.crc32(localContent);
|
||||||
var file = change.file;
|
var file = change.file;
|
||||||
var fileTitleChanged = localTitle != file.title;
|
var fileTitleChanged = localTitle != file.title;
|
||||||
var fileContentChanged = localContent != file.content;
|
var fileContentChanged = localContent != file.content;
|
||||||
@ -270,7 +270,7 @@ define(["jquery", "google-helper", "dropbox-helper"], function($, googleHelper,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var localContent = localStorage[fileIndex + ".content"];
|
var localContent = localStorage[fileIndex + ".content"];
|
||||||
var localContentChanged = localStorage[fileSyncIndex + ".contentCRC"] == core.crc32(localContent);
|
var localContentChanged = localStorage[fileSyncIndex + ".contentCRC"] != core.crc32(localContent);
|
||||||
var file = change.stat;
|
var file = change.stat;
|
||||||
var fileContentChanged = localContent != file.content;
|
var fileContentChanged = localContent != file.content;
|
||||||
// Conflict detection
|
// Conflict detection
|
||||||
|
Loading…
Reference in New Issue
Block a user