diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js
index a6c0931f4e..eb66456ce4 100644
--- a/platform/features/timeline/bundle.js
+++ b/platform/features/timeline/bundle.js
@@ -127,7 +127,16 @@ define([
14400000,
28800000,
43200000,
- 86400000
+ 86400000,
+ 86400000 * 2,
+ 86400000 * 5,
+ 86400000 * 10,
+ 86400000 * 20,
+ 86400000 * 30,
+ 86400000 * 60,
+ 86400000 * 120,
+ 86400000 * 240,
+ 86400000 * 365
],
"width": 200
}
diff --git a/platform/features/timeline/res/templates/timeline.html b/platform/features/timeline/res/templates/timeline.html
index 41a1c67a87..0bb53d1196 100644
--- a/platform/features/timeline/res/templates/timeline.html
+++ b/platform/features/timeline/res/templates/timeline.html
@@ -103,6 +103,13 @@
+
+ I
+
+
0 && !isNaN(amount)) {
+ var center = this.toMillis(bounds.x + bounds.width / 2);
setZoomLevel(zoomIndex + amount);
- storeZoom(zoomIndex);
+ bounds.x = this.toPixels(center) - bounds.width / 2;
}
return zoomLevels[zoomIndex];
},
+ /**
+ * Set the zoom level to fit the bounds of the timeline
+ * being viewed.
+ */
+ fit: initializeZoom,
/**
* Get the width, in pixels, of a specific time duration at
* the current zoom level.
* @returns {number} the number of pixels
*/
- toPixels: function (millis) {
- return tickWidth * millis / zoomLevels[zoomIndex];
- },
+ toPixels: toPixels,
/**
* Get the time duration, in milliseconds, occupied by the
* width (specified in pixels) at the current zoom level.
* @returns {number} the number of pixels
*/
- toMillis: function (pixels) {
- return (pixels / tickWidth) * zoomLevels[zoomIndex];
- },
+ toMillis: toMillis,
/**
* Get or set the current displayed duration. If used as a
* setter, this will typically be rounded up to ensure extra
diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js
index 1365fca7d6..47e79fefa8 100644
--- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js
+++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js
@@ -32,11 +32,7 @@ define(
beforeEach(function () {
testConfiguration = {
- levels: [
- 1000,
- 2000,
- 3500
- ],
+ levels: [1000, 2000, 3500],
width: 12321
};
mockScope = jasmine.createSpyObj("$scope", ['$watch']);
@@ -74,32 +70,61 @@ define(
expect(controller.zoom()).toEqual(3500);
});
- it("does not normally persist zoom changes", function () {
- controller.zoom(1);
- expect(mockScope.commit).not.toHaveBeenCalled();
+ it("observes scroll bounds", function () {
+ expect(mockScope.$watch)
+ .toHaveBeenCalledWith("scroll", jasmine.any(Function));
});
- it("persists zoom changes in Edit mode", function () {
- mockScope.domainObject = jasmine.createSpyObj(
- 'domainObject',
- ['hasCapability', 'getCapability']
- );
- mockScope.domainObject.hasCapability.andCallFake(function (c) {
- return c === 'editor';
+ describe("when watches have fired", function () {
+ var mockDomainObject,
+ mockPromise,
+ mockTimespan,
+ testStart,
+ testEnd;
+
+ beforeEach(function () {
+ testStart = 3000;
+ testEnd = 5500;
+
+ mockDomainObject = jasmine.createSpyObj('domainObject', [
+ 'getId',
+ 'getModel',
+ 'getCapability',
+ 'useCapability'
+ ]);
+ mockPromise = jasmine.createSpyObj('promise', ['then']);
+ mockTimespan = jasmine.createSpyObj('timespan', [
+ 'getStart',
+ 'getEnd',
+ 'getDuration'
+ ]);
+
+ mockDomainObject.useCapability.andCallFake(function (c) {
+ return c === 'timespan' && mockPromise;
+ });
+ mockPromise.then.andCallFake(function (callback) {
+ callback(mockTimespan);
+ });
+ mockTimespan.getStart.andReturn(testStart);
+ mockTimespan.getEnd.andReturn(testEnd);
+ mockTimespan.getDuration.andReturn(testEnd - testStart);
+
+ mockScope.scroll = { x: 0, width: 20000 };
+ mockScope.domainObject = mockDomainObject;
+
+ mockScope.$watch.calls.forEach(function (call) {
+ call.args[1](mockScope[call.args[0]]);
+ });
});
- mockScope.domainObject.getCapability.andCallFake(function (c) {
- if (c === 'editor') {
- return {
- inEditContext: function () {
- return true;
- }
- };
- }
+
+ it("zooms to fit the timeline", function () {
+ var x1 = mockScope.scroll.x,
+ x2 = mockScope.scroll.x + mockScope.scroll.width;
+ expect(Math.round(controller.toMillis(x1)))
+ .toEqual(testStart);
+ expect(Math.round(controller.toMillis(x2)))
+ .toBeGreaterThan(testEnd);
});
- controller.zoom(1);
- expect(mockScope.commit).toHaveBeenCalled();
- expect(mockScope.configuration.zoomLevel)
- .toEqual(jasmine.any(Number));
});
});