Merge remote-tracking branch 'origin/open879' into open-master

Conflicts:
	platform/commonUI/edit/res/templates/edit-object.html
This commit is contained in:
bwyu
2015-02-26 11:01:00 -08:00
27 changed files with 896 additions and 184 deletions

View File

@@ -15,6 +15,8 @@ view's scope.) These additional properties are:
then that function is assumed to be an accessor-mutator function
(that is, it will be called with no arguments to get, and with
an argument to set.)
* `method`: Name of a method to invoke upon a selected object when
a control is activated, e.g. on a button click.
* `inclusive`: Optional; true if this control should be considered
applicable whenever at least one element in the selection has
the associated property. Otherwise, all members of the current

View File

@@ -12,7 +12,7 @@
<div class='holder abs object-holder'>
<mct-representation key="representation.selected.key"
toolbar="toolbar"
mct-object="domainObject">
mct-object="representation.selected.key && domainObject">
</mct-representation>
</div>
</div>

View File

@@ -17,9 +17,10 @@ define(
*
* @param structure toolbar structure, as provided by view definition
* @param {Array} selection the current selection state
* @param {Function} commit callback to invoke after changes
* @constructor
*/
function EditToolbar(structure, selection) {
function EditToolbar(structure, selection, commit) {
var toolbarStructure = Object.create(structure || {}),
toolbarState,
properties = [];
@@ -106,23 +107,46 @@ define(
// to the current selection.
function isApplicable(item) {
var property = (item || {}).property,
method = (item || {}).method,
exclusive = !(item || {}).inclusive;
// Check if a selected item defines this property
function hasProperty(selected) {
return selected[property] !== undefined;
return (property && (selected[property] !== undefined)) ||
(method && (typeof selected[method] === 'function'));
}
return property && selection.map(hasProperty).reduce(
return selection.map(hasProperty).reduce(
exclusive ? and : or,
exclusive
) && isConsistent(property);
}
// Invoke all functions in selections with the given name
function invoke(method, value) {
if (method) {
// Make the change in the selection
selection.forEach(function (selected) {
if (typeof selected[method] === 'function') {
selected[method](value);
}
});
// ...and commit!
commit();
}
}
// Prepare a toolbar item based on current selection
function convertItem(item) {
var converted = Object.create(item || {});
converted.key = addKey(item.property);
if (item.property) {
converted.key = addKey(item.property);
}
if (item.method) {
converted.click = function (v) {
invoke(item.method, v);
};
}
return converted;
}

View File

@@ -20,6 +20,13 @@ define(
toolbar,
toolbarObject = {};
// Mark changes as ready to persist
function commit(message) {
if (scope.commit) {
scope.commit(message);
}
}
// Handle changes to the current selection
function updateSelection(selection) {
// Make sure selection is array-like
@@ -28,7 +35,7 @@ define(
(selection ? [selection] : []);
// Instantiate a new toolbar...
toolbar = new EditToolbar(definition, selection);
toolbar = new EditToolbar(definition, selection, commit);
// ...and expose its structure/state
toolbarObject.structure = toolbar.getStructure();
@@ -37,9 +44,12 @@ define(
// Update selection models to match changed toolbar state
function updateState(state) {
// Update underlying state based on toolbar changes
state.forEach(function (value, index) {
toolbar.updateState(index, value);
});
// Commit the changes.
commit("Changes from toolbar.");
}
// Represent a domain object using this definition

View File

@@ -15,7 +15,7 @@ define(
beforeEach(function () {
mockScope = jasmine.createSpyObj(
'$scope',
[ '$on', '$watch', '$watchCollection' ]
[ '$on', '$watch', '$watchCollection', "commit" ]
);
mockElement = {};
testAttrs = { toolbar: 'testToolbar' };

View File

@@ -11,7 +11,8 @@ define(
testABC,
testABC2,
testABCXYZ,
testABCYZ;
testABCYZ,
testM;
beforeEach(function () {
testStructure = {
@@ -29,6 +30,11 @@ define(
{ name: "Y", property: "y" },
{ name: "Z", property: "z" }
]
},
{
items: [
{ name: "M", method: "m" }
]
}
]
};
@@ -37,6 +43,7 @@ define(
testABC2 = { a: 4, b: 1, c: 2 }; // For inconsistent-state checking
testABCXYZ = { a: 0, b: 1, c: 2, x: 'X!', y: 'Y!', z: 'Z!' };
testABCYZ = { a: 0, b: 1, c: 2, y: 'Y!', z: 'Z!' };
testM = { m: jasmine.createSpy("method") };
});
it("provides properties from the original structure", function () {
@@ -182,6 +189,19 @@ define(
.length
).toEqual(2);
});
it("adds click functions when a method is specified", function () {
var testCommit = jasmine.createSpy('commit'),
toolbar = new EditToolbar(testStructure, [ testM ], testCommit);
// Verify precondition
expect(testM.m).not.toHaveBeenCalled();
// Click!
toolbar.getStructure().sections[0].items[0].click();
// Should have called the underlying function
expect(testM.m).toHaveBeenCalled();
// Should also have committed the change
expect(testCommit).toHaveBeenCalled();
});
});
}
);