diff --git a/modules/core/context.js b/modules/core/context.js index 8846a31d1..34769e3b2 100644 --- a/modules/core/context.js +++ b/modules/core/context.js @@ -459,10 +459,10 @@ export function coreContext() { issueManager = IssueManager(context); - var debouncedValidate = _debounce(issueManager.validate, 1000); - history.on('change', function(difference) { + // re-run validation upon a significant graph change + history.on('annotatedChange', function(difference) { if (difference) { - debouncedValidate(); + issueManager.validate(); } }); diff --git a/modules/core/history.js b/modules/core/history.js index 1c7c66d28..84fb45415 100644 --- a/modules/core/history.js +++ b/modules/core/history.js @@ -32,7 +32,7 @@ import { export function coreHistory(context) { - var dispatch = d3_dispatch('change', 'undone', 'redone'); + var dispatch = d3_dispatch('change', 'annotatedChange', 'undone', 'redone'); var lock = utilSessionMutex('lock'); var duration = 150; var _imageryUsed = []; @@ -71,9 +71,10 @@ export function coreHistory(context) { function _perform(args, t) { var previous = _stack[_index].graph; _stack = _stack.slice(0, _index + 1); - _stack.push(_act(args, t)); + var actionResult = _act(args, t); + _stack.push(actionResult); _index++; - return change(previous); + return change(previous, actionResult.annotation); } @@ -81,8 +82,9 @@ export function coreHistory(context) { function _replace(args, t) { var previous = _stack[_index].graph; // assert(_index == _stack.length - 1) - _stack[_index] = _act(args, t); - return change(previous); + var actionResult = _act(args, t); + _stack[_index] = actionResult; + return change(previous, actionResult.annotation); } @@ -94,16 +96,22 @@ export function coreHistory(context) { _stack.pop(); } _stack = _stack.slice(0, _index + 1); - _stack.push(_act(args, t)); + var actionResult = _act(args, t); + _stack.push(actionResult); _index++; - return change(previous); + return change(previous, actionResult.annotation); } // determine diffrence and dispatch a change event - function change(previous) { + function change(previous, isAnnotated) { var difference = coreDifference(previous, history.graph()); dispatch.call('change', this, difference); + if (isAnnotated) { + // actions like dragging a node can fire lots of changes, + // so use 'annotatedChange' to listen for grouped undo/redo changes + dispatch.call('annotatedChange', this, difference); + } return difference; } @@ -214,7 +222,7 @@ export function coreHistory(context) { } dispatch.call('undone', this, _stack[_index]); - return change(previous); + return change(previous, true); }, @@ -233,7 +241,7 @@ export function coreHistory(context) { } } - return change(previous); + return change(previous, true); }, diff --git a/modules/modes/drag_node.js b/modules/modes/drag_node.js index 9753f8e1e..8b8ae2212 100644 --- a/modules/modes/drag_node.js +++ b/modules/modes/drag_node.js @@ -210,8 +210,7 @@ export function modeDragNode(context) { } context.replace( - actionMoveNode(entity.id, loc), - moveAnnotation(entity) + actionMoveNode(entity.id, loc) ); // Below here: validations diff --git a/modules/modes/move.js b/modules/modes/move.js index d46e8fd5f..33d56464f 100644 --- a/modules/modes/move.js +++ b/modules/modes/move.js @@ -5,7 +5,10 @@ import { import { t } from '../util/locale'; -import { actionMove } from '../actions'; +import { + actionMove, + actionNoop +} from '../actions'; import { behaviorEdit } from '../behavior'; import { geoViewportEdge, geoVecSubtract } from '../geo'; import { modeBrowse, modeSelect } from './index'; @@ -63,7 +66,7 @@ export function modeMove(context, entityIDs, baseGraph) { var origMouse = context.projection(_origin); var delta = geoVecSubtract(geoVecSubtract(currMouse, origMouse), nudge); - fn(actionMove(entityIDs, delta, context.projection, _cache), annotation); + fn(actionMove(entityIDs, delta, context.projection, _cache)); _prevGraph = context.graph(); } @@ -98,6 +101,7 @@ export function modeMove(context, entityIDs, baseGraph) { function finish() { d3_event.stopPropagation(); + context.replace(actionNoop(), annotation); context.enter(modeSelect(context, entityIDs)); stopNudge(); } diff --git a/modules/modes/rotate.js b/modules/modes/rotate.js index d9d98d209..16f3eba90 100644 --- a/modules/modes/rotate.js +++ b/modules/modes/rotate.js @@ -9,7 +9,10 @@ import { } from 'd3-polygon'; import { t } from '../util/locale'; -import { actionRotate } from '../actions'; +import { + actionRotate, + actionNoop +} from '../actions'; import { behaviorEdit } from '../behavior'; import { geoVecInterp } from '../geo'; import { modeBrowse, modeSelect } from './index'; @@ -88,7 +91,7 @@ export function modeRotate(context, entityIDs) { if (typeof _prevAngle === 'undefined') _prevAngle = currAngle; var delta = currAngle - _prevAngle; - fn(actionRotate(entityIDs, _pivot, delta, projection), annotation); + fn(actionRotate(entityIDs, _pivot, delta, projection)); _prevTransform = currTransform; _prevAngle = currAngle; @@ -98,6 +101,7 @@ export function modeRotate(context, entityIDs) { function finish() { d3_event.stopPropagation(); + context.replace(actionNoop(), annotation); context.enter(modeSelect(context, entityIDs)); }