UI fixes
This commit is contained in:
parent
b5191a7457
commit
ab8b0cca02
@ -28,6 +28,7 @@
|
|||||||
"MutationObservers": "https://github.com/Polymer/MutationObservers.git#~0.2.1",
|
"MutationObservers": "https://github.com/Polymer/MutationObservers.git#~0.2.1",
|
||||||
"rangy": "~1.2.3",
|
"rangy": "~1.2.3",
|
||||||
"google-diff-match-patch-js": "~1.0.0",
|
"google-diff-match-patch-js": "~1.0.0",
|
||||||
"jsondiffpatch": "~0.1.5"
|
"jsondiffpatch": "~0.1.5",
|
||||||
|
"hammerjs": "~1.0.10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<link rel="shortcut icon" sizes="196x196" href="res-min/img/nice-highres.png">
|
<link rel="shortcut icon" sizes="196x196" href="res-min/img/nice-highres.png">
|
||||||
<meta name="description" content="Full-featured, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites.">
|
<meta name="description" content="Full-featured, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites.">
|
||||||
<meta name="author" content="Benoit Schweblin">
|
<meta name="author" content="Benoit Schweblin">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
<meta name="mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<meta name="msvalidate.01" content="5E47EE6F67B069C17E3CDD418351A612"
|
<meta name="msvalidate.01" content="5E47EE6F67B069C17E3CDD418351A612"
|
||||||
/>
|
/>
|
||||||
|
@ -62,7 +62,7 @@ define([
|
|||||||
fileDesc = selectedFileDesc;
|
fileDesc = selectedFileDesc;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Watcher used to detect editor changes
|
// Used to detect editor changes
|
||||||
function Watcher() {
|
function Watcher() {
|
||||||
this.isWatching = false;
|
this.isWatching = false;
|
||||||
var contentObserver;
|
var contentObserver;
|
||||||
@ -212,9 +212,6 @@ define([
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
this.getCoordinates = function(inputOffset, container, offset) {
|
this.getCoordinates = function(inputOffset, container, offset) {
|
||||||
if(inputOffset === textContent.length) {
|
|
||||||
return this.getCoordinates(inputOffset - 1);
|
|
||||||
}
|
|
||||||
if(!container) {
|
if(!container) {
|
||||||
offset = this.findOffset(inputOffset);
|
offset = this.findOffset(inputOffset);
|
||||||
container = offset.container;
|
container = offset.container;
|
||||||
@ -485,6 +482,8 @@ define([
|
|||||||
this.currentMode = undefined;
|
this.currentMode = undefined;
|
||||||
lastMode = undefined;
|
lastMode = undefined;
|
||||||
contentElt.textContent = content;
|
contentElt.textContent = content;
|
||||||
|
// Force this since the content could be the same
|
||||||
|
checkContentChange();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
var undoMgr = new UndoMgr();
|
var undoMgr = new UndoMgr();
|
||||||
@ -503,12 +502,20 @@ define([
|
|||||||
var trailingLfNode;
|
var trailingLfNode;
|
||||||
function checkContentChange() {
|
function checkContentChange() {
|
||||||
var newTextContent = inputElt.textContent;
|
var newTextContent = inputElt.textContent;
|
||||||
if(contentElt.lastChild === trailingLfNode && trailingLfNode.textContent.slice(-1) === '\n') {
|
if(contentElt.lastChild === trailingLfNode && trailingLfNode.textContent.slice(-1) == '\n') {
|
||||||
newTextContent = newTextContent.slice(0, -1);
|
newTextContent = newTextContent.slice(0, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fileChanged === false) {
|
if(fileChanged === false) {
|
||||||
if(contentElt.children.length && newTextContent == textContent) {
|
if(newTextContent == textContent) {
|
||||||
|
// User has removed the empty section
|
||||||
|
if(contentElt.children.length === 0) {
|
||||||
|
contentElt.innerHTML = '';
|
||||||
|
sectionList.forEach(function(section) {
|
||||||
|
contentElt.appendChild(section.elt);
|
||||||
|
});
|
||||||
|
addTrailingLfNode();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
undoMgr.currentMode = undoMgr.currentMode || 'typing';
|
undoMgr.currentMode = undoMgr.currentMode || 'typing';
|
||||||
@ -610,6 +617,15 @@ define([
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// See https://gist.github.com/shimondoodkin/1081133
|
||||||
|
if(/AppleWebKit\/([\d.]+)/.exec(navigator.userAgent)) {
|
||||||
|
var $editableFix = $('<input style="width:1px;height:1px;border:none;margin:0;padding:0;" tabIndex="-1">').appendTo('html');
|
||||||
|
$contentElt.blur(function () {
|
||||||
|
$editableFix[0].setSelectionRange(0, 0);
|
||||||
|
$editableFix.blur();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
inputElt.focus = focus;
|
inputElt.focus = focus;
|
||||||
|
|
||||||
Object.defineProperty(inputElt, 'value', {
|
Object.defineProperty(inputElt, 'value', {
|
||||||
@ -704,10 +720,8 @@ define([
|
|||||||
|
|
||||||
actions[action](state, options);
|
actions[action](state, options);
|
||||||
setValue(state.before + state.selection + state.after);
|
setValue(state.before + state.selection + state.after);
|
||||||
_.defer(function() {
|
selectionMgr.setSelectionStartEnd(state.selectionStart, state.selectionEnd);
|
||||||
selectionMgr.setSelectionStartEnd(state.selectionStart, state.selectionEnd);
|
|
||||||
//$inputElt.trigger('input');
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var actions = {
|
var actions = {
|
||||||
@ -873,12 +887,19 @@ define([
|
|||||||
childNode = nextNode;
|
childNode = nextNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trailingLfNode = document.createTextNode('\n');
|
addTrailingLfNode();
|
||||||
contentElt.appendChild(trailingLfNode);
|
|
||||||
selectionMgr.setSelectionStartEnd();
|
selectionMgr.setSelectionStartEnd();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addTrailingLfNode() {
|
||||||
|
trailingLfNode = crel('span', {
|
||||||
|
class: 'token lf',
|
||||||
|
});
|
||||||
|
trailingLfNode.textContent = '\n';
|
||||||
|
contentElt.appendChild(trailingLfNode);
|
||||||
|
}
|
||||||
|
|
||||||
var escape = (function() {
|
var escape = (function() {
|
||||||
var entityMap = {
|
var entityMap = {
|
||||||
"&": "&",
|
"&": "&",
|
||||||
|
@ -73,6 +73,10 @@ define([
|
|||||||
checkPublication();
|
checkPublication();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
buttonPublish.onReady = function() {
|
||||||
|
$(".action-update-publication").click(publisher.publish);
|
||||||
|
};
|
||||||
|
|
||||||
buttonPublish.onPublishRemoved = checkPublication;
|
buttonPublish.onPublishRemoved = checkPublication;
|
||||||
buttonPublish.onNewPublishSuccess = checkPublication;
|
buttonPublish.onNewPublishSuccess = checkPublication;
|
||||||
|
|
||||||
|
@ -93,6 +93,9 @@ define([
|
|||||||
synchronizer.sync() && (lastSync = utils.currentTime);
|
synchronizer.sync() && (lastSync = utils.currentTime);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
});
|
});
|
||||||
|
$(".action-force-synchronization").click(function() {
|
||||||
|
synchronizer.sync() && (lastSync = utils.currentTime);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return buttonSync;
|
return buttonSync;
|
||||||
|
@ -21,6 +21,7 @@ define([
|
|||||||
var syncListElt;
|
var syncListElt;
|
||||||
var $msgSyncListElt;
|
var $msgSyncListElt;
|
||||||
var $msgNoSyncElt;
|
var $msgNoSyncElt;
|
||||||
|
var $showAlreadySynchronizedElt;
|
||||||
var refreshDialog = function(fileDescParameter) {
|
var refreshDialog = function(fileDescParameter) {
|
||||||
if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) {
|
if(fileDescParameter !== undefined && fileDescParameter !== fileDesc) {
|
||||||
return;
|
return;
|
||||||
@ -35,6 +36,8 @@ define([
|
|||||||
$msgNoSyncElt.removeClass("hide");
|
$msgNoSyncElt.removeClass("hide");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$showAlreadySynchronizedElt.toggleClass("hide", _.size(fileDesc.syncLocations) === 0);
|
||||||
|
|
||||||
var syncListHtml = _.reduce(fileDesc.syncLocations, function(result, syncAttributes) {
|
var syncListHtml = _.reduce(fileDesc.syncLocations, function(result, syncAttributes) {
|
||||||
return result + _.template(dialogManageSynchronizationLocationHTML, {
|
return result + _.template(dialogManageSynchronizationLocationHTML, {
|
||||||
syncAttributes: syncAttributes,
|
syncAttributes: syncAttributes,
|
||||||
@ -66,6 +69,8 @@ define([
|
|||||||
syncListElt = modalElt.querySelector(".sync-list");
|
syncListElt = modalElt.querySelector(".sync-list");
|
||||||
$msgSyncListElt = $(modalElt.querySelectorAll(".msg-sync-list"));
|
$msgSyncListElt = $(modalElt.querySelectorAll(".msg-sync-list"));
|
||||||
$msgNoSyncElt = $(modalElt.querySelectorAll(".msg-no-sync"));
|
$msgNoSyncElt = $(modalElt.querySelectorAll(".msg-no-sync"));
|
||||||
|
|
||||||
|
$showAlreadySynchronizedElt = $(document.querySelectorAll(".show-already-synchronized"));
|
||||||
};
|
};
|
||||||
|
|
||||||
return dialogManageSynchronization;
|
return dialogManageSynchronization;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
'mod+z': bindPagedownButton('undo'),
|
'mod+z': bindPagedownButton('undo'),
|
||||||
'mod+y': bindPagedownButton('redo'),
|
'mod+y': bindPagedownButton('redo'),
|
||||||
'mod+shift+z': bindPagedownButton('redo'),
|
'mod+shift+z': bindPagedownButton('redo'),
|
||||||
'mod+p': function(evt) {
|
'mod+d': function(evt) {
|
||||||
$('.button-open-discussion').click();
|
$('.button-open-discussion').click();
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
},
|
},
|
||||||
|
@ -74,18 +74,25 @@
|
|||||||
</button>
|
</button>
|
||||||
<div class="panel-content">
|
<div class="panel-content">
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
|
|
||||||
<a href="viewer" title="StackEdit Viewer"
|
<a href="viewer" title="StackEdit Viewer"
|
||||||
class="list-group-item"><i class="icon-resize-full"></i>
|
class="list-group-item">
|
||||||
StackEdit Viewer</a>
|
<i class="icon-resize-full"></i> StackEdit Viewer
|
||||||
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class=dropdown-header>EXPORT</div>
|
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
|
|
||||||
<a href="#" data-toggle="collapse" data-target=".collapse-synchronize"
|
<a href="#" data-toggle="collapse" data-target=".collapse-synchronize"
|
||||||
class="list-group-item"><i
|
class="list-group-item">
|
||||||
class="icon-refresh"></i> Synchronize...</a>
|
<div><i class="icon-refresh"></i> Synchronize</div>
|
||||||
|
<small>Backup, collaborate in the cloud</small>
|
||||||
|
</a>
|
||||||
<div class="sub-menu collapse collapse-synchronize clearfix">
|
<div class="sub-menu collapse collapse-synchronize clearfix">
|
||||||
<ul class="nav">
|
<ul class="nav alert alert-danger show-already-synchronized">
|
||||||
|
<li><div>"<span class="file-title"></span>" is already synchronized.</div></li>
|
||||||
|
<li><a href="#" class="action-force-synchronization"><i class="icon-refresh"></i>
|
||||||
|
Force synchronization</a></li>
|
||||||
<li><a href="#" data-toggle="modal" data-target=".modal-manage-sync"
|
<li><a href="#" data-toggle="modal" data-target=".modal-manage-sync"
|
||||||
class="action-reset-input"><i
|
class="action-reset-input"><i
|
||||||
class="icon-refresh"></i> Manage synchronization</a></li>
|
class="icon-refresh"></i> Manage synchronization</a></li>
|
||||||
@ -93,22 +100,27 @@
|
|||||||
<ul class="nav">
|
<ul class="nav">
|
||||||
<li><a href="#" class="action-sync-export-dialog-dropbox"><i
|
<li><a href="#" class="action-sync-export-dialog-dropbox"><i
|
||||||
class="icon-provider-dropbox"></i> Save on Dropbox</a></li>
|
class="icon-provider-dropbox"></i> Save on Dropbox</a></li>
|
||||||
|
<li><a href="#" class="action-sync-import-dropbox"><i
|
||||||
|
class="icon-provider-dropbox"></i> Open from Dropbox</a></li>
|
||||||
<li><a href="#" class="submenu-sync-gdrive action-sync-export-dialog-gdrive"><i
|
<li><a href="#" class="submenu-sync-gdrive action-sync-export-dialog-gdrive"><i
|
||||||
class="icon-provider-gdrive"></i> Save on Google Drive</a></li>
|
class="icon-provider-gdrive"></i> Save on Google Drive</a></li>
|
||||||
|
<li><a href="#" class="submenu-sync-gdrive action-sync-import-gdrive"><i
|
||||||
|
class="icon-provider-gdrive"></i> Open from Google Drive</a></li>
|
||||||
<li><a href="#" class="submenu-sync-gdrivesec action-sync-export-dialog-gdrivesec"><i
|
<li><a href="#" class="submenu-sync-gdrivesec action-sync-export-dialog-gdrivesec"><i
|
||||||
class="icon-provider-gdrive"></i> Save on Google Drive <small>(2nd account)</small></a></li>
|
class="icon-provider-gdrive"></i> Save on Google Drive <small>(2nd account)</small></a></li>
|
||||||
|
<li><a href="#" class="submenu-sync-gdrivesec action-sync-import-gdrivesec"><i
|
||||||
|
class="icon-provider-gdrive"></i> Open from Google Drive <small>(2nd account)</small></a></li>
|
||||||
<li><a href="#" class="submenu-sync-gdriveter action-sync-export-dialog-gdriveter"><i
|
<li><a href="#" class="submenu-sync-gdriveter action-sync-export-dialog-gdriveter"><i
|
||||||
class="icon-provider-gdrive"></i> Save on Google Drive <small>(3rd account)</small></a></li>
|
class="icon-provider-gdrive"></i> Save on Google Drive <small>(3rd account)</small></a></li>
|
||||||
<li><a href="#" class="submenu-sync-gdrive action-autosync-dialog-gdrive"><i
|
<li><a href="#" class="submenu-sync-gdriveter action-sync-import-gdriveter"><i
|
||||||
class="icon-provider-gdrive"></i> Google Drive AutoSync</a></li>
|
class="icon-provider-gdrive"></i> Open from Google Drive <small>(3rd account)</small></a></li>
|
||||||
<li><a href="#" class="submenu-sync-gdrivesec action-autosync-dialog-gdrivesec"><i
|
|
||||||
class="icon-provider-gdrive"></i> Google Drive AutoSync <small>(2nd account)</small></a></li>
|
|
||||||
<li><a href="#" class="submenu-sync-gdriveter action-autosync-dialog-gdriveter"><i
|
|
||||||
class="icon-provider-gdrive"></i> Google Drive AutoSync <small>(3rd account)</small></a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<a href="#" data-toggle="collapse" data-target=".collapse-publish-on"
|
<a href="#" data-toggle="collapse" data-target=".collapse-publish-on"
|
||||||
class="list-group-item"><i class="icon-upload"></i> Publish...</a>
|
class="list-group-item">
|
||||||
|
<div><i class="icon-upload"></i>Publish</div>
|
||||||
|
<small>Export on the web</small>
|
||||||
|
</a>
|
||||||
<div class="sub-menu collapse collapse-publish-on clearfix">
|
<div class="sub-menu collapse collapse-publish-on clearfix">
|
||||||
<ul class="nav alert alert-danger show-already-published">
|
<ul class="nav alert alert-danger show-already-published">
|
||||||
<li><div>"<span class="file-title"></span>" is already published.</div></li>
|
<li><div>"<span class="file-title"></span>" is already published.</div></li>
|
||||||
@ -122,8 +134,13 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<a href="#" data-toggle="modal" data-target=".modal-manage-sharing"
|
<a href="#" data-toggle="modal" data-target=".modal-manage-sharing"
|
||||||
class="action-reset-input list-group-item"><i class="icon-link"></i>
|
class="action-reset-input list-group-item">
|
||||||
Sharing links</a>
|
<div><i class="icon-link"></i>Sharing</div>
|
||||||
|
<small>Share document links</small>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="list-group">
|
||||||
|
|
||||||
<a href="#" data-toggle="collapse" data-target=".collapse-save-as"
|
<a href="#" data-toggle="collapse" data-target=".collapse-save-as"
|
||||||
class="list-group-item"><i class="icon-hdd"></i> Export to disk</a>
|
class="list-group-item"><i class="icon-hdd"></i> Export to disk</a>
|
||||||
<div class="sub-menu collapse collapse-save-as clearfix">
|
<div class="sub-menu collapse collapse-save-as clearfix">
|
||||||
@ -138,21 +155,7 @@
|
|||||||
class="icon-download"></i> Export as PDF</a></li>
|
class="icon-download"></i> Export as PDF</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class=dropdown-header>IMPORT</div>
|
|
||||||
<div class="list-group">
|
|
||||||
<a class="list-group-item action-sync-import-dropbox" href="#"><i
|
|
||||||
class="icon-provider-dropbox"></i> Open from
|
|
||||||
Dropbox</a>
|
|
||||||
<a href="#" class="list-group-item submenu-sync-gdrive action-sync-import-gdrive"><i
|
|
||||||
class="icon-provider-gdrive"></i> Open from
|
|
||||||
Google Drive</a>
|
|
||||||
<a href="#" class="list-group-item submenu-sync-gdrivesec action-sync-import-gdrivesec"><i
|
|
||||||
class="icon-provider-gdrive"></i> Open from
|
|
||||||
Google Drive <small>(2nd account)</small></a>
|
|
||||||
<a href="#" class="list-group-item submenu-sync-gdriveter action-sync-import-gdriveter"><i
|
|
||||||
class="icon-provider-gdrive"></i> Open from
|
|
||||||
Google Drive <small>(3rd account)</small></a>
|
|
||||||
<a data-toggle="modal"
|
<a data-toggle="modal"
|
||||||
data-target=".modal-import-harddrive-markdown"
|
data-target=".modal-import-harddrive-markdown"
|
||||||
class="list-group-item action-reset-input" href="#"><i
|
class="list-group-item action-reset-input" href="#"><i
|
||||||
@ -303,7 +306,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a href="#" class="btn btn-default action-import-image-gplus"
|
<a href="#" class="btn btn-default pull-left action-import-image-gplus"
|
||||||
data-dismiss="modal"><i class="icon-provider-gplus"></i> Import
|
data-dismiss="modal"><i class="icon-provider-gplus"></i> Import
|
||||||
from Google+</a> <a href="#" class="btn btn-default"
|
from Google+</a> <a href="#" class="btn btn-default"
|
||||||
data-dismiss="modal">Cancel</a> <a href="#"
|
data-dismiss="modal">Cancel</a> <a href="#"
|
||||||
|
@ -8,19 +8,33 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>
|
<p>
|
||||||
<b>AutoSync</b> feature automatically exports every new document to your <i
|
<b>AutoSync</b> feature automatically saves all documents to your <i
|
||||||
class="icon-provider-<%= providerId %>"></i>
|
class="icon-provider-<%= providerId %>"></i>
|
||||||
<code>Google Drive</code>
|
<code>Google Drive</code>
|
||||||
account and keep it synchronized.
|
account and keep them synchronized.
|
||||||
</p>
|
</p>
|
||||||
<div class="form-horizontal">
|
<div class="form-horizontal">
|
||||||
<br/>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-lg-3 control-label"></div>
|
<div class="col-lg-3 control-label"></div>
|
||||||
<div class="col-lg-8">
|
<div class="col-lg-8">
|
||||||
<label> <input id="input-autosync-<%= providerId %>-enabled"
|
<div class="radio">
|
||||||
type="checkbox"> Enable AutoSync for <%= providerName %>
|
<label> <input type="radio"
|
||||||
</label>
|
name="radio-autosync-<%= providerId %>-mode" value="off">
|
||||||
|
Disabled
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="radio">
|
||||||
|
<label> <input type="radio"
|
||||||
|
name="radio-autosync-<%= providerId %>-mode" value="new">
|
||||||
|
New documents (not current)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="radio">
|
||||||
|
<label> <input type="radio"
|
||||||
|
name="radio-autosync-<%= providerId %>-mode" value="all">
|
||||||
|
Every document not yet synchronized
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
|
@ -55,6 +55,8 @@
|
|||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
<a href="#" class="btn btn-default pull-left action-autosync-dialog-<%= providerId %>" data-dismiss="modal"><i
|
||||||
|
class="icon-provider-gdrive"></i> Setup AutoSync</a>
|
||||||
<a href="#" class="btn btn-default" data-dismiss="modal">Cancel</a>
|
<a href="#" class="btn btn-default" data-dismiss="modal">Cancel</a>
|
||||||
<a href="#" data-dismiss="modal"
|
<a href="#" data-dismiss="modal"
|
||||||
class="btn btn-primary action-sync-export-<%= providerId %>">OK</a>
|
class="btn btn-primary action-sync-export-<%= providerId %>">OK</a>
|
||||||
|
@ -7,7 +7,8 @@ define([
|
|||||||
'eventMgr',
|
'eventMgr',
|
||||||
'crel',
|
'crel',
|
||||||
'mousetrap',
|
'mousetrap',
|
||||||
], function($, _, utils, constants, settings, eventMgr, crel, mousetrap) {
|
'hammerjs',
|
||||||
|
], function($, _, utils, constants, settings, eventMgr, crel, mousetrap, hammer) {
|
||||||
var layout = {};
|
var layout = {};
|
||||||
|
|
||||||
var resizerSize = 32;
|
var resizerSize = 32;
|
||||||
@ -23,10 +24,11 @@ define([
|
|||||||
};
|
};
|
||||||
var menuPanelWidth = 280;
|
var menuPanelWidth = 280;
|
||||||
var documentPanelWidth = 320;
|
var documentPanelWidth = 320;
|
||||||
|
var titleMinWidth = 200;
|
||||||
var windowSize;
|
var windowSize;
|
||||||
|
|
||||||
var wrapperL1, wrapperL2, wrapperL3;
|
var wrapperL1, wrapperL2, wrapperL3;
|
||||||
var navbar, menuPanel, documentPanel, editor, previewPanel, previewContainer, navbarToggler, previewToggler, previewResizer;
|
var navbar, menuPanel, documentPanel, editor, previewPanel, previewContainer, navbarToggler, previewToggler, previewResizer, previewButtons;
|
||||||
|
|
||||||
var animate = false;
|
var animate = false;
|
||||||
function startAnimation() {
|
function startAnimation() {
|
||||||
@ -126,6 +128,19 @@ define([
|
|||||||
resizeAll();
|
resizeAll();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
DomObject.prototype.initHammer = function(drag) {
|
||||||
|
this.hammer = hammer(this.elt, {
|
||||||
|
drag: drag ? true : false,
|
||||||
|
drag_max_touches: 0,
|
||||||
|
gesture: false,
|
||||||
|
hold: false,
|
||||||
|
release: false,
|
||||||
|
swipe: drag ? false : true,
|
||||||
|
tap: false,
|
||||||
|
touch: false,
|
||||||
|
transform: false
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
var maxWidthMap = [
|
var maxWidthMap = [
|
||||||
{ screenWidth: 0, maxWidth: 600 },
|
{ screenWidth: 0, maxWidth: 600 },
|
||||||
@ -154,9 +169,9 @@ define([
|
|||||||
});
|
});
|
||||||
var navbarMarginWidth = 18 * 2 + 25 + 25;
|
var navbarMarginWidth = 18 * 2 + 25 + 25;
|
||||||
var buttonsDropdownWidth = 40;
|
var buttonsDropdownWidth = 40;
|
||||||
var titleMinWidth = 200;
|
|
||||||
var workingIndicatorWidth = 18 + 70;
|
var workingIndicatorWidth = 18 + 70;
|
||||||
function onResize() {
|
function onResize() {
|
||||||
|
var paddingBottom = wrapperL3.height - 60;
|
||||||
|
|
||||||
var editorPadding = (editor.elt.offsetWidth - getMaxWidth()) / 2;
|
var editorPadding = (editor.elt.offsetWidth - getMaxWidth()) / 2;
|
||||||
if(editorPadding < constants.EDITOR_DEFAULT_PADDING) {
|
if(editorPadding < constants.EDITOR_DEFAULT_PADDING) {
|
||||||
@ -164,6 +179,7 @@ define([
|
|||||||
}
|
}
|
||||||
editorContentElt.style.paddingLeft = editorPadding + 'px';
|
editorContentElt.style.paddingLeft = editorPadding + 'px';
|
||||||
editorContentElt.style.paddingRight = editorPadding + 'px';
|
editorContentElt.style.paddingRight = editorPadding + 'px';
|
||||||
|
editorContentElt.style.paddingBottom = paddingBottom + 'px';
|
||||||
editorMarginElt.style.width = editorPadding + 'px';
|
editorMarginElt.style.width = editorPadding + 'px';
|
||||||
|
|
||||||
var previewPadding = (previewContainer.elt.offsetWidth - getMaxWidth()) / 2;
|
var previewPadding = (previewContainer.elt.offsetWidth - getMaxWidth()) / 2;
|
||||||
@ -172,6 +188,7 @@ define([
|
|||||||
}
|
}
|
||||||
previewContentElt.style.paddingLeft = previewPadding + 'px';
|
previewContentElt.style.paddingLeft = previewPadding + 'px';
|
||||||
previewContentElt.style.paddingRight = previewPadding + 'px';
|
previewContentElt.style.paddingRight = previewPadding + 'px';
|
||||||
|
previewContentElt.style.paddingBottom = paddingBottom + 'px';
|
||||||
|
|
||||||
if(!window.viewerMode) {
|
if(!window.viewerMode) {
|
||||||
var maxWidth = navbarMarginWidth + workingIndicatorWidth + titleMinWidth + buttonsDropdownWidth;
|
var maxWidth = navbarMarginWidth + workingIndicatorWidth + titleMinWidth + buttonsDropdownWidth;
|
||||||
@ -322,11 +339,11 @@ define([
|
|||||||
navbarToggler = new DomObject('.layout-toggler-navbar');
|
navbarToggler = new DomObject('.layout-toggler-navbar');
|
||||||
previewToggler = new DomObject('.layout-toggler-preview');
|
previewToggler = new DomObject('.layout-toggler-preview');
|
||||||
previewResizer = new DomObject('.layout-resizer-preview');
|
previewResizer = new DomObject('.layout-resizer-preview');
|
||||||
|
previewButtons = new DomObject('.extension-preview-buttons');
|
||||||
|
|
||||||
editorContentElt = editor.elt.querySelector('.editor-content');
|
editorContentElt = editor.elt.querySelector('.editor-content');
|
||||||
previewContentElt = document.getElementById('preview-contents');
|
previewContentElt = document.getElementById('preview-contents');
|
||||||
editorMarginElt = editor.elt.querySelector('.editor-margin');
|
editorMarginElt = editor.elt.querySelector('.editor-margin');
|
||||||
var $previewButtonsElt = $('.extension-preview-buttons');
|
|
||||||
navbarInnerElt = navbar.elt.querySelector('.navbar-inner');
|
navbarInnerElt = navbar.elt.querySelector('.navbar-inner');
|
||||||
navbarDropdownElt = navbar.elt.querySelector('.buttons-dropdown .dropdown-menu');
|
navbarDropdownElt = navbar.elt.querySelector('.buttons-dropdown .dropdown-menu');
|
||||||
$navbarDropdownBtnElt = navbar.$elt.find('.buttons-dropdown');
|
$navbarDropdownBtnElt = navbar.$elt.find('.buttons-dropdown');
|
||||||
@ -354,7 +371,7 @@ define([
|
|||||||
|
|
||||||
previewPanel.isOpen = true;
|
previewPanel.isOpen = true;
|
||||||
previewPanel.createToggler(false, function(isOpen) {
|
previewPanel.createToggler(false, function(isOpen) {
|
||||||
$previewButtonsElt.toggleClass('hide', !isOpen);
|
previewButtons.$elt.toggleClass('hide', !isOpen);
|
||||||
eventMgr.onPreviewToggle(isOpen);
|
eventMgr.onPreviewToggle(isOpen);
|
||||||
});
|
});
|
||||||
previewPanel.halfSize = true;
|
previewPanel.halfSize = true;
|
||||||
@ -368,57 +385,39 @@ define([
|
|||||||
documentPanel.createToggler(true);
|
documentPanel.createToggler(true);
|
||||||
documentPanel.$elt.find('.toggle-button').click(_.bind(documentPanel.toggle, documentPanel));
|
documentPanel.$elt.find('.toggle-button').click(_.bind(documentPanel.toggle, documentPanel));
|
||||||
|
|
||||||
// Hide menu panel when clicking 'Save as' button
|
// Gesture events
|
||||||
menuPanel.$elt.on('click', 'a[data-toggle!=collapse]', _.bind(menuPanel.toggle, menuPanel, false));
|
previewResizer.initHammer(true);
|
||||||
documentPanel.$elt.on('click', 'a[data-toggle!=collapse]', _.bind(documentPanel.toggle, documentPanel, false));
|
/*
|
||||||
|
navbar.initHammer();
|
||||||
|
menuPanel.initHammer();
|
||||||
|
documentPanel.initHammer();
|
||||||
|
previewButtons.initHammer();
|
||||||
|
|
||||||
menuPanel.$elt.on('show.bs.collapse', function() {
|
navbar.hammer.on('swiperight', _.bind(menuPanel.toggle, menuPanel, true));
|
||||||
// Close all open sub-menus when one submenu opens
|
navbar.hammer.on('swipeleft', _.bind(documentPanel.toggle, documentPanel, true));
|
||||||
menuPanel.$elt.find('.in').collapse('hide');
|
navbar.hammer.on('swipeup', _.bind(navbar.toggle, navbar, false));
|
||||||
});
|
|
||||||
|
|
||||||
var isDragging = false;
|
menuPanel.hammer.on('swiperight', _.bind(menuPanel.toggle, menuPanel, true));
|
||||||
var desiredWidth, desiredHeight;
|
menuPanel.hammer.on('swipeleft', _.bind(menuPanel.toggle, menuPanel, false));
|
||||||
var lastCoord;
|
|
||||||
wrapperL1.$elt.on('mousemove', function(evt) {
|
documentPanel.hammer.on('swipeleft', _.bind(documentPanel.toggle, documentPanel, true));
|
||||||
if(!isDragging) {
|
documentPanel.hammer.on('swiperight', _.bind(documentPanel.toggle, documentPanel, false));
|
||||||
return;
|
*/
|
||||||
}
|
|
||||||
if(evt.which !== 1) {
|
var initialWidth, initialHeight;
|
||||||
isDragging = false;
|
previewResizer.hammer.on('dragstart', function() {
|
||||||
|
initialWidth = previewPanel.width;
|
||||||
|
initialHeight = previewPanel.height;
|
||||||
|
}).on('drag', function(evt) {
|
||||||
|
if(isVertical) {
|
||||||
|
previewPanel.height = initialHeight - evt.gesture.deltaY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var newCoord = {
|
previewPanel.width = initialWidth - evt.gesture.deltaX;
|
||||||
x: evt.pageX,
|
|
||||||
y: evt.pageY,
|
|
||||||
};
|
|
||||||
if(isVertical && lastCoord.y !== newCoord.y) {
|
|
||||||
desiredHeight += lastCoord.y - newCoord.y;
|
|
||||||
previewPanel.height = desiredHeight;
|
|
||||||
previewPanel.halfSize = false;
|
|
||||||
resizeAll();
|
|
||||||
}
|
|
||||||
if(!isVertical && lastCoord.x !== newCoord.x) {
|
|
||||||
desiredWidth += lastCoord.x - newCoord.x;
|
|
||||||
previewPanel.width = desiredWidth;
|
|
||||||
previewPanel.halfSize = false;
|
|
||||||
resizeAll();
|
|
||||||
}
|
|
||||||
lastCoord = newCoord;
|
|
||||||
evt.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
previewResizer.$elt.on('mousedown', function(evt) {
|
|
||||||
if(evt.which === 1) {
|
|
||||||
isDragging = true;
|
|
||||||
desiredWidth = previewPanel.width;
|
|
||||||
desiredHeight = previewPanel.height;
|
|
||||||
lastCoord = {
|
|
||||||
x: evt.pageX,
|
|
||||||
y: evt.pageY,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
evt.gesture.preventDefault();
|
||||||
|
previewPanel.halfSize = false;
|
||||||
|
resizeAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
var isModalShown = false;
|
var isModalShown = false;
|
||||||
@ -431,6 +430,15 @@ define([
|
|||||||
isModalShown = false;
|
isModalShown = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Hide panels when clicking on a non collapse element
|
||||||
|
menuPanel.$elt.on('click', 'a[data-toggle!=collapse]', _.bind(menuPanel.toggle, menuPanel, false));
|
||||||
|
documentPanel.$elt.on('click', 'a[data-toggle!=collapse]', _.bind(documentPanel.toggle, documentPanel, false));
|
||||||
|
|
||||||
|
// In menu panel, close all open sub-menus when one submenu opens
|
||||||
|
menuPanel.$elt.on('show.bs.collapse', function() {
|
||||||
|
menuPanel.$elt.find('.in').collapse('hide');
|
||||||
|
});
|
||||||
|
|
||||||
// Configure Mousetrap
|
// Configure Mousetrap
|
||||||
mousetrap.stopCallback = function() {
|
mousetrap.stopCallback = function() {
|
||||||
return menuPanel.isOpen || documentPanel.isOpen || isModalShown;
|
return menuPanel.isOpen || documentPanel.isOpen || isModalShown;
|
||||||
@ -469,11 +477,36 @@ define([
|
|||||||
style.innerHTML = styleContent;
|
style.innerHTML = styleContent;
|
||||||
document.head.appendChild(style);
|
document.head.appendChild(style);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
resizeAll();
|
resizeAll();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eventMgr.addListener('onReady', function() {
|
||||||
|
var previewButtonsOffset = previewButtons.elt.offsetWidth + 5;
|
||||||
|
function openPreviewButtons() {
|
||||||
|
clearTimeout(closeTimeoutId);
|
||||||
|
previewButtons.x = 0;
|
||||||
|
previewButtons.applyCss();
|
||||||
|
}
|
||||||
|
var closeTimeoutId;
|
||||||
|
var dropdownOpen = false;
|
||||||
|
function closePreviewButtons() {
|
||||||
|
clearTimeout(closeTimeoutId);
|
||||||
|
closeTimeoutId = setTimeout(function() {
|
||||||
|
if(!dropdownOpen) {
|
||||||
|
previewButtons.x = previewButtonsOffset;
|
||||||
|
previewButtons.applyCss();
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
closePreviewButtons();
|
||||||
|
previewButtons.$elt.hover(openPreviewButtons, closePreviewButtons).on('show.bs.dropdown', function() {
|
||||||
|
dropdownOpen = true;
|
||||||
|
}).on('hidden.bs.dropdown', function() {
|
||||||
|
dropdownOpen = false;
|
||||||
|
closePreviewButtons();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
eventMgr.onLayoutCreated(layout);
|
eventMgr.onLayoutCreated(layout);
|
||||||
return layout;
|
return layout;
|
||||||
});
|
});
|
||||||
|
@ -59,7 +59,8 @@ requirejs.config({
|
|||||||
'rangy-cssclassapplier': 'bower-libs/rangy/rangy-cssclassapplier',
|
'rangy-cssclassapplier': 'bower-libs/rangy/rangy-cssclassapplier',
|
||||||
diff_match_patch: 'bower-libs/google-diff-match-patch-js/diff_match_patch',
|
diff_match_patch: 'bower-libs/google-diff-match-patch-js/diff_match_patch',
|
||||||
diff_match_patch_uncompressed: 'bower-libs/google-diff-match-patch-js/diff_match_patch_uncompressed',
|
diff_match_patch_uncompressed: 'bower-libs/google-diff-match-patch-js/diff_match_patch_uncompressed',
|
||||||
jsondiffpatch: 'bower-libs/jsondiffpatch/build/bundle'
|
jsondiffpatch: 'bower-libs/jsondiffpatch/build/bundle',
|
||||||
|
hammerjs: 'bower-libs/hammerjs/hammer'
|
||||||
},
|
},
|
||||||
shim: {
|
shim: {
|
||||||
underscore: {
|
underscore: {
|
||||||
|
@ -262,14 +262,14 @@ define([
|
|||||||
// Initialize the AutoSync dialog fields
|
// Initialize the AutoSync dialog fields
|
||||||
gdriveProvider.setAutosyncDialogConfig = function() {
|
gdriveProvider.setAutosyncDialogConfig = function() {
|
||||||
var config = gdriveProvider.autosyncConfig;
|
var config = gdriveProvider.autosyncConfig;
|
||||||
utils.setInputChecked('#input-autosync-' + providerId + '-enabled', config.enabled);
|
utils.setInputRadio('radio-autosync-' + providerId + '-mode', config.mode || 'off');
|
||||||
utils.setInputValue('#input-autosync-' + providerId + '-parentid', config.parentId);
|
utils.setInputValue('#input-autosync-' + providerId + '-parentid', config.parentId);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Retrieve the AutoSync dialog fields
|
// Retrieve the AutoSync dialog fields
|
||||||
gdriveProvider.getAutosyncDialogConfig = function() {
|
gdriveProvider.getAutosyncDialogConfig = function() {
|
||||||
var config = {};
|
var config = {};
|
||||||
config.enabled = utils.getInputChecked('#input-autosync-' + providerId + '-enabled');
|
config.mode = utils.getInputRadio('radio-autosync-' + providerId + '-mode');
|
||||||
config.parentId = utils.getInputTextValue('#input-autosync-' + providerId + '-parentid');
|
config.parentId = utils.getInputTextValue('#input-autosync-' + providerId + '-parentid');
|
||||||
return config;
|
return config;
|
||||||
};
|
};
|
||||||
|
@ -297,9 +297,7 @@ define([
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
$(".action-process-publish").click(performNewLocation);
|
$(".action-process-publish").click(performNewLocation);
|
||||||
$(".action-update-publication").click(publisher.publish);
|
|
||||||
|
|
||||||
var $customTmplCollapseElt = $('.publish-custom-template-collapse').collapse({
|
var $customTmplCollapseElt = $('.publish-custom-template-collapse').collapse({
|
||||||
toggle: false
|
toggle: false
|
||||||
|
@ -288,6 +288,7 @@ kbd {
|
|||||||
// Custom icons (not from Font Awesome)
|
// Custom icons (not from Font Awesome)
|
||||||
.icon-code {
|
.icon-code {
|
||||||
font-size: 83%;
|
font-size: 83%;
|
||||||
|
line-height: 1.65em;
|
||||||
&:before {
|
&:before {
|
||||||
margin-left: 0.1em;
|
margin-left: 0.1em;
|
||||||
margin-right: 0.6em;
|
margin-right: 0.6em;
|
||||||
|
@ -111,6 +111,7 @@
|
|||||||
@btn-info-color: fade(@secondary-desaturated, 35%);
|
@btn-info-color: fade(@secondary-desaturated, 35%);
|
||||||
@btn-info-bg: @transparent;
|
@btn-info-bg: @transparent;
|
||||||
@btn-info-border: @transparent;
|
@btn-info-border: @transparent;
|
||||||
|
@btn-info-hover-border: fade(@secondary, 8%);
|
||||||
@btn-info-hover-bg: lighten(@secondary-desaturated, 45%);
|
@btn-info-hover-bg: lighten(@secondary-desaturated, 45%);
|
||||||
@gray-lighter: @body-bg;
|
@gray-lighter: @body-bg;
|
||||||
@modal-header-border-color: @secondary-border-color-light;
|
@modal-header-border-color: @secondary-border-color-light;
|
||||||
@ -318,7 +319,7 @@ a {
|
|||||||
.info-tooltip &,
|
.info-tooltip &,
|
||||||
.open &.dropdown-toggle {
|
.open &.dropdown-toggle {
|
||||||
color: darken(@secondary, 30%);
|
color: darken(@secondary, 30%);
|
||||||
border-color: fade(@secondary, 8%);
|
border-color: @btn-info-hover-border;
|
||||||
background-color: @btn-info-hover-bg !important; // important to override .nav > li > a:hover
|
background-color: @btn-info-hover-bg !important; // important to override .nav > li > a:hover
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -583,10 +584,17 @@ a {
|
|||||||
.layout-panel();
|
.layout-panel();
|
||||||
width: @menu-panel-width;
|
width: @menu-panel-width;
|
||||||
.alert {
|
.alert {
|
||||||
padding: 15px 0;
|
padding: 10px 0;
|
||||||
}
|
}
|
||||||
|
i {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
small {
|
||||||
|
color: @dropdown-header-color;
|
||||||
|
padding-left: 30px;
|
||||||
|
}
|
||||||
.nav {
|
.nav {
|
||||||
margin: 20px 0;
|
margin: 10px 0 20px;
|
||||||
> li > * {
|
> li > * {
|
||||||
padding: 8px 30px;
|
padding: 8px 30px;
|
||||||
}
|
}
|
||||||
@ -794,18 +802,20 @@ a {
|
|||||||
.extension-preview-buttons {
|
.extension-preview-buttons {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
right: 35px;
|
right: 50px;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
.ui-layout-resizer-south-closed & {
|
background-color: @btn-info-hover-bg;
|
||||||
display: none !important;
|
border: 1px solid @btn-info-hover-border;
|
||||||
}
|
border-radius: @border-radius-base;
|
||||||
|
.transition-transform(350ms ease-in-out);
|
||||||
.btn-group {
|
.btn-group {
|
||||||
.btn {
|
.btn {
|
||||||
position: initial;
|
position: initial;
|
||||||
|
border: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
margin-top: 4px;
|
margin-top: 6px;
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1435,10 +1445,6 @@ div.dropdown-menu, {
|
|||||||
z-index: 1040 !important;
|
z-index: 1040 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-import-image-gplus {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip-inner {
|
.tooltip-inner {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
@ -1614,10 +1620,6 @@ div.jGrowl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-layout-toggler {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar .file-title-navbar {
|
.navbar .file-title-navbar {
|
||||||
cursor: initial;
|
cursor: initial;
|
||||||
.box-shadow(none);
|
.box-shadow(none);
|
||||||
|
@ -74,118 +74,149 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Standard synchronization
|
* Synchronization
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
// Recursive function to upload a single file on multiple locations
|
|
||||||
var uploadSyncAttributesList = [];
|
|
||||||
var uploadContent;
|
|
||||||
var uploadContentCRC;
|
|
||||||
var uploadTitle;
|
|
||||||
var uploadTitleCRC;
|
|
||||||
var uploadDiscussionList;
|
|
||||||
var uploadDiscussionListCRC;
|
|
||||||
function locationUp(callback) {
|
|
||||||
|
|
||||||
// No more synchronized location for this document
|
|
||||||
if(uploadSyncAttributesList.length === 0) {
|
|
||||||
return fileUp(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dequeue a synchronized location
|
|
||||||
var syncAttributes = uploadSyncAttributesList.pop();
|
|
||||||
|
|
||||||
syncAttributes.provider.syncUp(
|
|
||||||
uploadContent,
|
|
||||||
uploadContentCRC,
|
|
||||||
uploadTitle,
|
|
||||||
uploadTitleCRC,
|
|
||||||
uploadDiscussionList,
|
|
||||||
uploadDiscussionListCRC,
|
|
||||||
syncAttributes,
|
|
||||||
function(error, uploadFlag) {
|
|
||||||
if(uploadFlag === true) {
|
|
||||||
// If uploadFlag is true, request another upload cycle
|
|
||||||
uploadCycle = true;
|
|
||||||
}
|
|
||||||
if(error) {
|
|
||||||
return callback(error);
|
|
||||||
}
|
|
||||||
if(uploadFlag) {
|
|
||||||
// Update syncAttributes in storage
|
|
||||||
utils.storeAttributes(syncAttributes);
|
|
||||||
}
|
|
||||||
locationUp(callback);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursive function to upload multiple files
|
|
||||||
var uploadFileList = [];
|
|
||||||
function fileUp(callback) {
|
|
||||||
|
|
||||||
// No more fileDesc to synchronize
|
|
||||||
if(uploadFileList.length === 0) {
|
|
||||||
return syncUp(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dequeue a fileDesc to synchronize
|
|
||||||
var fileDesc = uploadFileList.pop();
|
|
||||||
uploadSyncAttributesList = _.values(fileDesc.syncLocations);
|
|
||||||
if(uploadSyncAttributesList.length === 0) {
|
|
||||||
return fileUp(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get document title/content
|
|
||||||
uploadContent = fileDesc.content;
|
|
||||||
uploadContentCRC = utils.crc32(uploadContent);
|
|
||||||
uploadTitle = fileDesc.title;
|
|
||||||
uploadTitleCRC = utils.crc32(uploadTitle);
|
|
||||||
uploadDiscussionList = fileDesc.discussionListJSON;
|
|
||||||
uploadDiscussionListCRC = utils.crc32(uploadDiscussionList);
|
|
||||||
locationUp(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry point for up synchronization (upload changes)
|
// Entry point for up synchronization (upload changes)
|
||||||
var uploadCycle = false;
|
var uploadCycle = false;
|
||||||
function syncUp(callback) {
|
function syncUp(callback) {
|
||||||
|
var uploadFileList = [];
|
||||||
|
|
||||||
|
// Recursive function to upload multiple files
|
||||||
|
function fileUp() {
|
||||||
|
// No more fileDesc to synchronize
|
||||||
|
if(uploadFileList.length === 0) {
|
||||||
|
return syncUp(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dequeue a fileDesc to synchronize
|
||||||
|
var fileDesc = uploadFileList.pop();
|
||||||
|
var uploadSyncAttributesList = _.values(fileDesc.syncLocations);
|
||||||
|
if(uploadSyncAttributesList.length === 0) {
|
||||||
|
return fileUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
var uploadContent = fileDesc.content;
|
||||||
|
var uploadContentCRC = utils.crc32(uploadContent);
|
||||||
|
var uploadTitle = fileDesc.title;
|
||||||
|
var uploadTitleCRC = utils.crc32(uploadTitle);
|
||||||
|
var uploadDiscussionList = fileDesc.discussionListJSON;
|
||||||
|
var uploadDiscussionListCRC = utils.crc32(uploadDiscussionList);
|
||||||
|
|
||||||
|
// Recursive function to upload a single file on multiple locations
|
||||||
|
function locationUp() {
|
||||||
|
|
||||||
|
// No more synchronized location for this document
|
||||||
|
if(uploadSyncAttributesList.length === 0) {
|
||||||
|
return fileUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dequeue a synchronized location
|
||||||
|
var syncAttributes = uploadSyncAttributesList.pop();
|
||||||
|
|
||||||
|
syncAttributes.provider.syncUp(
|
||||||
|
uploadContent,
|
||||||
|
uploadContentCRC,
|
||||||
|
uploadTitle,
|
||||||
|
uploadTitleCRC,
|
||||||
|
uploadDiscussionList,
|
||||||
|
uploadDiscussionListCRC,
|
||||||
|
syncAttributes,
|
||||||
|
function(error, uploadFlag) {
|
||||||
|
if(uploadFlag === true) {
|
||||||
|
// If uploadFlag is true, request another upload cycle
|
||||||
|
uploadCycle = true;
|
||||||
|
}
|
||||||
|
if(error) {
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
if(uploadFlag) {
|
||||||
|
// Update syncAttributes in storage
|
||||||
|
utils.storeAttributes(syncAttributes);
|
||||||
|
}
|
||||||
|
locationUp();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
locationUp();
|
||||||
|
}
|
||||||
|
|
||||||
if(uploadCycle === true) {
|
if(uploadCycle === true) {
|
||||||
// New upload cycle
|
// New upload cycle
|
||||||
uploadCycle = false;
|
uploadCycle = false;
|
||||||
uploadFileList = _.values(fileSystem);
|
uploadFileList = _.values(fileSystem);
|
||||||
fileUp(callback);
|
fileUp();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursive function to download changes from multiple providers
|
|
||||||
var providerList = [];
|
|
||||||
function providerDown(callback) {
|
|
||||||
if(providerList.length === 0) {
|
|
||||||
return callback();
|
|
||||||
}
|
|
||||||
var provider = providerList.pop();
|
|
||||||
|
|
||||||
// Check that provider has files to sync
|
|
||||||
if(!synchronizer.hasSync(provider)) {
|
|
||||||
return providerDown(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform provider's syncDown
|
|
||||||
provider.syncDown(function(error) {
|
|
||||||
if(error) {
|
|
||||||
return callback(error);
|
|
||||||
}
|
|
||||||
providerDown(callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entry point for down synchronization (download changes)
|
// Entry point for down synchronization (download changes)
|
||||||
function syncDown(callback) {
|
function syncDown(callback) {
|
||||||
providerList = _.values(providerMap);
|
var providerList = _.values(providerMap);
|
||||||
providerDown(callback);
|
|
||||||
|
// Recursive function to download changes from multiple providers
|
||||||
|
function providerDown() {
|
||||||
|
if(providerList.length === 0) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var provider = providerList.pop();
|
||||||
|
|
||||||
|
// Check that provider has files to sync
|
||||||
|
if(!synchronizer.hasSync(provider)) {
|
||||||
|
return providerDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform provider's syncDown
|
||||||
|
provider.syncDown(function(error) {
|
||||||
|
if(error) {
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
providerDown();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
providerDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry point for the autosync feature
|
||||||
|
function autosyncAll(callback) {
|
||||||
|
var autosyncFileList = _.filter(fileSystem, function(fileDesc) {
|
||||||
|
return _.size(fileDesc.syncLocations) === 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Recursive function to autosync multiple files
|
||||||
|
function fileAutosync() {
|
||||||
|
// No more fileDesc to synchronize
|
||||||
|
if(autosyncFileList.length === 0) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var fileDesc = autosyncFileList.pop();
|
||||||
|
|
||||||
|
var providerList = _.filter(providerMap, function(provider) {
|
||||||
|
return provider.autosyncConfig.mode == 'all';
|
||||||
|
});
|
||||||
|
function providerAutosync() {
|
||||||
|
// No more provider
|
||||||
|
if(providerList.length === 0) {
|
||||||
|
return fileAutosync();
|
||||||
|
}
|
||||||
|
var provider = providerList.pop();
|
||||||
|
|
||||||
|
provider.autosyncFile(fileDesc.title, fileDesc.content, fileDesc.discussionListJSON, provider.autosyncConfig, function(error, syncAttributes) {
|
||||||
|
if(error) {
|
||||||
|
return callback(error);
|
||||||
|
}
|
||||||
|
fileDesc.addSyncLocation(syncAttributes);
|
||||||
|
eventMgr.onSyncExportSuccess(fileDesc, syncAttributes);
|
||||||
|
providerAutosync();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
providerAutosync();
|
||||||
|
}
|
||||||
|
|
||||||
|
fileAutosync();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen to offline status changes
|
// Listen to offline status changes
|
||||||
@ -214,17 +245,22 @@ define([
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
syncDown(function(error) {
|
autosyncAll(function(error) {
|
||||||
if(isError(error)) {
|
if(isError(error)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
syncUp(function(error) {
|
syncDown(function(error) {
|
||||||
if(isError(error)) {
|
if(isError(error)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
syncRunning = false;
|
syncUp(function(error) {
|
||||||
eventMgr.onSyncRunning(false);
|
if(isError(error)) {
|
||||||
eventMgr.onSyncSuccess();
|
return;
|
||||||
|
}
|
||||||
|
syncRunning = false;
|
||||||
|
eventMgr.onSyncRunning(false);
|
||||||
|
eventMgr.onSyncSuccess();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
@ -261,7 +297,10 @@ define([
|
|||||||
eventMgr.addListener("onFileCreated", function(fileDesc) {
|
eventMgr.addListener("onFileCreated", function(fileDesc) {
|
||||||
if(_.size(fileDesc.syncLocations) === 0) {
|
if(_.size(fileDesc.syncLocations) === 0) {
|
||||||
_.each(providerMap, function(provider) {
|
_.each(providerMap, function(provider) {
|
||||||
provider.autosyncConfig.enabled && provider.autosyncFile(fileDesc.title, fileDesc.content, fileDesc.discussionListJSON, provider.autosyncConfig, function(error, syncAttributes) {
|
if(provider.autosyncConfig.mode != 'new') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
provider.autosyncFile(fileDesc.title, fileDesc.content, fileDesc.discussionListJSON, provider.autosyncConfig, function(error, syncAttributes) {
|
||||||
if(error) {
|
if(error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<link rel="shortcut icon" href="res-min/img/stackedit-32.ico" type="image/x-icon">
|
<link rel="shortcut icon" href="res-min/img/stackedit-32.ico" type="image/x-icon">
|
||||||
<meta name="description" content="Full-featured, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites.">
|
<meta name="description" content="Full-featured, open-source Markdown editor based on PageDown, the Markdown library used by Stack Overflow and the other Stack Exchange sites.">
|
||||||
<meta name="author" content="Benoit Schweblin">
|
<meta name="author" content="Benoit Schweblin">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
<meta name="msvalidate.01" content="5E47EE6F67B069C17E3CDD418351A612"
|
<meta name="msvalidate.01" content="5E47EE6F67B069C17E3CDD418351A612"
|
||||||
/>
|
/>
|
||||||
<script>
|
<script>
|
||||||
|
Loading…
Reference in New Issue
Block a user