[Actions] Remove Action

When an ascendant or parent or currently
selected object is removed the user is navigated
to the parent of the object being removed. Added variables
to RemoveAction test to test removing currently selected
domainObject.
This commit is contained in:
Shivam Dave 2015-08-21 13:04:47 -07:00
parent a7cc06a28b
commit d0183d44c9
3 changed files with 67 additions and 13 deletions

View File

@ -59,7 +59,7 @@
"glyph": "Z", "glyph": "Z",
"name": "Remove", "name": "Remove",
"description": "Remove this object from its containing object.", "description": "Remove this object from its containing object.",
"depends": [ "$q" ] "depends": [ "$q", "navigationService" ]
}, },
{ {
"key": "save", "key": "save",

View File

@ -40,8 +40,9 @@ define(
* @constructor * @constructor
* @memberof module:editor/actions/remove-action * @memberof module:editor/actions/remove-action
*/ */
function RemoveAction($q, context) { function RemoveAction($q, navigationService, context) {
var object = (context || {}).domainObject; var object = (context || {}).domainObject,
ROOT_ID = "ROOT";
/** /**
* Check whether an object ID matches the ID of the object being * Check whether an object ID matches the ID of the object being
@ -68,15 +69,39 @@ define(
var persistence = domainObject.getCapability('persistence'); var persistence = domainObject.getCapability('persistence');
return persistence && persistence.persist(); return persistence && persistence.persist();
} }
// Checks current object and ascendants of current
// object with object being removed, if the current
// object or any in the current object's path is being removed,
// navigate back to parent of removed object.
function checkObjectNavigation(object, parentObject) {
// Traverse object starts at current location
var traverseObject = navigationService.getNavigation();
// Stop at ROOT of folder path
while(traverseObject.getId() !== ROOT_ID) {
// If traverse object is object being removed
// navigate to parent of removed object
if (traverseObject.getId() === object.getId()) {
navigationService.setNavigation(parentObject);
return;
}
// Traverses to parent
traverseObject = traverseObject.getCapability('context').getParent();
}
}
/** /**
* Remove the object from its parent, as identified by its context * Remove the object from its parent, as identified by its context
* capability. * capability.
* @param {ContextCapability} contextCapability the "context" capability * @param {object} domain object being removed contextCapability
* of the domain object being removed. gotten from the "context" capability of this object
*/ */
function removeFromContext(contextCapability) { function removeFromContext(object) {
var parent = contextCapability.getParent(); var contextCapability = object.getCapability('context'),
parent = contextCapability.getParent();
// Navigates through/ascendant if deleting current object
checkObjectNavigation(object, parent)
$q.when( $q.when(
parent.useCapability('mutation', doMutate) parent.useCapability('mutation', doMutate)
).then(function () { ).then(function () {
@ -91,7 +116,7 @@ define(
* fulfilled when the action has completed. * fulfilled when the action has completed.
*/ */
perform: function () { perform: function () {
return $q.when(object.getCapability('context')) return $q.when(object)
.then(removeFromContext); .then(removeFromContext);
} }
}; };

View File

@ -28,8 +28,10 @@ define(
describe("The Remove action", function () { describe("The Remove action", function () {
var mockQ, var mockQ,
mockNavigationService,
mockDomainObject, mockDomainObject,
mockParent, mockParent,
mockGrandparent,
mockContext, mockContext,
mockMutation, mockMutation,
mockPersistence, mockPersistence,
@ -55,6 +57,20 @@ define(
[ "getId", "getCapability" ] [ "getId", "getCapability" ]
); );
mockQ = { when: mockPromise }; mockQ = { when: mockPromise };
mockGrandparent = {
getModel: function () {
return model;
},
getCapability: function (k) {
return capabilities[k];
},
useCapability: function (k, v) {
return capabilities[k].invoke(v);
},
getId: function () {
return "test";
}
};
mockParent = { mockParent = {
getModel: function () { getModel: function () {
return model; return model;
@ -64,31 +80,44 @@ define(
}, },
useCapability: function (k, v) { useCapability: function (k, v) {
return capabilities[k].invoke(v); return capabilities[k].invoke(v);
},
getParent: function () {
return mockGrandparent;
} }
}; };
mockContext = jasmine.createSpyObj("context", [ "getParent" ]); mockContext = jasmine.createSpyObj("context", [ "getParent" ]);
mockMutation = jasmine.createSpyObj("mutation", [ "invoke" ]); mockMutation = jasmine.createSpyObj("mutation", [ "invoke" ]);
mockPersistence = jasmine.createSpyObj("persistence", [ "persist" ]); mockPersistence = jasmine.createSpyObj("persistence", [ "persist" ]);
mockType = jasmine.createSpyObj("type", [ "hasFeature" ]); mockType = jasmine.createSpyObj("type", [ "hasFeature" ]);
mockNavigationService = jasmine.createSpyObj(
"navigationService",
[
"getNavigation",
"setNavigation",
"addListener",
"removeListener"
]
);
mockNavigationService.getNavigation.andReturn(mockDomainObject);
mockDomainObject.getId.andReturn("test"); mockDomainObject.getId.andReturn("test");
mockDomainObject.getCapability.andReturn(mockContext); mockDomainObject.getCapability.andReturn(mockContext);
mockContext.getParent.andReturn(mockParent); mockContext.getParent.andReturn(mockParent);
mockType.hasFeature.andReturn(true); mockType.hasFeature.andReturn(true);
capabilities = { capabilities = {
mutation: mockMutation, mutation: mockMutation,
persistence: mockPersistence, persistence: mockPersistence,
type: mockType type: mockType
}; };
model = { model = {
composition: [ "a", "test", "b", "c" ] composition: [ "a", "b", "test", "c" ]
}; };
actionContext = { domainObject: mockDomainObject }; actionContext = { domainObject: mockDomainObject };
action = new RemoveAction(mockQ, actionContext); action = new RemoveAction(mockQ, mockNavigationService, actionContext);
}); });
it("only applies to objects with parents", function () { it("only applies to objects with parents", function () {