Compare commits
	
		
			6 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					23dbbf965c | ||
| 
						 | 
					a72f193e97 | ||
| 
						 | 
					18e0aadfc1 | ||
| 
						 | 
					64b3580cf6 | ||
| 
						 | 
					08684fa14a | ||
| 
						 | 
					56a5a30f56 | 
@@ -25,11 +25,8 @@
 | 
			
		||||
 * Module defining CreateAction. Created by vwoeltje on 11/10/14.
 | 
			
		||||
 */
 | 
			
		||||
define(
 | 
			
		||||
    [
 | 
			
		||||
        './CreateWizard',
 | 
			
		||||
        '../../../edit/src/objects/EditableDomainObject'
 | 
			
		||||
    ],
 | 
			
		||||
    function (CreateWizard, EditableDomainObject) {
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -88,22 +85,19 @@ define(
 | 
			
		||||
        CreateAction.prototype.perform = function () {
 | 
			
		||||
            var newModel = this.type.getInitialModel(),
 | 
			
		||||
                parentObject = this.navigationService.getNavigation(),
 | 
			
		||||
                newObject,
 | 
			
		||||
                editableObject;
 | 
			
		||||
                newObject;
 | 
			
		||||
 | 
			
		||||
            newModel.type = this.type.getKey();
 | 
			
		||||
            newObject = parentObject.useCapability('instantiation', newModel);
 | 
			
		||||
            editableObject = new EditableDomainObject(newObject, this.$q);
 | 
			
		||||
            editableObject.setOriginalObject(parentObject);
 | 
			
		||||
            editableObject.getCapability('status').set('editing', true);
 | 
			
		||||
            editableObject.useCapability('mutation', function(model){
 | 
			
		||||
            newObject.useCapability('mutation', function(model){
 | 
			
		||||
                model.location = parentObject.getId();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (countEditableViews(editableObject) > 0 && editableObject.hasCapability('composition')) {
 | 
			
		||||
                this.navigationService.setNavigation(editableObject);
 | 
			
		||||
            if (countEditableViews(newObject) > 0 && newObject.hasCapability('composition')) {
 | 
			
		||||
                this.navigationService.setNavigation(newObject);
 | 
			
		||||
                newObject.getCapability("action").perform("edit");
 | 
			
		||||
            } else {
 | 
			
		||||
                return editableObject.getCapability('action').perform('save');
 | 
			
		||||
                return newObject.getCapability('action').perform('save');
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -40,6 +40,10 @@ define([
 | 
			
		||||
    "./src/policies/EditContextualActionPolicy",
 | 
			
		||||
    "./src/representers/EditRepresenter",
 | 
			
		||||
    "./src/representers/EditToolbarRepresenter",
 | 
			
		||||
    "./src/capabilities/EditorCapability",
 | 
			
		||||
    "./src/capabilities/TransactionDecorator",
 | 
			
		||||
    "./src/services/TransactionService",
 | 
			
		||||
    "./src/services/DirtyModelCache",
 | 
			
		||||
    "text!./res/templates/library.html",
 | 
			
		||||
    "text!./res/templates/edit-object.html",
 | 
			
		||||
    "text!./res/templates/edit-action-buttons.html",
 | 
			
		||||
@@ -65,6 +69,10 @@ define([
 | 
			
		||||
    EditContextualActionPolicy,
 | 
			
		||||
    EditRepresenter,
 | 
			
		||||
    EditToolbarRepresenter,
 | 
			
		||||
    EditorCapability,
 | 
			
		||||
    TransactionDecorator,
 | 
			
		||||
    TransactionService,
 | 
			
		||||
    DirtyModelCache,
 | 
			
		||||
    libraryTemplate,
 | 
			
		||||
    editObjectTemplate,
 | 
			
		||||
    editActionButtonsTemplate,
 | 
			
		||||
@@ -182,10 +190,7 @@ define([
 | 
			
		||||
                    "implementation": CancelAction,
 | 
			
		||||
                    "name": "Cancel",
 | 
			
		||||
                    "description": "Discard changes made to these objects.",
 | 
			
		||||
                    "depends": [
 | 
			
		||||
                        "$injector",
 | 
			
		||||
                        "navigationService"
 | 
			
		||||
                    ]
 | 
			
		||||
                    "depends": []
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "policies": [
 | 
			
		||||
@@ -252,6 +257,35 @@ define([
 | 
			
		||||
                    "template": topbarEditTemplate
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "components": [
 | 
			
		||||
                {
 | 
			
		||||
                    "type": "decorator",
 | 
			
		||||
                    "provides": "capabilityService",
 | 
			
		||||
                    "implementation": TransactionDecorator,
 | 
			
		||||
                    "depends": [
 | 
			
		||||
                        "$q",
 | 
			
		||||
                        "transactionService",
 | 
			
		||||
                        "dirtyModelCache"
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "type": "provider",
 | 
			
		||||
                    "provides": "transactionService",
 | 
			
		||||
                    "implementation": TransactionService,
 | 
			
		||||
                    "depends": [
 | 
			
		||||
                        "$q",
 | 
			
		||||
                        "dirtyModelCache"
 | 
			
		||||
                    ]
 | 
			
		||||
                },
 | 
			
		||||
                {
 | 
			
		||||
                    "type": "provider",
 | 
			
		||||
                    "provides": "dirtyModelCache",
 | 
			
		||||
                    "implementation": DirtyModelCache,
 | 
			
		||||
                    "depends": [
 | 
			
		||||
                        "topic"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "representers": [
 | 
			
		||||
                {
 | 
			
		||||
                    "implementation": EditRepresenter,
 | 
			
		||||
@@ -263,7 +297,19 @@ define([
 | 
			
		||||
                {
 | 
			
		||||
                    "implementation": EditToolbarRepresenter
 | 
			
		||||
                }
 | 
			
		||||
            ]
 | 
			
		||||
            ],
 | 
			
		||||
            "capabilities": [
 | 
			
		||||
                {
 | 
			
		||||
                    "key": "editor",
 | 
			
		||||
                    "name": "Editor Capability",
 | 
			
		||||
                    "description": "Provides transactional editing capabilities",
 | 
			
		||||
                    "implementation": EditorCapability,
 | 
			
		||||
                    "depends": [
 | 
			
		||||
                        "transactionService",
 | 
			
		||||
                        "dirtyModelCache"
 | 
			
		||||
                    ]
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -33,10 +33,8 @@ define(
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @implements {Action}
 | 
			
		||||
         */
 | 
			
		||||
        function CancelAction($injector, navigationService, context) {
 | 
			
		||||
        function CancelAction(context) {
 | 
			
		||||
            this.domainObject = context.domainObject;
 | 
			
		||||
            this.navigationService = navigationService;
 | 
			
		||||
            this.objectService = $injector.get('objectService');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -46,30 +44,16 @@ define(
 | 
			
		||||
         *          cancellation has completed
 | 
			
		||||
         */
 | 
			
		||||
        CancelAction.prototype.perform = function () {
 | 
			
		||||
            var domainObject = this.domainObject,
 | 
			
		||||
                self = this;
 | 
			
		||||
            var domainObject = this.domainObject;
 | 
			
		||||
 | 
			
		||||
            // Look up the object's "editor.completion" capability;
 | 
			
		||||
            // this is introduced by EditableDomainObject which is
 | 
			
		||||
            // used to insulate underlying objects from changes made
 | 
			
		||||
            // during editing.
 | 
			
		||||
            function getEditorCapability() {
 | 
			
		||||
                return domainObject.getCapability("editor");
 | 
			
		||||
            function returnToBrowse () {
 | 
			
		||||
                var parent;
 | 
			
		||||
                domainObject.getCapability("location").getOriginal().then(function (original) {
 | 
			
		||||
                    parent = original.getCapability("context").getParent();
 | 
			
		||||
                    parent.getCapability("action").perform("navigate");
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Invoke any save behavior introduced by the editor.completion
 | 
			
		||||
            // capability.
 | 
			
		||||
            function doCancel(editor) {
 | 
			
		||||
                return editor.cancel();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //Discard current 'editable' object, and retrieve original
 | 
			
		||||
            // un-edited object.
 | 
			
		||||
            function returnToBrowse() {
 | 
			
		||||
                return self.navigationService.setNavigation(self.domainObject.getOriginalObject());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return doCancel(getEditorCapability())
 | 
			
		||||
            return this.domainObject.getCapability("editor").cancel()
 | 
			
		||||
                .then(returnToBrowse);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@@ -82,7 +66,7 @@ define(
 | 
			
		||||
        CancelAction.appliesTo = function (context) {
 | 
			
		||||
            var domainObject = (context || {}).domainObject;
 | 
			
		||||
            return domainObject !== undefined &&
 | 
			
		||||
                domainObject.hasCapability("editor");
 | 
			
		||||
                domainObject.getCapability("status").get("editing");
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return CancelAction;
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,8 @@
 | 
			
		||||
 * Module defining EditAction. Created by vwoeltje on 11/14/14.
 | 
			
		||||
 */
 | 
			
		||||
define(
 | 
			
		||||
    ['../objects/EditableDomainObject'],
 | 
			
		||||
    function (EditableDomainObject) {
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        // A no-op action to return in the event that the action cannot
 | 
			
		||||
@@ -73,25 +73,12 @@ define(
 | 
			
		||||
         */
 | 
			
		||||
        EditAction.prototype.perform = function () {
 | 
			
		||||
            var self = this;
 | 
			
		||||
            if (!this.domainObject.hasCapability("editor")) {
 | 
			
		||||
                //TODO: This is only necessary because the drop gesture is
 | 
			
		||||
                // wrapping the object itself, need to refactor this later.
 | 
			
		||||
                // All responsibility for switching into edit mode should be
 | 
			
		||||
                // in the edit action, and not duplicated in the gesture
 | 
			
		||||
                this.domainObject = new EditableDomainObject(this.domainObject, this.$q);
 | 
			
		||||
            }
 | 
			
		||||
            this.navigationService.setNavigation(this.domainObject);
 | 
			
		||||
            this.domainObject.getCapability('status').set('editing', true);
 | 
			
		||||
 | 
			
		||||
            //Register a listener to automatically cancel this edit action
 | 
			
		||||
            //if the user navigates away from this object.
 | 
			
		||||
            function cancelEditing(navigatedTo){
 | 
			
		||||
                if (!navigatedTo || navigatedTo.getId() !== self.domainObject.getId()) {
 | 
			
		||||
                    self.domainObject.getCapability('editor').cancel();
 | 
			
		||||
                    self.navigationService.removeListener(cancelEditing);
 | 
			
		||||
                }
 | 
			
		||||
            function cancelEditing(){
 | 
			
		||||
                self.domainObject.getCapability('editor').cancel();
 | 
			
		||||
                self.navigationService.removeListener(cancelEditing);
 | 
			
		||||
            }
 | 
			
		||||
            this.navigationService.addListener(cancelEditing);
 | 
			
		||||
            this.domainObject.useCapability("editor");
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
 
 | 
			
		||||
@@ -115,15 +115,11 @@ define(
 | 
			
		||||
                return copyService.perform(domainObject, parent, allowClone);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function cancelEditingAfterClone(clonedObject) {
 | 
			
		||||
                return domainObject.getCapability("editor").cancel()
 | 
			
		||||
            function saveEdit(clonedObject) {
 | 
			
		||||
                return domainObject.getCapability("editor").save()
 | 
			
		||||
                    .then(resolveWith(clonedObject));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Invoke any save behavior introduced by the editor capability;
 | 
			
		||||
            // this is introduced by EditableDomainObject which is
 | 
			
		||||
            // used to insulate underlying objects from changes made
 | 
			
		||||
            // during editing.
 | 
			
		||||
            function doSave() {
 | 
			
		||||
                //This is a new 'virtual object' that has not been persisted
 | 
			
		||||
                // yet.
 | 
			
		||||
@@ -132,11 +128,10 @@ define(
 | 
			
		||||
                        .then(doWizardSave)
 | 
			
		||||
                        .then(getParent)
 | 
			
		||||
                        .then(cloneIntoParent)
 | 
			
		||||
                        .then(cancelEditingAfterClone)
 | 
			
		||||
                        .then(saveEdit)
 | 
			
		||||
                        .catch(resolveWith(false));
 | 
			
		||||
                } else {
 | 
			
		||||
                    return domainObject.getCapability("editor").save()
 | 
			
		||||
                        .then(resolveWith(domainObject.getOriginalObject()));
 | 
			
		||||
                    return domainObject.getCapability("editor").save();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -162,7 +157,7 @@ define(
 | 
			
		||||
        SaveAction.appliesTo = function (context) {
 | 
			
		||||
            var domainObject = (context || {}).domainObject;
 | 
			
		||||
            return domainObject !== undefined &&
 | 
			
		||||
                domainObject.hasCapability("editor");
 | 
			
		||||
                domainObject.getCapability("status").get("editing");
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return SaveAction;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    function () {
 | 
			
		||||
        'use strict';
 | 
			
		||||
        var DISALLOWED_ACTIONS = ["move", "copy", "link", "window", "follow"];
 | 
			
		||||
        /**
 | 
			
		||||
         * Editable Action Capability. Overrides the action capability
 | 
			
		||||
         * normally exhibited by a domain object and filters out certain
 | 
			
		||||
         * actions not applicable when an object is in edit mode.
 | 
			
		||||
         *
 | 
			
		||||
         * Meant specifically for use by EditableDomainObject and the
 | 
			
		||||
         * associated cache; the constructor signature is particular
 | 
			
		||||
         * to a pattern used there and may contain unused arguments.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @implements {PersistenceCapability}
 | 
			
		||||
         */
 | 
			
		||||
        function EditableActionCapability(
 | 
			
		||||
            actionCapability,
 | 
			
		||||
            editableObject,
 | 
			
		||||
            domainObject,
 | 
			
		||||
            cache
 | 
			
		||||
        ) {
 | 
			
		||||
            var action = Object.create(actionCapability);
 | 
			
		||||
 | 
			
		||||
            action.getActions = function(domainObject) {
 | 
			
		||||
                return actionCapability.getActions(domainObject).filter(function(action){
 | 
			
		||||
                   return DISALLOWED_ACTIONS.indexOf(action.getMetadata().key) === -1;
 | 
			
		||||
                });
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            return action;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return EditableActionCapability;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ['./EditableLookupCapability'],
 | 
			
		||||
    function (EditableLookupCapability) {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Wrapper for the "composition" capability;
 | 
			
		||||
         * ensures that any domain objects reachable in Edit mode
 | 
			
		||||
         * are also wrapped as EditableDomainObjects.
 | 
			
		||||
         *
 | 
			
		||||
         * Meant specifically for use by EditableDomainObject and the
 | 
			
		||||
         * associated cache; the constructor signature is particular
 | 
			
		||||
         * to a pattern used there and may contain unused arguments.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @implements {CompositionCapability}
 | 
			
		||||
         */
 | 
			
		||||
        return function EditableCompositionCapability(
 | 
			
		||||
            contextCapability,
 | 
			
		||||
            editableObject,
 | 
			
		||||
            domainObject,
 | 
			
		||||
            cache
 | 
			
		||||
        ) {
 | 
			
		||||
            // This is a "lookup" style capability (it looks up other
 | 
			
		||||
            // domain objects), but we do not want to return the same
 | 
			
		||||
            // specific value every time (composition may change)
 | 
			
		||||
            return new EditableLookupCapability(
 | 
			
		||||
                contextCapability,
 | 
			
		||||
                editableObject,
 | 
			
		||||
                domainObject,
 | 
			
		||||
                cache,
 | 
			
		||||
                false // Not idempotent
 | 
			
		||||
            );
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,78 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ['./EditableLookupCapability'],
 | 
			
		||||
    function (EditableLookupCapability) {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Wrapper for the "context" capability;
 | 
			
		||||
         * ensures that any domain objects reachable in Edit mode
 | 
			
		||||
         * are also wrapped as EditableDomainObjects.
 | 
			
		||||
         *
 | 
			
		||||
         * Meant specifically for use by EditableDomainObject and the
 | 
			
		||||
         * associated cache; the constructor signature is particular
 | 
			
		||||
         * to a pattern used there and may contain unused arguments.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @implements {ContextCapability}
 | 
			
		||||
         */
 | 
			
		||||
        return function EditableContextCapability(
 | 
			
		||||
            contextCapability,
 | 
			
		||||
            editableObject,
 | 
			
		||||
            domainObject,
 | 
			
		||||
            cache
 | 
			
		||||
        ) {
 | 
			
		||||
            // This is a "lookup" style capability (it looks up other
 | 
			
		||||
            // domain objects), and it should be idempotent
 | 
			
		||||
            var capability = new EditableLookupCapability(
 | 
			
		||||
                    contextCapability,
 | 
			
		||||
                    editableObject,
 | 
			
		||||
                    domainObject,
 | 
			
		||||
                    cache,
 | 
			
		||||
                    true // Idempotent
 | 
			
		||||
                ),
 | 
			
		||||
                // Track the real root object for the Elements pane
 | 
			
		||||
                trueRoot = capability.getRoot();
 | 
			
		||||
 | 
			
		||||
            // Provide access to the real root, for the Elements pane.
 | 
			
		||||
            capability.getTrueRoot = function () {
 | 
			
		||||
                return trueRoot;
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Hide ancestry after the root of this subgraph
 | 
			
		||||
            if (cache.isRoot(domainObject)) {
 | 
			
		||||
                capability.getRoot = function () {
 | 
			
		||||
                    return editableObject;
 | 
			
		||||
                };
 | 
			
		||||
                capability.getPath = function () {
 | 
			
		||||
                    return [editableObject];
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return capability;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ['./EditableLookupCapability'],
 | 
			
		||||
    function (EditableLookupCapability) {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Wrapper for the "instantiation" capability;
 | 
			
		||||
         * ensures that any domain objects instantiated in Edit mode
 | 
			
		||||
         * are also wrapped as EditableDomainObjects.
 | 
			
		||||
         *
 | 
			
		||||
         * Meant specifically for use by EditableDomainObject and the
 | 
			
		||||
         * associated cache; the constructor signature is particular
 | 
			
		||||
         * to a pattern used there and may contain unused arguments.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @implements {CompositionCapability}
 | 
			
		||||
         */
 | 
			
		||||
        return function EditableInstantiationCapability(
 | 
			
		||||
            contextCapability,
 | 
			
		||||
            editableObject,
 | 
			
		||||
            domainObject,
 | 
			
		||||
            cache
 | 
			
		||||
        ) {
 | 
			
		||||
            // This is a "lookup" style capability (it looks up other
 | 
			
		||||
            // domain objects), but we do not want to return the same
 | 
			
		||||
            // specific value every time (composition may change)
 | 
			
		||||
            return new EditableLookupCapability(
 | 
			
		||||
                contextCapability,
 | 
			
		||||
                editableObject,
 | 
			
		||||
                domainObject,
 | 
			
		||||
                cache,
 | 
			
		||||
                false // Not idempotent
 | 
			
		||||
            );
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,125 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Wrapper for both "context" and "composition" capabilities;
 | 
			
		||||
         * ensures that any domain objects reachable in Edit mode
 | 
			
		||||
         * are also wrapped as EditableDomainObjects.
 | 
			
		||||
         *
 | 
			
		||||
         * Meant specifically for use by EditableDomainObject and the
 | 
			
		||||
         * associated cache; the constructor signature is particular
 | 
			
		||||
         * to a pattern used there and may contain unused arguments.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         */
 | 
			
		||||
        return function EditableLookupCapability(
 | 
			
		||||
            contextCapability,
 | 
			
		||||
            editableObject,
 | 
			
		||||
            domainObject,
 | 
			
		||||
            cache,
 | 
			
		||||
            idempotent
 | 
			
		||||
        ) {
 | 
			
		||||
            var capability = Object.create(contextCapability),
 | 
			
		||||
                method;
 | 
			
		||||
 | 
			
		||||
            // Check for domain object interface. If something has these
 | 
			
		||||
            // three methods, we assume it's a domain object.
 | 
			
		||||
            function isDomainObject(obj) {
 | 
			
		||||
                return obj !== undefined &&
 | 
			
		||||
                        typeof obj.getId === 'function' &&
 | 
			
		||||
                        typeof obj.getModel === 'function' &&
 | 
			
		||||
                        typeof obj.getCapability === 'function';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Check an object returned by the wrapped capability; if it
 | 
			
		||||
            // is a domain object, we want to make it editable and/or get
 | 
			
		||||
            // it from the cache of editable domain objects. This will
 | 
			
		||||
            // prevent changes made in edit mode from modifying the actual
 | 
			
		||||
            // underlying domain object.
 | 
			
		||||
            function makeEditableObject(obj) {
 | 
			
		||||
                return isDomainObject(obj) ?
 | 
			
		||||
                        cache.getEditableObject(obj) :
 | 
			
		||||
                        obj;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Wrap a returned value (see above); if it's an array, wrap
 | 
			
		||||
            // all elements.
 | 
			
		||||
            function makeEditable(returnValue) {
 | 
			
		||||
                return Array.isArray(returnValue) ?
 | 
			
		||||
                        returnValue.map(makeEditableObject) :
 | 
			
		||||
                        makeEditableObject(returnValue);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Wrap a returned value (see above); if it's a promise, wrap
 | 
			
		||||
            // the resolved value.
 | 
			
		||||
            function wrapResult(result) {
 | 
			
		||||
                return (result && result.then) ? // promise-like
 | 
			
		||||
                        result.then(makeEditable) :
 | 
			
		||||
                        makeEditable(result);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Return a wrapped version of a function, which ensures
 | 
			
		||||
            // all results are editable domain objects.
 | 
			
		||||
            function wrapFunction(fn) {
 | 
			
		||||
                return function () {
 | 
			
		||||
                    return wrapResult(contextCapability[fn].apply(
 | 
			
		||||
                        capability,
 | 
			
		||||
                        arguments
 | 
			
		||||
                    ));
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Wrap a method such that it only delegates once.
 | 
			
		||||
            function oneTimeFunction(fn) {
 | 
			
		||||
                return function () {
 | 
			
		||||
                    var result = wrapFunction(fn).apply(this, arguments);
 | 
			
		||||
                    capability[fn] = function () {
 | 
			
		||||
                        return result;
 | 
			
		||||
                    };
 | 
			
		||||
                    return result;
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Wrap a method of this capability
 | 
			
		||||
            function wrapMethod(fn) {
 | 
			
		||||
                if (typeof capability[fn] === 'function') {
 | 
			
		||||
                    capability[fn] =
 | 
			
		||||
                        (idempotent ? oneTimeFunction : wrapFunction)(fn);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Wrap all methods; return only editable domain objects.
 | 
			
		||||
            for (method in contextCapability) {
 | 
			
		||||
                wrapMethod(method);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return capability;
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,68 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    function () {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Editable Persistence Capability. Overrides the persistence capability
 | 
			
		||||
         * normally exhibited by a domain object to ensure that changes made
 | 
			
		||||
         * during edit mode are not immediately stored to the database or other
 | 
			
		||||
         * backing storage.
 | 
			
		||||
         *
 | 
			
		||||
         * Meant specifically for use by EditableDomainObject and the
 | 
			
		||||
         * associated cache; the constructor signature is particular
 | 
			
		||||
         * to a pattern used there and may contain unused arguments.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @implements {PersistenceCapability}
 | 
			
		||||
         */
 | 
			
		||||
        function EditablePersistenceCapability(
 | 
			
		||||
            persistenceCapability,
 | 
			
		||||
            editableObject,
 | 
			
		||||
            domainObject,
 | 
			
		||||
            cache
 | 
			
		||||
        ) {
 | 
			
		||||
            var persistence = Object.create(persistenceCapability);
 | 
			
		||||
 | 
			
		||||
            // Simply trigger refresh of in-view objects; do not
 | 
			
		||||
            // write anything to database.
 | 
			
		||||
            persistence.persist = function () {
 | 
			
		||||
                return cache.markDirty(editableObject);
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Delegate refresh to the original object; this avoids refreshing
 | 
			
		||||
            // the editable instance of the object, and ensures that refresh
 | 
			
		||||
            // correctly targets the "real" version of the object.
 | 
			
		||||
            persistence.refresh = function () {
 | 
			
		||||
                return domainObject.getCapability('persistence').refresh();
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            return persistence;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return EditablePersistenceCapability;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ['./EditableLookupCapability'],
 | 
			
		||||
    function (EditableLookupCapability) {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Wrapper for the "relationship" capability;
 | 
			
		||||
         * ensures that any domain objects reachable in Edit mode
 | 
			
		||||
         * are also wrapped as EditableDomainObjects.
 | 
			
		||||
         *
 | 
			
		||||
         * Meant specifically for use by EditableDomainObject and the
 | 
			
		||||
         * associated cache; the constructor signature is particular
 | 
			
		||||
         * to a pattern used there and may contain unused arguments.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @implements {RelationshipCapability}
 | 
			
		||||
         */
 | 
			
		||||
        return function EditableRelationshipCapability(
 | 
			
		||||
            relationshipCapability,
 | 
			
		||||
            editableObject,
 | 
			
		||||
            domainObject,
 | 
			
		||||
            cache
 | 
			
		||||
        ) {
 | 
			
		||||
            // This is a "lookup" style capability (it looks up other
 | 
			
		||||
            // domain objects), but we do not want to return the same
 | 
			
		||||
            // specific value every time (composition may change)
 | 
			
		||||
            return new EditableLookupCapability(
 | 
			
		||||
                relationshipCapability,
 | 
			
		||||
                editableObject,
 | 
			
		||||
                domainObject,
 | 
			
		||||
                cache,
 | 
			
		||||
                false // Not idempotent
 | 
			
		||||
            );
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -26,117 +26,61 @@ define(
 | 
			
		||||
    function () {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Implements "save" and "cancel" as capabilities of
 | 
			
		||||
         * the object. In editing mode, user is seeing/using
 | 
			
		||||
         * a copy of the object (an EditableDomainObject)
 | 
			
		||||
         * which is disconnected from persistence; the Save
 | 
			
		||||
         * and Cancel actions can use this capability to
 | 
			
		||||
         * propagate changes from edit mode to the underlying
 | 
			
		||||
         * actual persistable object.
 | 
			
		||||
         *
 | 
			
		||||
         * Meant specifically for use by EditableDomainObject and the
 | 
			
		||||
         * associated cache; the constructor signature is particular
 | 
			
		||||
         * to a pattern used there and may contain unused arguments.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         */
 | 
			
		||||
        function EditorCapability(
 | 
			
		||||
            persistenceCapability,
 | 
			
		||||
            editableObject,
 | 
			
		||||
            domainObject,
 | 
			
		||||
            cache
 | 
			
		||||
            transactionService,
 | 
			
		||||
            dirtyModelCache,
 | 
			
		||||
            domainObject
 | 
			
		||||
        ) {
 | 
			
		||||
            this.editableObject = editableObject;
 | 
			
		||||
            this.transactionService = transactionService;
 | 
			
		||||
            this.dirtyModelCache = dirtyModelCache;
 | 
			
		||||
            this.domainObject = domainObject;
 | 
			
		||||
            this.cache = cache;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Simulate Promise.resolve (or $q.when); the former
 | 
			
		||||
        // causes a delayed reaction from Angular (since it
 | 
			
		||||
        // does not trigger a digest) and the latter is not
 | 
			
		||||
        // readily accessible, since we're a few classes
 | 
			
		||||
        // removed from the layer which gets dependency
 | 
			
		||||
        // injection.
 | 
			
		||||
        function resolvePromise(value) {
 | 
			
		||||
            return (value && value.then) ? value : {
 | 
			
		||||
                then: function (callback) {
 | 
			
		||||
                    return resolvePromise(callback(value));
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
        EditorCapability.prototype.edit = function () {
 | 
			
		||||
            this.transactionService.startTransaction();
 | 
			
		||||
            this.domainObject.getCapability('status').set('editing', true);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        function isEditing (domainObject) {
 | 
			
		||||
            return domainObject.getCapability('status').get('editing') ||
 | 
			
		||||
                domainObject.hasCapability('context') && isEditing(domainObject.getCapability('context').getParent());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Save any changes that have been made to this domain object
 | 
			
		||||
         * (as well as to others that might have been retrieved and
 | 
			
		||||
         * modified during the editing session)
 | 
			
		||||
         * @param {boolean} nonrecursive if true, save only this
 | 
			
		||||
         *        object (and not other objects with associated changes)
 | 
			
		||||
         * @returns {Promise} a promise that will be fulfilled after
 | 
			
		||||
         *          persistence has completed.
 | 
			
		||||
         * @memberof platform/commonUI/edit.EditorCapability#
 | 
			
		||||
         * Determines whether this object, or any of its ancestors are
 | 
			
		||||
         * currently being edited.
 | 
			
		||||
         * @returns boolean
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.save = function (nonrecursive) {
 | 
			
		||||
            var domainObject = this.domainObject,
 | 
			
		||||
                editableObject = this.editableObject,
 | 
			
		||||
                self = this,
 | 
			
		||||
                cache = this.cache,
 | 
			
		||||
                returnPromise;
 | 
			
		||||
        EditorCapability.prototype.isEditing = function () {
 | 
			
		||||
            return isEditing(this.domainObject);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
            // Update the underlying, "real" domain object's model
 | 
			
		||||
            // with changes made to the copy used for editing.
 | 
			
		||||
            function doMutate() {
 | 
			
		||||
                return domainObject.useCapability('mutation', function () {
 | 
			
		||||
                    return editableObject.getModel();
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Persist the underlying domain object
 | 
			
		||||
            function doPersist() {
 | 
			
		||||
                return domainObject.getCapability('persistence').persist();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            editableObject.getCapability("status").set("editing", false);
 | 
			
		||||
 | 
			
		||||
            if (nonrecursive) {
 | 
			
		||||
                returnPromise = resolvePromise(doMutate())
 | 
			
		||||
                    .then(doPersist)
 | 
			
		||||
                    .then(function(){
 | 
			
		||||
                        self.cancel();
 | 
			
		||||
                    });
 | 
			
		||||
            } else {
 | 
			
		||||
                returnPromise = resolvePromise(cache.saveAll());
 | 
			
		||||
            }
 | 
			
		||||
            //Return the original (non-editable) object
 | 
			
		||||
            return returnPromise.then(function() {
 | 
			
		||||
                return domainObject.getOriginalObject ? domainObject.getOriginalObject() : domainObject;
 | 
			
		||||
        EditorCapability.prototype.save = function () {
 | 
			
		||||
            var domainObject = this.domainObject;
 | 
			
		||||
            return this.transactionService.commit().then(function() {
 | 
			
		||||
                domainObject.getCapability('status').set('editing', false);
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Cancel editing; Discard any changes that have been made to
 | 
			
		||||
         * this domain object (as well as to others that might have
 | 
			
		||||
         * been retrieved and modified during the editing session)
 | 
			
		||||
         * @returns {Promise} a promise that will be fulfilled after
 | 
			
		||||
         *          cancellation has completed.
 | 
			
		||||
         * @memberof platform/commonUI/edit.EditorCapability#
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.invoke = EditorCapability.prototype.edit;
 | 
			
		||||
 | 
			
		||||
        EditorCapability.prototype.cancel = function () {
 | 
			
		||||
            this.editableObject.getCapability("status").set("editing", false);
 | 
			
		||||
            this.cache.markClean();
 | 
			
		||||
            return resolvePromise(undefined);
 | 
			
		||||
            var domainObject = this.domainObject;
 | 
			
		||||
            return this.transactionService.cancel().then(function(){
 | 
			
		||||
                domainObject.getCapability("status").set("editing", false);
 | 
			
		||||
                return domainObject;
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check if there are any unsaved changes.
 | 
			
		||||
         * @returns {boolean} true if there are unsaved changes
 | 
			
		||||
         * @memberof platform/commonUI/edit.EditorCapability#
 | 
			
		||||
         */
 | 
			
		||||
        EditorCapability.prototype.dirty = function () {
 | 
			
		||||
            return this.cache.dirty();
 | 
			
		||||
            return this.dirtyModelCache.isDirty(this.domainObject);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        EditorCapability.prototype.appliesTo = function(context) {
 | 
			
		||||
            var domainObject = context.domainObject;
 | 
			
		||||
            return domainObject && domainObject.getType().hasFeature("creation");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return EditorCapability;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,68 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ['./TransactionalPersistenceCapability'],
 | 
			
		||||
    function (TransactionalPersistenceCapability) {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        function TransactionDecorator(
 | 
			
		||||
            $q,
 | 
			
		||||
            transactionService,
 | 
			
		||||
            dirtyModelCache,
 | 
			
		||||
            capabilityService
 | 
			
		||||
        ) {
 | 
			
		||||
            this.capabilityService = capabilityService;
 | 
			
		||||
            this.transactionService = transactionService;
 | 
			
		||||
            this.dirtyModelCache = dirtyModelCache;
 | 
			
		||||
            this.$q = $q;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Decorate PersistenceCapability to ignore persistence calls when a
 | 
			
		||||
         * transaction is in progress.
 | 
			
		||||
         */
 | 
			
		||||
        TransactionDecorator.prototype.getCapabilities = function (model) {
 | 
			
		||||
            var self = this,
 | 
			
		||||
                capabilities = this.capabilityService.getCapabilities(model),
 | 
			
		||||
                persistenceCapability = capabilities.persistence;
 | 
			
		||||
 | 
			
		||||
            capabilities.persistence = function (domainObject) {
 | 
			
		||||
                var original =
 | 
			
		||||
                    (typeof persistenceCapability === 'function') ?
 | 
			
		||||
                        persistenceCapability(domainObject) :
 | 
			
		||||
                        persistenceCapability;
 | 
			
		||||
                return new TransactionalPersistenceCapability(
 | 
			
		||||
                    self.$q,
 | 
			
		||||
                    self.transactionService,
 | 
			
		||||
                    self.dirtyModelCache,
 | 
			
		||||
                    original,
 | 
			
		||||
                    domainObject
 | 
			
		||||
                );
 | 
			
		||||
            };
 | 
			
		||||
            return capabilities;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return TransactionDecorator;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -0,0 +1,75 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        function TransactionalPersistenceCapability(
 | 
			
		||||
            $q,
 | 
			
		||||
            transactionService,
 | 
			
		||||
            dirtyModelCache,
 | 
			
		||||
            persistenceCapability,
 | 
			
		||||
            domainObject
 | 
			
		||||
        ) {
 | 
			
		||||
            this.transactionService = transactionService;
 | 
			
		||||
            this.dirtyModelCache = dirtyModelCache;
 | 
			
		||||
            this.persistenceCapability = Object.create(persistenceCapability);
 | 
			
		||||
            this.domainObject = domainObject;
 | 
			
		||||
            this.$q = $q;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TransactionalPersistenceCapability.prototype.persist = function () {
 | 
			
		||||
            var domainObject = this.domainObject,
 | 
			
		||||
                dirtyModelCache = this.dirtyModelCache;
 | 
			
		||||
            if (this.transactionService.isActive() && !this.transactionService.isCommitting()) {
 | 
			
		||||
                dirtyModelCache.markDirty(domainObject);
 | 
			
		||||
                //Using $q here because need to return something
 | 
			
		||||
                // from which 'catch' can be chained
 | 
			
		||||
                return this.$q.when(true);
 | 
			
		||||
            } else {
 | 
			
		||||
                return this.persistenceCapability.persist().then(function (result) {
 | 
			
		||||
                    dirtyModelCache.markClean(domainObject);
 | 
			
		||||
                    return result;
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TransactionalPersistenceCapability.prototype.refresh = function () {
 | 
			
		||||
            var domainObject = this.domainObject,
 | 
			
		||||
                dirtyModelCache = this.dirtyModelCache;
 | 
			
		||||
 | 
			
		||||
            return this.persistenceCapability.refresh().then(function (result) {
 | 
			
		||||
                dirtyModelCache.markClean(domainObject);
 | 
			
		||||
                return result;
 | 
			
		||||
            });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TransactionalPersistenceCapability.prototype.getSpace = function () {
 | 
			
		||||
            return this.persistenceCapability.getSpace();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return TransactionalPersistenceCapability;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,132 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Defines EditableDomainObject, which wraps domain objects
 | 
			
		||||
 * such that user code may work with and mutate a copy of the
 | 
			
		||||
 * domain object model; these changes may then be propagated
 | 
			
		||||
 * up to the real domain object (or not) by way of invoking
 | 
			
		||||
 * save or cancel behaviors of the "editor.completion"
 | 
			
		||||
 * capability (a capability intended as internal to edit
 | 
			
		||||
 * mode; invoked by way of the Save and Cancel actions.)
 | 
			
		||||
 */
 | 
			
		||||
define(
 | 
			
		||||
    [
 | 
			
		||||
        '../capabilities/EditablePersistenceCapability',
 | 
			
		||||
        '../capabilities/EditableContextCapability',
 | 
			
		||||
        '../capabilities/EditableCompositionCapability',
 | 
			
		||||
        '../capabilities/EditableRelationshipCapability',
 | 
			
		||||
        '../capabilities/EditableInstantiationCapability',
 | 
			
		||||
        '../capabilities/EditorCapability',
 | 
			
		||||
        '../capabilities/EditableActionCapability',
 | 
			
		||||
        './EditableDomainObjectCache'
 | 
			
		||||
    ],
 | 
			
		||||
    function (
 | 
			
		||||
        EditablePersistenceCapability,
 | 
			
		||||
        EditableContextCapability,
 | 
			
		||||
        EditableCompositionCapability,
 | 
			
		||||
        EditableRelationshipCapability,
 | 
			
		||||
        EditableInstantiationCapability,
 | 
			
		||||
        EditorCapability,
 | 
			
		||||
        EditableActionCapability,
 | 
			
		||||
        EditableDomainObjectCache
 | 
			
		||||
    ) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        var capabilityFactories = {
 | 
			
		||||
            persistence: EditablePersistenceCapability,
 | 
			
		||||
            context: EditableContextCapability,
 | 
			
		||||
            composition: EditableCompositionCapability,
 | 
			
		||||
            relationship: EditableRelationshipCapability,
 | 
			
		||||
            instantiation: EditableInstantiationCapability,
 | 
			
		||||
            editor: EditorCapability
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Handle special case where "editor.completion" wraps persistence
 | 
			
		||||
        // (other capability overrides wrap capabilities of the same type.)
 | 
			
		||||
        function getDelegateArguments(name, args) {
 | 
			
		||||
            return name === "editor" ? ['persistence'] : args;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An EditableDomainObject overrides capabilities
 | 
			
		||||
         * which need to behave differently in edit mode,
 | 
			
		||||
         * and provides a "working copy" of the object's
 | 
			
		||||
         * model to allow changes to be easily cancelled.
 | 
			
		||||
         * @constructor
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @implements {DomainObject}
 | 
			
		||||
         */
 | 
			
		||||
        function EditableDomainObject(domainObject, $q) {
 | 
			
		||||
            // The cache will hold all domain objects reached from
 | 
			
		||||
            // the initial EditableDomainObject; this ensures that
 | 
			
		||||
            // different versions of the same editable domain object
 | 
			
		||||
            // are not shown in different sections of the same Edit
 | 
			
		||||
            // UI, which might thereby fall out of sync.
 | 
			
		||||
            var cache,
 | 
			
		||||
                originalObject = domainObject,
 | 
			
		||||
                cachedObject;
 | 
			
		||||
 | 
			
		||||
            // Constructor for EditableDomainObject, which adheres
 | 
			
		||||
            // to the same shared cache.
 | 
			
		||||
            function EditableDomainObjectImpl(domainObject, model) {
 | 
			
		||||
                var editableObject = Object.create(domainObject);
 | 
			
		||||
 | 
			
		||||
                // Only provide the cloned model.
 | 
			
		||||
                editableObject.getModel = function () { return model; };
 | 
			
		||||
 | 
			
		||||
                // Override certain capabilities
 | 
			
		||||
                editableObject.getCapability = function (name) {
 | 
			
		||||
                    var delegateArguments = getDelegateArguments(name, arguments),
 | 
			
		||||
                        capability = domainObject.getCapability.apply(
 | 
			
		||||
                            this,
 | 
			
		||||
                            delegateArguments
 | 
			
		||||
                        ),
 | 
			
		||||
                        Factory = capabilityFactories[name];
 | 
			
		||||
 | 
			
		||||
                    return (Factory && capability) ?
 | 
			
		||||
                            new Factory(capability, editableObject, domainObject, cache) :
 | 
			
		||||
                            capability;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                editableObject.setOriginalObject = function(object) {
 | 
			
		||||
                    originalObject = object;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                editableObject.getOriginalObject = function() {
 | 
			
		||||
                    return originalObject;
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                return editableObject;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            cache = new EditableDomainObjectCache(EditableDomainObjectImpl, $q);
 | 
			
		||||
            cachedObject = cache.getEditableObject(domainObject);
 | 
			
		||||
 | 
			
		||||
            return cachedObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return EditableDomainObject;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,173 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * An editable domain object cache stores domain objects that have been
 | 
			
		||||
 * made editable, in a group that can be saved all-at-once. This supports
 | 
			
		||||
 * Edit mode, which is launched for a specific object but may contain
 | 
			
		||||
 * changes across many objects.
 | 
			
		||||
 *
 | 
			
		||||
 * Editable domain objects have certain specific capabilities overridden
 | 
			
		||||
 * to ensure that changes made while in edit mode do not propagate up
 | 
			
		||||
 * to the objects used in browse mode (or to persistence) until the user
 | 
			
		||||
 * initiates a Save.
 | 
			
		||||
 */
 | 
			
		||||
define(
 | 
			
		||||
    ["./EditableModelCache"],
 | 
			
		||||
    function (EditableModelCache) {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Construct a new cache for editable domain objects. This can be used
 | 
			
		||||
         * to get-or-create editable objects, particularly to support wrapping
 | 
			
		||||
         * of objects retrieved via composition or context capabilities as
 | 
			
		||||
         * editable domain objects.
 | 
			
		||||
         *
 | 
			
		||||
         * @param {Constructor<DomainObject>} EditableDomainObject a
 | 
			
		||||
         *        constructor function which takes a regular domain object as
 | 
			
		||||
         *        an argument, and returns an editable domain object as its
 | 
			
		||||
         *        result.
 | 
			
		||||
         * @param $q Angular's $q, for promise handling
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @constructor
 | 
			
		||||
         */
 | 
			
		||||
        function EditableDomainObjectCache(EditableDomainObject, $q) {
 | 
			
		||||
            this.cache = new EditableModelCache();
 | 
			
		||||
            this.dirtyObjects = {};
 | 
			
		||||
            this.root = undefined;
 | 
			
		||||
            this.$q = $q;
 | 
			
		||||
            this.EditableDomainObject = EditableDomainObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Wrap this domain object in an editable form, or pull such
 | 
			
		||||
         * an object from the cache if one already exists.
 | 
			
		||||
         *
 | 
			
		||||
         * @param {DomainObject} domainObject the regular domain object
 | 
			
		||||
         * @returns {DomainObject} the domain object in an editable form
 | 
			
		||||
         */
 | 
			
		||||
        EditableDomainObjectCache.prototype.getEditableObject = function (domainObject) {
 | 
			
		||||
            var type = domainObject.getCapability('type'),
 | 
			
		||||
                EditableDomainObject = this.EditableDomainObject,
 | 
			
		||||
                editableObject,
 | 
			
		||||
                statusListener;
 | 
			
		||||
 | 
			
		||||
            // Track the top-level domain object; this will have
 | 
			
		||||
            // some special behavior for its context capability.
 | 
			
		||||
            this.root = this.root || domainObject;
 | 
			
		||||
 | 
			
		||||
            // Avoid double-wrapping (WTD-1017)
 | 
			
		||||
            if (domainObject.hasCapability('editor')) {
 | 
			
		||||
                return domainObject;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Don't bother wrapping non-editable objects
 | 
			
		||||
            if (!type || !type.hasFeature('creation')) {
 | 
			
		||||
                return domainObject;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Provide an editable form of the object
 | 
			
		||||
            editableObject = new EditableDomainObject(
 | 
			
		||||
                domainObject,
 | 
			
		||||
                this.cache.getCachedModel(domainObject)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            return editableObject;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check if a domain object is (effectively) the top-level
 | 
			
		||||
         * object in this editable subgraph.
 | 
			
		||||
         * @returns {boolean} true if it is the root
 | 
			
		||||
         */
 | 
			
		||||
        EditableDomainObjectCache.prototype.isRoot = function (domainObject) {
 | 
			
		||||
            return domainObject === this.root;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Mark an editable domain object (presumably already cached)
 | 
			
		||||
         * as having received modifications during editing; it should be
 | 
			
		||||
         * included in the bulk save invoked when editing completes.
 | 
			
		||||
         *
 | 
			
		||||
         * @param {DomainObject} domainObject the domain object
 | 
			
		||||
         * @memberof platform/commonUI/edit.EditableDomainObjectCache#
 | 
			
		||||
         */
 | 
			
		||||
        EditableDomainObjectCache.prototype.markDirty = function (domainObject) {
 | 
			
		||||
            this.dirtyObjects[domainObject.getId()] = domainObject;
 | 
			
		||||
            return this.$q.when(true);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Mark an object (presumably already cached) as having had its
 | 
			
		||||
         * changes saved (and thus no longer needing to be subject to a
 | 
			
		||||
         * save operation.)
 | 
			
		||||
         *
 | 
			
		||||
         * @param {DomainObject} domainObject the domain object
 | 
			
		||||
         */
 | 
			
		||||
        EditableDomainObjectCache.prototype.markClean = function (domainObject) {
 | 
			
		||||
            var self = this;
 | 
			
		||||
            if (!domainObject) {
 | 
			
		||||
                Object.keys(this.dirtyObjects).forEach(function(key) {
 | 
			
		||||
                    delete self.dirtyObjects[key];
 | 
			
		||||
                });
 | 
			
		||||
            } else {
 | 
			
		||||
                delete this.dirtyObjects[domainObject.getId()];
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Initiate a save on all objects that have been cached.
 | 
			
		||||
         * @return {Promise} A promise which will resolve when all objects are
 | 
			
		||||
         *         persisted.
 | 
			
		||||
         */
 | 
			
		||||
        EditableDomainObjectCache.prototype.saveAll = function () {
 | 
			
		||||
            // Get a list of all dirty objects
 | 
			
		||||
            var dirty = this.dirtyObjects,
 | 
			
		||||
                objects = Object.keys(dirty).map(function (k) {
 | 
			
		||||
                    return dirty[k];
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            // Clear dirty set, since we're about to save.
 | 
			
		||||
            this.dirtyObjects = {};
 | 
			
		||||
 | 
			
		||||
            // Most save logic is handled by the "editor.completion"
 | 
			
		||||
            // capability, so that is delegated here.
 | 
			
		||||
            return this.$q.all(objects.map(function (object) {
 | 
			
		||||
                // Save; pass a nonrecursive flag to avoid looping
 | 
			
		||||
                return object.getCapability('editor').save(true);
 | 
			
		||||
            }));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Check if any objects have been marked dirty in this cache.
 | 
			
		||||
         * @returns {boolean} true if objects are dirty
 | 
			
		||||
         */
 | 
			
		||||
        EditableDomainObjectCache.prototype.dirty = function () {
 | 
			
		||||
            return Object.keys(this.dirtyObjects).length > 0;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return EditableDomainObjectCache;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
@@ -1,62 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    [],
 | 
			
		||||
    function () {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * An editable model cache stores domain object models that have been
 | 
			
		||||
         * made editable, to support a group that can be saved all-at-once.
 | 
			
		||||
         * This is useful in Edit mode, which is launched for a specific
 | 
			
		||||
         * object but may contain changes across many objects.
 | 
			
		||||
         * @memberof platform/commonUI/edit
 | 
			
		||||
         * @constructor
 | 
			
		||||
         */
 | 
			
		||||
        function EditableModelCache() {
 | 
			
		||||
            this.cache = {};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Deep-copy a model. Models are JSONifiable, so this can be
 | 
			
		||||
        // done by stringification then destringification
 | 
			
		||||
        function clone(model) {
 | 
			
		||||
            return JSON.parse(JSON.stringify(model));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Get this domain object's model from the cache (or
 | 
			
		||||
         * place it in the cache if it isn't in the cache yet)
 | 
			
		||||
         * @returns a clone of the domain object's model
 | 
			
		||||
         */
 | 
			
		||||
        EditableModelCache.prototype.getCachedModel = function (domainObject) {
 | 
			
		||||
            var id = domainObject.getId(),
 | 
			
		||||
                cache = this.cache;
 | 
			
		||||
 | 
			
		||||
            return (cache[id] =
 | 
			
		||||
                cache[id] || clone(domainObject.getModel()));
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return EditableModelCache;
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -37,11 +37,12 @@ define([], function () {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    EditableLinkPolicy.prototype.allow = function (action, context) {
 | 
			
		||||
        var key = action.getMetadata().key;
 | 
			
		||||
        var key = action.getMetadata().key,
 | 
			
		||||
            object;
 | 
			
		||||
 | 
			
		||||
        if (key === 'link') {
 | 
			
		||||
            return !((context.selectedObject || context.domainObject)
 | 
			
		||||
                .hasCapability('editor'));
 | 
			
		||||
            object = context.selectedObject || context.domainObject;
 | 
			
		||||
            return !(object.hasCapability("editor") && object.getCapability("editor").isEditing());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Like all policies, allow by default.
 | 
			
		||||
 
 | 
			
		||||
@@ -39,8 +39,8 @@ define([], function () {
 | 
			
		||||
            selectedObject = context.selectedObject,
 | 
			
		||||
            key = action.getMetadata().key;
 | 
			
		||||
 | 
			
		||||
        if (key === 'move' && domainObject.hasCapability('editor')) {
 | 
			
		||||
            return !!selectedObject && selectedObject.hasCapability('editor');
 | 
			
		||||
        if (key === 'move' && domainObject.hasCapability('editor') && domainObject.getCapability('editor').isEditing()) {
 | 
			
		||||
            return !!selectedObject && selectedObject.hasCapability('editor') && selectedObject.getCapability('editor').isEditing();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Like all policies, allow by default.
 | 
			
		||||
 
 | 
			
		||||
@@ -39,7 +39,7 @@ define(
 | 
			
		||||
            // If a view is flagged as non-editable, only allow it
 | 
			
		||||
            // while we're not in Edit mode.
 | 
			
		||||
            if ((view || {}).editable === false) {
 | 
			
		||||
                return !domainObject.hasCapability('editor');
 | 
			
		||||
                return !(domainObject.hasCapability('editor') && domainObject.getCapability('editor').isEditing());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Like all policies, allow by default.
 | 
			
		||||
 
 | 
			
		||||
@@ -19,15 +19,29 @@
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define,describe,it,expect,beforeEach,jasmine*/
 | 
			
		||||
 | 
			
		||||
/*global define*/
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/objects/EditableDomainObject"],
 | 
			
		||||
    function (EditableDomainObject) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
    [],
 | 
			
		||||
    function() {
 | 
			
		||||
        function DirtyModelCache(topic) {
 | 
			
		||||
            this.cache = {};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        describe("Editable domain object", function () {
 | 
			
		||||
        DirtyModelCache.prototype.get = function () {
 | 
			
		||||
            return this.cache;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
        DirtyModelCache.prototype.isDirty = function (domainObject) {
 | 
			
		||||
            return !!this.cache[domainObject.getId()];
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        DirtyModelCache.prototype.markDirty = function (domainObject) {
 | 
			
		||||
            this.cache[domainObject.getId()] = domainObject;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        DirtyModelCache.prototype.markClean = function (domainObject) {
 | 
			
		||||
            delete this.cache[domainObject.getId()];
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return DirtyModelCache;
 | 
			
		||||
    });
 | 
			
		||||
							
								
								
									
										118
									
								
								platform/commonUI/edit/src/services/TransactionService.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								platform/commonUI/edit/src/services/TransactionService.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define*/
 | 
			
		||||
define(
 | 
			
		||||
    [],
 | 
			
		||||
    function() {
 | 
			
		||||
        /**
 | 
			
		||||
         * Implements an application-wide transaction state. Once a
 | 
			
		||||
         * transaction is started, calls to PersistenceCapability.persist()
 | 
			
		||||
         * will be deferred until a subsequent call to
 | 
			
		||||
         * TransactionService.commit() is made.
 | 
			
		||||
         *
 | 
			
		||||
         * @param $q
 | 
			
		||||
         * @constructor
 | 
			
		||||
         */
 | 
			
		||||
        function TransactionService($q, dirtyModelCache) {
 | 
			
		||||
            this.$q = $q;
 | 
			
		||||
            this.transaction = false;
 | 
			
		||||
            this.committing = false;
 | 
			
		||||
            this.cache = dirtyModelCache;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TransactionService.prototype.startTransaction = function () {
 | 
			
		||||
            if (this.transaction)
 | 
			
		||||
                console.error("Transaction already in progress")
 | 
			
		||||
            this.transaction = true;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TransactionService.prototype.isActive = function () {
 | 
			
		||||
            return this.transaction;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        TransactionService.prototype.isCommitting = function () {
 | 
			
		||||
            return this.committing;
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * All persist calls deferred since the beginning of the transaction
 | 
			
		||||
         * will be committed. Any failures will be reported via a promise
 | 
			
		||||
         * rejection.
 | 
			
		||||
         * @returns {*}
 | 
			
		||||
         */
 | 
			
		||||
        TransactionService.prototype.commit = function () {
 | 
			
		||||
            var self = this;
 | 
			
		||||
                cache = this.cache.get();
 | 
			
		||||
 | 
			
		||||
            this.committing = true;
 | 
			
		||||
 | 
			
		||||
            function keyToObject(key) {
 | 
			
		||||
                return cache[key];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function objectToPromise(object) {
 | 
			
		||||
                return object.getCapability('persistence').persist();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return this.$q.all(
 | 
			
		||||
                Object.keys(cache)
 | 
			
		||||
                    .map(keyToObject)
 | 
			
		||||
                    .map(objectToPromise))
 | 
			
		||||
                .then(function () {
 | 
			
		||||
                    self.transaction = false;
 | 
			
		||||
                    this.committing = false;
 | 
			
		||||
                }).catch(function() {
 | 
			
		||||
                    return this.committing = false;
 | 
			
		||||
                });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Cancel the current transaction, replacing any dirty objects from
 | 
			
		||||
         * persistence. Not a true rollback, as it cannot be used to undo any
 | 
			
		||||
         * persist calls that were successful in the event one of a batch of
 | 
			
		||||
         * persists failing.
 | 
			
		||||
         *
 | 
			
		||||
         * @returns {*}
 | 
			
		||||
         */
 | 
			
		||||
        TransactionService.prototype.cancel = function () {
 | 
			
		||||
            var self = this,
 | 
			
		||||
                cache = this.cache.get();
 | 
			
		||||
 | 
			
		||||
            function keyToObject(key) {
 | 
			
		||||
                return cache[key];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function objectToPromise(object) {
 | 
			
		||||
                return self.$q.when(object.getModel().persisted && object.getCapability('persistence').refresh());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return this.$q.all(Object.keys(cache)
 | 
			
		||||
                .map(keyToObject)
 | 
			
		||||
                .map(objectToPromise))
 | 
			
		||||
                .then(function () {
 | 
			
		||||
                    self.transaction = false;
 | 
			
		||||
                    this.committing = false;
 | 
			
		||||
                });
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return TransactionService;
 | 
			
		||||
});
 | 
			
		||||
@@ -1,75 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define,describe,it,expect,beforeEach,jasmine*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/capabilities/EditableCompositionCapability"],
 | 
			
		||||
    function (EditableCompositionCapability) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        describe("An editable composition capability", function () {
 | 
			
		||||
            var mockContext,
 | 
			
		||||
                mockEditableObject,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                mockTestObject,
 | 
			
		||||
                someValue,
 | 
			
		||||
                mockFactory,
 | 
			
		||||
                capability;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                // EditableContextCapability should watch ALL
 | 
			
		||||
                // methods for domain objects, so give it an
 | 
			
		||||
                // arbitrary interface to wrap.
 | 
			
		||||
                mockContext =
 | 
			
		||||
                    jasmine.createSpyObj("context", [ "getDomainObject" ]);
 | 
			
		||||
                mockTestObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    [ "getId", "getModel", "getCapability" ]
 | 
			
		||||
                );
 | 
			
		||||
                mockFactory =
 | 
			
		||||
                    jasmine.createSpyObj("factory", ["getEditableObject"]);
 | 
			
		||||
 | 
			
		||||
                someValue = { x: 42 };
 | 
			
		||||
 | 
			
		||||
                mockContext.getDomainObject.andReturn(mockTestObject);
 | 
			
		||||
                mockFactory.getEditableObject.andReturn(someValue);
 | 
			
		||||
 | 
			
		||||
                capability = new EditableCompositionCapability(
 | 
			
		||||
                    mockContext,
 | 
			
		||||
                    mockEditableObject,
 | 
			
		||||
                    mockDomainObject,
 | 
			
		||||
                    mockFactory
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Most behavior is tested for EditableLookupCapability,
 | 
			
		||||
            // so just verify that this isse
 | 
			
		||||
            it("presumes non-idempotence of its wrapped capability", function () {
 | 
			
		||||
                expect(capability.getDomainObject())
 | 
			
		||||
                    .toEqual(capability.getDomainObject());
 | 
			
		||||
                expect(mockContext.getDomainObject.calls.length).toEqual(2);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define,describe,it,expect,beforeEach,jasmine*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/capabilities/EditableContextCapability"],
 | 
			
		||||
    function (EditableContextCapability) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        describe("An editable context capability", function () {
 | 
			
		||||
            var mockContext,
 | 
			
		||||
                mockEditableObject,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                mockTestObject,
 | 
			
		||||
                someValue,
 | 
			
		||||
                mockFactory,
 | 
			
		||||
                capability;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                // EditableContextCapability should watch ALL
 | 
			
		||||
                // methods for domain objects, so give it an
 | 
			
		||||
                // arbitrary interface to wrap.
 | 
			
		||||
                mockContext =
 | 
			
		||||
                    jasmine.createSpyObj("context", [ "getDomainObject", "getRoot" ]);
 | 
			
		||||
                mockTestObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    [ "getId", "getModel", "getCapability" ]
 | 
			
		||||
                );
 | 
			
		||||
                mockFactory = jasmine.createSpyObj(
 | 
			
		||||
                    "factory",
 | 
			
		||||
                    ["getEditableObject", "isRoot"]
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                someValue = { x: 42 };
 | 
			
		||||
 | 
			
		||||
                mockContext.getRoot.andReturn(mockTestObject);
 | 
			
		||||
                mockContext.getDomainObject.andReturn(mockTestObject);
 | 
			
		||||
                mockFactory.getEditableObject.andReturn(someValue);
 | 
			
		||||
                mockFactory.isRoot.andReturn(true);
 | 
			
		||||
 | 
			
		||||
                capability = new EditableContextCapability(
 | 
			
		||||
                    mockContext,
 | 
			
		||||
                    mockEditableObject,
 | 
			
		||||
                    mockDomainObject,
 | 
			
		||||
                    mockFactory
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("presumes idempotence of its wrapped capability", function () {
 | 
			
		||||
                expect(capability.getDomainObject())
 | 
			
		||||
                    .toEqual(capability.getDomainObject());
 | 
			
		||||
                expect(mockContext.getDomainObject.calls.length).toEqual(1);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("hides the root object", function () {
 | 
			
		||||
                expect(capability.getRoot()).toEqual(mockEditableObject);
 | 
			
		||||
                expect(capability.getPath()).toEqual([mockEditableObject]);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("exposes the root object through a different method", function () {
 | 
			
		||||
                // Should still go through the factory...
 | 
			
		||||
                expect(capability.getTrueRoot()).toEqual(someValue);
 | 
			
		||||
                // ...with value of the unwrapped capability's getRoot
 | 
			
		||||
                expect(mockFactory.getEditableObject)
 | 
			
		||||
                    .toHaveBeenCalledWith(mockTestObject);
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,146 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define,describe,it,expect,beforeEach,jasmine*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/capabilities/EditableLookupCapability"],
 | 
			
		||||
    function (EditableLookupCapability) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        describe("An editable lookup capability", function () {
 | 
			
		||||
            var mockContext,
 | 
			
		||||
                mockEditableObject,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                mockTestObject,
 | 
			
		||||
                someValue,
 | 
			
		||||
                factory,
 | 
			
		||||
                capability;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                // EditableContextCapability should watch ALL
 | 
			
		||||
                // methods for domain objects, so give it an
 | 
			
		||||
                // arbitrary interface to wrap.
 | 
			
		||||
                mockContext = jasmine.createSpyObj(
 | 
			
		||||
                    "context",
 | 
			
		||||
                    [
 | 
			
		||||
                        "getSomething",
 | 
			
		||||
                        "getDomainObject",
 | 
			
		||||
                        "getDomainObjectArray"
 | 
			
		||||
                    ]
 | 
			
		||||
                );
 | 
			
		||||
                mockTestObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    [ "getId", "getModel", "getCapability" ]
 | 
			
		||||
                );
 | 
			
		||||
                factory = {
 | 
			
		||||
                    getEditableObject: function (v) {
 | 
			
		||||
                        return {
 | 
			
		||||
                            isFromTestFactory: true,
 | 
			
		||||
                            calledWith: v
 | 
			
		||||
                        };
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                someValue = { x: 42 };
 | 
			
		||||
 | 
			
		||||
                mockContext.getSomething.andReturn(someValue);
 | 
			
		||||
                mockContext.getDomainObject.andReturn(mockTestObject);
 | 
			
		||||
                mockContext.getDomainObjectArray.andReturn([mockTestObject]);
 | 
			
		||||
 | 
			
		||||
                capability = new EditableLookupCapability(
 | 
			
		||||
                    mockContext,
 | 
			
		||||
                    mockEditableObject,
 | 
			
		||||
                    mockDomainObject,
 | 
			
		||||
                    factory,
 | 
			
		||||
                    false
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("wraps retrieved domain objects", function () {
 | 
			
		||||
                var object = capability.getDomainObject();
 | 
			
		||||
                expect(object.isFromTestFactory).toBe(true);
 | 
			
		||||
                expect(object.calledWith).toEqual(mockTestObject);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("wraps retrieved domain object arrays", function () {
 | 
			
		||||
                var object = capability.getDomainObjectArray()[0];
 | 
			
		||||
                expect(object.isFromTestFactory).toBe(true);
 | 
			
		||||
                expect(object.calledWith).toEqual(mockTestObject);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("does not wrap non-domain-objects", function () {
 | 
			
		||||
                expect(capability.getSomething()).toEqual(someValue);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("caches idempotent lookups", function () {
 | 
			
		||||
                capability = new EditableLookupCapability(
 | 
			
		||||
                    mockContext,
 | 
			
		||||
                    mockEditableObject,
 | 
			
		||||
                    mockDomainObject,
 | 
			
		||||
                    factory,
 | 
			
		||||
                    true // idempotent
 | 
			
		||||
                );
 | 
			
		||||
                expect(capability.getDomainObject())
 | 
			
		||||
                    .toEqual(capability.getDomainObject());
 | 
			
		||||
                expect(mockContext.getDomainObject.calls.length).toEqual(1);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("does not cache non-idempotent lookups", function () {
 | 
			
		||||
                capability = new EditableLookupCapability(
 | 
			
		||||
                    mockContext,
 | 
			
		||||
                    mockEditableObject,
 | 
			
		||||
                    mockDomainObject,
 | 
			
		||||
                    factory,
 | 
			
		||||
                    false // Not idempotent
 | 
			
		||||
                );
 | 
			
		||||
                expect(capability.getDomainObject())
 | 
			
		||||
                    .toEqual(capability.getDomainObject());
 | 
			
		||||
                expect(mockContext.getDomainObject.calls.length).toEqual(2);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("wraps inherited methods", function () {
 | 
			
		||||
                var CapabilityClass = function(){
 | 
			
		||||
                };
 | 
			
		||||
                CapabilityClass.prototype.inheritedMethod=function () {
 | 
			
		||||
                    return "an inherited method";
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                mockContext = new CapabilityClass();
 | 
			
		||||
 | 
			
		||||
                capability = new EditableLookupCapability(
 | 
			
		||||
                    mockContext,
 | 
			
		||||
                    mockEditableObject,
 | 
			
		||||
                    mockDomainObject,
 | 
			
		||||
                    factory,
 | 
			
		||||
                    false
 | 
			
		||||
                );
 | 
			
		||||
                expect(capability.inheritedMethod()).toEqual("an inherited method");
 | 
			
		||||
                expect(capability.hasOwnProperty('inheritedMethod')).toBe(true);
 | 
			
		||||
                // The presence of an own property indicates that the method
 | 
			
		||||
                // has been wrapped on the object itself and this is a valid
 | 
			
		||||
                // test that the inherited method has been wrapped.
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,96 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define,describe,it,expect,beforeEach,jasmine*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/capabilities/EditablePersistenceCapability"],
 | 
			
		||||
    function (EditablePersistenceCapability) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        describe("An editable persistence capability", function () {
 | 
			
		||||
            var mockPersistence,
 | 
			
		||||
                mockEditableObject,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                mockCache,
 | 
			
		||||
                mockPromise,
 | 
			
		||||
                capability;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockPersistence = jasmine.createSpyObj(
 | 
			
		||||
                    "persistence",
 | 
			
		||||
                    [ "persist", "refresh" ]
 | 
			
		||||
                );
 | 
			
		||||
                mockEditableObject = jasmine.createSpyObj(
 | 
			
		||||
                    "editableObject",
 | 
			
		||||
                    [ "getId", "getModel", "getCapability" ]
 | 
			
		||||
                );
 | 
			
		||||
                mockDomainObject = jasmine.createSpyObj(
 | 
			
		||||
                    "editableObject",
 | 
			
		||||
                    [ "getId", "getModel", "getCapability" ]
 | 
			
		||||
                );
 | 
			
		||||
                mockCache = jasmine.createSpyObj(
 | 
			
		||||
                    "cache",
 | 
			
		||||
                    [ "markDirty" ]
 | 
			
		||||
                );
 | 
			
		||||
                mockPromise = jasmine.createSpyObj("promise", ["then"]);
 | 
			
		||||
 | 
			
		||||
                mockCache.markDirty.andReturn(mockPromise);
 | 
			
		||||
                mockDomainObject.getCapability.andReturn(mockPersistence);
 | 
			
		||||
 | 
			
		||||
                capability = new EditablePersistenceCapability(
 | 
			
		||||
                    mockPersistence,
 | 
			
		||||
                    mockEditableObject,
 | 
			
		||||
                    mockDomainObject,
 | 
			
		||||
                    mockCache
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("marks objects as dirty (in the cache) upon persist", function () {
 | 
			
		||||
                capability.persist();
 | 
			
		||||
                expect(mockCache.markDirty)
 | 
			
		||||
                    .toHaveBeenCalledWith(mockEditableObject);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("does not invoke the underlying persistence capability", function () {
 | 
			
		||||
                capability.persist();
 | 
			
		||||
                expect(mockPersistence.persist).not.toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("refreshes using the original domain object's persistence", function () {
 | 
			
		||||
                // Refreshing needs to delegate via the unwrapped domain object.
 | 
			
		||||
                // Otherwise, only the editable version of the object will be updated;
 | 
			
		||||
                // we instead want the real version of the object to receive these
 | 
			
		||||
                // changes.
 | 
			
		||||
                expect(mockDomainObject.getCapability).not.toHaveBeenCalled();
 | 
			
		||||
                expect(mockPersistence.refresh).not.toHaveBeenCalled();
 | 
			
		||||
                capability.refresh();
 | 
			
		||||
                expect(mockDomainObject.getCapability).toHaveBeenCalledWith('persistence');
 | 
			
		||||
                expect(mockPersistence.refresh).toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("returns a promise from persist", function () {
 | 
			
		||||
                expect(capability.persist().then).toEqual(jasmine.any(Function));
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,75 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define,describe,it,expect,beforeEach,jasmine*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/capabilities/EditableRelationshipCapability"],
 | 
			
		||||
    function (EditableRelationshipCapability) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        describe("An editable relationship capability", function () {
 | 
			
		||||
            var mockContext,
 | 
			
		||||
                mockEditableObject,
 | 
			
		||||
                mockDomainObject,
 | 
			
		||||
                mockTestObject,
 | 
			
		||||
                someValue,
 | 
			
		||||
                mockFactory,
 | 
			
		||||
                capability;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                // EditableContextCapability should watch ALL
 | 
			
		||||
                // methods for domain objects, so give it an
 | 
			
		||||
                // arbitrary interface to wrap.
 | 
			
		||||
                mockContext =
 | 
			
		||||
                    jasmine.createSpyObj("context", [ "getDomainObject" ]);
 | 
			
		||||
                mockTestObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    [ "getId", "getModel", "getCapability" ]
 | 
			
		||||
                );
 | 
			
		||||
                mockFactory =
 | 
			
		||||
                    jasmine.createSpyObj("factory", ["getEditableObject"]);
 | 
			
		||||
 | 
			
		||||
                someValue = { x: 42 };
 | 
			
		||||
 | 
			
		||||
                mockContext.getDomainObject.andReturn(mockTestObject);
 | 
			
		||||
                mockFactory.getEditableObject.andReturn(someValue);
 | 
			
		||||
 | 
			
		||||
                capability = new EditableRelationshipCapability(
 | 
			
		||||
                    mockContext,
 | 
			
		||||
                    mockEditableObject,
 | 
			
		||||
                    mockDomainObject,
 | 
			
		||||
                    mockFactory
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            // Most behavior is tested for EditableLookupCapability,
 | 
			
		||||
            // so just verify that this isse
 | 
			
		||||
            it("presumes non-idempotence of its wrapped capability", function () {
 | 
			
		||||
                expect(capability.getDomainObject())
 | 
			
		||||
                    .toEqual(capability.getDomainObject());
 | 
			
		||||
                expect(mockContext.getDomainObject.calls.length).toEqual(2);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -1,180 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define,describe,it,expect,beforeEach,jasmine*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/objects/EditableDomainObjectCache"],
 | 
			
		||||
    function (EditableDomainObjectCache) {
 | 
			
		||||
        'use strict';
 | 
			
		||||
 | 
			
		||||
        describe("Editable domain object cache", function () {
 | 
			
		||||
 | 
			
		||||
            var captured,
 | 
			
		||||
                completionCapability,
 | 
			
		||||
                object,
 | 
			
		||||
                mockQ,
 | 
			
		||||
                mockType,
 | 
			
		||||
                cache;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            // Constructors for test objects
 | 
			
		||||
            function TestObject(id) {
 | 
			
		||||
                return {
 | 
			
		||||
                    getId: function () { return id; },
 | 
			
		||||
                    getModel: function () { return {}; },
 | 
			
		||||
                    getCapability: function (key) {
 | 
			
		||||
                        return {
 | 
			
		||||
                            editor: completionCapability,
 | 
			
		||||
                            type: mockType
 | 
			
		||||
                        }[key];
 | 
			
		||||
                    },
 | 
			
		||||
                    hasCapability: function (key) {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function WrapObject(domainObject, model) {
 | 
			
		||||
                var result = Object.create(domainObject);
 | 
			
		||||
                result.wrapped = true;
 | 
			
		||||
                result.wrappedModel = model;
 | 
			
		||||
                result.hasCapability = function (name) {
 | 
			
		||||
                    return name === 'editor';
 | 
			
		||||
                };
 | 
			
		||||
                captured.wraps = (captured.wraps || 0) + 1;
 | 
			
		||||
                return result;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                mockQ = jasmine.createSpyObj('$q', ['when', 'all']);
 | 
			
		||||
                mockType = jasmine.createSpyObj('type', ['hasFeature']);
 | 
			
		||||
                mockType.hasFeature.andReturn(true);
 | 
			
		||||
                captured = {};
 | 
			
		||||
                completionCapability = {
 | 
			
		||||
                    save: function () {
 | 
			
		||||
                        captured.saved = (captured.saved || 0) + 1;
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                cache = new EditableDomainObjectCache(WrapObject, mockQ);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("wraps objects using provided constructor", function () {
 | 
			
		||||
                var domainObject = new TestObject('test-id'),
 | 
			
		||||
                    wrappedObject = cache.getEditableObject(domainObject);
 | 
			
		||||
                expect(wrappedObject.wrapped).toBeTruthy();
 | 
			
		||||
                expect(wrappedObject.getId()).toEqual(domainObject.getId());
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("wraps objects repeatedly, wraps models once", function () {
 | 
			
		||||
                var domainObject = new TestObject('test-id'),
 | 
			
		||||
                    wrappedObjects = [];
 | 
			
		||||
 | 
			
		||||
                // Verify precondition
 | 
			
		||||
                expect(captured.wraps).toBeUndefined();
 | 
			
		||||
 | 
			
		||||
                // Invoke a few more times; expect count not to increment
 | 
			
		||||
                wrappedObjects.push(cache.getEditableObject(domainObject));
 | 
			
		||||
                expect(captured.wraps).toEqual(1);
 | 
			
		||||
                wrappedObjects.push(cache.getEditableObject(domainObject));
 | 
			
		||||
                expect(captured.wraps).toEqual(2);
 | 
			
		||||
                wrappedObjects.push(cache.getEditableObject(domainObject));
 | 
			
		||||
                expect(captured.wraps).toEqual(3);
 | 
			
		||||
 | 
			
		||||
                // Verify that the last call still gave us a wrapped object
 | 
			
		||||
                expect(wrappedObjects[0].wrapped).toBeTruthy();
 | 
			
		||||
                expect(wrappedObjects[0].getId()).toEqual(domainObject.getId());
 | 
			
		||||
 | 
			
		||||
                // Verify that objects are distinct but models are identical
 | 
			
		||||
                expect(wrappedObjects[0].wrappedModel)
 | 
			
		||||
                    .toBe(wrappedObjects[1].wrappedModel);
 | 
			
		||||
                expect(wrappedObjects[0]).not
 | 
			
		||||
                    .toBe(wrappedObjects[1]);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("saves objects that have been marked dirty", function () {
 | 
			
		||||
                var objects = ['a', 'b', 'c'].map(TestObject).map(function (domainObject) {
 | 
			
		||||
                    return cache.getEditableObject(domainObject);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                cache.markDirty(objects[0]);
 | 
			
		||||
                cache.markDirty(objects[2]);
 | 
			
		||||
 | 
			
		||||
                cache.saveAll();
 | 
			
		||||
 | 
			
		||||
                expect(captured.saved).toEqual(2);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("does not save objects that have been marked clean", function () {
 | 
			
		||||
                var objects = ['a', 'b', 'c'].map(TestObject).map(function (domainObject) {
 | 
			
		||||
                    return cache.getEditableObject(domainObject);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                cache.markDirty(objects[0]);
 | 
			
		||||
                cache.markDirty(objects[2]);
 | 
			
		||||
                cache.markClean(objects[0]);
 | 
			
		||||
 | 
			
		||||
                cache.saveAll();
 | 
			
		||||
 | 
			
		||||
                expect(captured.saved).toEqual(1);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("tracks the root object of the Edit mode subgraph", function () {
 | 
			
		||||
                // Root object is the first object exposed to the cache
 | 
			
		||||
                var domainObjects = ['a', 'b', 'c'].map(TestObject);
 | 
			
		||||
                domainObjects.forEach(function (obj) {
 | 
			
		||||
                    cache.getEditableObject(obj);
 | 
			
		||||
                });
 | 
			
		||||
                expect(cache.isRoot(domainObjects[0])).toBeTruthy();
 | 
			
		||||
                expect(cache.isRoot(domainObjects[1])).toBeFalsy();
 | 
			
		||||
                expect(cache.isRoot(domainObjects[2])).toBeFalsy();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("does not double-wrap objects", function () {
 | 
			
		||||
                var domainObject = new TestObject('test-id'),
 | 
			
		||||
                    wrappedObject = cache.getEditableObject(domainObject);
 | 
			
		||||
 | 
			
		||||
                // Same instance should be returned if you try to wrap
 | 
			
		||||
                // twice. This is necessary, since it's possible to (e.g.)
 | 
			
		||||
                // use a context capability on an object retrieved via
 | 
			
		||||
                // composition, in which case a result will already be
 | 
			
		||||
                // wrapped.
 | 
			
		||||
                expect(cache.getEditableObject(wrappedObject))
 | 
			
		||||
                    .toBe(wrappedObject);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("does not wrap non-editable objects", function () {
 | 
			
		||||
                var domainObject = new TestObject('test-id');
 | 
			
		||||
 | 
			
		||||
                mockType.hasFeature.andCallFake(function (key) {
 | 
			
		||||
                    return key !== 'creation';
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                expect(cache.getEditableObject(domainObject))
 | 
			
		||||
                    .toBe(domainObject);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
);
 | 
			
		||||
@@ -1,81 +0,0 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT Web, Copyright (c) 2014-2015, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT Web includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
/*global define,describe,it,expect,beforeEach,jasmine*/
 | 
			
		||||
 | 
			
		||||
define(
 | 
			
		||||
    ["../../src/objects/EditableModelCache"],
 | 
			
		||||
    function (EditableModelCache) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        describe("The editable model cache", function () {
 | 
			
		||||
            var mockObject,
 | 
			
		||||
                mockOtherObject,
 | 
			
		||||
                testModel,
 | 
			
		||||
                testId,
 | 
			
		||||
                otherModel,
 | 
			
		||||
                otherId,
 | 
			
		||||
                cache;
 | 
			
		||||
 | 
			
		||||
            beforeEach(function () {
 | 
			
		||||
                testId = "test";
 | 
			
		||||
                testModel = { someKey: "some value" };
 | 
			
		||||
                otherId = "other";
 | 
			
		||||
                otherModel = { someKey: "some other value" };
 | 
			
		||||
 | 
			
		||||
                mockObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    [ "getId", "getModel" ]
 | 
			
		||||
                );
 | 
			
		||||
                mockOtherObject = jasmine.createSpyObj(
 | 
			
		||||
                    "domainObject",
 | 
			
		||||
                    [ "getId", "getModel" ]
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                mockObject.getId.andReturn(testId);
 | 
			
		||||
                mockObject.getModel.andReturn(testModel);
 | 
			
		||||
                mockOtherObject.getId.andReturn(otherId);
 | 
			
		||||
                mockOtherObject.getModel.andReturn(otherModel);
 | 
			
		||||
 | 
			
		||||
                cache = new EditableModelCache();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("provides clones of domain object models", function () {
 | 
			
		||||
                var model = cache.getCachedModel(mockObject);
 | 
			
		||||
                // Should be identical...
 | 
			
		||||
                expect(model).toEqual(testModel);
 | 
			
		||||
                // ...but not pointer-identical
 | 
			
		||||
                expect(model).not.toBe(testModel);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("provides only one clone per object", function () {
 | 
			
		||||
                var model = cache.getCachedModel(mockObject);
 | 
			
		||||
                expect(cache.getCachedModel(mockObject)).toBe(model);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("maintains separate caches per-object", function () {
 | 
			
		||||
                expect(cache.getCachedModel(mockObject))
 | 
			
		||||
                    .not.toEqual(cache.getCachedModel(mockOtherObject));
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
@@ -48,7 +48,11 @@ define(
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $scope.regions = filterRegions(typeCapability.getDefinition().inspector || new InspectorRegion());
 | 
			
		||||
            function setRegions() {
 | 
			
		||||
                $scope.regions = filterRegions(typeCapability.getDefinition().inspector || new InspectorRegion());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            setRegions();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return InspectorController;
 | 
			
		||||
 
 | 
			
		||||
@@ -173,13 +173,10 @@ define(
 | 
			
		||||
                }, modified);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Only update if we don't have unsaved changes
 | 
			
		||||
            return (model.modified === model.persisted) ?
 | 
			
		||||
                this.persistenceService.readObject(
 | 
			
		||||
            return this.persistenceService.readObject(
 | 
			
		||||
                    this.getSpace(),
 | 
			
		||||
                    this.domainObject.getId()
 | 
			
		||||
                ).then(updateModel) :
 | 
			
		||||
                fastPromise(false);
 | 
			
		||||
                ).then(updateModel);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
 
 | 
			
		||||
@@ -41,9 +41,10 @@ define(
 | 
			
		||||
                };
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Check if we are in edit mode
 | 
			
		||||
            function inEditMode() {
 | 
			
		||||
                return swimlane.domainObject.hasCapability("editor");
 | 
			
		||||
            // Check if we are in edit mode (also check parents)
 | 
			
		||||
            function inEditMode(swimlane) {
 | 
			
		||||
                return swimlane.domainObject.hasCapability('editor') &&
 | 
			
		||||
                    swimlane.domainObject.getCapability('editor').isEditing();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Boolean and (for reduce below)
 | 
			
		||||
@@ -175,7 +176,7 @@ define(
 | 
			
		||||
                 * @returns {boolean} true if this should be allowed
 | 
			
		||||
                 */
 | 
			
		||||
                allowDropIn: function (id, domainObject) {
 | 
			
		||||
                    return inEditMode() &&
 | 
			
		||||
                    return inEditMode(swimlane) &&
 | 
			
		||||
                        !pathContains(swimlane, id) &&
 | 
			
		||||
                        !contains(swimlane, id) &&
 | 
			
		||||
                        canDrop(swimlane.domainObject, domainObject);
 | 
			
		||||
@@ -190,7 +191,7 @@ define(
 | 
			
		||||
                allowDropAfter: function (id, domainObject) {
 | 
			
		||||
                    var target = expandedForDropInto() ?
 | 
			
		||||
                            swimlane : swimlane.parent;
 | 
			
		||||
                    return inEditMode() &&
 | 
			
		||||
                    return inEditMode(swimlane) &&
 | 
			
		||||
                        target &&
 | 
			
		||||
                        !pathContains(target, id) &&
 | 
			
		||||
                        canDrop(target.domainObject, domainObject);
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,8 @@ define(
 | 
			
		||||
         */
 | 
			
		||||
        function MCTRepresentation(representations, views, representers, $q, templateLinker, $log) {
 | 
			
		||||
            var representationMap = {},
 | 
			
		||||
                gestureMap = {};
 | 
			
		||||
                gestureMap = {},
 | 
			
		||||
                listeners = 0;
 | 
			
		||||
 | 
			
		||||
            // Assemble all representations and views
 | 
			
		||||
            // The distinction between views and representations is
 | 
			
		||||
@@ -94,6 +95,7 @@ define(
 | 
			
		||||
                    couldEdit = false,
 | 
			
		||||
                    lastIdPath = [],
 | 
			
		||||
                    lastKey,
 | 
			
		||||
                    statusListener,
 | 
			
		||||
                    changeTemplate = templateLinker.link($scope, element);
 | 
			
		||||
 | 
			
		||||
                // Populate scope with any capabilities indicated by the
 | 
			
		||||
@@ -170,7 +172,7 @@ define(
 | 
			
		||||
                        representation = lookup($scope.key, domainObject),
 | 
			
		||||
                        uses = ((representation || {}).uses || []),
 | 
			
		||||
                        canRepresent = !!(representation && domainObject),
 | 
			
		||||
                        canEdit = !!(domainObject && domainObject.hasCapability('editor')),
 | 
			
		||||
                        canEdit = !!(domainObject && domainObject.hasCapability('editor') && domainObject.getCapability('editor').isEditing()),
 | 
			
		||||
                        idPath = getIdPath(domainObject),
 | 
			
		||||
                        key = $scope.key;
 | 
			
		||||
 | 
			
		||||
@@ -242,6 +244,25 @@ define(
 | 
			
		||||
                // (to a different object)
 | 
			
		||||
                $scope.$watch("domainObject", refresh);
 | 
			
		||||
 | 
			
		||||
                function listenForStatusChange(object) {
 | 
			
		||||
                    if (statusListener) {
 | 
			
		||||
                        statusListener();
 | 
			
		||||
                    }
 | 
			
		||||
                    statusListener = object.getCapability("status").listen(refresh);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /**
 | 
			
		||||
                 * Add a listener for status changes to the object itself.
 | 
			
		||||
                 */
 | 
			
		||||
                $scope.$watch("domainObject", function(domainObject, oldDomainObject) {
 | 
			
		||||
                    if (domainObject!==oldDomainObject){
 | 
			
		||||
                        listenForStatusChange(domainObject);
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
                if ($scope.domainObject) {
 | 
			
		||||
                    listenForStatusChange($scope.domainObject);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Finally, also update when there is a new version of that
 | 
			
		||||
                // same domain object; these changes should be tracked in the
 | 
			
		||||
                // model's "modified" field, by the mutation capability.
 | 
			
		||||
@@ -250,6 +271,11 @@ define(
 | 
			
		||||
                // Make sure any resources allocated by representers also get
 | 
			
		||||
                // released.
 | 
			
		||||
                $scope.$on("$destroy", destroyRepresenters);
 | 
			
		||||
                $scope.$on("$destroy", function () {
 | 
			
		||||
                    if (statusListener) {
 | 
			
		||||
                        statusListener();
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // Do one initial refresh, so that we don't need another
 | 
			
		||||
                // digest iteration just to populate the scope. Failure to
 | 
			
		||||
 
 | 
			
		||||
@@ -25,9 +25,8 @@
 | 
			
		||||
 * Module defining DropGesture. Created by vwoeltje on 11/17/14.
 | 
			
		||||
 */
 | 
			
		||||
define(
 | 
			
		||||
    ['./GestureConstants',
 | 
			
		||||
     '../../../commonUI/edit/src/objects/EditableDomainObject'],
 | 
			
		||||
    function (GestureConstants, EditableDomainObject) {
 | 
			
		||||
    ['./GestureConstants'],
 | 
			
		||||
    function (GestureConstants) {
 | 
			
		||||
        "use strict";
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -43,7 +42,6 @@ define(
 | 
			
		||||
         */
 | 
			
		||||
        function DropGesture(dndService, $q, navigationService, instantiate, typeService, element, domainObject) {
 | 
			
		||||
            var actionCapability = domainObject.getCapability('action'),
 | 
			
		||||
                editableDomainObject,
 | 
			
		||||
                scope = element.scope && element.scope(),
 | 
			
		||||
                action; // Action for the drop, when it occurs
 | 
			
		||||
            
 | 
			
		||||
@@ -68,30 +66,13 @@ define(
 | 
			
		||||
                            x: event.pageX - rect.left,
 | 
			
		||||
                            y: event.pageY - rect.top
 | 
			
		||||
                        },
 | 
			
		||||
                        editableDomainObject
 | 
			
		||||
                        domainObject
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function canCompose(domainObject, selectedObject){
 | 
			
		||||
                return domainObject.getCapability("action").getActions({
 | 
			
		||||
                    key: 'compose',
 | 
			
		||||
                    selectedObject: selectedObject
 | 
			
		||||
                }).length > 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            function dragOver(e) {
 | 
			
		||||
                //Refresh domain object on each dragOver to catch external
 | 
			
		||||
                // updates to the model
 | 
			
		||||
                //Don't use EditableDomainObject for folders, allow immediate persistence
 | 
			
		||||
                if (domainObject.hasCapability('editor') ||
 | 
			
		||||
                    domainObject.getModel().type==='folder') {
 | 
			
		||||
                    editableDomainObject = domainObject;
 | 
			
		||||
                } else {
 | 
			
		||||
                    editableDomainObject = new EditableDomainObject(domainObject, $q);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                actionCapability = editableDomainObject.getCapability('action');
 | 
			
		||||
                actionCapability = domainObject.getCapability('action');
 | 
			
		||||
 | 
			
		||||
                var event = (e || {}).originalEvent || e,
 | 
			
		||||
                    selectedObject = dndService.getData(
 | 
			
		||||
@@ -117,18 +98,18 @@ define(
 | 
			
		||||
            function drop(e) {
 | 
			
		||||
                var event = (e || {}).originalEvent || e,
 | 
			
		||||
                    id = event.dataTransfer.getData(GestureConstants.MCT_DRAG_TYPE),
 | 
			
		||||
                    domainObjectType = editableDomainObject.getModel().type;
 | 
			
		||||
                    domainObjectType = domainObject.getModel().type;
 | 
			
		||||
 | 
			
		||||
                // Handle the drop; add the dropped identifier to the
 | 
			
		||||
                // destination domain object's composition, and persist
 | 
			
		||||
                // the change.
 | 
			
		||||
                if (id) {
 | 
			
		||||
                    e.preventDefault();
 | 
			
		||||
                    $q.when(action && action.perform()).then(function (result) {
 | 
			
		||||
                        //Don't go into edit mode for folders
 | 
			
		||||
                        if (domainObjectType!=='folder') {
 | 
			
		||||
                            editableDomainObject.getCapability('action').perform('edit');
 | 
			
		||||
                        }
 | 
			
		||||
                    if (domainObjectType!=='folder') {
 | 
			
		||||
                        domainObject.getCapability('action').perform('edit');
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    $q.when(action && action.perform()).then(function () {
 | 
			
		||||
                        broadcastDrop(id, event);
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user