diff --git a/build-docs.sh b/build-docs.sh
index 73d387bcff..29841f921e 100755
--- a/build-docs.sh
+++ b/build-docs.sh
@@ -32,7 +32,7 @@ WEBSITE_DIRECTORY="website"
BUILD_SHA=`git rev-parse HEAD`
# A remote will be created for the git repository we are pushing to.
-# Don't worry, as this entire directory will get trashed inbetween builds.
+# Don't worry, as this entire directory will get trashed in between builds.
REMOTE_NAME="documentation"
WEBSITE_BRANCH="master"
diff --git a/docs/src/architecture/platform.md b/docs/src/architecture/platform.md
index f7f0c48cda..48ceebb9ef 100644
--- a/docs/src/architecture/platform.md
+++ b/docs/src/architecture/platform.md
@@ -616,7 +616,7 @@ follows:
part of an action's extension definition.
* `CreateActionProvider` provides the various Create actions which
populate the Create menu. These are driven by the available types,
- so do not map easily ot extension category `actions`; instead, these
+ so do not map easily to extension category `actions`; instead, these
are generated after looking up which actions are available from the
[`TypeService`](#type-service).
* `ActionAggregator` merges together actions from multiple providers.
diff --git a/docs/src/design/proposals/APIRedesign.md b/docs/src/design/proposals/APIRedesign.md
index e6230823ed..03ce2f212f 100644
--- a/docs/src/design/proposals/APIRedesign.md
+++ b/docs/src/design/proposals/APIRedesign.md
@@ -98,7 +98,7 @@ Worked on bug fixes in the platform and a plugin for search.
It is hard to figure out what the difference between the various ways of
dealing with telemetry are. e.g., what is the difference between just
"Telemetry" and the "Telemetry Service"? There are many
- "Telemetry Thing"s which seem related, but in an unclear way.
+ "Telemetry Things" which seem related, but in an unclear way.
### Developer Intern 2
@@ -456,7 +456,7 @@ Instead, propose that:
For parity with actions, a `View` would be a constructor which
takes an `ActionContext` as a parameter (with similarly-defined
properties) and exposes a method to retrieve the HTML elements
-associateed with it.
+associated with it.
The platform would then additionally expose an `AngularView`
implementation to improve compatibility with existing
diff --git a/docs/src/design/proposals/APIRedesign_PeteRichards.md b/docs/src/design/proposals/APIRedesign_PeteRichards.md
index dce80c41ae..517d61cc50 100644
--- a/docs/src/design/proposals/APIRedesign_PeteRichards.md
+++ b/docs/src/design/proposals/APIRedesign_PeteRichards.md
@@ -99,7 +99,7 @@ To reduce interface depth, we can replace our own provider and registry patterns
## More angular: for all services
-Increasing our commitment to angular would mean using more of the angular factorys, services, etc, and less of our home grown tools. We'd implement our services and extension points as angular providers, and make them configurable via app.config.
+Increasing our commitment to angular would mean using more of the angular factories, services, etc, and less of our home grown tools. We'd implement our services and extension points as angular providers, and make them configurable via app.config.
As an example, registering a specific type of model provider in angular would look like:
diff --git a/docs/src/tutorials/index.md b/docs/src/tutorials/index.md
index 0e48fcf11f..d8842de9d7 100644
--- a/docs/src/tutorials/index.md
+++ b/docs/src/tutorials/index.md
@@ -3238,7 +3238,7 @@ define(
__tutorials/telemetry/src/ExampleTelemetryServerAdapter.js__
Here, we have added `subscribe` and `unsubscribe` methods which issue the
-corresponding requests to the server. Seperately, we introduce the ability to
+corresponding requests to the server. Separately, we introduce the ability to
listen for `data` messages as they come in: These will contain the data associated
with these subscriptions.
diff --git a/example/eventGenerator/data/transcript.json b/example/eventGenerator/data/transcript.json
index 0416220e71..ce78735330 100644
--- a/example/eventGenerator/data/transcript.json
+++ b/example/eventGenerator/data/transcript.json
@@ -10,7 +10,7 @@
"LMP: 47 degrees.",
"CC: Eagle, looking great. You're GO.",
"CC: Roger. 1202. We copy it.",
- "O1: LMP 35 degrees. 35 degrees. 750. Coming aown to 23.fl",
+ "O1: LMP 35 degrees. 35 degrees. 750. Coming down to 23.fl",
"LMP: 700 feet, 21 down, 33 degrees.",
"LMP: 600 feet, down at 19.",
"LMP: 540 feet, down at - 30. Down at 15.",
diff --git a/main.js b/main.js
index 3fc2c4da36..34d1afeeeb 100644
--- a/main.js
+++ b/main.js
@@ -29,7 +29,7 @@ requirejs.config({
"csv": "bower_components/comma-separated-values/csv.min",
"es6-promise": "bower_components/es6-promise/es6-promise.min",
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
- "jsPDF": "bower_components/jspdf/dist/jspdf.min",
+ "jsPDF": "bower_components/jspdf/dist/jspdf.debug",
"moment": "bower_components/moment/moment",
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
diff --git a/package.json b/package.json
index 555375007e..e47a64e50e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "openmct",
- "version": "0.11.3-SNAPSHOT",
+ "version": "0.12.0-SNAPSHOT",
"description": "The Open MCT core platform",
"dependencies": {
"express": "^4.13.1",
diff --git a/platform/commonUI/browse/src/navigation/NavigateAction.js b/platform/commonUI/browse/src/navigation/NavigateAction.js
index b3d935812a..6121213a51 100644
--- a/platform/commonUI/browse/src/navigation/NavigateAction.js
+++ b/platform/commonUI/browse/src/navigation/NavigateAction.js
@@ -48,20 +48,35 @@ define(
*/
NavigateAction.prototype.perform = function () {
var self = this,
- navigationAllowed = true;
+ navigateTo = this.domainObject,
+ currentObject = self.navigationService.getNavigation();
function allow() {
- self.policyService.allow("navigation", self.navigationService.getNavigation(), self.domainObject, function (message) {
+ var navigationAllowed = true;
+ self.policyService.allow("navigation", currentObject, navigateTo, function (message) {
navigationAllowed = self.$window.confirm(message + "\r\n\r\n" +
" Are you sure you want to continue?");
});
return navigationAllowed;
}
- // Set navigation, and wrap like a promise
- return this.$q.when(
- allow() && this.navigationService.setNavigation(this.domainObject)
- );
+ function cancelIfEditing() {
+ var editing = currentObject.hasCapability('editor') &&
+ currentObject.getCapability('editor').isEditContextRoot();
+
+ return self.$q.when(editing && currentObject.getCapability("editor").finish());
+ }
+
+ function navigate() {
+ return self.navigationService.setNavigation(navigateTo);
+ }
+
+ if (allow()) {
+ return cancelIfEditing().then(navigate);
+ } else {
+ return this.$q.when(false);
+ }
+
};
/**
diff --git a/platform/commonUI/browse/test/navigation/NavigateActionSpec.js b/platform/commonUI/browse/test/navigation/NavigateActionSpec.js
index 003012372b..f9b756eeaa 100644
--- a/platform/commonUI/browse/test/navigation/NavigateActionSpec.js
+++ b/platform/commonUI/browse/test/navigation/NavigateActionSpec.js
@@ -32,7 +32,9 @@ define(
mockQ,
mockDomainObject,
mockPolicyService,
+ mockNavigatedObject,
mockWindow,
+ capabilities,
action;
function mockPromise(value) {
@@ -44,6 +46,29 @@ define(
}
beforeEach(function () {
+ capabilities = {};
+
+ mockQ = { when: mockPromise };
+ mockNavigatedObject = jasmine.createSpyObj(
+ "domainObject",
+ [
+ "getId",
+ "getModel",
+ "hasCapability",
+ "getCapability"
+ ]
+ );
+
+ capabilities.editor = jasmine.createSpyObj("editorCapability", [
+ "isEditContextRoot",
+ "finish"
+ ]);
+
+ mockNavigatedObject.getCapability.andCallFake(function (capability) {
+ return capabilities[capability];
+ });
+ mockNavigatedObject.hasCapability.andReturn(false);
+
mockNavigationService = jasmine.createSpyObj(
"navigationService",
[
@@ -51,11 +76,14 @@ define(
"getNavigation"
]
);
- mockNavigationService.getNavigation.andReturn({});
- mockQ = { when: mockPromise };
+ mockNavigationService.getNavigation.andReturn(mockNavigatedObject);
+
mockDomainObject = jasmine.createSpyObj(
"domainObject",
- ["getId", "getModel", "getCapability"]
+ [
+ "getId",
+ "getModel"
+ ]
);
mockPolicyService = jasmine.createSpyObj("policyService",
@@ -112,6 +140,21 @@ define(
});
});
+ describe("in edit mode", function () {
+ beforeEach(function () {
+ mockNavigatedObject.hasCapability.andCallFake(function (capability) {
+ return capability === "editor";
+ });
+ capabilities.editor.isEditContextRoot.andReturn(true);
+ });
+
+ it("finishes editing if in edit mode", function () {
+ action.perform();
+ expect(capabilities.editor.finish)
+ .toHaveBeenCalled();
+ });
+ });
+
it("is only applicable when a domain object is in context", function () {
expect(NavigateAction.appliesTo({})).toBeFalsy();
expect(NavigateAction.appliesTo({
diff --git a/platform/commonUI/dialog/res/templates/overlay.html b/platform/commonUI/dialog/res/templates/overlay.html
index 825d8fe4f4..215fe97aac 100644
--- a/platform/commonUI/dialog/res/templates/overlay.html
+++ b/platform/commonUI/dialog/res/templates/overlay.html
@@ -19,7 +19,7 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+ ng-class="{ major: $index === 0 && saveActions.length === 0 }">
{{currentAction.getMetadata().name}}
diff --git a/platform/commonUI/edit/src/actions/CancelAction.js b/platform/commonUI/edit/src/actions/CancelAction.js
index 13b005958e..a48ceec996 100644
--- a/platform/commonUI/edit/src/actions/CancelAction.js
+++ b/platform/commonUI/edit/src/actions/CancelAction.js
@@ -62,7 +62,7 @@ define(
}
function cancel(allowed) {
- return allowed && domainObject.getCapability("editor").cancel();
+ return allowed && domainObject.getCapability("editor").finish();
}
//Do navigation first in order to trigger unsaved changes dialog
diff --git a/platform/commonUI/edit/src/actions/EditAction.js b/platform/commonUI/edit/src/actions/EditAction.js
index bd30968289..e65f035edf 100644
--- a/platform/commonUI/edit/src/actions/EditAction.js
+++ b/platform/commonUI/edit/src/actions/EditAction.js
@@ -69,18 +69,13 @@ define(
* Enter edit mode.
*/
EditAction.prototype.perform = function () {
- var self = this;
- function cancelEditing() {
- self.domainObject.getCapability('editor').cancel();
- self.navigationService.removeListener(cancelEditing);
- }
+
//If this is not the currently navigated object, then navigate
// to it.
if (this.navigationService.getNavigation() !== this.domainObject) {
this.navigationService.setNavigation(this.domainObject);
}
- this.navigationService.addListener(cancelEditing);
this.domainObject.useCapability("editor");
};
diff --git a/platform/commonUI/edit/src/actions/SaveAction.js b/platform/commonUI/edit/src/actions/SaveAction.js
index 6f96e84192..8d3ea7f509 100644
--- a/platform/commonUI/edit/src/actions/SaveAction.js
+++ b/platform/commonUI/edit/src/actions/SaveAction.js
@@ -25,9 +25,8 @@ define(
function (SaveInProgressDialog) {
/**
- * The "Save" action; the action triggered by clicking Save from
- * Edit Mode. Exits the editing user interface and invokes object
- * capabilities to persist the changes that have been made.
+ * The "Save" action; it invokes object capabilities to persist
+ * the changes that have been made.
* @constructor
* @implements {Action}
* @memberof platform/commonUI/edit
@@ -41,7 +40,7 @@ define(
}
/**
- * Save changes and conclude editing.
+ * Save changes.
*
* @returns {Promise} a promise that will be fulfilled when
* cancellation has completed
@@ -51,40 +50,22 @@ define(
var domainObject = this.domainObject,
dialog = new SaveInProgressDialog(this.dialogService);
- function resolveWith(object) {
- return function () {
- return object;
- };
- }
-
// 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() {
- return domainObject.getCapability("editor").save()
- .then(resolveWith(domainObject));
+ return domainObject.getCapability("editor").save();
}
- // Discard the current root view (which will be the editing
- // UI, which will have been pushed atop the Browse UI.)
- function returnToBrowse(object) {
- if (object) {
- object.getCapability("action").perform("navigate");
- }
- return object;
- }
-
- function hideBlockingDialog(object) {
+ function hideBlockingDialog() {
dialog.hide();
- return object;
}
dialog.show();
return doSave()
.then(hideBlockingDialog)
- .then(returnToBrowse)
.catch(hideBlockingDialog);
};
diff --git a/platform/commonUI/edit/src/actions/SaveAndStopEditingAction.js b/platform/commonUI/edit/src/actions/SaveAndStopEditingAction.js
new file mode 100644
index 0000000000..a0a0583048
--- /dev/null
+++ b/platform/commonUI/edit/src/actions/SaveAndStopEditingAction.js
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2016, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT 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 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.
+ *****************************************************************************/
+
+define(
+ ["./SaveAction"],
+ function (SaveAction) {
+
+ /**
+ * The "Save and Stop Editing" action performs a [Save action]{@link SaveAction}
+ * on the object under edit followed by exiting the edit user interface.
+ * @constructor
+ * @implements {Action}
+ * @memberof platform/commonUI/edit
+ */
+ function SaveAndStopEditingAction(
+ dialogService,
+ context
+ ) {
+ this.context = context;
+ this.domainObject = (context || {}).domainObject;
+ this.dialogService = dialogService;
+ }
+
+ /**
+ * Trigger a save operation and exit edit mode.
+ *
+ * @returns {Promise} a promise that will be fulfilled when
+ * cancellation has completed
+ * @memberof platform/commonUI/edit.SaveAndStopEditingAction#
+ */
+ SaveAndStopEditingAction.prototype.perform = function () {
+ var domainObject = this.domainObject,
+ saveAction = new SaveAction(this.dialogService, this.context);
+
+ function closeEditor() {
+ return domainObject.getCapability("editor").finish();
+ }
+
+ return saveAction.perform()
+ .then(closeEditor)
+ .catch(closeEditor);
+ };
+
+ /**
+ * Check if this action is applicable in a given context.
+ * This will ensure that a domain object is present in the context,
+ * and that this domain object is in Edit mode.
+ * @returns true if applicable
+ */
+ SaveAndStopEditingAction.appliesTo = SaveAction.appliesTo;
+
+ return SaveAndStopEditingAction;
+ }
+);
diff --git a/platform/commonUI/edit/src/actions/SaveAsAction.js b/platform/commonUI/edit/src/actions/SaveAsAction.js
index 57a055429a..2befea07fd 100644
--- a/platform/commonUI/edit/src/actions/SaveAsAction.js
+++ b/platform/commonUI/edit/src/actions/SaveAsAction.js
@@ -42,7 +42,6 @@ define([
$injector,
policyService,
dialogService,
- creationService,
copyService,
context
) {
@@ -52,7 +51,6 @@ define([
};
this.policyService = policyService;
this.dialogService = dialogService;
- this.creationService = creationService;
this.copyService = copyService;
}
@@ -166,11 +164,16 @@ define([
.then(resolveWith(object));
}
- function commitEditingAfterClone(clonedObject) {
+ function saveAfterClone(clonedObject) {
return domainObject.getCapability("editor").save()
.then(resolveWith(clonedObject));
}
+ function finishEditing(clonedObject) {
+ return domainObject.getCapability("editor").finish()
+ .then(resolveWith(clonedObject));
+ }
+
function onFailure() {
hideBlockingDialog();
return false;
@@ -182,7 +185,8 @@ define([
.then(getParent)
.then(cloneIntoParent)
.then(undirtyOriginals)
- .then(commitEditingAfterClone)
+ .then(saveAfterClone)
+ .then(finishEditing)
.then(hideBlockingDialog)
.catch(onFailure);
};
diff --git a/platform/commonUI/edit/src/actions/SaveInProgressDialog.js b/platform/commonUI/edit/src/actions/SaveInProgressDialog.js
index 56c2c1ad86..78cd371934 100644
--- a/platform/commonUI/edit/src/actions/SaveInProgressDialog.js
+++ b/platform/commonUI/edit/src/actions/SaveInProgressDialog.js
@@ -9,7 +9,8 @@ define([], function () {
title: "Saving...",
hint: "Do not navigate away from this page or close this browser tab while this message is displayed.",
unknownProgress: true,
- severity: "info"
+ severity: "info",
+ delay: true
});
};
diff --git a/platform/commonUI/edit/src/capabilities/EditorCapability.js b/platform/commonUI/edit/src/capabilities/EditorCapability.js
index aa7670d8aa..1cbf239d7d 100644
--- a/platform/commonUI/edit/src/capabilities/EditorCapability.js
+++ b/platform/commonUI/edit/src/capabilities/EditorCapability.js
@@ -28,8 +28,8 @@ define(
* A capability that implements an editing 'session' for a domain
* object. An editing session is initiated via a call to .edit().
* Once initiated, any persist operations will be queued pending a
- * subsequent call to [.save()](@link #save) or [.cancel()](@link
- * #cancel).
+ * subsequent call to [.save()](@link #save) or [.finish()](@link
+ * #finish).
* @param transactionService
* @param domainObject
* @constructor
@@ -45,7 +45,7 @@ define(
/**
* Initiate an editing session. This will start a transaction during
* which any persist operations will be deferred until either save()
- * or cancel() are called.
+ * or finish() are called.
*/
EditorCapability.prototype.edit = function () {
this.transactionService.startTransaction();
@@ -81,25 +81,25 @@ define(
};
/**
- * Save any changes from this editing session. This will flush all
- * pending persists and end the current transaction
+ * Save any unsaved changes from this editing session. This will
+ * end the current transaction and continue with a new one.
* @returns {*}
*/
EditorCapability.prototype.save = function () {
- var domainObject = this.domainObject;
- return this.transactionService.commit().then(function () {
- domainObject.getCapability('status').set('editing', false);
+ var transactionService = this.transactionService;
+ return transactionService.commit().then(function () {
+ transactionService.startTransaction();
});
};
EditorCapability.prototype.invoke = EditorCapability.prototype.edit;
/**
- * Cancel the current editing session. This will discard any pending
+ * Finish the current editing session. This will discard any pending
* persist operations
* @returns {*}
*/
- EditorCapability.prototype.cancel = function () {
+ EditorCapability.prototype.finish = function () {
var domainObject = this.domainObject;
return this.transactionService.cancel().then(function () {
domainObject.getCapability("status").set("editing", false);
diff --git a/platform/commonUI/edit/src/controllers/EditActionController.js b/platform/commonUI/edit/src/controllers/EditActionController.js
index 19fddf931d..7c33799ebb 100644
--- a/platform/commonUI/edit/src/controllers/EditActionController.js
+++ b/platform/commonUI/edit/src/controllers/EditActionController.js
@@ -27,7 +27,8 @@ define(
[],
function () {
- var ACTION_CONTEXT = { category: 'conclude-editing' };
+ var SAVE_ACTION_CONTEXT = { category: 'save' };
+ var OTHERS_ACTION_CONTEXT = { category: 'conclude-editing' };
/**
* Controller which supplies action instances for Save/Cancel.
@@ -35,11 +36,30 @@ define(
* @constructor
*/
function EditActionController($scope) {
- // Maintain all "conclude-editing" actions in the present
- // context.
+
+ function actionToMenuOption(action) {
+ return {
+ key: action,
+ name: action.getMetadata().name,
+ cssclass: action.getMetadata().cssclass
+ };
+ }
+
+ // Maintain all "conclude-editing" and "save" actions in the
+ // present context.
function updateActions() {
- $scope.editActions = $scope.action ?
- $scope.action.getActions(ACTION_CONTEXT) :
+ $scope.saveActions = $scope.action ?
+ $scope.action.getActions(SAVE_ACTION_CONTEXT) :
+ [];
+
+ $scope.saveActionsAsMenuOptions = $scope.saveActions.map(actionToMenuOption);
+
+ $scope.saveActionMenuClickHandler = function (clickedAction) {
+ clickedAction.perform();
+ };
+
+ $scope.otherEditActions = $scope.action ?
+ $scope.action.getActions(OTHERS_ACTION_CONTEXT) :
[];
}
diff --git a/platform/commonUI/edit/src/creation/CreateAction.js b/platform/commonUI/edit/src/creation/CreateAction.js
index 14b8443462..b83351544f 100644
--- a/platform/commonUI/edit/src/creation/CreateAction.js
+++ b/platform/commonUI/edit/src/creation/CreateAction.js
@@ -67,12 +67,17 @@ define(
editAction,
editorCapability;
+ function closeEditor() {
+ return editorCapability.finish();
+ }
+
function onSave() {
- return editorCapability.save();
+ return editorCapability.save()
+ .then(closeEditor);
}
function onCancel() {
- return editorCapability.cancel();
+ return closeEditor();
}
newModel.type = this.type.getKey();
@@ -85,9 +90,9 @@ define(
if (editAction) {
return editAction.perform();
} else if (editorCapability) {
- //otherwise, use the save action
+ //otherwise, use the save as action
editorCapability.edit();
- return newObject.getCapability("action").perform("save").then(onSave, onCancel);
+ return newObject.getCapability("action").perform("save-as").then(onSave, onCancel);
}
};
diff --git a/platform/commonUI/edit/src/services/TransactionService.js b/platform/commonUI/edit/src/services/TransactionService.js
index 119e314b17..df0a051f0d 100644
--- a/platform/commonUI/edit/src/services/TransactionService.js
+++ b/platform/commonUI/edit/src/services/TransactionService.js
@@ -138,7 +138,7 @@ define(
try {
results.push(onCancel());
} catch (error) {
- this.$log.error("Error committing transaction.");
+ this.$log.error("Error cancelling transaction.");
}
}
return this.$q.all(results).then(function () {
diff --git a/platform/commonUI/edit/test/actions/CancelActionSpec.js b/platform/commonUI/edit/test/actions/CancelActionSpec.js
index 3bd0cee72f..7fdc51b0e9 100644
--- a/platform/commonUI/edit/test/actions/CancelActionSpec.js
+++ b/platform/commonUI/edit/test/actions/CancelActionSpec.js
@@ -63,7 +63,7 @@ define(
capabilities.editor = jasmine.createSpyObj(
"editor",
- ["save", "cancel", "isEditContextRoot"]
+ ["save", "finish", "isEditContextRoot"]
);
capabilities.action = jasmine.createSpyObj(
"actionCapability",
@@ -105,7 +105,7 @@ define(
return !!capabilities[name];
});
- capabilities.editor.cancel.andReturn(mockPromise(true));
+ capabilities.editor.finish.andReturn(mockPromise(true));
action = new CancelAction(actionContext);
@@ -130,8 +130,8 @@ define(
capabilities.action.perform.andReturn(mockPromise(true));
action.perform();
- // Should have called cancel
- expect(capabilities.editor.cancel).toHaveBeenCalled();
+ // Should have called finish
+ expect(capabilities.editor.finish).toHaveBeenCalled();
// Definitely shouldn't call save!
expect(capabilities.editor.save).not.toHaveBeenCalled();
diff --git a/platform/commonUI/edit/test/actions/EditActionSpec.js b/platform/commonUI/edit/test/actions/EditActionSpec.js
index c896e83dd1..c1a21c83bf 100644
--- a/platform/commonUI/edit/test/actions/EditActionSpec.js
+++ b/platform/commonUI/edit/test/actions/EditActionSpec.js
@@ -58,7 +58,7 @@ define(
);
mockEditor = jasmine.createSpyObj(
"editorCapability",
- ["edit", "isEditContextRoot", "cancel"]
+ ["edit", "isEditContextRoot"]
);
capabilities = {
@@ -98,13 +98,6 @@ define(
expect(EditAction.appliesTo(actionContext)).toBe(false);
});
- it ("cancels editing when user navigates away", function () {
- action.perform();
- expect(mockNavigationService.addListener).toHaveBeenCalled();
- mockNavigationService.addListener.mostRecentCall.args[0]();
- expect(mockEditor.cancel).toHaveBeenCalled();
- });
-
it ("invokes the Edit capability on the object", function () {
action.perform();
expect(mockDomainObject.useCapability).toHaveBeenCalledWith("editor");
diff --git a/platform/commonUI/edit/test/actions/SaveActionSpec.js b/platform/commonUI/edit/test/actions/SaveActionSpec.js
index 0243f89a11..7230c09448 100644
--- a/platform/commonUI/edit/test/actions/SaveActionSpec.js
+++ b/platform/commonUI/edit/test/actions/SaveActionSpec.js
@@ -56,7 +56,7 @@ define(
);
mockEditorCapability = jasmine.createSpyObj(
"editor",
- ["save", "cancel", "isEditContextRoot"]
+ ["save", "isEditContextRoot"]
);
mockActionCapability = jasmine.createSpyObj(
"actionCapability",
@@ -105,12 +105,6 @@ define(
expect(mockEditorCapability.save).toHaveBeenCalled();
});
- it("navigates to the object after saving",
- function () {
- action.perform();
- expect(mockActionCapability.perform).toHaveBeenCalledWith("navigate");
- });
-
describe("a blocking dialog", function () {
var mockDialogHandle;
diff --git a/platform/commonUI/edit/test/actions/SaveAndStopEditingActionSpec.js b/platform/commonUI/edit/test/actions/SaveAndStopEditingActionSpec.js
new file mode 100644
index 0000000000..1fb8fa6492
--- /dev/null
+++ b/platform/commonUI/edit/test/actions/SaveAndStopEditingActionSpec.js
@@ -0,0 +1,123 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2014-2016, United States Government
+ * as represented by the Administrator of the National Aeronautics and Space
+ * Administration. All rights reserved.
+ *
+ * Open MCT 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 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.
+ *****************************************************************************/
+
+define(
+ ["../../src/actions/SaveAndStopEditingAction"],
+ function (SaveAndStopEditingAction) {
+
+ describe("The Save and Stop Editing action", function () {
+
+ // Some mocks appear unused because the
+ // underlying SaveAction that this action
+ // depends on is not mocked, so we mock some
+ // of SaveAction's own dependencies to make
+ // it run.
+ var mockDomainObject,
+ mockEditorCapability,
+ actionContext,
+ dialogService,
+ mockActionCapability,
+ capabilities = {},
+ action;
+
+ function mockPromise(value) {
+ return {
+ then: function (callback) {
+ return mockPromise(callback(value));
+ },
+ catch: function (callback) {
+ return mockPromise(callback(value));
+ }
+ };
+ }
+
+ beforeEach(function () {
+ mockDomainObject = jasmine.createSpyObj(
+ "domainObject",
+ [
+ "getCapability",
+ "hasCapability",
+ "getModel",
+ "getOriginalObject"
+ ]
+ );
+ mockEditorCapability = jasmine.createSpyObj(
+ "editor",
+ ["save", "finish", "isEditContextRoot"]
+ );
+ mockActionCapability = jasmine.createSpyObj(
+ "actionCapability",
+ ["perform"]
+ );
+ capabilities.editor = mockEditorCapability;
+ capabilities.action = mockActionCapability;
+
+ actionContext = {
+ domainObject: mockDomainObject
+ };
+ dialogService = jasmine.createSpyObj(
+ "dialogService",
+ ["showBlockingMessage"]
+ );
+
+ mockDomainObject.hasCapability.andReturn(true);
+ mockDomainObject.getCapability.andCallFake(function (capability) {
+ return capabilities[capability];
+ });
+ mockDomainObject.getModel.andReturn({ persisted: 0 });
+ mockEditorCapability.save.andReturn(mockPromise(true));
+ mockEditorCapability.isEditContextRoot.andReturn(true);
+
+ action = new SaveAndStopEditingAction(dialogService, actionContext);
+ });
+
+
+ it("only applies to domain object with an editor capability", function () {
+ expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(true);
+ expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
+
+ mockDomainObject.hasCapability.andReturn(false);
+ mockDomainObject.getCapability.andReturn(undefined);
+ expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(false);
+ });
+
+ it("only applies to domain object that has already been persisted", function () {
+ mockDomainObject.getModel.andReturn({ persisted: undefined });
+ expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(false);
+ });
+
+ it("does not close the editor before completing the save", function () {
+ mockEditorCapability.save.andReturn(new Promise(function () {
+ }));
+ action.perform();
+ expect(mockEditorCapability.save).toHaveBeenCalled();
+ expect(mockEditorCapability.finish).not.toHaveBeenCalled();
+ });
+
+ it("closes the editor after saving", function () {
+ action.perform();
+ expect(mockEditorCapability.save).toHaveBeenCalled();
+ expect(mockEditorCapability.finish).toHaveBeenCalled();
+ });
+ });
+ }
+);
diff --git a/platform/commonUI/edit/test/actions/SaveAsActionSpec.js b/platform/commonUI/edit/test/actions/SaveAsActionSpec.js
index fd8ce18c07..f87cf4766f 100644
--- a/platform/commonUI/edit/test/actions/SaveAsActionSpec.js
+++ b/platform/commonUI/edit/test/actions/SaveAsActionSpec.js
@@ -19,7 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
-/*global describe,it,expect,beforeEach,jasmine*/
+/*global describe,it,expect,beforeEach,jasmine,runs,waitsFor,spyOn*/
define(
["../../src/actions/SaveAsAction"],
@@ -33,7 +33,6 @@ define(
mockDialogService,
mockCopyService,
mockParent,
- mockUrlService,
actionContext,
capabilities = {},
action;
@@ -78,10 +77,10 @@ define(
mockEditorCapability = jasmine.createSpyObj(
"editor",
- ["save", "cancel", "isEditContextRoot"]
+ ["save", "finish", "isEditContextRoot"]
);
- mockEditorCapability.cancel.andReturn(mockPromise(undefined));
mockEditorCapability.save.andReturn(mockPromise(true));
+ mockEditorCapability.finish.andReturn(mockPromise(true));
mockEditorCapability.isEditContextRoot.andReturn(true);
capabilities.editor = mockEditorCapability;
@@ -113,16 +112,11 @@ define(
]
);
- mockUrlService = jasmine.createSpyObj(
- "urlService",
- ["urlForLocation"]
- );
-
actionContext = {
domainObject: mockDomainObject
};
- action = new SaveAsAction(undefined, undefined, mockDialogService, undefined, mockCopyService, actionContext);
+ action = new SaveAsAction(undefined, undefined, mockDialogService, mockCopyService, actionContext);
spyOn(action, "getObjectService");
action.getObjectService.andReturn(mockObjectService);
@@ -156,6 +150,28 @@ define(
expect(SaveAsAction.appliesTo(actionContext)).toBe(false);
});
+ it("uses the editor capability to save the object", function () {
+ mockEditorCapability.save.andReturn(new Promise(function () {}));
+ runs(function () {
+ action.perform();
+ });
+ waitsFor(function () {
+ return mockEditorCapability.save.calls.length > 0;
+ }, "perform() should call EditorCapability.save");
+ runs(function () {
+ expect(mockEditorCapability.finish).not.toHaveBeenCalled();
+ });
+ });
+
+ it("uses the editor capability to finish editing the object", function () {
+ runs(function () {
+ action.perform();
+ });
+ waitsFor(function () {
+ return mockEditorCapability.finish.calls.length > 0;
+ }, "perform() should call EditorCapability.finish");
+ });
+
it("returns to browse after save", function () {
spyOn(action, "save");
action.save.andReturn(mockPromise(mockDomainObject));
diff --git a/platform/commonUI/edit/test/capabilities/EditorCapabilitySpec.js b/platform/commonUI/edit/test/capabilities/EditorCapabilitySpec.js
index 3ffb81921d..77fbd9b74f 100644
--- a/platform/commonUI/edit/test/capabilities/EditorCapabilitySpec.js
+++ b/platform/commonUI/edit/test/capabilities/EditorCapabilitySpec.js
@@ -134,15 +134,15 @@ define(
it("commits the transaction", function () {
expect(mockTransactionService.commit).toHaveBeenCalled();
});
- it("resets the edit state", function () {
- expect(mockStatusCapability.set).toHaveBeenCalledWith('editing', false);
+ it("begins a new transaction", function () {
+ expect(mockTransactionService.startTransaction).toHaveBeenCalled();
});
});
- describe("cancel", function () {
+ describe("finish", function () {
beforeEach(function () {
capability.edit();
- capability.cancel();
+ capability.finish();
});
it("cancels the transaction", function () {
expect(mockTransactionService.cancel).toHaveBeenCalled();
@@ -158,7 +158,7 @@ define(
beforeEach(function () {
mockDomainObject.getModel.andReturn(model);
capability.edit();
- capability.cancel();
+ capability.finish();
});
it("returns true if the object has been modified since it" +
" was last persisted", function () {
diff --git a/platform/commonUI/edit/test/controllers/EditActionControllerSpec.js b/platform/commonUI/edit/test/controllers/EditActionControllerSpec.js
index 36faf7beb8..bd5c8a9524 100644
--- a/platform/commonUI/edit/test/controllers/EditActionControllerSpec.js
+++ b/platform/commonUI/edit/test/controllers/EditActionControllerSpec.js
@@ -19,22 +19,51 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
+/*global describe,it,expect,beforeEach,jasmine*/
define(
["../../src/controllers/EditActionController"],
function (EditActionController) {
describe("The Edit Action controller", function () {
+ var mockSaveActionMetadata = {
+ name: "mocked-save-action",
+ cssclass: "mocked-save-action-css"
+ };
+
+ function fakeGetActions(actionContext) {
+ if (actionContext.category === "save") {
+ var mockedSaveActions = [
+ jasmine.createSpyObj("mockSaveAction", ["getMetadata", "perform"]),
+ jasmine.createSpyObj("mockSaveAction", ["getMetadata", "perform"])
+ ];
+ mockedSaveActions.forEach(function (action) {
+ action.getMetadata.andReturn(mockSaveActionMetadata);
+ });
+ return mockedSaveActions;
+ } else if (actionContext.category === "conclude-editing") {
+ return ["a", "b", "c"];
+ } else {
+ throw "EditActionController uses a context that's not covered by tests.";
+ }
+ }
+
var mockScope,
mockActions,
controller;
beforeEach(function () {
mockActions = jasmine.createSpyObj("action", ["getActions"]);
+ mockActions.getActions.andCallFake(fakeGetActions);
mockScope = jasmine.createSpyObj("$scope", ["$watch"]);
+ mockScope.action = mockActions;
controller = new EditActionController(mockScope);
});
+ function makeControllerUpdateActions() {
+ mockScope.$watch.mostRecentCall.args[1]();
+ }
+
it("watches scope that may change applicable actions", function () {
// The action capability
expect(mockScope.$watch).toHaveBeenCalledWith(
@@ -43,16 +72,34 @@ define(
);
});
- it("populates the scope with grouped and ungrouped actions", function () {
- mockScope.action = mockActions;
+ it("populates the scope with 'save' actions", function () {
+ makeControllerUpdateActions();
+ expect(mockScope.saveActions.length).toEqual(2);
+ });
- mockActions.getActions.andReturn(["a", "b", "c"]);
+ it("converts 'save' actions to their menu counterparts", function () {
+ makeControllerUpdateActions();
+ var menuOptions = mockScope.saveActionsAsMenuOptions;
- // Call the watch
- mockScope.$watch.mostRecentCall.args[1]();
+ expect(menuOptions.length).toEqual(2);
+ expect(menuOptions[0].key).toEqual(mockScope.saveActions[0]);
+ expect(menuOptions[1].key).toEqual(mockScope.saveActions[1]);
+ menuOptions.forEach(function (option) {
+ expect(option.name).toEqual(mockSaveActionMetadata.name);
+ expect(option.cssclass).toEqual(mockSaveActionMetadata.cssclass);
+ });
+ });
- // Should have grouped and ungrouped actions in scope now
- expect(mockScope.editActions.length).toEqual(3);
+ it("uses a click handler to perform the clicked action", function () {
+ makeControllerUpdateActions();
+ var sampleSaveAction = mockScope.saveActions[0];
+ mockScope.saveActionMenuClickHandler(sampleSaveAction);
+ expect(sampleSaveAction.perform).toHaveBeenCalled();
+ });
+
+ it("populates the scope with other editing actions", function () {
+ makeControllerUpdateActions();
+ expect(mockScope.otherEditActions).toEqual(["a", "b", "c"]);
});
});
}
diff --git a/platform/commonUI/edit/test/creation/CreateActionSpec.js b/platform/commonUI/edit/test/creation/CreateActionSpec.js
index d65621f9a8..cd3d3fbc91 100644
--- a/platform/commonUI/edit/test/creation/CreateActionSpec.js
+++ b/platform/commonUI/edit/test/creation/CreateActionSpec.js
@@ -103,7 +103,7 @@ define(
[
"edit",
"save",
- "cancel"
+ "finish"
]
);
@@ -142,6 +142,7 @@ define(
});
describe("the perform function", function () {
+ var promise = jasmine.createSpyObj("promise", ["then"]);
beforeEach(function () {
capabilities.action.getActions.andReturn([mockEditAction]);
});
@@ -156,19 +157,20 @@ define(
expect(mockEditAction.perform).toHaveBeenCalled();
});
- it("uses the save action if object does not have an edit action" +
+ it("uses the save-as action if object does not have an edit action" +
" available", function () {
capabilities.action.getActions.andReturn([]);
capabilities.action.perform.andReturn(mockPromise(undefined));
+ capabilities.editor.save.andReturn(promise);
action.perform();
- expect(capabilities.action.perform).toHaveBeenCalledWith("save");
+ expect(capabilities.action.perform).toHaveBeenCalledWith("save-as");
});
describe("uses to editor capability", function () {
- var promise = jasmine.createSpyObj("promise", ["then"]);
beforeEach(function () {
capabilities.action.getActions.andReturn([]);
capabilities.action.perform.andReturn(promise);
+ capabilities.editor.save.andReturn(promise);
});
it("to save the edit if user saves dialog", function () {
@@ -178,10 +180,10 @@ define(
expect(capabilities.editor.save).toHaveBeenCalled();
});
- it("to cancel the edit if user cancels dialog", function () {
+ it("to finish the edit if user cancels dialog", function () {
action.perform();
promise.then.mostRecentCall.args[1]();
- expect(capabilities.editor.cancel).toHaveBeenCalled();
+ expect(capabilities.editor.finish).toHaveBeenCalled();
});
});
});
diff --git a/platform/commonUI/edit/test/creation/CreationServiceSpec.js b/platform/commonUI/edit/test/creation/CreationServiceSpec.js
index 1cc6d55e1b..090437b8c7 100644
--- a/platform/commonUI/edit/test/creation/CreationServiceSpec.js
+++ b/platform/commonUI/edit/test/creation/CreationServiceSpec.js
@@ -195,7 +195,7 @@ define(
expect(failure).toHaveBeenCalled();
});
- it("logs an error when mutaton fails", function () {
+ it("logs an error when mutation fails", function () {
// If mutation of the parent fails, we've lost the
// created object - this is an error.
var model = { someKey: "some value" };
diff --git a/platform/commonUI/edit/test/representers/EditRepresenterSpec.js b/platform/commonUI/edit/test/representers/EditRepresenterSpec.js
index 7cb2626e64..7af3740fd6 100644
--- a/platform/commonUI/edit/test/representers/EditRepresenterSpec.js
+++ b/platform/commonUI/edit/test/representers/EditRepresenterSpec.js
@@ -112,7 +112,7 @@ define(
expect(mockPersistence.persist).toHaveBeenCalled();
// Finally, check that the provided mutation function
- // includes both model and configuratioon
+ // includes both model and configuration
expect(
mockDomainObject.useCapability.mostRecentCall.args[1]()
).toEqual({
diff --git a/platform/commonUI/edit/test/representers/EditToolbarRepresenterSpec.js b/platform/commonUI/edit/test/representers/EditToolbarRepresenterSpec.js
index 0147601d7d..7cc8314fc6 100644
--- a/platform/commonUI/edit/test/representers/EditToolbarRepresenterSpec.js
+++ b/platform/commonUI/edit/test/representers/EditToolbarRepresenterSpec.js
@@ -79,7 +79,7 @@ define(
it("removes state from parent scope on destroy", function () {
// Verify precondition
expect(mockScope.$parent.testToolbar).toBeDefined();
- // Destroy the represeter
+ // Destroy the representer
representer.destroy();
// Should have removed toolbar state from view
expect(mockScope.$parent.testToolbar).toBeUndefined();
diff --git a/platform/commonUI/general/res/sass/_constants.scss b/platform/commonUI/general/res/sass/_constants.scss
index 8fb1a39cb1..1e609cc038 100644
--- a/platform/commonUI/general/res/sass/_constants.scss
+++ b/platform/commonUI/general/res/sass/_constants.scss
@@ -62,6 +62,9 @@ $ueDesktopMinW: 600px;
$ovrTopBarH: 45px;
$ovrFooterH: 24px;
$overlayMargin: 25px;
+/*************** Progress Overlay */
+$durEntryMs: 50ms;
+$delayEntryMs: 100ms;
/*************** Items */
$ueBrowseGridItemLg: 200px;
$ueBrowseGridItemTopBarH: 20px;
diff --git a/platform/commonUI/general/res/sass/_views.scss b/platform/commonUI/general/res/sass/_views.scss
index 357f9f3c7c..0a4cc651dd 100644
--- a/platform/commonUI/general/res/sass/_views.scss
+++ b/platform/commonUI/general/res/sass/_views.scss
@@ -31,23 +31,10 @@
.has-control-bar {
$btnExportH: $btnFrameH;
.l-control-bar {
- @include trans-prop-nice(opacity, $dur: 50ms);
- opacity: 0;
+ display: none;
}
.l-view-section {
- @include trans-prop-nice(top, $dur: 150ms, $delay: 50ms);
top: 0;
}
- &:hover {
- .l-control-bar {
- @include trans-prop-nice(opacity, 150ms, 100ms);
- opacity: 1;
- }
- .l-view-section {
- @include trans-prop-nice(top, $dur: 150ms);
- top: $btnExportH + $interiorMargin;
- }
- }
}
-
}
\ No newline at end of file
diff --git a/platform/commonUI/general/res/sass/controls/_controls.scss b/platform/commonUI/general/res/sass/controls/_controls.scss
index 7900739668..d1935d8ce0 100644
--- a/platform/commonUI/general/res/sass/controls/_controls.scss
+++ b/platform/commonUI/general/res/sass/controls/_controls.scss
@@ -216,6 +216,7 @@ input[type="search"] {
.l-input-lg input[type="text"] { width: 100% !important; }
.l-input-med input[type="text"] { width: 200px !important; }
.l-input-sm input[type="text"] { width: 50px !important; }
+.l-textarea-sm textarea { position: relative; height: 50px; }
.l-numeric input[type="text"] { text-align: right; }
.input-labeled {
diff --git a/platform/commonUI/general/res/sass/overlay/_overlay.scss b/platform/commonUI/general/res/sass/overlay/_overlay.scss
index 018197dac0..2c60aa99af 100644
--- a/platform/commonUI/general/res/sass/overlay/_overlay.scss
+++ b/platform/commonUI/general/res/sass/overlay/_overlay.scss
@@ -19,8 +19,17 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
+
.overlay {
font-size: 90%;
+ &.delayEntry100ms {
+ @include keyframes(fadeInFromNone) {
+ 0% { display: none; opacity: 0; }
+ 100% { display: block; opacity: 1; }
+ }
+ @include animation-delay($delayEntryMs);
+ @include animation(fadeInFromNone $durEntryMs ease-in);
+ }
.blocker {
background: $colorOvrBlocker;
z-index: 100;
diff --git a/platform/commonUI/general/src/controllers/ObjectInspectorController.js b/platform/commonUI/general/src/controllers/ObjectInspectorController.js
index eb164dc76b..ef066d6774 100644
--- a/platform/commonUI/general/src/controllers/ObjectInspectorController.js
+++ b/platform/commonUI/general/src/controllers/ObjectInspectorController.js
@@ -38,7 +38,7 @@ define(
$scope.contextutalParents = [];
//$scope.isLink = false;
- // Gets an array of the contextual parents/anscestors of the selected object
+ // Gets an array of the contextual parents/ancestors of the selected object
function getContextualPath() {
var currentObj = $scope.ngModel.selectedObject,
currentParent,
@@ -61,7 +61,7 @@ define(
$scope.contextutalParents = parents;
}
- // Gets an array of the parents/anscestors of the selected object's
+ // Gets an array of the parents/ancestors of the selected object's
// primary location (locational of original non-link)
function getPrimaryPath(current) {
var location;
diff --git a/platform/commonUI/general/src/filters/ReverseFilter.js b/platform/commonUI/general/src/filters/ReverseFilter.js
index a951e940e4..775d9fca86 100644
--- a/platform/commonUI/general/src/filters/ReverseFilter.js
+++ b/platform/commonUI/general/src/filters/ReverseFilter.js
@@ -25,7 +25,7 @@ define(function () {
/**
* Implements the `reverse` filter, which reverses text strings.
* Useful in cases where text should be reversed for presentational
- * reasons (e.g. in conjunction with CSS tricks involing text direction),
+ * reasons (e.g. in conjunction with CSS tricks involving text direction),
* allowing such behavior to be handled independently from the controller
* layer.
*
diff --git a/platform/commonUI/general/src/services/PopupService.js b/platform/commonUI/general/src/services/PopupService.js
index b87c553ccd..3f65106fb0 100644
--- a/platform/commonUI/general/src/services/PopupService.js
+++ b/platform/commonUI/general/src/services/PopupService.js
@@ -35,7 +35,7 @@ define(
}
/**
- * Options controlling how the popup is displaed.
+ * Options controlling how the popup is displayed.
*
* @typedef PopupOptions
* @memberof platform/commonUI/general
diff --git a/platform/commonUI/general/test/controllers/ClickAwayControllerSpec.js b/platform/commonUI/general/test/controllers/ClickAwayControllerSpec.js
index 22b4035919..8b114f9948 100644
--- a/platform/commonUI/general/test/controllers/ClickAwayControllerSpec.js
+++ b/platform/commonUI/general/test/controllers/ClickAwayControllerSpec.js
@@ -60,7 +60,7 @@ define(
expect(controller.isActive()).toBe(false);
});
- it("allows active state to be explictly specified", function () {
+ it("allows active state to be explicitly specified", function () {
controller.setState(true);
expect(controller.isActive()).toBe(true);
controller.setState(true);
diff --git a/platform/commonUI/general/test/controllers/ToggleControllerSpec.js b/platform/commonUI/general/test/controllers/ToggleControllerSpec.js
index 32a9568200..b51e2f0920 100644
--- a/platform/commonUI/general/test/controllers/ToggleControllerSpec.js
+++ b/platform/commonUI/general/test/controllers/ToggleControllerSpec.js
@@ -46,7 +46,7 @@ define(
expect(controller.isActive()).toBe(false);
});
- it("allows active state to be explictly specified", function () {
+ it("allows active state to be explicitly specified", function () {
controller.setState(true);
expect(controller.isActive()).toBe(true);
controller.setState(true);
diff --git a/platform/commonUI/mobile/test/MCTDeviceSpec.js b/platform/commonUI/mobile/test/MCTDeviceSpec.js
index 4d130c56ee..421d3d7aca 100644
--- a/platform/commonUI/mobile/test/MCTDeviceSpec.js
+++ b/platform/commonUI/mobile/test/MCTDeviceSpec.js
@@ -72,7 +72,7 @@ define(
expect(directive.restrict).toEqual("A");
});
- it("transcludes at the elmeent level", function () {
+ it("transcludes at the element level", function () {
expect(directive.transclude).toEqual('element');
});
diff --git a/platform/commonUI/notification/src/NotificationService.js b/platform/commonUI/notification/src/NotificationService.js
index 5412eb951e..e37571759a 100644
--- a/platform/commonUI/notification/src/NotificationService.js
+++ b/platform/commonUI/notification/src/NotificationService.js
@@ -361,7 +361,7 @@ define(
autodismiss specified), leave it to run. Otherwise force a
timeout.
- This notifcation has been added to queue and will be
+ This notification has been added to queue and will be
serviced as soon as possible.
*/
this.active.timeout = this.$timeout(function () {
diff --git a/platform/containment/test/CapabilityTableSpec.js b/platform/containment/test/CapabilityTableSpec.js
index 851ac2f99f..646ef82882 100644
--- a/platform/containment/test/CapabilityTableSpec.js
+++ b/platform/containment/test/CapabilityTableSpec.js
@@ -45,7 +45,7 @@ define(
['getKey', 'getDefinition', 'getInitialModel']
);
mockType.getKey.andReturn(type);
- // Return a model to drive apparant capabilities
+ // Return a model to drive apparent capabilities
mockType.getInitialModel.andReturn({ id: type });
return mockType;
});
diff --git a/platform/containment/test/ContainmentTableSpec.js b/platform/containment/test/ContainmentTableSpec.js
index d0ab71b459..a83d9c1c82 100644
--- a/platform/containment/test/ContainmentTableSpec.js
+++ b/platform/containment/test/ContainmentTableSpec.js
@@ -50,7 +50,7 @@ define(
// third one defines no containership rules
contains: (index < 2) ? [{ has: 'b' }] : undefined
});
- // Return a model to drive apparant capabilities
+ // Return a model to drive apparent capabilities
mockType.getInitialModel.andReturn({ id: type });
return mockType;
});
diff --git a/platform/core/bundle.js b/platform/core/bundle.js
index 8b4baf83ff..4b9e2b9adb 100644
--- a/platform/core/bundle.js
+++ b/platform/core/bundle.js
@@ -252,6 +252,14 @@ define([
"pattern": "\\S+",
"required": true,
"cssclass": "l-input-lg"
+ },
+ {
+ "name": "Notes",
+ "key": "notes",
+ "property": "notes",
+ "control": "textarea",
+ "required": false,
+ "cssclass": "l-textarea-sm"
}
]
},
diff --git a/platform/core/src/models/ModelCacheService.js b/platform/core/src/models/ModelCacheService.js
index a204ef0b87..783509a774 100644
--- a/platform/core/src/models/ModelCacheService.js
+++ b/platform/core/src/models/ModelCacheService.js
@@ -24,7 +24,7 @@ define([], function () {
/**
* Provides a cache for domain object models which exist in memory,
- * but may or may not exist in backing persistene stores.
+ * but may or may not exist in backing persistence stores.
* @constructor
* @memberof platform/core
*/
diff --git a/platform/core/src/models/RootModelProvider.js b/platform/core/src/models/RootModelProvider.js
index 0dfb656c31..205d41e66b 100644
--- a/platform/core/src/models/RootModelProvider.js
+++ b/platform/core/src/models/RootModelProvider.js
@@ -42,7 +42,7 @@ define(
* @implements {ModelService}
* @param {Array} roots all `roots[]` extensions
* @param $q Angular's $q, for promises
- * @param $log Anuglar's $log, for logging
+ * @param $log Angular's $log, for logging
*/
function RootModelProvider(roots, $q, $log) {
// Pull out identifiers to used as ROOT's
diff --git a/platform/core/src/models/StaticModelProvider.js b/platform/core/src/models/StaticModelProvider.js
index 45d89dbe2f..e20f9232fb 100644
--- a/platform/core/src/models/StaticModelProvider.js
+++ b/platform/core/src/models/StaticModelProvider.js
@@ -49,7 +49,7 @@ define(
}
}
- // Prepoulate maps with models to make subsequent lookup faster.
+ // Prepopulate maps with models to make subsequent lookup faster.
models.forEach(addModelToMap);
this.modelMap = modelMap;
diff --git a/platform/core/src/types/TypePropertyConversion.js b/platform/core/src/types/TypePropertyConversion.js
index 84fba54e02..fcf71b2011 100644
--- a/platform/core/src/types/TypePropertyConversion.js
+++ b/platform/core/src/types/TypePropertyConversion.js
@@ -43,7 +43,7 @@ define(
},
ARRAY_SUFFIX = '[]';
- // Utility function to handle arrays of conversiions
+ // Utility function to handle arrays of conversions
function ArrayConversion(conversion) {
return {
toModelValue: function (formValue) {
diff --git a/platform/core/src/types/TypeProvider.js b/platform/core/src/types/TypeProvider.js
index c3256c57ba..e8cf83f3e2 100644
--- a/platform/core/src/types/TypeProvider.js
+++ b/platform/core/src/types/TypeProvider.js
@@ -68,7 +68,7 @@ define(
}) : array;
}
- // Reduce an array of type definitions to a single type definiton,
+ // Reduce an array of type definitions to a single type definition,
// which has merged all properties in order.
function collapse(typeDefs) {
var collapsed = typeDefs.reduce(function (a, b) {
diff --git a/platform/entanglement/README.md b/platform/entanglement/README.md
index f3685bad05..aaf517decf 100644
--- a/platform/entanglement/README.md
+++ b/platform/entanglement/README.md
@@ -3,7 +3,7 @@
Entanglement is the process of moving, copying, and linking domain objects
in such a way that their relationships are impossible to discern.
-This bundle provides move, copy, and link functionality. Acheiving a state of
+This bundle provides move, copy, and link functionality. Achieving a state of
entanglement is left up to the end user.
diff --git a/platform/features/layout/src/FixedDragHandle.js b/platform/features/layout/src/FixedDragHandle.js
index de4b8ec92d..86fa4fb8c3 100644
--- a/platform/features/layout/src/FixedDragHandle.js
+++ b/platform/features/layout/src/FixedDragHandle.js
@@ -94,7 +94,7 @@ define(
};
/**
- * End a drag gesture. This should be callled when a drag
+ * End a drag gesture. This should be called when a drag
* concludes to trigger commit of changes.
*/
FixedDragHandle.prototype.endDrag = function () {
diff --git a/platform/features/layout/src/LayoutController.js b/platform/features/layout/src/LayoutController.js
index 80470f25b3..88eae7462c 100644
--- a/platform/features/layout/src/LayoutController.js
+++ b/platform/features/layout/src/LayoutController.js
@@ -152,7 +152,7 @@ define(
}
// Convert from { positions: ..., dimensions: ... } to an
- // apropriate ng-style argument, to position frames.
+ // appropriate ng-style argument, to position frames.
LayoutController.prototype.convertPosition = function (raw) {
var gridSize = this.gridSize;
// Multiply position/dimensions by grid size
diff --git a/platform/features/layout/test/LayoutControllerSpec.js b/platform/features/layout/test/LayoutControllerSpec.js
index dbc79e2769..6a23a29c04 100644
--- a/platform/features/layout/test/LayoutControllerSpec.js
+++ b/platform/features/layout/test/LayoutControllerSpec.js
@@ -164,7 +164,7 @@ define(
// Populate scope
mockScope.$watchCollection.mostRecentCall.args[1]();
- // Verify precondtion
+ // Verify precondition
expect(testConfiguration.panels.b).not.toBeDefined();
// Do a drag
diff --git a/platform/features/plot/test/Canvas2DChartSpec.js b/platform/features/plot/test/Canvas2DChartSpec.js
index b20d7b9c70..446c07d841 100644
--- a/platform/features/plot/test/Canvas2DChartSpec.js
+++ b/platform/features/plot/test/Canvas2DChartSpec.js
@@ -59,7 +59,7 @@ define(
expect(mock2d.clearRect).toHaveBeenCalled();
});
- it("doees not construct if 2D is unavailable", function () {
+ it("does not construct if 2D is unavailable", function () {
mockCanvas.getContext.andReturn(undefined);
expect(function () {
return new Canvas2DChart(mockCanvas);
diff --git a/platform/features/plot/test/GLChartSpec.js b/platform/features/plot/test/GLChartSpec.js
index fb575d7709..1ab0e6ea0a 100644
--- a/platform/features/plot/test/GLChartSpec.js
+++ b/platform/features/plot/test/GLChartSpec.js
@@ -82,7 +82,7 @@ define(
expect(mockGL.clear).toHaveBeenCalled();
});
- it("doees not construct if WebGL is unavailable", function () {
+ it("does not construct if WebGL is unavailable", function () {
mockCanvas.getContext.andReturn(undefined);
expect(function () {
return new GLChart(mockCanvas);
diff --git a/platform/features/timeline/src/controllers/TimelineGanttController.js b/platform/features/timeline/src/controllers/TimelineGanttController.js
index 7c3ee03244..6153064ebe 100644
--- a/platform/features/timeline/src/controllers/TimelineGanttController.js
+++ b/platform/features/timeline/src/controllers/TimelineGanttController.js
@@ -26,7 +26,7 @@ define(
/**
* Control for Gantt bars in a timeline view.
- * Primarily reesponsible for supporting the positioning of Gantt
+ * Primarily responsible for supporting the positioning of Gantt
* bars; particularly, this ensures that the left and right edges
* never go to far off screen, because in some environments this
* will effect rendering performance without visible results.
diff --git a/platform/features/timeline/src/controllers/TimelineTickController.js b/platform/features/timeline/src/controllers/TimelineTickController.js
index 41c57dedbf..56275a6d16 100644
--- a/platform/features/timeline/src/controllers/TimelineTickController.js
+++ b/platform/features/timeline/src/controllers/TimelineTickController.js
@@ -28,7 +28,7 @@ define(
/**
* Provides labels for the tick mark area of a timeline view.
- * Since the tick mark regin is potentially extremeley large,
+ * Since the tick mark region is potentially extremely large,
* only the subset of ticks which will actually be shown in
* view are provided.
* @constructor
diff --git a/platform/features/timeline/src/controllers/drag/TimelineDragHandler.js b/platform/features/timeline/src/controllers/drag/TimelineDragHandler.js
index 7a356d91dc..745c3cc5cf 100644
--- a/platform/features/timeline/src/controllers/drag/TimelineDragHandler.js
+++ b/platform/features/timeline/src/controllers/drag/TimelineDragHandler.js
@@ -148,7 +148,7 @@ define(
var timespan = timespans[toId(id)];
// Use as setter if argument is present
if ((typeof value === 'number') && timespan) {
- // Set the end (ensuring it doesn't preceed start)
+ // Set the end (ensuring it doesn't precede start)
timespan.setEnd(
Math.max(value, timespan.getStart())
);
diff --git a/platform/features/timeline/src/controllers/drag/TimelineSnapHandler.js b/platform/features/timeline/src/controllers/drag/TimelineSnapHandler.js
index 70d854d008..42d13b8681 100644
--- a/platform/features/timeline/src/controllers/drag/TimelineSnapHandler.js
+++ b/platform/features/timeline/src/controllers/drag/TimelineSnapHandler.js
@@ -41,7 +41,7 @@ define(
ids,
candidates;
- // Filter an id for inclustion
+ // Filter an id for inclusion
function include(id) {
return id !== exclude;
}
diff --git a/platform/forms/bundle.js b/platform/forms/bundle.js
index daa7063ffe..d3ee14f440 100644
--- a/platform/forms/bundle.js
+++ b/platform/forms/bundle.js
@@ -32,6 +32,7 @@ define([
"text!./res/templates/controls/datetime.html",
"text!./res/templates/controls/select.html",
"text!./res/templates/controls/textfield.html",
+ "text!./res/templates/controls/textarea.html",
"text!./res/templates/controls/button.html",
"text!./res/templates/controls/color.html",
"text!./res/templates/controls/composite.html",
@@ -51,6 +52,7 @@ define([
datetimeTemplate,
selectTemplate,
textfieldTemplate,
+ textareaTemplate,
buttonTemplate,
colorTemplate,
compositeTemplate,
@@ -103,6 +105,10 @@ define([
"key": "textfield",
"template": textfieldTemplate
},
+ {
+ "key": "textarea",
+ "template": textareaTemplate
+ },
{
"key": "button",
"template": buttonTemplate
diff --git a/platform/forms/res/templates/controls/textarea.html b/platform/forms/res/templates/controls/textarea.html
new file mode 100644
index 0000000000..45c4db4e1e
--- /dev/null
+++ b/platform/forms/res/templates/controls/textarea.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
diff --git a/platform/framework/src/load/Bundle.js b/platform/framework/src/load/Bundle.js
index a97dc3af5b..91bd966754 100644
--- a/platform/framework/src/load/Bundle.js
+++ b/platform/framework/src/load/Bundle.js
@@ -174,7 +174,7 @@ define(
* category.
*
* @param {string} category name of the extension category
- * @returns {Array} extension definitions of that cataegory
+ * @returns {Array} extension definitions of that category
*/
Bundle.prototype.getExtensions = function (category) {
var extensions = this.definition.extensions[category] || [],
diff --git a/platform/persistence/couch/src/CouchDocument.js b/platform/persistence/couch/src/CouchDocument.js
index 59fa3bfa3f..c16ca27f5c 100644
--- a/platform/persistence/couch/src/CouchDocument.js
+++ b/platform/persistence/couch/src/CouchDocument.js
@@ -27,7 +27,7 @@ define(
/**
* A CouchDocument describes domain object model in a format
* which is easily read-written to CouchDB. This includes
- * Couch's _id and _rev fields, as well as a sseparate
+ * Couch's _id and _rev fields, as well as a separate
* metadata field which contains a subset of information found
* in the model itself (to support search optimization with
* CouchDB views.)
@@ -37,7 +37,7 @@ define(
* @param {object} model the model to store
* @param {string} rev the revision to include (or undefined,
* if no revision should be noted for couch)
- * @param {boolean} whether or not to mark this documnet as
+ * @param {boolean} whether or not to mark this document as
* deleted (see CouchDB docs for _deleted)
*/
function CouchDocument(id, model, rev, markDeleted) {
diff --git a/platform/persistence/couch/test/CouchIndicatorSpec.js b/platform/persistence/couch/test/CouchIndicatorSpec.js
index 01fb3d7d23..166b8fc82a 100644
--- a/platform/persistence/couch/test/CouchIndicatorSpec.js
+++ b/platform/persistence/couch/test/CouchIndicatorSpec.js
@@ -69,7 +69,7 @@ define(
initialDescrption = indicator.getDescription(),
initialGlyphClass = indicator.getGlyphClass();
- // Nominal just means getting back an objeect, without
+ // Nominal just means getting back an object, without
// an error field.
mockPromise.then.mostRecentCall.args[0]({ data: {} });
@@ -88,7 +88,7 @@ define(
initialDescrption = indicator.getDescription(),
initialGlyphClass = indicator.getGlyphClass();
- // Nominal just means getting back an objeect, with
+ // Nominal just means getting back an object, with
// an error field.
mockPromise.then.mostRecentCall.args[0](
{ data: { error: "Uh oh." } }
@@ -110,7 +110,7 @@ define(
initialDescrption = indicator.getDescription(),
initialGlyphClass = indicator.getGlyphClass();
- // Nominal just means getting back an objeect, without
+ // Nominal just means getting back an object, without
// an error field.
mockPromise.then.mostRecentCall.args[1]({ data: {} });
diff --git a/platform/persistence/elastic/src/ElasticSearchProvider.js b/platform/persistence/elastic/src/ElasticSearchProvider.js
index 4bc0504760..c0930c7025 100644
--- a/platform/persistence/elastic/src/ElasticSearchProvider.js
+++ b/platform/persistence/elastic/src/ElasticSearchProvider.js
@@ -51,7 +51,7 @@ define([
* Search for domain objects using elasticsearch as a search provider.
*
* @param {String} searchTerm the term to search by.
- * @param {Number} [maxResults] the max numer of results to return.
+ * @param {Number} [maxResults] the max number of results to return.
* @returns {Promise} promise for a modelResults object.
*/
ElasticSearchProvider.prototype.query = function (searchTerm, maxResults) {
diff --git a/platform/persistence/elastic/test/ElasticIndicatorSpec.js b/platform/persistence/elastic/test/ElasticIndicatorSpec.js
index 3086b52c66..bfc3effcd0 100644
--- a/platform/persistence/elastic/test/ElasticIndicatorSpec.js
+++ b/platform/persistence/elastic/test/ElasticIndicatorSpec.js
@@ -71,7 +71,7 @@ define(
initialDescrption = indicator.getDescription(),
initialGlyphClass = indicator.getGlyphClass();
- // Nominal just means getting back an objeect, without
+ // Nominal just means getting back an object, without
// an error field.
mockPromise.then.mostRecentCall.args[0]({ data: {} });
@@ -90,7 +90,7 @@ define(
initialDescrption = indicator.getDescription(),
initialGlyphClass = indicator.getGlyphClass();
- // Nominal just means getting back an objeect, without
+ // Nominal just means getting back an object, without
// an error field.
mockPromise.then.mostRecentCall.args[1]({ data: {} });
diff --git a/platform/persistence/queue/src/PersistenceQueue.js b/platform/persistence/queue/src/PersistenceQueue.js
index de9ede2cfe..d0d4671f72 100644
--- a/platform/persistence/queue/src/PersistenceQueue.js
+++ b/platform/persistence/queue/src/PersistenceQueue.js
@@ -35,7 +35,7 @@ define(
/**
* The PersistenceQueue is used by the QueuingPersistenceCapability
- * to aggregrate calls for object persistence. These are then issued
+ * to aggregate calls for object persistence. These are then issued
* in a group, such that if some or all are rejected, this result can
* be shown to the user (again, in a group.)
*
diff --git a/platform/persistence/queue/src/PersistenceQueueHandler.js b/platform/persistence/queue/src/PersistenceQueueHandler.js
index 958b954e8f..679fbbb8df 100644
--- a/platform/persistence/queue/src/PersistenceQueueHandler.js
+++ b/platform/persistence/queue/src/PersistenceQueueHandler.js
@@ -25,7 +25,7 @@ define(
function () {
/**
- * Handles actual persistence invocations for queeud persistence
+ * Handles actual persistence invocations for queued persistence
* attempts, in a group. Handling in a group in this manner
* also allows failure to be handled in a group (e.g. in a single
* summary dialog.)
diff --git a/platform/search/src/services/GenericSearchProvider.js b/platform/search/src/services/GenericSearchProvider.js
index 8e35373fbb..6c8ce257ef 100644
--- a/platform/search/src/services/GenericSearchProvider.js
+++ b/platform/search/src/services/GenericSearchProvider.js
@@ -246,7 +246,7 @@ define([
/**
* @private
- * @returns {Number} a unique, unusued query Id.
+ * @returns {Number} a unique, unused query Id.
*/
GenericSearchProvider.prototype.makeQueryId = function () {
var queryId = Math.ceil(Math.random() * 100000);
diff --git a/platform/search/test/controllers/SearchControllerSpec.js b/platform/search/test/controllers/SearchControllerSpec.js
index bcb7b01dd0..b8c5c0c496 100644
--- a/platform/search/test/controllers/SearchControllerSpec.js
+++ b/platform/search/test/controllers/SearchControllerSpec.js
@@ -123,7 +123,7 @@ define([
expect(mockScope.results).toContain('a');
});
- it('is loading until the service\'s promise fufills', function () {
+ it('is loading until the service\'s promise fulfills', function () {
expect(mockScope.loading).toBeTruthy();
// Then resolve the promises
@@ -163,7 +163,7 @@ define([
// Flag should be true with nonempty input
expect(mockScope.ngModel.search).toEqual(true);
- // Flag should be flase with empty input
+ // Flag should be false with empty input
mockScope.ngModel.input = '';
controller.search();
mockPromise.then.mostRecentCall.args[0]({hits: [], total: 0});
diff --git a/platform/search/test/controllers/SearchMenuControllerSpec.js b/platform/search/test/controllers/SearchMenuControllerSpec.js
index 611f0d5a08..e4d566431c 100644
--- a/platform/search/test/controllers/SearchMenuControllerSpec.js
+++ b/platform/search/test/controllers/SearchMenuControllerSpec.js
@@ -54,7 +54,7 @@ define(
controller = new SearchMenuController(mockScope, mockTypes);
});
- it("gets types on initiliztion", function () {
+ it("gets types on initialization", function () {
expect(mockScope.ngModel.types).toBeDefined();
});
diff --git a/platform/telemetry/src/TelemetrySubscriber.js b/platform/telemetry/src/TelemetrySubscriber.js
index 9cf17b5fa7..6466566423 100644
--- a/platform/telemetry/src/TelemetrySubscriber.js
+++ b/platform/telemetry/src/TelemetrySubscriber.js
@@ -31,7 +31,7 @@ define(
* `telemetrySubscriber`.
*
* Subscriptions may also be made directly using the
- * `telemetry` capability of a domain objcet; the subscriber
+ * `telemetry` capability of a domain object; the subscriber
* uses this as well, but additionally handles delegation
* (e.g. for telemetry panels) as well as latest-value
* extraction.
diff --git a/platform/telemetry/src/TelemetrySubscription.js b/platform/telemetry/src/TelemetrySubscription.js
index ca0f11125d..dd5e4d3191 100644
--- a/platform/telemetry/src/TelemetrySubscription.js
+++ b/platform/telemetry/src/TelemetrySubscription.js
@@ -57,7 +57,7 @@ define(
* `telemetrySubscriber` service.
*
* Subscriptions may also be made directly using the
- * `telemetry` capability of a domain objcet; the subscriber
+ * `telemetry` capability of a domain object; the subscriber
* uses this as well, but additionally handles delegation
* (e.g. for telemetry panels) as well as latest-value
* extraction.
diff --git a/test-main.js b/test-main.js
index 43142766b9..ff8a50ca6b 100644
--- a/test-main.js
+++ b/test-main.js
@@ -55,7 +55,7 @@ requirejs.config({
"csv": "bower_components/comma-separated-values/csv.min",
"es6-promise": "bower_components/es6-promise/es6-promise.min",
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
- "jsPDF": "bower_components/jspdf/dist/jspdf.min",
+ "jsPDF": "bower_components/jspdf/dist/jspdf.debug",
"moment": "bower_components/moment/moment",
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
"saveAs": "bower_components/FileSaver.js/FileSaver.min",