diff --git a/webodf/lib/gui/SessionController.js b/webodf/lib/gui/SessionController.js
index 278875607..1e1236659 100644
--- a/webodf/lib/gui/SessionController.js
+++ b/webodf/lib/gui/SessionController.js
@@ -304,7 +304,7 @@ gui.SessionControllerOptions = function () {
* @return {undefined}
*/
function forwardUndoStackChange(e) {
- odtDocument.emit(ops.OdtDocument.signalUndoStackChanged, e);
+ odtDocument.DONOTUSE_emitSignalUndoStackChanged(e);
}
/**
@@ -374,7 +374,7 @@ gui.SessionControllerOptions = function () {
newSelectionRange.setEnd(shadowCursorIterator.container(), shadowCursorIterator.unfilteredDomOffset());
}
shadowCursor.setSelectedRange(newSelectionRange, handleEnd === 'right');
- odtDocument.emit(ops.Document.signalCursorMoved, shadowCursor);
+ odtDocument.DONOTUSE_emitSignalCursorMoved(shadowCursor);
}
}
}
@@ -400,7 +400,7 @@ gui.SessionControllerOptions = function () {
selectionController.expandToParagraphBoundaries(selectionRange.range);
}
shadowCursor.setSelectedRange(selectionRange.range, selectionRange.hasForwardSelection);
- odtDocument.emit(ops.Document.signalCursorMoved, shadowCursor);
+ odtDocument.DONOTUSE_emitSignalCursorMoved(shadowCursor);
}
}
}
diff --git a/webodf/lib/gui/SessionView.js b/webodf/lib/gui/SessionView.js
index d2b5dd484..dd72894be 100644
--- a/webodf/lib/gui/SessionView.js
+++ b/webodf/lib/gui/SessionView.js
@@ -410,7 +410,7 @@ gui.SessionViewOptions = function () {
var annotationViewManager = odfCanvas.getAnnotationViewManager();
if (annotationViewManager) {
annotationViewManager.rehighlightAnnotations();
- odtDocument.fixCursorPositions();
+ odtDocument.fixCursorPositions(false); // TODO: workaround, ideally this would not be needed
}
}
diff --git a/webodf/lib/ops/OdtDocument.js b/webodf/lib/ops/OdtDocument.js
index af2b42628..ccb32cc7c 100644
--- a/webodf/lib/ops/OdtDocument.js
+++ b/webodf/lib/ops/OdtDocument.js
@@ -154,7 +154,7 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
initialDoc = rootElement.cloneNode(true);
odfCanvas.refreshAnnotations();
// workaround AnnotationViewManager not fixing up cursor positions after creating the highlighting
- self.fixCursorPositions();
+ self.fixCursorPositions(false);
return initialDoc;
};
@@ -165,9 +165,6 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
var odfContainer = odfCanvas.odfContainer(),
rootNode;
- eventNotifier.unsubscribe(ops.OdtDocument.signalStepsInserted, stepsTranslator.handleStepsInserted);
- eventNotifier.unsubscribe(ops.OdtDocument.signalStepsRemoved, stepsTranslator.handleStepsRemoved);
-
// TODO Replace with a neater hack for reloading the Odt tree
// Once this is fixed, SelectionView.addOverlays can be removed
odfContainer.setRootElement(documentElement);
@@ -175,8 +172,6 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
odfCanvas.refreshCSS();
rootNode = getRootNode();
stepsTranslator = new ops.OdtStepsTranslator(rootNode, createPositionIterator(rootNode), filter, 500);
- eventNotifier.subscribe(ops.OdtDocument.signalStepsInserted, stepsTranslator.handleStepsInserted);
- eventNotifier.subscribe(ops.OdtDocument.signalStepsRemoved, stepsTranslator.handleStepsRemoved);
};
/**
@@ -449,15 +444,20 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
* document's metadata, such as dc:creator,
* meta:editing-cycles, and dc:creator.
* @param {!ops.Operation} op
+ * @param {!Array.} events
+ * @return {undefined}
*/
- function handleOperationExecuted(op) {
+ function finishOperationExecution(op, events) {
var opspec = op.spec(),
memberId = opspec.memberid,
date = new Date(opspec.timestamp).toISOString(),
odfContainer = odfCanvas.odfContainer(),
- /**@type{!{setProperties: !Object, removedProperties: ?Array.}}*/
+ /**@type{!ops.Operation.Event}*/
+ changedMetadataEvent,
+ /**@type{!{setProperties: !Object, removedProperties: !Array.}}*/
changedMetadata,
- fullName;
+ fullName,
+ i;
// If the operation is an edit (that changes the
// ODF that will be saved), then update metadata.
@@ -468,13 +468,25 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
"dc:date": date
}, null);
- changedMetadata = {
- setProperties: {
- "dc:creator": fullName,
- "dc:date": date
- },
- removedProperties: []
- };
+ // find any existing metadataupdated event or create one
+ for (i = 0; i < events.length; i += 1) {
+ if (events[i].eventid === ops.OdtDocument.signalMetadataUpdated) {
+ changedMetadataEvent = events[i];
+ changedMetadata = /**@type{!{setProperties: !Object, removedProperties: !Array.}}*/(changedMetadataEvent.args);
+ break;
+ }
+ }
+ if (!changedMetadataEvent) {
+ changedMetadata = { setProperties: {}, removedProperties: [] };
+ changedMetadataEvent = {
+ eventid: ops.OdtDocument.signalMetadataUpdated,
+ args: changedMetadata
+ };
+ events.push(changedMetadataEvent);
+ }
+
+ changedMetadata.setProperties["dc:creator"] = fullName;
+ changedMetadata.setProperties["dc:date"] = date;
// If no previous op was found in this session,
// then increment meta:editing-cycles by 1.
@@ -492,10 +504,49 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
}
lastEditingOp = op;
- self.emit(ops.OdtDocument.signalMetadataUpdated, changedMetadata);
}
+
+ eventNotifier.emit(ops.OdtDocument.signalOperationEnd, op);
+
+ events.forEach(function(event) {
+ eventNotifier.emit(event.eventid, event.args);
+ });
}
+ /**
+ * @param {!ops.Operation} op
+ * @return {!boolean}
+ */
+ this.executeOperation = function(op) {
+ var events;
+
+ eventNotifier.emit(ops.OdtDocument.signalOperationStart, op);
+
+ events = op.execute(self);
+ if (events === null) {
+ return false;
+ }
+
+ finishOperationExecution(op, events);
+ return true;
+ };
+
+ /**
+ * @param {*} args
+ * @return {undefined}
+ */
+ this.prepareBatchProcessing = function(args) {
+ eventNotifier.emit(ops.OdtDocument.signalProcessingBatchStart, args);
+ };
+
+ /**
+ * @param {*} args
+ * @return {undefined}
+ */
+ this.finishBatchProcessing = function (args) {
+ eventNotifier.emit(ops.OdtDocument.signalProcessingBatchEnd, args);
+ };
+
/**
* Upgrades literal whitespaces (' ') to ,
* when given a textNode containing the whitespace and an offset
@@ -673,8 +724,14 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
* walkable positions; if not, move the cursor 1 filtered step backward
* which guarantees walkable state for all cursors,
* while keeping them inside the same root. An event will be raised for this cursor if it is moved
+ * @param {!Array.|!boolean} events array to add events for moved cursors, needs to be otherwise explicitely set to false
+ * @return {undefined}
*/
- this.fixCursorPositions = function () {
+ this.fixCursorPositions = function (events) {
+ var /** @type{!Array.}*/ movedCursors = [];
+
+ runtime.assert(Array.isArray(events) || (typeof events === "boolean" && events === false), "second parameter to fixCursorPositions needs to be set to false or an event");
+
Object.keys(cursors).forEach(function (memberId) {
var cursor = cursors[memberId],
root = getRoot(cursor.getNode()),
@@ -717,9 +774,19 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
if (cursorMoved) {
cursor.setSelectedRange(selectedRange, cursor.hasForwardSelection());
- self.emit(ops.Document.signalCursorMoved, cursor);
+ movedCursors.push(cursor);
}
});
+
+ if (events) {
+ movedCursors.forEach(function(cursor) {
+ events.push({ eventid: ops.Document.signalCursorMoved, args: cursor });
+ });
+ } else {
+ movedCursors.forEach(function(cursor) {
+ eventNotifier.emit(ops.Document.signalCursorMoved, cursor);
+ });
+ }
};
/**
@@ -856,7 +923,6 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
if (cursor) {
cursor.removeFromDocument();
delete cursors[memberid];
- self.emit(ops.Document.signalCursorRemoved, memberid);
return true;
}
return false;
@@ -890,15 +956,6 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
return odfCanvas.getFormatting();
};
- /**
- * @param {!string} eventid
- * @param {*} args
- * @return {undefined}
- */
- this.emit = function (eventid, args) {
- eventNotifier.emit(eventid, args);
- };
-
/**
* @param {!string} eventid
* @param {!Function} cb
@@ -942,6 +999,60 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
callback();
};
+ /**
+ * Process steps being inserted into the document. Will add a steps inserted signal
+ * to the passed events list
+ * @param {!{position: !number}} args
+ * @param {!Array.} events
+ * @return {undefined}
+ */
+ this.handleStepsInserted = function(args, events) {
+ stepsTranslator.handleStepsInserted(args);
+ // signal not used in webodf, but 3rd-party (NVivo)
+ events.push({
+ eventid: ops.OdtDocument.signalStepsInserted,
+ args: args
+ });
+ };
+
+ /**
+ * Process steps being removed from the document. Will emit a steps removed signal on
+ * behalf of the caller
+ * @param {!{position: !number}} args
+ * @param {!Array.} events
+ * @return {undefined}
+ */
+ this.handleStepsRemoved = function(args, events) {
+ stepsTranslator.handleStepsRemoved(args);
+ // signal not used in webodf, but 3rd-party (NVivo)
+ events.push({
+ eventid: ops.OdtDocument.signalStepsRemoved,
+ args: args
+ });
+ };
+
+ /**
+ * Emit the signal that the passed cursor moved.
+ * TODO: get rid of this method, noone should be able to emit signals by direct calls, only by op execution
+ * @internal
+ * @param {!ops.OdtCursor} cursor
+ * @return {undefined}
+ */
+ this.DONOTUSE_emitSignalCursorMoved = function(cursor) {
+ eventNotifier.emit(ops.Document.signalCursorMoved, cursor);
+ };
+
+ /**
+ * Emit the signal that the passed cursor moved.
+ * TODO: get rid of this method, noone should be able to emit signals by direct calls, only by op execution
+ * @internal
+ * @param {?Event} e
+ * @return {undefined}
+ */
+ this.DONOTUSE_emitSignalUndoStackChanged = function(e) {
+ eventNotifier.emit(ops.OdtDocument.signalUndoStackChanged, e);
+ };
+
/**
* @return {undefined}
*/
@@ -951,9 +1062,6 @@ ops.OdtDocument = function OdtDocument(odfCanvas) {
filter = new ops.TextPositionFilter();
stepUtils = new odf.StepUtils();
stepsTranslator = new ops.OdtStepsTranslator(rootNode, createPositionIterator(rootNode), filter, 500);
- eventNotifier.subscribe(ops.OdtDocument.signalStepsInserted, stepsTranslator.handleStepsInserted);
- eventNotifier.subscribe(ops.OdtDocument.signalStepsRemoved, stepsTranslator.handleStepsRemoved);
- eventNotifier.subscribe(ops.OdtDocument.signalOperationEnd, handleOperationExecuted);
eventNotifier.subscribe(ops.OdtDocument.signalProcessingBatchEnd, core.Task.processTasks);
}
init();
diff --git a/webodf/lib/ops/OpAddAnnotation.js b/webodf/lib/ops/OpAddAnnotation.js
index 9feff3b62..8665a28b0 100644
--- a/webodf/lib/ops/OpAddAnnotation.js
+++ b/webodf/lib/ops/OpAddAnnotation.js
@@ -137,13 +137,15 @@ ops.OpAddAnnotation = function OpAddAnnotation() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
annotation, annotationEnd,
cursor = odtDocument.getCursor(memberid),
selectedRange,
- paragraphElement;
+ paragraphElement,
+ events = [];
doc = odtDocument.getDOMDocument();
@@ -158,7 +160,7 @@ ops.OpAddAnnotation = function OpAddAnnotation() {
insertNodeAtPosition(odtDocument, annotationEnd, position + length);
}
insertNodeAtPosition(odtDocument, annotation, position);
- odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
+ odtDocument.handleStepsInserted({position: position}, events);
// Move the cursor inside the new annotation,
// by selecting the paragraph's range.
@@ -168,14 +170,14 @@ ops.OpAddAnnotation = function OpAddAnnotation() {
selectedRange.selectNodeContents(paragraphElement);
cursor.setSelectedRange(selectedRange, false);
cursor.setSelectionType(ops.OdtCursor.RangeSelection);
- odtDocument.emit(ops.Document.signalCursorMoved, cursor);
+ events.push({eventid: ops.Document.signalCursorMoved, args: cursor});
}
// Track this annotation
odtDocument.getOdfCanvas().addAnnotation(annotation);
- odtDocument.fixCursorPositions();
- odtDocument.emit(ops.OdtDocument.signalAnnotationAdded, { memberId: memberid, annotation: annotation });
+ odtDocument.fixCursorPositions(events);
+ events.push({eventid: ops.OdtDocument.signalAnnotationAdded, args: { memberId: memberid, annotation: annotation }});
- return true;
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpAddCursor.js b/webodf/lib/ops/OpAddCursor.js
index a3ade9ea0..d909938b9 100644
--- a/webodf/lib/ops/OpAddCursor.js
+++ b/webodf/lib/ops/OpAddCursor.js
@@ -46,6 +46,7 @@ ops.OpAddCursor = function OpAddCursor() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -53,13 +54,13 @@ ops.OpAddCursor = function OpAddCursor() {
// there should be none
if (cursor) {
- return false;
+ return null;
}
cursor = new ops.OdtCursor(memberid, odtDocument);
odtDocument.addCursor(cursor);
- odtDocument.emit(ops.Document.signalCursorAdded, cursor);
- return true;
+
+ return [{eventid: ops.Document.signalCursorAdded, args: cursor}];
};
/**
diff --git a/webodf/lib/ops/OpAddMember.js b/webodf/lib/ops/OpAddMember.js
index 5afce4329..6c4e84228 100644
--- a/webodf/lib/ops/OpAddMember.js
+++ b/webodf/lib/ops/OpAddMember.js
@@ -52,19 +52,19 @@ ops.OpAddMember = function OpAddMember() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
member;
if (odtDocument.getMember(memberid)) {
- return false;
+ return null;
}
member = new ops.Member(memberid, setProperties);
odtDocument.addMember(member);
- odtDocument.emit(ops.Document.signalMemberAdded, member);
- return true;
+ return [{eventid: ops.Document.signalMemberAdded, args: member}];
};
/**
diff --git a/webodf/lib/ops/OpAddStyle.js b/webodf/lib/ops/OpAddStyle.js
index 0a2d83fed..3a37e68aa 100644
--- a/webodf/lib/ops/OpAddStyle.js
+++ b/webodf/lib/ops/OpAddStyle.js
@@ -56,6 +56,7 @@ ops.OpAddStyle = function OpAddStyle() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -65,7 +66,7 @@ ops.OpAddStyle = function OpAddStyle() {
styleNode = dom.createElementNS(stylens, 'style:style');
if (!styleNode) {
- return false;
+ return null;
}
if (setProperties) {
@@ -83,9 +84,9 @@ ops.OpAddStyle = function OpAddStyle() {
odtDocument.getOdfCanvas().refreshCSS();
if (!isAutomaticStyle) {
- odtDocument.emit(ops.OdtDocument.signalCommonStyleCreated, {name: styleName, family: styleFamily});
+ return [{eventid: ops.OdtDocument.signalCommonStyleCreated, args: {name: styleName, family: styleFamily}}];
}
- return true;
+ return [];
};
/**
diff --git a/webodf/lib/ops/OpApplyDirectStyling.js b/webodf/lib/ops/OpApplyDirectStyling.js
index 515b6427f..5e5b5de6e 100644
--- a/webodf/lib/ops/OpApplyDirectStyling.js
+++ b/webodf/lib/ops/OpApplyDirectStyling.js
@@ -80,28 +80,33 @@ ops.OpApplyDirectStyling = function OpApplyDirectStyling() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
range = odtDocument.convertCursorToDomRange(position, length),
- impactedParagraphs = odfUtils.getParagraphElements(range);
+ impactedParagraphs = odfUtils.getParagraphElements(range),
+ events = [];
applyStyle(odtDocument, range, setProperties);
range.detach();
odtDocument.getOdfCanvas().refreshCSS();
- odtDocument.fixCursorPositions(); // The container splits may leave the cursor in an invalid spot
+ odtDocument.fixCursorPositions(events); // The container splits may leave the cursor in an invalid spot
impactedParagraphs.forEach(function (n) {
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: n,
- memberId: memberid,
- timeStamp: timestamp
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: n,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
});
odtDocument.getOdfCanvas().rerenderAnnotations();
- return true;
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpApplyHyperlink.js b/webodf/lib/ops/OpApplyHyperlink.js
index 584c860ed..24aa11737 100644
--- a/webodf/lib/ops/OpApplyHyperlink.js
+++ b/webodf/lib/ops/OpApplyHyperlink.js
@@ -78,6 +78,7 @@ ops.OpApplyHyperlink = function OpApplyHyperlink() {
/**
* TODO: support adding image link
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -86,10 +87,11 @@ ops.OpApplyHyperlink = function OpApplyHyperlink() {
boundaryNodes = domUtils.splitBoundaries(range),
/**@type{!Array.}*/
modifiedParagraphs = [],
- textNodes = odfUtils.getTextNodes(range, false);
+ textNodes = odfUtils.getTextNodes(range, false),
+ events = [];
if (textNodes.length === 0) {
- return false;
+ return null;
}
textNodes.forEach(function (node) {
@@ -110,18 +112,21 @@ ops.OpApplyHyperlink = function OpApplyHyperlink() {
boundaryNodes.forEach(domUtils.normalizeTextNodes);
range.detach();
- odtDocument.fixCursorPositions();
+ odtDocument.fixCursorPositions(events);
odtDocument.getOdfCanvas().refreshSize();
odtDocument.getOdfCanvas().rerenderAnnotations();
modifiedParagraphs.forEach(function (paragraph) {
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: paragraph,
- memberId: memberid,
- timeStamp: timestamp
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: paragraph,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
});
- return true;
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpInsertImage.js b/webodf/lib/ops/OpInsertImage.js
index 190f433b9..8d6ca7ce1 100644
--- a/webodf/lib/ops/OpInsertImage.js
+++ b/webodf/lib/ops/OpInsertImage.js
@@ -80,15 +80,17 @@ ops.OpInsertImage = function OpInsertImage() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
odfCanvas = odtDocument.getOdfCanvas(),
domPosition = odtDocument.getTextNodeAtStep(position, memberid),
- textNode, refNode, paragraphElement, frameElement;
+ textNode, refNode, paragraphElement, frameElement,
+ events = [];
if (!domPosition) {
- return false;
+ return null;
}
textNode = domPosition.textNode;
@@ -97,7 +99,7 @@ ops.OpInsertImage = function OpInsertImage() {
textNode.splitText(domPosition.offset) : textNode.nextSibling;
frameElement = createFrameElement(odtDocument.getDOMDocument());
textNode.parentNode.insertBefore(frameElement, refNode);
- odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
+ odtDocument.handleStepsInserted({position: position}, events);
// clean up any empty text node which was created by odtDocument.getTextNodeAtStep
if (textNode.length === 0) {
@@ -106,13 +108,18 @@ ops.OpInsertImage = function OpInsertImage() {
odfCanvas.addCssForFrameWithImage(frameElement);
odfCanvas.refreshCSS();
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: paragraphElement,
- memberId: memberid,
- timeStamp: timestamp
- });
odfCanvas.rerenderAnnotations();
- return true;
+
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: paragraphElement,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
+ });
+
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpInsertTable.js b/webodf/lib/ops/OpInsertTable.js
index a60d8b042..c9a91115f 100644
--- a/webodf/lib/ops/OpInsertTable.js
+++ b/webodf/lib/ops/OpInsertTable.js
@@ -142,13 +142,15 @@ ops.OpInsertTable = function OpInsertTable() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
domPosition = odtDocument.getTextNodeAtStep(position),
rootNode = odtDocument.getRootNode(),
previousSibling,
- tableNode;
+ tableNode,
+ events = [];
if (domPosition) {
tableNode = createTableNode(odtDocument.getDOMDocument());
@@ -157,19 +159,22 @@ ops.OpInsertTable = function OpInsertTable() {
previousSibling = odfUtils.getParagraphElement(domPosition.textNode);
rootNode.insertBefore(tableNode, previousSibling.nextSibling);
// The parent table counts for 1 position, and 1 paragraph is added per cell
- odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
+ odtDocument.handleStepsInserted({position: position}, events);
odtDocument.getOdfCanvas().refreshSize();
- odtDocument.emit(ops.OdtDocument.signalTableAdded, {
- tableElement: tableNode,
- memberId: memberid,
- timeStamp: timestamp
+ odtDocument.getOdfCanvas().rerenderAnnotations();
+ events.push({
+ eventid: ops.OdtDocument.signalTableAdded,
+ args: {
+ tableElement: tableNode,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
- odtDocument.getOdfCanvas().rerenderAnnotations();
- return true;
+ return events;
}
- return false;
+ return null;
};
/**
diff --git a/webodf/lib/ops/OpInsertText.js b/webodf/lib/ops/OpInsertText.js
index 14185dfc6..cd37ecbed 100644
--- a/webodf/lib/ops/OpInsertText.js
+++ b/webodf/lib/ops/OpInsertText.js
@@ -101,6 +101,7 @@ ops.OpInsertText = function OpInsertText() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -115,7 +116,8 @@ ops.OpInsertText = function OpInsertText() {
toInsertIndex = 0,
spaceElement,
cursor = odtDocument.getCursor(memberid),
- i;
+ i,
+ events = [];
/**
* @param {string} toInsertText
@@ -186,7 +188,7 @@ ops.OpInsertText = function OpInsertText() {
previousNode.parentNode.removeChild(previousNode);
}
- odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
+ odtDocument.handleStepsInserted({position: position}, events);
if (cursor && moveCursor) {
// Explicitly place the cursor in the desired position after insertion
@@ -196,23 +198,26 @@ ops.OpInsertText = function OpInsertText() {
// the textnode + cursor reordering logic from OdtDocument's
// getTextNodeAtStep.
odtDocument.moveCursor(memberid, position + text.length, 0);
- odtDocument.emit(ops.Document.signalCursorMoved, cursor);
+ events.push({eventid: ops.Document.signalCursorMoved, args: cursor});
}
odtDocument.downgradeWhitespacesAtPosition(position);
odtDocument.downgradeWhitespacesAtPosition(position + text.length);
odtDocument.getOdfCanvas().refreshSize();
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: paragraphElement,
- memberId: memberid,
- timeStamp: timestamp
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: paragraphElement,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
odtDocument.getOdfCanvas().rerenderAnnotations();
- return true;
+ return events;
}
- return false;
+ return null;
};
/**
diff --git a/webodf/lib/ops/OpMergeParagraph.js b/webodf/lib/ops/OpMergeParagraph.js
index 90fb2468b..ac1cb5e7d 100644
--- a/webodf/lib/ops/OpMergeParagraph.js
+++ b/webodf/lib/ops/OpMergeParagraph.js
@@ -206,7 +206,7 @@ ops.OpMergeParagraph = function OpMergeParagraph() {
/**
* @param {!ops.Document} document
- * @return {!boolean}
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{!ops.OdtDocument}*/(document),
@@ -216,7 +216,8 @@ ops.OpMergeParagraph = function OpMergeParagraph() {
rootNode = odtDocument.getRootNode(),
collapseRules = new odf.CollapsingRules(rootNode),
stepIterator = odtDocument.createStepIterator(rootNode, 0, [odtDocument.getPositionFilter()], rootNode),
- downgradeOffset;
+ downgradeOffset,
+ events = [];
// Asserting a specific order for destination + source makes it easier to decide which ends to upgrade
runtime.assert(destinationStartPosition < sourceStartPosition,
@@ -244,7 +245,7 @@ ops.OpMergeParagraph = function OpMergeParagraph() {
collapseRules.mergeChildrenIntoParent(sourceParagraph);
// Merging removes a single step between the boundary of the two paragraphs
- odtDocument.emit(ops.OdtDocument.signalStepsRemoved, {position: sourceStartPosition - 1});
+ odtDocument.handleStepsRemoved({position: sourceStartPosition - 1}, events);
// Downgrade trailing spaces at the end of the destination paragraph, and the beginning of the source paragraph.
// These are the only two places that might need downgrading as a result of the merge.
@@ -267,20 +268,23 @@ ops.OpMergeParagraph = function OpMergeParagraph() {
if (cursor && moveCursor) {
odtDocument.moveCursor(memberid, sourceStartPosition - 1, 0);
- odtDocument.emit(ops.Document.signalCursorMoved, cursor);
+ events.push({eventid: ops.Document.signalCursorMoved, args:cursor});
}
- odtDocument.fixCursorPositions();
+ odtDocument.fixCursorPositions(events);
odtDocument.getOdfCanvas().refreshSize();
// TODO: signal also the deleted paragraphs, so e.g. SessionView can clean up the EditInfo
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: destinationParagraph,
- memberId: memberid,
- timeStamp: timestamp
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: destinationParagraph,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
odtDocument.getOdfCanvas().rerenderAnnotations();
- return true;
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpMoveCursor.js b/webodf/lib/ops/OpMoveCursor.js
index 5bf2eb6ef..c4acc2c4b 100644
--- a/webodf/lib/ops/OpMoveCursor.js
+++ b/webodf/lib/ops/OpMoveCursor.js
@@ -49,6 +49,7 @@ ops.OpMoveCursor = function OpMoveCursor() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -56,14 +57,14 @@ ops.OpMoveCursor = function OpMoveCursor() {
selectedRange;
if (!cursor) {
- return false;
+ return null;
}
selectedRange = odtDocument.convertCursorToDomRange(position, length);
cursor.setSelectedRange(selectedRange, length >= 0);
cursor.setSelectionType(selectionType);
- odtDocument.emit(ops.Document.signalCursorMoved, cursor);
- return true;
+
+ return [{eventid: ops.Document.signalCursorMoved, args: cursor}];
};
/**
diff --git a/webodf/lib/ops/OpRemoveAnnotation.js b/webodf/lib/ops/OpRemoveAnnotation.js
index 3a3031663..780d985b1 100644
--- a/webodf/lib/ops/OpRemoveAnnotation.js
+++ b/webodf/lib/ops/OpRemoveAnnotation.js
@@ -52,20 +52,22 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
iterator = odtDocument.getIteratorAtPosition(position),
container = iterator.container(),
annotationNode,
- annotationEnd;
+ annotationEnd,
+ events = [];
while (!(container.namespaceURI === odf.Namespaces.officens
&& container.localName === 'annotation')) {
container = container.parentNode;
}
if (container === null) {
- return false;
+ return null;
}
annotationNode = /**@type{!odf.AnnotationElement}*/(container);
@@ -90,11 +92,12 @@ ops.OpRemoveAnnotation = function OpRemoveAnnotation() {
annotationEnd.parentNode.removeChild(annotationEnd);
}
// The specified position is the first walkable step in the annotation. The position is always just before the first point of change
- odtDocument.emit(ops.OdtDocument.signalStepsRemoved, {position: position > 0 ? position - 1 : position});
+ odtDocument.handleStepsRemoved({position: position > 0 ? position - 1 : position}, events);
odtDocument.getOdfCanvas().rerenderAnnotations();
- odtDocument.fixCursorPositions();
- return true;
+ odtDocument.fixCursorPositions(events);
+
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpRemoveBlob.js b/webodf/lib/ops/OpRemoveBlob.js
index 487e7ff1c..9be150fc4 100644
--- a/webodf/lib/ops/OpRemoveBlob.js
+++ b/webodf/lib/ops/OpRemoveBlob.js
@@ -47,11 +47,12 @@ ops.OpRemoveBlob = function OpRemoveBlob() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document);
odtDocument.getOdfCanvas().odfContainer().removeBlob(filename);
- return true;
+ return [];
};
/**
diff --git a/webodf/lib/ops/OpRemoveCursor.js b/webodf/lib/ops/OpRemoveCursor.js
index 60eef7138..58e762742 100644
--- a/webodf/lib/ops/OpRemoveCursor.js
+++ b/webodf/lib/ops/OpRemoveCursor.js
@@ -46,14 +46,15 @@ ops.OpRemoveCursor = function OpRemoveCursor() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document);
if (!odtDocument.removeCursor(memberid)) {
- return false;
+ return null;
}
- return true;
+ return [{eventid:ops.Document.signalCursorRemoved, args: memberid}];
};
/**
diff --git a/webodf/lib/ops/OpRemoveHyperlink.js b/webodf/lib/ops/OpRemoveHyperlink.js
index 8106d7d24..efcbb2a98 100644
--- a/webodf/lib/ops/OpRemoveHyperlink.js
+++ b/webodf/lib/ops/OpRemoveHyperlink.js
@@ -50,26 +50,31 @@ ops.OpRemoveHyperlink = function OpRemoveHyperlink() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
range = odtDocument.convertCursorToDomRange(position, length),
links = odfUtils.getHyperlinkElements(range),
- node;
+ node,
+ events = [];
runtime.assert(links.length === 1, "The given range should only contain a single link.");
node = domUtils.mergeIntoParent(/**@type{!Node}*/(links[0]));
range.detach();
- odtDocument.fixCursorPositions();
+ odtDocument.fixCursorPositions(events);
odtDocument.getOdfCanvas().refreshSize();
odtDocument.getOdfCanvas().rerenderAnnotations();
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: odfUtils.getParagraphElement(node),
- memberId: memberid,
- timeStamp: timestamp
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: odfUtils.getParagraphElement(node),
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
- return true;
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpRemoveMember.js b/webodf/lib/ops/OpRemoveMember.js
index e7b08aff1..b8be17c25 100644
--- a/webodf/lib/ops/OpRemoveMember.js
+++ b/webodf/lib/ops/OpRemoveMember.js
@@ -46,17 +46,16 @@ ops.OpRemoveMember = function OpRemoveMember() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document);
if (!odtDocument.getMember(memberid)) {
- return false;
+ return null;
}
odtDocument.removeMember(memberid);
- odtDocument.emit(ops.Document.signalMemberRemoved, memberid);
-
- return true;
+ return [{ eventid: ops.Document.signalMemberRemoved, args: memberid}];
};
/**
diff --git a/webodf/lib/ops/OpRemoveStyle.js b/webodf/lib/ops/OpRemoveStyle.js
index e6dedade8..9cc23b890 100644
--- a/webodf/lib/ops/OpRemoveStyle.js
+++ b/webodf/lib/ops/OpRemoveStyle.js
@@ -48,20 +48,21 @@ ops.OpRemoveStyle = function OpRemoveStyle() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
styleNode = odtDocument.getFormatting().getStyleElement(styleName, styleFamily);
if (!styleNode) {
- return false;
+ return null;
}
styleNode.parentNode.removeChild(styleNode);
odtDocument.getOdfCanvas().refreshCSS();
- odtDocument.emit(ops.OdtDocument.signalCommonStyleDeleted, {name: styleName, family: styleFamily});
- return true;
+
+ return [{eventid: ops.OdtDocument.signalCommonStyleDeleted, args: {name: styleName, family: styleFamily}}];
};
/**
diff --git a/webodf/lib/ops/OpRemoveText.js b/webodf/lib/ops/OpRemoveText.js
index 0a09e22d5..f6314121a 100644
--- a/webodf/lib/ops/OpRemoveText.js
+++ b/webodf/lib/ops/OpRemoveText.js
@@ -55,6 +55,7 @@ ops.OpRemoveText = function OpRemoveText() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -62,7 +63,8 @@ ops.OpRemoveText = function OpRemoveText() {
textNodes,
paragraph,
cursor = odtDocument.getCursor(memberid),
- collapseRules = new odf.CollapsingRules(odtDocument.getRootNode());
+ collapseRules = new odf.CollapsingRules(odtDocument.getRootNode()),
+ events = [];
odtDocument.upgradeWhitespacesAtPosition(position);
odtDocument.upgradeWhitespacesAtPosition(position + length);
@@ -91,23 +93,26 @@ ops.OpRemoveText = function OpRemoveText() {
}
});
- odtDocument.emit(ops.OdtDocument.signalStepsRemoved, {position: position});
+ odtDocument.handleStepsRemoved({position: position}, events);
odtDocument.downgradeWhitespacesAtPosition(position);
- odtDocument.fixCursorPositions();
+ odtDocument.fixCursorPositions(events);
odtDocument.getOdfCanvas().refreshSize();
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: paragraph,
- memberId: memberid,
- timeStamp: timestamp
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: paragraph,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
if (cursor) {
cursor.resetSelectionType();
- odtDocument.emit(ops.Document.signalCursorMoved, cursor);
+ events.push({eventid: ops.Document.signalCursorMoved, args: cursor});
}
odtDocument.getOdfCanvas().rerenderAnnotations();
- return true;
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpSetBlob.js b/webodf/lib/ops/OpSetBlob.js
index 8978bd0fe..858c6ab59 100644
--- a/webodf/lib/ops/OpSetBlob.js
+++ b/webodf/lib/ops/OpSetBlob.js
@@ -49,11 +49,12 @@ ops.OpSetBlob = function OpSetBlob() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document);
odtDocument.getOdfCanvas().odfContainer().setBlob(filename, mimetype, content);
- return true;
+ return [];
};
/**
diff --git a/webodf/lib/ops/OpSetParagraphStyle.js b/webodf/lib/ops/OpSetParagraphStyle.js
index 0c33350c0..d6947f0cc 100644
--- a/webodf/lib/ops/OpSetParagraphStyle.js
+++ b/webodf/lib/ops/OpSetParagraphStyle.js
@@ -71,6 +71,7 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -89,16 +90,18 @@ ops.OpSetParagraphStyle = function OpSetParagraphStyle() {
}
odtDocument.getOdfCanvas().refreshSize();
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: paragraphNode,
- timeStamp: timestamp,
- memberId: memberid
- });
-
odtDocument.getOdfCanvas().rerenderAnnotations();
- return true;
+
+ return [{
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: paragraphNode,
+ timeStamp: timestamp,
+ memberId: memberid
+ }
+ }];
}
- return false;
+ return null;
};
/**
diff --git a/webodf/lib/ops/OpSplitParagraph.js b/webodf/lib/ops/OpSplitParagraph.js
index d84f6167a..1538e125d 100644
--- a/webodf/lib/ops/OpSplitParagraph.js
+++ b/webodf/lib/ops/OpSplitParagraph.js
@@ -71,22 +71,24 @@ ops.OpSplitParagraph = function OpSplitParagraph() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{!ops.OdtDocument}*/(document),
domPosition, paragraphNode, targetNode,
node, splitNode, splitChildNode, keptChildNode,
- cursor = odtDocument.getCursor(memberid);
+ cursor = odtDocument.getCursor(memberid),
+ events = [];
odtDocument.upgradeWhitespacesAtPosition(position);
domPosition = odtDocument.getTextNodeAtStep(position);
if (!domPosition) {
- return false;
+ return null;
}
paragraphNode = odfUtils.getParagraphElement(domPosition.textNode);
if (!paragraphNode) {
- return false;
+ return null;
}
if (odfUtils.isListItem(paragraphNode.parentNode)) {
@@ -168,29 +170,35 @@ ops.OpSplitParagraph = function OpSplitParagraph() {
if (domPosition.textNode.length === 0) {
domPosition.textNode.parentNode.removeChild(domPosition.textNode);
}
- odtDocument.emit(ops.OdtDocument.signalStepsInserted, {position: position});
+ odtDocument.handleStepsInserted({position: position}, events);
if (cursor && moveCursor) {
odtDocument.moveCursor(memberid, position + 1, 0);
- odtDocument.emit(ops.Document.signalCursorMoved, cursor);
+ events.push({eventid: ops.Document.signalCursorMoved, args: cursor});
}
- odtDocument.fixCursorPositions();
+ odtDocument.fixCursorPositions(events);
odtDocument.getOdfCanvas().refreshSize();
// mark both paragraphs as edited
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: paragraphNode,
- memberId: memberid,
- timeStamp: timestamp
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: paragraphNode,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
- odtDocument.emit(ops.OdtDocument.signalParagraphChanged, {
- paragraphElement: splitChildNode,
- memberId: memberid,
- timeStamp: timestamp
+ events.push({
+ eventid: ops.OdtDocument.signalParagraphChanged,
+ args: {
+ paragraphElement: splitChildNode,
+ memberId: memberid,
+ timeStamp: timestamp
+ }
});
odtDocument.getOdfCanvas().rerenderAnnotations();
- return true;
+ return events;
};
/**
diff --git a/webodf/lib/ops/OpUpdateMember.js b/webodf/lib/ops/OpUpdateMember.js
index ce8f72597..b8c328ff8 100644
--- a/webodf/lib/ops/OpUpdateMember.js
+++ b/webodf/lib/ops/OpUpdateMember.js
@@ -77,12 +77,13 @@ ops.OpUpdateMember = function OpUpdateMember() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
member = odtDocument.getMember(memberid);
if (!member) {
- return false;
+ return null;
}
if (removedProperties) {
@@ -95,8 +96,7 @@ ops.OpUpdateMember = function OpUpdateMember() {
}
}
- odtDocument.emit(ops.Document.signalMemberUpdated, member);
- return true;
+ return [{eventid: ops.Document.signalMemberUpdated, args: member}];
};
/**
diff --git a/webodf/lib/ops/OpUpdateMetadata.js b/webodf/lib/ops/OpUpdateMetadata.js
index aeb2f80c5..edfbc4a6f 100644
--- a/webodf/lib/ops/OpUpdateMetadata.js
+++ b/webodf/lib/ops/OpUpdateMetadata.js
@@ -56,6 +56,7 @@ ops.OpUpdateMetadata = function OpUpdateMetadata() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -68,12 +69,13 @@ ops.OpUpdateMetadata = function OpUpdateMetadata() {
odfContainer.setMetadata(setProperties, removedPropertiesArray);
- odtDocument.emit(ops.OdtDocument.signalMetadataUpdated, {
- setProperties: setProperties !== null ? setProperties : {},
- removedProperties: removedPropertiesArray !== null ? removedPropertiesArray : []
- });
-
- return true;
+ return [{
+ eventid: ops.OdtDocument.signalMetadataUpdated,
+ args: {
+ setProperties: setProperties !== null ? setProperties : {},
+ removedProperties: removedPropertiesArray !== null ? removedPropertiesArray : []
+ }
+ }];
};
/**
diff --git a/webodf/lib/ops/OpUpdateParagraphStyle.js b/webodf/lib/ops/OpUpdateParagraphStyle.js
index 0345cb301..e82d86e49 100644
--- a/webodf/lib/ops/OpUpdateParagraphStyle.js
+++ b/webodf/lib/ops/OpUpdateParagraphStyle.js
@@ -76,6 +76,7 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() {
/**
* @param {!ops.Document} document
+ * @return {?Array.}
*/
this.execute = function (document) {
var odtDocument = /**@type{ops.OdtDocument}*/(document),
@@ -122,11 +123,10 @@ ops.OpUpdateParagraphStyle = function OpUpdateParagraphStyle() {
}
odtDocument.getOdfCanvas().refreshCSS();
- odtDocument.emit(ops.OdtDocument.signalParagraphStyleModified, styleName);
odtDocument.getOdfCanvas().rerenderAnnotations();
- return true;
+ return [{eventid:ops.OdtDocument.signalParagraphStyleModified, args: styleName}];
}
- return false;
+ return null;
};
/**
diff --git a/webodf/lib/ops/Operation.js b/webodf/lib/ops/Operation.js
index 3a682d212..450831bbb 100644
--- a/webodf/lib/ops/Operation.js
+++ b/webodf/lib/ops/Operation.js
@@ -33,6 +33,12 @@ ops.Operation = function Operation() {
"use strict";
};
+/**@typedef{{
+ eventid:!string,
+ args:*
+}}*/
+ops.Operation.Event;
+
/**
* @param {?} data
* @return {undefined}
@@ -55,7 +61,7 @@ ops.Operation.prototype.group;
/**
* @param {!ops.Document} document
- * @return {!boolean} true if the operation was executed
+ * @return {?Array.} a list of events if the operation was executed, otherwise null
*/
ops.Operation.prototype.execute = function (document) {"use strict"; };
diff --git a/webodf/lib/ops/Session.js b/webodf/lib/ops/Session.js
index 1685afffe..2fd5bb5e1 100644
--- a/webodf/lib/ops/Session.js
+++ b/webodf/lib/ops/Session.js
@@ -46,7 +46,7 @@ ops.Session = function Session(odfCanvas) {
* @return {undefined}
*/
function forwardBatchStart(args) {
- odtDocument.emit(ops.OdtDocument.signalProcessingBatchStart, args);
+ odtDocument.prepareBatchProcessing(args);
}
/**
@@ -55,7 +55,7 @@ ops.Session = function Session(odfCanvas) {
* @return {undefined}
*/
function forwardBatchEnd(args) {
- odtDocument.emit(ops.OdtDocument.signalProcessingBatchEnd, args);
+ odtDocument.finishBatchProcessing(args);
}
/**
@@ -81,12 +81,7 @@ ops.Session = function Session(odfCanvas) {
operationRouter.subscribe(ops.OperationRouter.signalProcessingBatchStart, forwardBatchStart);
operationRouter.subscribe(ops.OperationRouter.signalProcessingBatchEnd, forwardBatchEnd);
opRouter.setPlaybackFunction(function (op) {
- odtDocument.emit(ops.OdtDocument.signalOperationStart, op);
- if (op.execute(odtDocument)) {
- odtDocument.emit(ops.OdtDocument.signalOperationEnd, op);
- return true;
- }
- return false;
+ return odtDocument.executeOperation(op);
});
opRouter.setOperationFactory(operationFactory);
};
diff --git a/webodf/tests/gui/DirectFormattingControllerTests.js b/webodf/tests/gui/DirectFormattingControllerTests.js
index be6e8c805..1a22b334c 100644
--- a/webodf/tests/gui/DirectFormattingControllerTests.js
+++ b/webodf/tests/gui/DirectFormattingControllerTests.js
@@ -140,7 +140,7 @@ gui.DirectFormattingControllerTests = function DirectFormattingControllerTests(r
domUtils.getElementsByTagNameNS(node, testns, '*').forEach(function(node) {
node.parentNode.removeChild(node);
});
- t.odtDocument.emit(ops.Document.signalCursorMoved, t.cursor);
+ t.odtDocument.DONOTUSE_emitSignalCursorMoved(t.cursor);
}
return node;
}
diff --git a/webodf/tests/gui/MetadataControllerTests.js b/webodf/tests/gui/MetadataControllerTests.js
index dce0b07f6..dd97f1bbd 100644
--- a/webodf/tests/gui/MetadataControllerTests.js
+++ b/webodf/tests/gui/MetadataControllerTests.js
@@ -84,10 +84,8 @@ gui.MetadataControllerTests = function MetadataControllerTests(runner) {
// need to set the timestamp, otherwise things fail in odtDocument
opspec.timestamp = Date.now();
- timedOp = operationFactory.create(opspec);
- if (timedOp.execute(odtDocument)) {
- odtDocument.emit(ops.OdtDocument.signalOperationEnd, timedOp);
- }
+ timedOp = /**@type {!ops.Operation}*/(operationFactory.create(opspec));
+ odtDocument.executeOperation(timedOp);
});
};
@@ -123,7 +121,7 @@ gui.MetadataControllerTests = function MetadataControllerTests(runner) {
});
changes.removedProperties.forEach(function (key) {
delete changedMetadata.setProperties[key];
- if (changedMetadata.removedProperties.indexOf(key) !== -1) {
+ if (changedMetadata.removedProperties.indexOf(key) === -1) {
changedMetadata.removedProperties.push(key);
}
});
diff --git a/webodf/tests/manifest.json b/webodf/tests/manifest.json
index cac860cd1..de0b3babb 100644
--- a/webodf/tests/manifest.json
+++ b/webodf/tests/manifest.json
@@ -49,7 +49,6 @@
"odf.ObjectNameGenerator",
"odf.OdfCanvas",
"odf.OdfContainer",
- "ops.Document",
"ops.OdtCursor",
"ops.OdtDocument",
"ops.Session"
@@ -230,6 +229,7 @@
"ops.Document",
"ops.Member",
"ops.OdtDocument",
+ "ops.Operation",
"ops.OperationFactory",
"ops.OperationTestHelper",
"xmldom.LSSerializer"
diff --git a/webodf/tests/ops/OdtDocumentTests.js b/webodf/tests/ops/OdtDocumentTests.js
index 5182b2189..3851ace4b 100644
--- a/webodf/tests/ops/OdtDocumentTests.js
+++ b/webodf/tests/ops/OdtDocumentTests.js
@@ -216,7 +216,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) {
setCursorPosition(1, 2);
wrapInDiv(t.cursor.getAnchorNode());
- t.odtDocument.fixCursorPositions();
+ t.odtDocument.fixCursorPositions(false);
t.isWalkable = isCursorSelectionInWalkablePositions();
t.anchorInDiv = t.cursor.getAnchorNode().parentNode.localName === "div";
@@ -234,7 +234,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) {
setCursorPosition(1, 2);
wrapInDiv(t.cursor.getNode());
- t.odtDocument.fixCursorPositions();
+ t.odtDocument.fixCursorPositions(false);
t.isWalkable = isCursorSelectionInWalkablePositions();
t.anchorInDiv = t.cursor.getAnchorNode().parentNode.localName === "div";
@@ -253,7 +253,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) {
wrapInDiv(t.cursor.getNode());
wrapInDiv(t.cursor.getAnchorNode());
- t.odtDocument.fixCursorPositions();
+ t.odtDocument.fixCursorPositions(false);
t.isWalkable = isCursorSelectionInWalkablePositions();
t.anchorInDiv = t.cursor.getAnchorNode().parentNode.localName === "div";
@@ -272,7 +272,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) {
wrapInDiv(t.cursor.getNode());
wrapInDiv(t.cursor.getAnchorNode());
- t.odtDocument.fixCursorPositions();
+ t.odtDocument.fixCursorPositions(false);
t.isWalkable = isCursorSelectionInWalkablePositions();
t.anchorInDiv = t.cursor.getAnchorNode().parentNode.localName === "div";
@@ -291,7 +291,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) {
wrapInDiv(t.cursor.getNode());
wrapInDiv(t.cursor.getAnchorNode());
- t.odtDocument.fixCursorPositions();
+ t.odtDocument.fixCursorPositions(false);
t.isWalkable = isCursorSelectionInWalkablePositions();
t.anchorInDiv = t.cursor.getAnchorNode().parentNode.localName === "div";
@@ -312,7 +312,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) {
wrapInDiv(t.cursor.getNode());
wrapInDiv(t.cursor.getAnchorNode());
- t.odtDocument.fixCursorPositions();
+ t.odtDocument.fixCursorPositions(false);
t.isWalkable = isCursorSelectionInWalkablePositions();
t.anchorInDiv = t.cursor.getAnchorNode().parentNode.localName === "div";
@@ -333,7 +333,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) {
wrapInDiv(t.cursor.getNode());
wrapInDiv(t.cursor.getAnchorNode());
- t.odtDocument.fixCursorPositions();
+ t.odtDocument.fixCursorPositions(false);
t.isWalkable = isCursorSelectionInWalkablePositions();
t.anchorInDiv = t.cursor.getAnchorNode().parentNode.localName === "div";
@@ -353,7 +353,7 @@ ops.OdtDocumentTests = function OdtDocumentTests(runner) {
setCursorPosition(1);
wrapInDiv(t.cursor.getNode());
- t.odtDocument.fixCursorPositions();
+ t.odtDocument.fixCursorPositions(false);
t.isWalkable = isCursorSelectionInWalkablePositions();
t.anchorInDiv = t.cursor.getAnchorNode().parentNode.localName === "div";
diff --git a/webodf/tests/ops/OperationTests.js b/webodf/tests/ops/OperationTests.js
index 3ec12fe1b..b8d00e594 100644
--- a/webodf/tests/ops/OperationTests.js
+++ b/webodf/tests/ops/OperationTests.js
@@ -177,7 +177,8 @@ ops.OperationTests = function OperationTests(runner) {
opsElement = before.nextElementSibling,
after = opsElement.nextElementSibling,
ops = [],
- op,
+ opElement, opspec,
+ now = Date.now(),
setup;
runtime.assert(before.localName === "before", "Expected in " + name + ".");
runtime.assert(checkWhitespace(before, "s", " "), "Unexpanded text:s element or text:c attribute found in " + name + ".");
@@ -187,11 +188,20 @@ ops.OperationTests = function OperationTests(runner) {
runtime.assert(checkWhitespace(after, "s", " "), "Unexpanded text:s element or text:c attribute found in " + name + ".");
runtime.assert(checkWhitespace(after, "tab", "\t"), "Unexpanded text:tab element found in " + name + ".");
opsTestHelper.removeInsignificantTextNodes(node);
- op = opsElement.firstElementChild;
- while (op) {
- runtime.assert(op.localName === "op", "Expected in " + name + ".");
- ops.push(parseOperation(op));
- op = op.nextElementSibling;
+ opElement = opsElement.firstElementChild;
+ while (opElement) {
+ runtime.assert(opElement.localName === "op", "Expected in " + name + ".");
+ opspec = parseOperation(opElement);
+ // default to Alice
+ if (!opspec.memberid) {
+ opspec.memberid = 'Alice';
+ }
+ // default to now
+ if (!opspec.timestamp) {
+ opspec.timestamp = now;
+ }
+ ops.push(opspec);
+ opElement = opElement.nextElementSibling;
}
setup = self.setUps.hasOwnProperty(name) ? self.setUps[name]() : null;
if (hasSetup) {
@@ -288,11 +298,8 @@ ops.OperationTests = function OperationTests(runner) {
// execute test ops
for (i = 0; i < test.ops.length; i += 1) {
- op = factory.create(test.ops[i]);
- op.execute(t.odtDocument);
- if (metabefore) {
- t.odtDocument.emit(ops.OdtDocument.signalOperationEnd, op);
- }
+ op = /**@type {!ops.Operation}*/(factory.create(test.ops[i]));
+ t.odtDocument.executeOperation(op);
checkForEmptyTextNodes(t.odtDocument.getCanvas().getElement());
}
@@ -403,18 +410,20 @@ ops.OperationTests = function OperationTests(runner) {
}
this.setUp = function () {
- var testarea, properties;
+ var testarea;
t = {};
testarea = core.UnitTest.provideTestAreaDiv();
t.odfcanvas = new odf.OdfCanvas(testarea);
t.odfContainer = new odf.OdfContainer(odf.OdfContainer.DocumentType.TEXT, null);
t.odfcanvas.setOdfContainer(t.odfContainer);
t.odtDocument = new ops.OdtDocument(t.odfcanvas);
- properties = new ops.MemberProperties();
- properties.color = "black";
- properties.fullName = "Alice";
- properties.imageUrl = "";
- t.odtDocument.addMember(new ops.Member('Alice', properties));
+ ["Alice", "Bob", "Eve", "Joe"].forEach(function(name) {
+ var properties = new ops.MemberProperties();
+ properties.color = "black";
+ properties.fullName = name;
+ properties.imageUrl = "";
+ t.odtDocument.addMember(new ops.Member(name, properties));
+ });
};
this.tearDown = function () {
t.odfcanvas.destroy(function () { return; });
diff --git a/webodf/tests/ops/TransformationTests.js b/webodf/tests/ops/TransformationTests.js
index 6fdb1fa93..b1aac0591 100644
--- a/webodf/tests/ops/TransformationTests.js
+++ b/webodf/tests/ops/TransformationTests.js
@@ -458,13 +458,13 @@ ops.TransformationTests = function TransformationTests(runner) {
// runtime.log("Going to apply:"+runtime.toJson(opspecs[i]));
op = t.operationFactory.create(opspecs[i]);
t.opResult = op.execute(odtDocument);
- r.shouldBe(t, "t.opResult", "true");
+ r.shouldBeNonNull(t, "t.opResult");
}
// execute transformedOps
for (i = 0; i < transformedOps.length; i += 1) {
// runtime.log("Going to apply:"+runtime.toJson(transformedOps[i].spec()));
t.opResult = transformedOps[i].execute(odtDocument);
- r.shouldBe(t, "t.opResult", "true");
+ r.shouldBeNonNull(t, "t.opResult");
}
// check result