Implemented fast defer
This commit is contained in:
parent
6d8ed95352
commit
ea77258cac
@ -214,9 +214,7 @@ define([
|
||||
patch = diffMatchPatch.patch_make(oldContent, diffs);
|
||||
var patchResult = diffMatchPatch.patch_apply(patch, remoteContent);
|
||||
newContent = patchResult[0];
|
||||
if(patchResult[1].some(function(patchSuccess) {
|
||||
return !patchSuccess;
|
||||
})) {
|
||||
if(!patchResult[1].every(_.identity)) {
|
||||
// Remaining conflicts
|
||||
diffs = diffMatchPatch.diff_main(localContent, newContent);
|
||||
diffs = cleanupDiffs(diffs);
|
||||
@ -328,8 +326,7 @@ define([
|
||||
}
|
||||
|
||||
if(contentChanged || discussionListChanged) {
|
||||
var self = this;
|
||||
editor.watcher.noWatch(function() {
|
||||
editor.watcher.noWatch(_.bind(function() {
|
||||
if(contentChanged) {
|
||||
if(!/\n$/.test(newContent)) {
|
||||
newContent += '\n';
|
||||
@ -363,11 +360,11 @@ define([
|
||||
}
|
||||
editor.undoMgr.currentMode = 'sync';
|
||||
editor.undoMgr.saveState();
|
||||
eventMgr.onMessage('"' + remoteTitle + '" has been updated from ' + self.providerName + '.');
|
||||
eventMgr.onMessage('"' + remoteTitle + '" has been updated from ' + this.providerName + '.');
|
||||
if(conflictList.length) {
|
||||
eventMgr.onMessage('"' + remoteTitle + '" has conflicts that you have to review.');
|
||||
}
|
||||
});
|
||||
}), this);
|
||||
}
|
||||
|
||||
// Return remote CRCs
|
||||
|
@ -826,7 +826,7 @@ define([
|
||||
if(openedTooltip && openedTooltip[0] === elt) {
|
||||
return;
|
||||
}
|
||||
_.defer(function() {
|
||||
utils.defer(function() {
|
||||
$(document).on("click.close-tooltip", function() {
|
||||
openedTooltip && openedTooltip.tooltip('hide');
|
||||
openedTooltip = undefined;
|
||||
|
@ -3,6 +3,7 @@
|
||||
define([
|
||||
'jquery',
|
||||
'underscore',
|
||||
'utils',
|
||||
'settings',
|
||||
'eventMgr',
|
||||
'prism-core',
|
||||
@ -12,7 +13,7 @@ define([
|
||||
'rangy',
|
||||
'MutationObservers',
|
||||
'libs/prism-markdown'
|
||||
], function ($, _, settings, eventMgr, Prism, diff_match_patch, jsondiffpatch, crel, rangy) {
|
||||
], function ($, _, utils, settings, eventMgr, Prism, diff_match_patch, jsondiffpatch, crel, rangy) {
|
||||
|
||||
var editor = {};
|
||||
var scrollTop = 0;
|
||||
@ -213,7 +214,7 @@ define([
|
||||
}
|
||||
undoMgr.saveSelectionState();
|
||||
}
|
||||
var debouncedSave = _.debounce(save, 0);
|
||||
var debouncedSave = utils.debounce(save);
|
||||
return function(debounced) {
|
||||
debounced ? debouncedSave() : save();
|
||||
};
|
||||
@ -287,12 +288,10 @@ define([
|
||||
}
|
||||
var selectionMgr = new SelectionMgr();
|
||||
editor.selectionMgr = selectionMgr;
|
||||
$(document).on('selectionchange', function() {
|
||||
selectionMgr.saveSelectionState(true);
|
||||
});
|
||||
$(document).on('selectionchange', _.bind(selectionMgr.saveSelectionState, selectionMgr, true));
|
||||
|
||||
var adjustCursorPosition = (function() {
|
||||
var adjust = _.debounce(function() {
|
||||
var adjust = utils.debounce(function() {
|
||||
var adjust = inputElt.offsetHeight / 2;
|
||||
if(adjust > 130) {
|
||||
adjust = 130;
|
||||
@ -305,7 +304,7 @@ define([
|
||||
else if(selectionMgr.cursorY > cursorMaxY) {
|
||||
inputElt.scrollTop += selectionMgr.cursorY - cursorMaxY;
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
return function() {
|
||||
if(inputElt === undefined) {
|
||||
return;
|
||||
@ -365,7 +364,7 @@ define([
|
||||
};
|
||||
this.setMode = function() {}; // For compatibility with PageDown
|
||||
this.onButtonStateChange = function() {}; // To be overridden by PageDown
|
||||
this.saveState = _.debounce(function() {
|
||||
this.saveState = utils.debounce(function() {
|
||||
redoStack = [];
|
||||
var currentTime = Date.now();
|
||||
if(this.currentMode == 'comment' || (this.currentMode != lastMode && lastMode != 'newlines') || currentTime - lastTime > 1000) {
|
||||
@ -391,7 +390,7 @@ define([
|
||||
lastMode = this.currentMode;
|
||||
this.currentMode = undefined;
|
||||
this.onButtonStateChange();
|
||||
}, 0);
|
||||
}, this);
|
||||
this.saveSelectionState = _.debounce(function() {
|
||||
if(this.currentMode === undefined) {
|
||||
selectionStartBefore = selectionMgr.selectionStart;
|
||||
@ -404,7 +403,6 @@ define([
|
||||
this.canRedo = function() {
|
||||
return redoStack.length;
|
||||
};
|
||||
var self = this;
|
||||
function restoreState(state, selectionStart, selectionEnd) {
|
||||
// Update editor
|
||||
watcher.noWatch(function() {
|
||||
@ -439,9 +437,9 @@ define([
|
||||
selectionStartBefore = selectionStart;
|
||||
selectionEndBefore = selectionEnd;
|
||||
currentState = state;
|
||||
self.currentMode = undefined;
|
||||
this.currentMode = undefined;
|
||||
lastMode = undefined;
|
||||
self.onButtonStateChange();
|
||||
this.onButtonStateChange();
|
||||
adjustCursorPosition();
|
||||
}
|
||||
this.undo = function() {
|
||||
@ -450,7 +448,7 @@ define([
|
||||
return;
|
||||
}
|
||||
redoStack.push(currentState);
|
||||
restoreState(state, currentState.selectionStartBefore, currentState.selectionEndBefore);
|
||||
restoreState.call(this, state, currentState.selectionStartBefore, currentState.selectionEndBefore);
|
||||
};
|
||||
this.redo = function() {
|
||||
var state = redoStack.pop();
|
||||
@ -458,7 +456,7 @@ define([
|
||||
return;
|
||||
}
|
||||
undoStack.push(currentState);
|
||||
restoreState(state, state.selectionStartAfter, state.selectionEndAfter);
|
||||
restoreState.call(this, state, state.selectionStartAfter, state.selectionEndAfter);
|
||||
};
|
||||
this.init = function() {
|
||||
var content = fileDesc.content;
|
||||
@ -481,7 +479,7 @@ define([
|
||||
|
||||
function onComment() {
|
||||
if(watcher.isWatching === true) {
|
||||
undoMgr.currentMode = 'comment';
|
||||
undoMgr.currentMode = undoMgr.currentMode || 'comment';
|
||||
undoMgr.saveState();
|
||||
}
|
||||
}
|
||||
@ -490,19 +488,19 @@ define([
|
||||
eventMgr.addListener('onCommentsChanged', onComment);
|
||||
|
||||
function checkContentChange() {
|
||||
var currentTextContent = inputElt.textContent;
|
||||
var newTextContent = inputElt.textContent;
|
||||
if(fileChanged === false) {
|
||||
if(currentTextContent == textContent) {
|
||||
if(newTextContent == textContent) {
|
||||
return;
|
||||
}
|
||||
if(!/\n$/.test(currentTextContent)) {
|
||||
currentTextContent += '\n';
|
||||
if(!/\n$/.test(newTextContent)) {
|
||||
newTextContent += '\n';
|
||||
}
|
||||
undoMgr.currentMode = undoMgr.currentMode || 'typing';
|
||||
var discussionList = _.values(fileDesc.discussionList);
|
||||
fileDesc.newDiscussion && discussionList.push(fileDesc.newDiscussion);
|
||||
var updateDiscussionList = adjustCommentOffsets(textContent, currentTextContent, discussionList);
|
||||
textContent = currentTextContent;
|
||||
var updateDiscussionList = adjustCommentOffsets(textContent, newTextContent, discussionList);
|
||||
textContent = newTextContent;
|
||||
if(updateDiscussionList === true) {
|
||||
fileDesc.discussionList = fileDesc.discussionList; // Write discussionList in localStorage
|
||||
}
|
||||
@ -513,11 +511,11 @@ define([
|
||||
undoMgr.saveState();
|
||||
}
|
||||
else {
|
||||
if(!/\n$/.test(currentTextContent)) {
|
||||
currentTextContent += '\n';
|
||||
fileDesc.content = currentTextContent;
|
||||
textContent = newTextContent;
|
||||
if(!/\n$/.test(textContent)) {
|
||||
textContent += '\n';
|
||||
fileDesc.content = textContent;
|
||||
}
|
||||
textContent = currentTextContent;
|
||||
selectionMgr.setSelectionStartEnd(fileDesc.editorStart, fileDesc.editorEnd);
|
||||
eventMgr.onFileOpen(fileDesc, textContent);
|
||||
previewElt.scrollTop = fileDesc.previewScrollTop;
|
||||
@ -575,10 +573,10 @@ define([
|
||||
}
|
||||
editor.adjustCommentOffsets = adjustCommentOffsets;
|
||||
|
||||
editor.init = function(elt1, elt2) {
|
||||
inputElt = elt1;
|
||||
editor.init = function(inputEltParam, previewEltParam) {
|
||||
inputElt = inputEltParam;
|
||||
$inputElt = $(inputElt);
|
||||
previewElt = elt2;
|
||||
previewElt = previewEltParam;
|
||||
|
||||
contentElt = crel('div', {
|
||||
class: 'editor-content',
|
||||
@ -676,9 +674,7 @@ define([
|
||||
clearNewline = false;
|
||||
}
|
||||
})
|
||||
.on('mouseup', function() {
|
||||
selectionMgr.saveSelectionState(true);
|
||||
})
|
||||
.on('mouseup', _.bind(selectionMgr.saveSelectionState, selectionMgr, true))
|
||||
.on('paste', function () {
|
||||
undoMgr.currentMode = 'paste';
|
||||
adjustCursorPosition();
|
||||
|
@ -228,7 +228,7 @@ define([
|
||||
logger.log("onAsyncPreview");
|
||||
function recursiveCall(callbackList) {
|
||||
var callback = callbackList.length ? callbackList.shift() : function() {
|
||||
_.defer(function() {
|
||||
setTimeout(function() {
|
||||
var html = "";
|
||||
_.each(previewContentsElt.children, function(elt) {
|
||||
html += elt.innerHTML;
|
||||
@ -236,7 +236,7 @@ define([
|
||||
var htmlWithComments = utils.trim(html);
|
||||
var htmlWithoutComments = htmlWithComments.replace(/ <span class="comment label label-danger">.*?<\/span> /g, '');
|
||||
onPreviewFinished(htmlWithComments, htmlWithoutComments);
|
||||
});
|
||||
}, 10);
|
||||
};
|
||||
callback(function() {
|
||||
recursiveCall(callbackList);
|
||||
|
@ -44,14 +44,14 @@ define([
|
||||
buttonHtmlCode.onReady = function() {
|
||||
var textareaElt = document.getElementById('input-html-code');
|
||||
$(".action-html-code").click(function() {
|
||||
_.defer(function() {
|
||||
setTimeout(function() {
|
||||
$("#input-html-code").each(function() {
|
||||
if($(this).is(":hidden")) {
|
||||
return;
|
||||
}
|
||||
this.select();
|
||||
});
|
||||
});
|
||||
}, 10);
|
||||
}).parent().on('show.bs.dropdown', function() {
|
||||
try {
|
||||
var htmlCode = _.template(buttonHtmlCode.config.template, {
|
||||
|
@ -170,7 +170,7 @@ define([
|
||||
marginElt.appendChild(commentElt);
|
||||
commentEltMap[discussion.discussionIndex] = commentElt;
|
||||
|
||||
if(currentContext && currentContext.getDiscussion() == discussion) {
|
||||
if(currentContext && currentContext.getDiscussion() === discussion) {
|
||||
inputElt.scrollTop += parseInt(commentElt.style.top) - inputElt.scrollTop - inputElt.offsetHeight * 3 / 4;
|
||||
movePopover(commentElt);
|
||||
}
|
||||
@ -179,6 +179,7 @@ define([
|
||||
clearTimeout(refreshTimeoutId);
|
||||
refreshTimeoutId = setTimeout(refreshOne, 5);
|
||||
}, 50);
|
||||
comments.onLayoutResize = refreshDiscussions;
|
||||
|
||||
comments.onFileOpen = function(fileDesc) {
|
||||
currentFileDesc = fileDesc;
|
||||
@ -237,10 +238,6 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
comments.onLayoutResize = function() {
|
||||
refreshDiscussions();
|
||||
};
|
||||
|
||||
function getDiscussionComments() {
|
||||
var discussion = currentContext.getDiscussion();
|
||||
var author = storage['author.name'];
|
||||
@ -310,15 +307,10 @@ define([
|
||||
closeCurrentPopover();
|
||||
var context = new Context(evt.target, currentFileDesc);
|
||||
currentContext = context;
|
||||
inputElt.scrollTop += parseInt(evt.target.style.top) - inputElt.scrollTop - inputElt.offsetHeight * 3 / 4;
|
||||
|
||||
// If it's an existing discussion
|
||||
// If it's not an existing discussion
|
||||
var discussion = context.getDiscussion();
|
||||
if(discussion) {
|
||||
context.selectionRange = selectionMgr.setSelectionStartEnd(discussion.selectionStart, discussion.selectionEnd, undefined, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!discussion) {
|
||||
// Get selected text
|
||||
var selectionStart = Math.min(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
||||
var selectionEnd = Math.max(selectionMgr.selectionStart, selectionMgr.selectionEnd);
|
||||
@ -327,12 +319,16 @@ define([
|
||||
selectionStart = offset.start;
|
||||
selectionEnd = offset.end;
|
||||
}
|
||||
context.selectionRange = selectionMgr.setSelectionStartEnd(selectionStart, selectionEnd, undefined, true);
|
||||
currentFileDesc.newDiscussion = {
|
||||
discussion = {
|
||||
selectionStart: selectionStart,
|
||||
selectionEnd: selectionEnd,
|
||||
commentList: []
|
||||
};
|
||||
currentFileDesc.newDiscussion = discussion;
|
||||
}
|
||||
context.selectionRange = selectionMgr.setSelectionStartEnd(discussion.selectionStart, discussion.selectionEnd, undefined, true);
|
||||
inputElt.scrollTop += parseInt(evt.target.style.top) - inputElt.scrollTop - inputElt.offsetHeight * 3 / 4;
|
||||
|
||||
}).on('shown.bs.popover', '#wmd-input > .editor-margin', function(evt) {
|
||||
var context = currentContext;
|
||||
var popoverElt = context.getPopoverElt();
|
||||
|
@ -130,9 +130,9 @@ define([
|
||||
liIndex = -1;
|
||||
}
|
||||
selectedLi = liEltList[(liIndex + liEltList.length) % liEltList.length];
|
||||
_.defer(function() {
|
||||
setTimeout(function() {
|
||||
selectedLi.find("a").focus();
|
||||
});
|
||||
}, 10);
|
||||
return false;
|
||||
});
|
||||
var shortcutNext = documentSelector.config.shortcutNext.toLowerCase();
|
||||
@ -143,9 +143,9 @@ define([
|
||||
}
|
||||
var liIndex = _.indexOf(liEltList, selectedLi) + 1;
|
||||
selectedLi = liEltList[liIndex % liEltList.length];
|
||||
_.defer(function() {
|
||||
setTimeout(function() {
|
||||
selectedLi.find("a").focus();
|
||||
});
|
||||
}, 10);
|
||||
return false;
|
||||
});
|
||||
var delimiter1 = shortcutPrevious.indexOf("+");
|
||||
|
@ -143,9 +143,9 @@ define([
|
||||
$previewElt.scrollTop(lastPreviewScrollTop);
|
||||
},
|
||||
done: function() {
|
||||
_.defer(function() {
|
||||
setTimeout(function() {
|
||||
isPreviewMoving = false;
|
||||
});
|
||||
}, 10);
|
||||
},
|
||||
}).dequeue('scrollLinkFx');
|
||||
|
||||
@ -179,9 +179,9 @@ define([
|
||||
$editorElt.scrollTop(lastEditorScrollTop);
|
||||
},
|
||||
done: function() {
|
||||
_.defer(function() {
|
||||
setTimeout(function() {
|
||||
isEditorMoving = false;
|
||||
});
|
||||
}, 10);
|
||||
},
|
||||
}).dequeue('scrollLinkFx');
|
||||
}
|
||||
|
@ -186,9 +186,9 @@ define([
|
||||
}
|
||||
$fileTitleElt.addClass('hide');
|
||||
var fileTitleInput = $fileTitleInputElt.removeClass('hide');
|
||||
_.defer(function() {
|
||||
setTimeout(function() {
|
||||
fileTitleInput.focus().get(0).select();
|
||||
});
|
||||
}, 10);
|
||||
});
|
||||
function applyTitle() {
|
||||
$fileTitleInputElt.addClass('hide');
|
||||
|
@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<a data-toggle="collapse" data-parent=".accordion-extensions"
|
||||
class="accordion-toggle" href="#accordion-extensions-collapse-<%= extensionId %>">
|
||||
<%= extensionName %> </a>
|
||||
<%= extensionName %> <i class="icon-down-dir"></i></a>
|
||||
</div>
|
||||
<div id="accordion-extensions-collapse-<%= extensionId %>" class="collapse">
|
||||
<div class="accordion-inner clearfix"><%= settingsBlock %></div>
|
||||
|
@ -568,8 +568,8 @@ define([
|
||||
});
|
||||
|
||||
// Also listen to "save success" event
|
||||
doc.addEventListener(gapi.drive.realtime.EventType.DOCUMENT_SAVE_STATE_CHANGED, function(e) {
|
||||
if(e.isPending === false && e.isSaving === false) {
|
||||
doc.addEventListener(gapi.drive.realtime.EventType.DOCUMENT_SAVE_STATE_CHANGED, function(evt) {
|
||||
if(evt.isPending === false && evt.isSaving === false) {
|
||||
updateCRCs();
|
||||
}
|
||||
});
|
||||
@ -587,16 +587,8 @@ define([
|
||||
setUndoRedoButtonStates = pagedownEditor.uiManager.setUndoRedoButtonStates;
|
||||
|
||||
// Set temporary actions for undo/redo buttons
|
||||
pagedownEditor.uiManager.buttons.undo.execute = function() {
|
||||
if(model.canUndo) {
|
||||
model.undo();
|
||||
}
|
||||
};
|
||||
pagedownEditor.uiManager.buttons.redo.execute = function() {
|
||||
if(model.canRedo) {
|
||||
model.redo();
|
||||
}
|
||||
};
|
||||
pagedownEditor.uiManager.buttons.undo.execute = model.undo;
|
||||
pagedownEditor.uiManager.buttons.redo.execute = model.redo;
|
||||
|
||||
// Add event handler for model's UndoRedoStateChanged events
|
||||
pagedownEditor.uiManager.setUndoRedoButtonStates = _.debounce(function() {
|
||||
@ -620,7 +612,7 @@ define([
|
||||
gdriveProvider.stopRealtimeSync();
|
||||
}
|
||||
else if(err.isFatal) {
|
||||
eventMgr.onError('An error has forced real time synchronization to stop.');
|
||||
eventMgr.onError('Real time synchronization is temporarily unavailable.');
|
||||
gdriveProvider.stopRealtimeSync();
|
||||
}
|
||||
});
|
||||
|
@ -1473,12 +1473,15 @@ input[type="file"] {
|
||||
color: @input-color;
|
||||
}
|
||||
.icon-comment {
|
||||
font-size: 14px;
|
||||
font-size: 15px;
|
||||
color: fade(@label-warning-bg, 60%);
|
||||
}
|
||||
.reply .icon-comment {
|
||||
color: fade(@label-danger-bg, 70%);
|
||||
}
|
||||
.new-comment-block .icon-comment {
|
||||
color: fade(@tertiary-color, 35%);
|
||||
}
|
||||
.input-comment-author {
|
||||
border: none;
|
||||
background: none;
|
||||
|
@ -10,6 +10,40 @@ define([
|
||||
|
||||
var utils = {};
|
||||
|
||||
// Faster than setTimeout (see http://dbaron.org/log/20100309-faster-timeouts)
|
||||
utils.defer = (function() {
|
||||
var timeouts = [];
|
||||
var messageName = "delay";
|
||||
window.addEventListener("message", function(evt) {
|
||||
if(evt.source == window && evt.data == messageName) {
|
||||
evt.stopPropagation();
|
||||
if(timeouts.length > 0) {
|
||||
timeouts.shift()();
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
return function(fn) {
|
||||
timeouts.push(fn);
|
||||
window.postMessage(messageName, "*");
|
||||
};
|
||||
})();
|
||||
|
||||
// Implements underscore debounce using our defer function
|
||||
utils.debounce = function(func, context) {
|
||||
var isExpected = false;
|
||||
function later() {
|
||||
isExpected = false;
|
||||
func.call(context);
|
||||
}
|
||||
return function() {
|
||||
if(isExpected === true) {
|
||||
return;
|
||||
}
|
||||
isExpected = true;
|
||||
utils.defer(later);
|
||||
};
|
||||
};
|
||||
|
||||
// Return a parameter from the URL
|
||||
utils.getURLParameter = function(name) {
|
||||
// Parameter can be either a search parameter (&name=...) or a hash fragment parameter (#!name=...)
|
||||
|
Loading…
Reference in New Issue
Block a user