Skip to content

Commit ae2cfe1

Browse files
committed
Merge pull request #823 from peitschie/delay-emit
Only process signals created by an operation after execution is complete
2 parents d761802 + 662c2c8 commit ae2cfe1

15 files changed

+75
-17
lines changed

webodf/lib/ops/OdtDocument.js

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
7979
/**@const*/ SHOW_ALL = NodeFilter.SHOW_ALL,
8080
blacklistedNodes = new gui.BlacklistNamespaceNodeFilter(["urn:webodf:names:cursor", "urn:webodf:names:editinfo"]),
8181
odfTextBodyFilter = new gui.OdfTextBodyNodeFilter(),
82-
defaultNodeFilter = new core.NodeFilterChain([blacklistedNodes, odfTextBodyFilter]);
82+
defaultNodeFilter = new core.NodeFilterChain([blacklistedNodes, odfTextBodyFilter]),
83+
/**@type{!Array.<!function():undefined>}*/
84+
pendingSignals = [];
8385

8486
/**
8587
*
@@ -890,12 +892,18 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
890892
};
891893

892894
/**
895+
* Emit a signal to interested subscribers. Note, signals are not emitted
896+
* until *after* the current operation has completed execution in order to
897+
* ensure operation atomicity.
898+
*
893899
* @param {!string} eventid
894900
* @param {*} args
895901
* @return {undefined}
896902
*/
897903
this.emit = function (eventid, args) {
898-
eventNotifier.emit(eventid, args);
904+
pendingSignals.push(function() {
905+
eventNotifier.emit(eventid, args);
906+
});
899907
};
900908

901909
/**
@@ -941,15 +949,47 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
941949
callback();
942950
};
943951

952+
/**
953+
* Process steps being inserted into the document. Will emit a steps inserted signal on
954+
* behalf of the caller
955+
* @param {!{position: !number}} args
956+
* @return {undefined}
957+
*/
958+
this.handleStepsInserted = function(args) {
959+
stepsTranslator.handleStepsInserted(args);
960+
self.emit(ops.OdtDocument.signalStepsInserted, args);
961+
};
962+
963+
/**
964+
* Process steps being removed from the document. Will emit a steps removed signal on
965+
* behalf of the caller
966+
* @param {!{position: !number}} args
967+
* @return {undefined}
968+
*/
969+
this.handleStepsRemoved = function(args) {
970+
stepsTranslator.handleStepsRemoved(args);
971+
self.emit(ops.OdtDocument.signalStepsRemoved, args);
972+
};
973+
974+
/**
975+
* Process all signals queued up during operation execution
976+
* @return {undefined}
977+
*/
978+
this.processPendingSignals = function() {
979+
var signal = pendingSignals.shift();
980+
while (signal) {
981+
signal();
982+
signal = pendingSignals.shift();
983+
}
984+
};
985+
944986
/**
945987
* @return {undefined}
946988
*/
947989
function init() {
948990
filter = new ops.TextPositionFilter();
949991
stepUtils = new odf.StepUtils();
950992
stepsTranslator = new ops.OdtStepsTranslator(getRootNode, createPositionIterator, filter, 500);
951-
eventNotifier.subscribe(ops.OdtDocument.signalStepsInserted, stepsTranslator.handleStepsInserted);
952-
eventNotifier.subscribe(ops.OdtDocument.signalStepsRemoved, stepsTranslator.handleStepsRemoved);
953993
eventNotifier.subscribe(ops.OdtDocument.signalOperationEnd, handleOperationExecuted);
954994
eventNotifier.subscribe(ops.OdtDocument.signalProcessingBatchEnd, core.Task.processTasks);
955995
}

webodf/lib/ops/OpAddAnnotation.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ ops.OpAddAnnotation = function OpAddAnnotation() {
158158
insertNodeAtPosition(odtDocument, annotationEnd, position + length);
159159
}
160160
insertNodeAtPosition(odtDocument, annotation, position);
161-
odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
161+
odtDocument.handleStepsInserted({position: position});
162162

163163
// Move the cursor inside the new annotation,
164164
// by selecting the paragraph's range.

webodf/lib/ops/OpInsertImage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ ops.OpInsertImage = function OpInsertImage() {
9797
textNode.splitText(domPosition.offset) : textNode.nextSibling;
9898
frameElement = createFrameElement(odtDocument.getDOMDocument());
9999
textNode.parentNode.insertBefore(frameElement, refNode);
100-
odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
100+
odtDocument.handleStepsInserted({position: position});
101101

102102
// clean up any empty text node which was created by odtDocument.getTextNodeAtStep
103103
if (textNode.length === 0) {

webodf/lib/ops/OpInsertTable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ ops.OpInsertTable = function OpInsertTable() {
157157
previousSibling = odfUtils.getParagraphElement(domPosition.textNode);
158158
rootNode.insertBefore(tableNode, previousSibling.nextSibling);
159159
// The parent table counts for 1 position, and 1 paragraph is added per cell
160-
odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
160+
odtDocument.handleStepsInserted({position: position});
161161

162162
odtDocument.getOdfCanvas().refreshSize();
163163
odtDocument.emit(ops.OdtDocument.signalTableAdded, {

webodf/lib/ops/OpInsertText.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ ops.OpInsertText = function OpInsertText() {
186186
previousNode.parentNode.removeChild(previousNode);
187187
}
188188

189-
odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
189+
odtDocument.handleStepsInserted({position: position});
190190

191191
if (cursor && moveCursor) {
192192
// Explicitly place the cursor in the desired position after insertion

webodf/lib/ops/OpMergeParagraph.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ ops.OpMergeParagraph = function OpMergeParagraph() {
241241
collapseRules.mergeChildrenIntoParent(sourceParagraph);
242242

243243
// Merging removes a single step between the boundary of the two paragraphs
244-
odtDocument.emit(ops.OdtDocument.signalStepsRemoved, {position: sourceStartPosition - 1});
244+
odtDocument.handleStepsRemoved({position: sourceStartPosition - 1});
245245

246246
// Downgrade trailing spaces at the end of the destination paragraph, and the beginning of the source paragraph.
247247
// These are the only two places that might need downgrading as a result of the merge.

webodf/lib/ops/OpRemoveAnnotation.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() {
9090
annotationEnd.parentNode.removeChild(annotationEnd);
9191
}
9292
// The specified position is the first walkable step in the annotation. The position is always just before the first point of change
93-
odtDocument.emit(ops.OdtDocument.signalStepsRemoved, {position: position > 0 ? position - 1 : position});
93+
odtDocument.handleStepsRemoved({position: position > 0 ? position - 1 : position});
9494

9595
odtDocument.fixCursorPositions();
9696
odtDocument.getOdfCanvas().refreshAnnotations();

webodf/lib/ops/OpRemoveText.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ ops.OpRemoveText = function OpRemoveText() {
9191
}
9292
});
9393

94-
odtDocument.emit(ops.OdtDocument.signalStepsRemoved, {position: position});
94+
odtDocument.handleStepsRemoved({position: position});
9595
odtDocument.downgradeWhitespacesAtPosition(position);
9696
odtDocument.fixCursorPositions();
9797
odtDocument.getOdfCanvas().refreshSize();

webodf/lib/ops/OpSplitParagraph.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ ops.OpSplitParagraph = function OpSplitParagraph() {
168168
if (domPosition.textNode.length === 0) {
169169
domPosition.textNode.parentNode.removeChild(domPosition.textNode);
170170
}
171-
odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
171+
odtDocument.handleStepsInserted({position: position});
172172

173173
if (cursor && moveCursor) {
174174
odtDocument.moveCursor(memberid, position + 1, 0);

webodf/lib/ops/Session.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ ops.Session = function Session(odfCanvas) {
4747
*/
4848
function forwardBatchStart(args) {
4949
odtDocument.emit(ops.OdtDocument.signalProcessingBatchStart, args);
50+
odtDocument.processPendingSignals();
5051
}
5152

5253
/**
@@ -56,6 +57,7 @@ ops.Session = function Session(odfCanvas) {
5657
*/
5758
function forwardBatchEnd(args) {
5859
odtDocument.emit(ops.OdtDocument.signalProcessingBatchEnd, args);
60+
odtDocument.processPendingSignals();
5961
}
6062

6163
/**
@@ -81,12 +83,14 @@ ops.Session = function Session(odfCanvas) {
8183
operationRouter.subscribe(ops.OperationRouter.signalProcessingBatchStart, forwardBatchStart);
8284
operationRouter.subscribe(ops.OperationRouter.signalProcessingBatchEnd, forwardBatchEnd);
8385
opRouter.setPlaybackFunction(function (op) {
86+
var result = false;
8487
odtDocument.emit(ops.OdtDocument.signalOperationStart, op);
8588
if (op.execute(odtDocument)) {
8689
odtDocument.emit(ops.OdtDocument.signalOperationEnd, op);
87-
return true;
90+
result = true;
8891
}
89-
return false;
92+
odtDocument.processPendingSignals();
93+
return result;
9094
});
9195
opRouter.setOperationFactory(operationFactory);
9296
};

0 commit comments

Comments
 (0)