/// <summary> /// Filter the queued events and merge duplicates. /// </summary> /// <param name="queueIn"></param> /// <param name="forward"></param> /// <returns></returns> public static JsArray <Events.Abstract> filter(JsArray <Events.Abstract> queueIn, bool forward) { var queue = new JsArray <Events.Abstract>(queueIn.Clone()); if (!forward) { // Undo is merged in reverse order. queue.Reverse(); } // Merge duplicates. O(n^2), but n should be very small. for (var i = 0; i < queue.Length; i++) { var event1 = queue[i]; for (var j = i + 1; j < queue.Length; j++) { var event2 = queue[j]; if (event1.type == event2.type && event1.blockId == event2.blockId && event1.workspaceId == event2.workspaceId) { if (event1.type == Events.MOVE) { // Merge move events. ((Events.Move)event1).newParentId = ((Events.Move)event2).newParentId; ((Events.Move)event1).newInputName = ((Events.Move)event2).newInputName; ((Events.Move)event1).newCoordinate = ((Events.Move)event2).newCoordinate; queue.Splice(j, 1); j--; } else if (event1.type == Events.CHANGE && ((Events.Change)event1).element == ((Events.Change)event2).element && ((Events.Change)event1).name == ((Events.Change)event2).name) { // Merge change events. ((Events.Change)event1).newValue = ((Events.Change)event2).newValue; queue.Splice(j, 1); j--; } else if (event1.type == Events.UI && ((Events.Ui)event2).element == "click" && (((Events.Ui)event1).element == "commentOpen" || ((Events.Ui)event1).element == "mutatorOpen" || ((Events.Ui)event1).element == "warningOpen")) { // Merge change events. ((Events.Ui)event1).newValue = ((Events.Ui)event2).newValue; queue.Splice(j, 1); j--; } } } } // Remove null events. for (var i = queue.Length - 1; i >= 0; i--) { if (queue[i].isNull()) { queue.Splice(i, 1); } } if (!forward) { // Restore undo order. queue.Reverse(); } // Move mutation events to the top of the queue. // Intentionally skip first event. Events.Abstract ev; for (var i = 1; i < queue.Length; i++) { ev = queue[i]; if (ev.type == Events.CHANGE && ((Events.Change)ev).element == "mutation") { queue.Unshift(queue.Splice(i, 1)[0]); } } return(queue); }