[Common UI] Add in-line docs for Browse

Add in-line docs for bundle platform/commonUI/browse,
which implements Browse mode, one of the common user
interface bundles being transitioned in WTD-574.
This commit is contained in:
Victor Woeltjen
2014-11-25 16:53:22 -08:00
parent b97e2d0324
commit 36fab50825
8 changed files with 116 additions and 39 deletions

View File

@@ -79,7 +79,7 @@
{
"key": "navigate",
"implementation": "navigation/NavigateAction.js",
"depends": [ "navigationService" ]
"depends": [ "navigationService", "$q" ]
},
{
"key": "window",

View File

@@ -9,7 +9,8 @@ define(
"use strict";
/**
*
* Controller for the view switcher; populates and maintains a list
* of applicable views for a represented domain object.
* @constructor
*/
function ViewSwitcherController($scope) {

View File

@@ -15,11 +15,16 @@ define(
/**
* The creation service is responsible for instantiating and
* persisting new domain objects. This is
* persisting new domain objects. Handles all actual object
* mutation and persistence associated with domain object
* creation.
* @constructor
*/
function CreationService(persistenceService, $q, $log) {
// Persist the new domain object's model; it will be fully
// constituted as a domain object when loaded back, as all
// domain object models are.
function doPersist(space, id, model) {
return persistenceService.createObject(
space,
@@ -28,60 +33,72 @@ define(
).then(function () { return id; });
}
function addToComposition(id, parent) {
// Add the newly-created object's id to the parent's
// composition, so that it will subsequently appear
// as a child contained by that parent.
function addToComposition(id, parent, parentPersistence) {
var mutatationResult = parent.useCapability("mutation", function (model) {
if (Array.isArray(model.composition)) {
// Don't add if the id is already there
if (model.composition.indexOf(id) === -1) {
model.composition.push(id);
}
} else {
// This is abnormal; composition should be an array
$log.warn(NO_COMPOSITION_WARNING + parent.getId());
return false; // Cancel mutation
}
});
return $q.when(mutatationResult).then(function (result) {
var persistence = parent.getCapability("persistence");
if (!result) {
$log.error("Could not mutate " + parent.getId());
}
if (!persistence) {
$log.error([
"Expected to be able to persist ",
parent.getId(),
" but could not."
].join(""));
return undefined;
}
return persistence.persist();
return parentPersistence.persist();
});
}
// Create a new domain object with the provided model as a
// member of the specified parent's composition
function createObject(model, parent) {
var persistence = parent.getCapability("persistence"),
result = $q.defer(),
space;
var persistence = parent.getCapability("persistence");
if (persistence) {
space = persistence.getSpace();
return $q.when(
uuid()
).then(function (id) {
return doPersist(space, id, model);
}).then(function (id) {
return addToComposition(id, parent);
});
} else {
// We need the parent's persistence capability to determine
// what space to create the new object's model in.
if (!persistence) {
$log.warn(NON_PERSISTENT_WARNING);
$q.reject(new Error(NON_PERSISTENT_WARNING));
return $q.reject(new Error(NON_PERSISTENT_WARNING));
}
return result.promise;
// We create a new domain object in three sequential steps:
// 1. Get a new UUID for the object
// 2. Create a model with that ID in the persistence space
// 3. Add that ID to
return $q.when(
uuid()
).then(function (id) {
return doPersist(persistence.getSpace(), id, model);
}).then(function (id) {
return addToComposition(id, parent, persistence);
});
}
return {
/**
* Create a new domain object with the provided model, as
* a member of the provided parent domain object's composition.
* This parent will additionally determine which persistence
* space an object is created within (as it is possible to
* have multiple persistence spaces attached.)
*
* @param {object} model the model for the newly-created
* domain object
* @param {DomainObject} parent the domain object which
* should contain the newly-created domain object
* in its composition
*/
createObject: createObject
};
}

View File

@@ -9,23 +9,34 @@ define(
"use strict";
/**
*
* The navigate action navigates to a specific domain object.
* @constructor
*/
function NavigateAction(navigationService, context) {
function NavigateAction(navigationService, $q, context) {
var domainObject = context.domainObject;
function perform() {
return Promise.resolve(
navigationService.setNavigation(domainObject)
);
// Set navigation, and wrap like a promise
return $q.when(navigationService.setNavigation(domainObject));
}
return {
/**
* Navigate to the object described in the context.
* @returns {Promise} a promise that is resolved once the
* navigation has been updated
*/
perform: perform
};
}
/**
* Navigate as an action is only applicable when a domain object
* is described in the action context.
* @param {ActionContext} context the context in which the action
* will be performed
* @returns true if applicable
*/
NavigateAction.appliesTo = function (context) {
return context.domainObject !== undefined;
};

View File

@@ -9,17 +9,20 @@ define(
"use strict";
/**
*
* The navigation service maintains the application's current
* navigation state, and allows listening for changes thereto.
* @constructor
*/
function NavigationService() {
var navigated,
callbacks = [];
// Getter for current navigation
function getNavigation() {
return navigated;
}
// Setter for navigation; invokes callbacks
function setNavigation(value) {
navigated = value;
callbacks.forEach(function (callback) {
@@ -27,10 +30,12 @@ define(
});
}
// Adds a callback
function addListener(callback) {
callbacks.push(callback);
}
// Filters out a callback
function removeListener(callback) {
callbacks = callbacks.filter(function (cb) {
return cb !== callback;
@@ -38,9 +43,30 @@ define(
}
return {
/**
* Get the current navigation state.
*/
getNavigation: getNavigation,
/**
* Set the current navigation state. Thiswill invoke listeners.
* @param {DomainObject} value the domain object to navigate
* to
*/
setNavigation: setNavigation,
/**
* Listen for changes in navigation. The passed callback will
* be invoked with the new domain object of navigation when
* this changes.
* @param {function} callback the callback to invoke when
* navigation state changes
*/
addListener: addListener,
/**
* Stop listening for changes in navigation state.
* @param {function} callback the callback which should
* no longer be invoked when navigation state
* changes
*/
removeListener: removeListener
};
}

View File

@@ -12,14 +12,22 @@ define(
EXIT_FULLSCREEN = "Exit full screen mode.";
/**
*
* The fullscreen action toggles between fullscreen display
* and regular in-window display.
* @constructor
*/
function FullscreenAction(context) {
return {
/**
* Toggle full screen state
*/
perform: function () {
screenfull.toggle();
},
/**
* Get metadata about this action, including the
* applicable glyph to display.
*/
getMetadata: function () {
// We override getMetadata, because the glyph and
// description need to be determined at run-time

View File

@@ -9,11 +9,17 @@ define(
"use strict";
/**
*
* The new window action allows a domain object to be opened
* into a new browser window. (Currently this is a stub, present
* to allow the control to appear in the appropriate location in
* the user interface.)
* @constructor
*/
function NewWindowAction($window) {
return {
/**
* Open the object in a new window (currently a stub)
*/
perform: function () {
$window.alert("Not yet functional. This will open objects in a new window.");
}