+ ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }">
+ ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }">
diff --git a/platform/features/timeline/src/controllers/TimelineController.js b/platform/features/timeline/src/controllers/TimelineController.js
index 64900b586c..68ca8c4bc7 100644
--- a/platform/features/timeline/src/controllers/TimelineController.js
+++ b/platform/features/timeline/src/controllers/TimelineController.js
@@ -79,15 +79,6 @@ define(
graphPopulator.populate(swimlanePopulator.get());
}
- // Get pixel width for right pane, using zoom controller
- function width(zoomController) {
- var start = swimlanePopulator.start(),
- end = swimlanePopulator.end();
- return zoomController.toPixels(zoomController.duration(
- Math.max(end - start, MINIMUM_DURATION)
- ));
- }
-
// Refresh resource graphs
function refresh() {
if (graphPopulator) {
@@ -121,10 +112,10 @@ define(
// Expose active set of swimlanes
return {
/**
- * Get the width, in pixels, of the timeline area
- * @returns {number} width, in pixels
+ * Get the end of the displayed timeline, in milliseconds.
+ * @returns {number} the end of the displayed timeline
*/
- width: width,
+ end: swimlanePopulator.end.bind(swimlanePopulator),
/**
* Get the swimlanes which should currently be displayed.
* @returns {TimelineSwimlane[]} the swimlanes
diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js
index 990a83a5b3..620e871d11 100644
--- a/platform/features/timeline/src/controllers/TimelineZoomController.js
+++ b/platform/features/timeline/src/controllers/TimelineZoomController.js
@@ -22,27 +22,17 @@
define(
[],
function () {
+ var PADDING = 0.25;
/**
* Controls the pan-zoom state of a timeline view.
* @constructor
*/
- function TimelineZoomController($scope, ZOOM_CONFIGURATION) {
+ function TimelineZoomController($scope, $window, ZOOM_CONFIGURATION) {
// Prefer to start with the middle index
var zoomLevels = ZOOM_CONFIGURATION.levels || [1000],
zoomIndex = Math.floor(zoomLevels.length / 2),
- tickWidth = ZOOM_CONFIGURATION.width || 200,
- bounds = { x: 0, width: tickWidth },
- duration = 86400000; // Default duration in view
-
- // Round a duration to a larger value, to ensure space for editing
- function roundDuration(value) {
- // Ensure there's always an extra day or so
- var tickCount = bounds.width / tickWidth,
- sz = zoomLevels[zoomLevels.length - 1] * tickCount;
- value *= 1.25; // Add 25% padding to start
- return Math.ceil(value / sz) * sz;
- }
+ tickWidth = ZOOM_CONFIGURATION.width || 200;
function toMillis(pixels) {
return (pixels / tickWidth) * zoomLevels[zoomIndex];
@@ -63,14 +53,21 @@ define(
}
}
+ function setScroll(x) {
+ $window.requestAnimationFrame(function () {
+ $scope.scroll.x = x;
+ $scope.$apply();
+ });
+ }
+
function initializeZoomFromTimespan(timespan) {
var timelineDuration = timespan.getDuration();
zoomIndex = 0;
- while (toMillis(bounds.width) < timelineDuration &&
+ while (toMillis($scope.scroll.width) < timelineDuration &&
zoomIndex < zoomLevels.length - 1) {
zoomIndex += 1;
}
- bounds.x = toPixels(timespan.getStart());
+ setScroll(toPixels(timespan.getStart()));
}
function initializeZoom() {
@@ -80,9 +77,6 @@ define(
}
}
- $scope.$watch("scroll", function (scroll) {
- bounds = scroll;
- });
$scope.$watch("domainObject", initializeZoom);
return {
@@ -100,9 +94,10 @@ define(
zoom: function (amount) {
// Update the zoom level if called with an argument
if (arguments.length > 0 && !isNaN(amount)) {
+ var bounds = $scope.scroll;
var center = this.toMillis(bounds.x + bounds.width / 2);
setZoomLevel(zoomIndex + amount);
- bounds.x = this.toPixels(center) - bounds.width / 2;
+ setScroll(this.toPixels(center) - bounds.width / 2);
}
return zoomLevels[zoomIndex];
},
@@ -124,16 +119,14 @@ define(
*/
toMillis: toMillis,
/**
- * Get or set the current displayed duration. If used as a
- * setter, this will typically be rounded up to ensure extra
- * space is available at the right.
- * @returns {number} duration, in milliseconds
+ * Get the pixel width necessary to fit the specified
+ * timestamp, expressed as an offset in milliseconds from
+ * the start of the timeline.
+ * @param {number} timestamp the time to display
*/
- duration: function (value) {
- if (arguments.length > 0) {
- duration = roundDuration(value);
- }
- return duration;
+ width: function (timestamp) {
+ var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING)));
+ return Math.max($scope.scroll.width, pixels);
}
};
}
diff --git a/platform/features/timeline/test/controllers/TimelineControllerSpec.js b/platform/features/timeline/test/controllers/TimelineControllerSpec.js
index aa88866ebc..7912dba149 100644
--- a/platform/features/timeline/test/controllers/TimelineControllerSpec.js
+++ b/platform/features/timeline/test/controllers/TimelineControllerSpec.js
@@ -214,23 +214,6 @@ define(
});
- it("reports full scrollable width using zoom controller", function () {
- var mockZoom = jasmine.createSpyObj('zoom', ['toPixels', 'duration']);
- mockZoom.toPixels.andReturn(54321);
- mockZoom.duration.andReturn(12345);
-
- // Initially populate
- fireWatch('domainObject', mockDomainObject);
-
- expect(controller.width(mockZoom)).toEqual(54321);
- // Verify interactions; we took zoom's duration for our start/end,
- // and converted it to pixels.
- // First, check that we used the start/end (from above)
- expect(mockZoom.duration).toHaveBeenCalledWith(12321 - 42);
- // Next, verify that the result was passed to toPixels
- expect(mockZoom.toPixels).toHaveBeenCalledWith(12345);
- });
-
it("provides drag handles", function () {
// TimelineDragPopulator et al are tested for these,
// so just verify that handles are indeed exposed.
diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js
index 47e79fefa8..18ed911671 100644
--- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js
+++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js
@@ -28,6 +28,7 @@ define(
describe("The timeline zoom state controller", function () {
var testConfiguration,
mockScope,
+ mockWindow,
controller;
beforeEach(function () {
@@ -35,10 +36,16 @@ define(
levels: [1000, 2000, 3500],
width: 12321
};
- mockScope = jasmine.createSpyObj("$scope", ['$watch']);
+ mockScope =
+ jasmine.createSpyObj("$scope", ['$watch', '$apply']);
mockScope.commit = jasmine.createSpy('commit');
+ mockScope.scroll = { x: 0, width: 1000 };
+ mockWindow = {
+ requestAnimationFrame: jasmine.createSpy('raf')
+ };
controller = new TimelineZoomController(
mockScope,
+ mockWindow,
testConfiguration
);
});
@@ -47,12 +54,6 @@ define(
expect(controller.zoom()).toEqual(2000);
});
- it("allows duration to be changed", function () {
- var initial = controller.duration();
- controller.duration(initial * 3.33);
- expect(controller.duration() > initial).toBeTruthy();
- });
-
it("handles time-to-pixel conversions", function () {
var zoomLevel = controller.zoom();
expect(controller.toPixels(zoomLevel)).toEqual(12321);
@@ -70,11 +71,6 @@ define(
expect(controller.zoom()).toEqual(3500);
});
- it("observes scroll bounds", function () {
- expect(mockScope.$watch)
- .toHaveBeenCalledWith("scroll", jasmine.any(Function));
- });
-
describe("when watches have fired", function () {
var mockDomainObject,
mockPromise,
@@ -115,6 +111,10 @@ define(
mockScope.$watch.calls.forEach(function (call) {
call.args[1](mockScope[call.args[0]]);
});
+
+ mockWindow.requestAnimationFrame.calls.forEach(function (call) {
+ call.args[0]();
+ });
});
it("zooms to fit the timeline", function () {
@@ -125,6 +125,27 @@ define(
expect(Math.round(controller.toMillis(x2)))
.toBeGreaterThan(testEnd);
});
+
+ it("provides a width which is not less than scroll area width", function () {
+ var testPixel = mockScope.scroll.width / 4,
+ testMillis = controller.toMillis(testPixel);
+ expect(controller.width(testMillis))
+ .not.toBeLessThan(mockScope.scroll.width);
+ });
+
+ it("provides a width with some margin past timestamp", function () {
+ var testPixel = mockScope.scroll.width * 4,
+ testMillis = controller.toMillis(testPixel);
+ expect(controller.width(testMillis))
+ .toBeGreaterThan(controller.toPixels(testMillis));
+ });
+
+ it("provides a width which does not greatly exceed timestamp", function () {
+ var testPixel = mockScope.scroll.width * 4,
+ testMillis = controller.toMillis(testPixel);
+ expect(controller.width(testMillis))
+ .toBeLessThan(controller.toPixels(testMillis * 2));
+ });
});
});
diff --git a/platform/representation/src/gestures/DropGesture.js b/platform/representation/src/gestures/DropGesture.js
index 966618d88c..8da98b38a7 100644
--- a/platform/representation/src/gestures/DropGesture.js
+++ b/platform/representation/src/gestures/DropGesture.js
@@ -61,8 +61,7 @@ define(
{
x: event.pageX - rect.left,
y: event.pageY - rect.top
- },
- domainObject
+ }
);
}
}
diff --git a/platform/representation/test/gestures/DropGestureSpec.js b/platform/representation/test/gestures/DropGestureSpec.js
index 79ed9d1139..f8ed7c80da 100644
--- a/platform/representation/test/gestures/DropGestureSpec.js
+++ b/platform/representation/test/gestures/DropGestureSpec.js
@@ -34,8 +34,7 @@ define(
TEST_ID = "test-id",
DROP_ID = "drop-id";
- //TODO: Disabled for NEM Beta
- xdescribe("The drop gesture", function () {
+ describe("The drop gesture", function () {
var mockDndService,
mockQ,
mockElement,
@@ -144,23 +143,6 @@ define(
expect(mockCompose.perform).toHaveBeenCalled();
});
-
- it("does not invoke compose on drop in browse mode for non-folders", function () {
- // Set the mockDomainObject to not have the editor capability
- mockDomainObject.hasCapability.andReturn(false);
- // Set the mockDomainObject to not have a type of folder
- mockDomainObject.getModel.andReturn({type: 'notAFolder'});
-
- callbacks.dragover(mockEvent);
- expect(mockAction.getActions).toHaveBeenCalledWith({
- key: 'compose',
- selectedObject: mockDraggedObject
- });
- callbacks.drop(mockEvent);
- expect(mockCompose.perform).not.toHaveBeenCalled();
- });
-
-
it("invokes compose on drop in browse mode for folders", function () {
// Set the mockDomainObject to not have the editor capability
mockDomainObject.hasCapability.andReturn(false);
diff --git a/protractor/common/EditItem.js b/protractor/common/EditItem.js
index fffd8108a9..ceffcdb3ea 100644
--- a/protractor/common/EditItem.js
+++ b/protractor/common/EditItem.js
@@ -34,8 +34,8 @@ var EditItem = (function () {
EditItem.prototype.EditButton = function () {
return element.all(by.css('[ng-click="parameters.action.perform()"]')).filter(function (arg) {
return arg.getAttribute("title").then(function (title){
- //expect(title).toEqual("Edit this object.");
- return title == 'Edit this object.';
+ //expect(title).toEqual("Edit");
+ return title == 'Edit';
})
});
};