From eda1f23df9ca36f10c83332ed8c4e1cd8300153f Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 26 May 2016 11:35:56 -0700 Subject: [PATCH 01/30] [Edit Mode] #629 rewriting disabled tests --- .../edit/test/actions/CancelActionSpec.js | 109 +++++++++++++----- .../test/ConductorRepresenterSpec.js | 2 +- 2 files changed, 79 insertions(+), 32 deletions(-) diff --git a/platform/commonUI/edit/test/actions/CancelActionSpec.js b/platform/commonUI/edit/test/actions/CancelActionSpec.js index 411fdb1659..b83fbdab2b 100644 --- a/platform/commonUI/edit/test/actions/CancelActionSpec.js +++ b/platform/commonUI/edit/test/actions/CancelActionSpec.js @@ -24,12 +24,11 @@ define( ["../../src/actions/CancelAction"], function (CancelAction) { - //TODO: Disabled for NEM Beta - xdescribe("The Cancel action", function () { - var mockLocation, - mockDomainObject, - mockEditorCapability, - mockUrlService, + describe("The Cancel action", function () { + var mockDomainObject, + mockParentObject, + capabilities = {}, + parentCapabilities = {}, actionContext, action; @@ -42,61 +41,109 @@ define( } beforeEach(function () { - mockLocation = jasmine.createSpyObj( - "$location", - ["path"] - ); mockDomainObject = jasmine.createSpyObj( "domainObject", - ["getCapability", "hasCapability"] + [ + "getCapability", + "hasCapability", + "getModel" + ] ); - mockEditorCapability = jasmine.createSpyObj( + mockDomainObject.getModel.andReturn({}); + + mockParentObject = jasmine.createSpyObj( + "parentObject", + [ + "getCapability" + ] + ); + mockParentObject.getCapability.andCallFake(function (name) { + return parentCapabilities[name]; + }); + + capabilities.editor = jasmine.createSpyObj( "editor", - ["save", "cancel"] + ["save", "cancel", "isEditContextRoot"] ); - mockUrlService = jasmine.createSpyObj( - "urlService", - ["urlForLocation"] + capabilities.action = jasmine.createSpyObj( + "actionCapability", + [ + "perform" + ] + ); + capabilities.location = jasmine.createSpyObj( + "locationCapability", + [ + "getOriginal" + ] + ); + capabilities.location.getOriginal.andReturn(mockPromise(mockDomainObject)); + capabilities.context = jasmine.createSpyObj( + "contextCapability", + [ + "getParent" + ] + ); + capabilities.context.getParent.andReturn(mockParentObject); + + parentCapabilities.action = jasmine.createSpyObj( + "actionCapability", + [ + "perform" + ] ); actionContext = { domainObject: mockDomainObject }; - mockDomainObject.hasCapability.andReturn(true); - mockDomainObject.getCapability.andReturn(mockEditorCapability); - mockEditorCapability.cancel.andReturn(mockPromise(true)); + mockDomainObject.getCapability.andCallFake(function (name) { + return capabilities[name]; + }); - action = new CancelAction(mockLocation, mockUrlService, actionContext); + mockDomainObject.hasCapability.andCallFake(function (name) { + return !!capabilities[name]; + }); + + capabilities.editor.cancel.andReturn(mockPromise(true)); + + action = new CancelAction(actionContext); }); - it("only applies to domain object with an editor capability", function () { + it("only applies to domain object that is being edited", function () { + capabilities.editor.isEditContextRoot.andReturn(true); expect(CancelAction.appliesTo(actionContext)).toBeTruthy(); expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); + capabilities.editor.isEditContextRoot.andReturn(false); + expect(CancelAction.appliesTo(actionContext)).toBeFalsy(); + mockDomainObject.hasCapability.andReturn(false); - mockDomainObject.getCapability.andReturn(undefined); expect(CancelAction.appliesTo(actionContext)).toBeFalsy(); }); - it("invokes the editor capability's save functionality when performed", function () { - // Verify precondition - expect(mockEditorCapability.cancel).not.toHaveBeenCalled(); + it("invokes the editor capability's cancel functionality when" + + " performed", function () { action.perform(); // Should have called cancel - expect(mockEditorCapability.cancel).toHaveBeenCalled(); + expect(capabilities.editor.cancel).toHaveBeenCalled(); // Definitely shouldn't call save! - expect(mockEditorCapability.save).not.toHaveBeenCalled(); + expect(capabilities.editor.save).not.toHaveBeenCalled(); }); - it("returns to browse when performed", function () { + it("navigates to object if existing", function () { + mockDomainObject.getModel.andReturn({persisted: 1}); action.perform(); - expect(mockLocation.path).toHaveBeenCalledWith( - mockUrlService.urlForLocation("browse", mockDomainObject) - ); + expect(capabilities.action.perform).toHaveBeenCalledWith("navigate"); + }); + + it("navigates to parent if new", function () { + mockDomainObject.getModel.andReturn({persisted: undefined}); + action.perform(); + expect(parentCapabilities.action.perform).toHaveBeenCalledWith("navigate"); }); }); } diff --git a/platform/features/conductor/test/ConductorRepresenterSpec.js b/platform/features/conductor/test/ConductorRepresenterSpec.js index 83d37fb8a6..bd60b303e1 100644 --- a/platform/features/conductor/test/ConductorRepresenterSpec.js +++ b/platform/features/conductor/test/ConductorRepresenterSpec.js @@ -42,7 +42,7 @@ define( 'parent' ]; - xdescribe("ConductorRepresenter", function () { + describe("ConductorRepresenter", function () { var mockThrottle, mockConductorService, mockCompile, From f30174185261c6adf4515ac3debe4d86e8061ed4 Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 26 May 2016 11:42:15 -0700 Subject: [PATCH 02/30] [Edit Mode] #629 restored disabled tests for DropGesture. Removed extraneous argument to broadcast function --- .../src/gestures/DropGesture.js | 3 +-- .../test/gestures/DropGestureSpec.js | 20 +------------------ 2 files changed, 2 insertions(+), 21 deletions(-) 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); From 165e158f3770a979f5d0818888df3cbb926bacdb Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 26 May 2016 11:44:43 -0700 Subject: [PATCH 03/30] [Edit Mode] #629 Removed redundant test from DomainObjectProviderSpec --- platform/core/test/objects/DomainObjectProviderSpec.js | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/platform/core/test/objects/DomainObjectProviderSpec.js b/platform/core/test/objects/DomainObjectProviderSpec.js index c8450551f4..4e60f19645 100644 --- a/platform/core/test/objects/DomainObjectProviderSpec.js +++ b/platform/core/test/objects/DomainObjectProviderSpec.js @@ -82,16 +82,6 @@ define( expect(result.a.getModel()).toEqual(model); }); - //TODO: Disabled for NEM Beta - xit("provides a new, fully constituted domain object for a" + - " provided model", function () { - var model = { someKey: "some value"}, - result; - result = provider.newObject("a", model); - expect(result.getId()).toEqual("a"); - expect(result.getModel()).toEqual(model); - }); - }); } ); From 7fc2fcfa07afbaff5eb1fd7cfb4a7649957f80ed Mon Sep 17 00:00:00 2001 From: Henry Date: Thu, 26 May 2016 11:55:13 -0700 Subject: [PATCH 04/30] [Edit Mode] #629 Rewrote obsolete DomainColumn tests --- .../features/table/test/DomainColumnSpec.js | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/platform/features/table/test/DomainColumnSpec.js b/platform/features/table/test/DomainColumnSpec.js index e707c8dd0b..516c32deae 100644 --- a/platform/features/table/test/DomainColumnSpec.js +++ b/platform/features/table/test/DomainColumnSpec.js @@ -30,23 +30,21 @@ define( var TEST_DOMAIN_VALUE = "some formatted domain value"; describe("A domain column", function () { - var mockDataSet, + var mockDatum, testMetadata, mockFormatter, column; beforeEach(function () { - mockDataSet = jasmine.createSpyObj( - "data", - ["getDomainValue"] - ); + mockFormatter = jasmine.createSpyObj( "formatter", ["formatDomainValue", "formatRangeValue"] ); testMetadata = { key: "testKey", - name: "Test Name" + name: "Test Name", + format: "Test Format" }; mockFormatter.formatDomainValue.andReturn(TEST_DOMAIN_VALUE); @@ -57,24 +55,24 @@ define( expect(column.getTitle()).toEqual("Test Name"); }); - xit("looks up data from a data set", function () { - column.getValue(undefined, mockDataSet, 42); - expect(mockDataSet.getDomainValue) - .toHaveBeenCalledWith(42, "testKey"); - }); + describe("when given a datum", function () { + beforeEach(function () { + mockDatum = { + testKey: "testKeyValue" + }; + }); - xit("formats domain values as time", function () { - mockDataSet.getDomainValue.andReturn(402513731000); + it("looks up data from the given datum", function () { + expect(column.getValue(undefined, mockDatum)) + .toEqual({ text: TEST_DOMAIN_VALUE }); + }); - // Should have just given the value the formatter gave - expect(column.getValue(undefined, mockDataSet, 42).text) - .toEqual(TEST_DOMAIN_VALUE); + it("uses formatter to format domain values as requested", function () { + column.getValue(undefined, mockDatum); + expect(mockFormatter.formatDomainValue) + .toHaveBeenCalledWith("testKeyValue", "Test Format"); + }); - // Make sure that service interactions were as expected - expect(mockFormatter.formatDomainValue) - .toHaveBeenCalledWith(402513731000); - expect(mockFormatter.formatRangeValue) - .not.toHaveBeenCalled(); }); }); From 35d7d9b3803c8722c7331b3fcac2463cfebbc36a Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 31 May 2016 16:05:06 -0700 Subject: [PATCH 05/30] [Timeline] Remove width method ...from TimelineController. Will replace with a more straightforward call to the zoom controller that uses the exposed end time instead, to address #981. --- .../src/controllers/TimelineController.js | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) 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 From 787f3815df1e4606f465d358c61c0e3ead8f604c Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 31 May 2016 16:12:49 -0700 Subject: [PATCH 06/30] [Timeline] Expose width from ZoomController ...and ensure that the width exposed is not excessively large; fixes #981 --- .../timeline/res/templates/timeline.html | 6 ++-- .../src/controllers/TimelineZoomController.js | 29 ++++++------------- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/platform/features/timeline/res/templates/timeline.html b/platform/features/timeline/res/templates/timeline.html index 0bb53d1196..7582a515c8 100644 --- a/platform/features/timeline/res/templates/timeline.html +++ b/platform/features/timeline/res/templates/timeline.html @@ -128,7 +128,7 @@
+ ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }">
+ ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }">
diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 990a83a5b3..5482891004 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -22,6 +22,7 @@ define( [], function () { + var PADDING = 0.25; /** * Controls the pan-zoom state of a timeline view. @@ -32,17 +33,7 @@ define( 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; - } + bounds = { x: 0, width: tickWidth }; // Default duration in view function toMillis(pixels) { return (pixels / tickWidth) * zoomLevels[zoomIndex]; @@ -124,16 +115,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(bounds.width, pixels) } }; } From be9f56107ceb5c302913afe9127749d637e12f9b Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 31 May 2016 16:15:57 -0700 Subject: [PATCH 07/30] [Timeline] Remove obsolete test cases --- .../test/controllers/TimelineControllerSpec.js | 17 ----------------- .../controllers/TimelineZoomControllerSpec.js | 6 ------ 2 files changed, 23 deletions(-) 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..bf87d17916 100644 --- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js +++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js @@ -47,12 +47,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); From 4f0e3fdf852960752439d3b78d49ea2450c43a5e Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 31 May 2016 16:21:40 -0700 Subject: [PATCH 08/30] [Timeline] Test zoom controller's width --- .../controllers/TimelineZoomControllerSpec.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js index bf87d17916..9e67eecc3f 100644 --- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js +++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js @@ -119,6 +119,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)) + .toEqual(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)); + }); }); }); From 5a2d1a746d629a3fc94c3d3b17576ef301754ed8 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 31 May 2016 16:27:59 -0700 Subject: [PATCH 09/30] [Timeline] Add missing semicolon --- .../features/timeline/src/controllers/TimelineZoomController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 5482891004..3075460428 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -122,7 +122,7 @@ define( */ width: function (timestamp) { var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING))); - return Math.max(bounds.width, pixels) + return Math.max(bounds.width, pixels); } }; } From cc7d0477e8df900db9eec30be4f5c38ceb10c822 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 31 May 2016 16:41:30 -0700 Subject: [PATCH 10/30] [Timeline] Check for existence of timespan ...before attempting to calculate a width based on it. Fixes #978. --- platform/features/timeline/res/templates/activity-gantt.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/features/timeline/res/templates/activity-gantt.html b/platform/features/timeline/res/templates/activity-gantt.html index 1615431e91..8515872352 100644 --- a/platform/features/timeline/res/templates/activity-gantt.html +++ b/platform/features/timeline/res/templates/activity-gantt.html @@ -20,7 +20,7 @@ at runtime from the About dialog for additional information. -->
Date: Wed, 1 Jun 2016 19:18:55 -0700 Subject: [PATCH 12/30] [Frontend] Added transitional animation to Edit mode fixes #709 - When going from browse to edit mode, the wrapper around the object being edited will now transition in from its edges, and the edit controls toolbar will animate its height; - There is no transition applied for going from edit to browse; to do this we'd need to mod the JS on exiting to look for the end of an animation event; - Tested in Chrome, Safari and Firefox; - May not be smooth with very complex objects like Layouts with a large number of components; - Added transitional animations to .l-object-wrapper and .l-edit-controls; - New 'animTo' mixin added to _effects.scss; --- .../commonUI/general/res/sass/_constants.scss | 2 + .../commonUI/general/res/sass/_effects.scss | 25 ++++--- .../res/sass/user-environ/_layout.scss | 71 +++++++++++-------- .../themes/espresso/res/sass/_constants.scss | 2 +- 4 files changed, 59 insertions(+), 41 deletions(-) diff --git a/platform/commonUI/general/res/sass/_constants.scss b/platform/commonUI/general/res/sass/_constants.scss index c36a6cb00a..8c216f0151 100644 --- a/platform/commonUI/general/res/sass/_constants.scss +++ b/platform/commonUI/general/res/sass/_constants.scss @@ -124,6 +124,8 @@ $dirImgs: $dirCommonRes + 'images/'; /************************** TIMINGS */ $controlFadeMs: 100ms; +$browseToEditAnimMs: 400ms; +$editBorderPulseMs: 500ms; /************************** LIMITS */ $glyphLimit: '\e603'; diff --git a/platform/commonUI/general/res/sass/_effects.scss b/platform/commonUI/general/res/sass/_effects.scss index a048eb75d0..1a13b07d06 100644 --- a/platform/commonUI/general/res/sass/_effects.scss +++ b/platform/commonUI/general/res/sass/_effects.scss @@ -39,15 +39,20 @@ @include pulse($animName: pulse-subtle, $dur: 500ms, $opacity0: 0.7); } -@mixin pulseBorder($c: red, $dur: 500ms, $iteration: infinite, $delay: 0s, $opacity0: 0, $opacity100: 1) { - @include keyframes(pulseBorder) { - 0% { border-color: rgba($c, $opacity0); } - 100% { border-color: rgba($c, $opacity100); } +@mixin animTo($animName, $propName, $propValStart, $propValEnd, $dur: 500ms, $delay: 0) { + @include keyframes($animName) { + from { #{propName}: $propValStart; } + to { #{$propName}: $propValEnd; } } - @include animation-name(pulseBorder); - @include animation-duration($dur); - @include animation-direction(alternate); - @include animation-iteration-count($iteration); - @include animation-timing-function(ease); - @include animation-delay($delay); + @include animToParams($animName, $dur: 500ms, $delay: 0) } + +@mixin animToParams($animName, $dur: 500ms, $delay: 0) { + @include animation-name($animName); + @include animation-duration($dur); + @include animation-delay($delay); + @include animation-fill-mode(both); + @include animation-direction(normal); + @include animation-iteration-count(1); + @include animation-timing-function(ease-in-out); +} \ No newline at end of file diff --git a/platform/commonUI/general/res/sass/user-environ/_layout.scss b/platform/commonUI/general/res/sass/user-environ/_layout.scss index 8537c85520..9ab8e0f65f 100644 --- a/platform/commonUI/general/res/sass/user-environ/_layout.scss +++ b/platform/commonUI/general/res/sass/user-environ/_layout.scss @@ -237,30 +237,10 @@ body.desktop .pane .mini-tab-icon.toggle-pane { top: $ueTopBarH + $interiorMarginLg; } -.l-object-wrapper { - @extend .abs; - - .object-holder-main { - @extend .abs; - } - .l-edit-controls { - //@include trans-prop-nice((opacity, height), 0.25s); - border-bottom: 1px solid $colorInteriorBorder; - line-height: $ueEditToolBarH; - height: 0px; - opacity: 0; - .tool-bar { - right: $interiorMargin; - } - } -} - .l-object-wrapper-inner { @include trans-prop-nice-resize(0.25s); } - - .object-browse-bar .s-btn, .top-bar .buttons-main .s-btn, .top-bar .s-menu-btn, @@ -377,19 +357,50 @@ body.desktop { .s-status-editing { .l-object-wrapper { - @include pulseBorder($colorEditAreaFg, $dur: 1s, $opacity0: 0.3); - border-radius: $controlCr; + $t2Dur: $browseToEditAnimMs; + $t1Dur: $t2Dur / 2; + $pulseDur: $editBorderPulseMs; + $bC0: rgba($colorEditAreaFg, 0.5); + $bC100: rgba($colorEditAreaFg, 1); + background-color: $colorEditAreaBg; - border-color: $colorEditAreaFg; - border-width: 2px; - border-style: dotted; - .l-object-wrapper-inner { - @include absPosDefault(3px, hidden); + border-radius: $controlCr; + border: 1px dotted $bC0; + + // Transition 1 + @include keyframes(wrapperIn) { + from { border: 0px dotted transparent; padding: 0; } + to { border: 1px dotted $bC0; padding: 5px; } } + + // Do last + @include keyframes(pulseNew) { + from { border-color: $bC0; } + to { border-color: $bC100; } + } + + @include animation-name(wrapperIn, pulseNew); + @include animation-duration($t1Dur, $pulseDur); + @include animation-delay(0s, $t1Dur + $t2Dur); + @include animation-direction(normal, alternate); + @include animation-fill-mode(both, none); + @include animation-iteration-count(1, infinite); + @include animation-timing-function(ease-in-out, linear); + + .l-edit-controls { - height: $ueEditToolBarH + $interiorMargin; - margin-bottom: $interiorMargin; - opacity: 1; + height: 0; + border-bottom: 1px solid $colorInteriorBorder; + overflow: hidden; + // Transition 2: reveal edit controls + @include keyframes(editIn) { + from { border-bottom: 0px solid transparent; height: 0; margin-bottom: 0; } + to { border-bottom: 1px solid $colorInteriorBorder; height: $ueEditToolBarH + $interiorMargin; margin-bottom: $interiorMargin; } + } + @include animToParams(editIn, $dur: $t2Dur, $delay: $t1Dur); + .tool-bar { + right: $interiorMargin; + } } } } diff --git a/platform/commonUI/themes/espresso/res/sass/_constants.scss b/platform/commonUI/themes/espresso/res/sass/_constants.scss index bb774fb7a8..1ab6d734f3 100644 --- a/platform/commonUI/themes/espresso/res/sass/_constants.scss +++ b/platform/commonUI/themes/espresso/res/sass/_constants.scss @@ -14,7 +14,7 @@ $colorAHov: #fff; $contrastRatioPercent: 7%; $hoverRatioPercent: 10%; $basicCr: 3px; -$controlCr: 3px; +$controlCr: 2px; $smallCr: 2px; // Buttons and Controls From 76edba10149c9f157f360272842d8642a840c0d4 Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Wed, 1 Jun 2016 19:19:58 -0700 Subject: [PATCH 13/30] [Frontend] Mods to Edit button fixes #709 - Changed title and style of main Edit button; - Updated EditItem.js protractor ID accordingly; --- platform/commonUI/edit/bundle.js | 2 +- .../general/res/sass/controls/_buttons.scss | 30 ++++++++----------- protractor/common/EditItem.js | 4 +-- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/platform/commonUI/edit/bundle.js b/platform/commonUI/edit/bundle.js index b8906107a0..3a9deb649e 100644 --- a/platform/commonUI/edit/bundle.js +++ b/platform/commonUI/edit/bundle.js @@ -170,7 +170,7 @@ define([ "navigationService", "$log" ], - "description": "Edit this object.", + "description": "Edit", "category": "view-control", "glyph": "p" }, diff --git a/platform/commonUI/general/res/sass/controls/_buttons.scss b/platform/commonUI/general/res/sass/controls/_buttons.scss index 7b585f8eec..d3cb8091f2 100644 --- a/platform/commonUI/general/res/sass/controls/_buttons.scss +++ b/platform/commonUI/general/res/sass/controls/_buttons.scss @@ -36,15 +36,7 @@ $pad: $interiorMargin * $baseRatio; padding: 0 $pad; font-size: 0.7rem; vertical-align: top; - - .icon { - font-size: 0.8rem; - color: $colorKey; - } - - .title-label { - vertical-align: top; - } + @include btnSubtle($colorBtnBg, $colorBtnBgHov, $colorBtnFg, $colorBtnIcon); &.lg { font-size: 1rem; @@ -58,19 +50,13 @@ $pad: $interiorMargin * $baseRatio; padding: 0 ($pad / $baseRatio) / 2; } - &.major { + &.major, + &.key-edit { $bg: $colorBtnMajorBg; $hc: lighten($bg, 10%); @include btnSubtle($bg, $hc, $colorBtnMajorFg, $colorBtnMajorFg); } - &:not(.major) { - // bg, bgHov, fg, ic - @include btnSubtle($colorBtnBg, $colorBtnBgHov, $colorBtnFg, $colorBtnIcon); - } - &.pause-play { - - } &.t-save:before { content:'\e612'; font-family: symbolsfont; @@ -109,6 +95,15 @@ $pad: $interiorMargin * $baseRatio; content: "\000039"; } } + + .icon { + font-size: 0.8rem; + color: $colorKey; + } + + .title-label { + vertical-align: top; + } } .s-icon-btn { @@ -275,4 +270,3 @@ body.desktop .mini-tab-icon { color: $colorPausedBg !important; } } - 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'; }) }); }; From f167022eea525f4589225d37809ab0b502477978 Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Thu, 2 Jun 2016 10:26:38 +0100 Subject: [PATCH 14/30] Changed logic of persisted check slightly --- .../edit/src/capabilities/TransactionalPersistenceCapability.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/commonUI/edit/src/capabilities/TransactionalPersistenceCapability.js b/platform/commonUI/edit/src/capabilities/TransactionalPersistenceCapability.js index 073e5c8fad..9bcf19c002 100644 --- a/platform/commonUI/edit/src/capabilities/TransactionalPersistenceCapability.js +++ b/platform/commonUI/edit/src/capabilities/TransactionalPersistenceCapability.js @@ -67,7 +67,7 @@ define( } function onCancel() { - if (self.domainObject.getModel().persisted) { + if (self.domainObject.getModel().persisted !== undefined) { //Fetch clean model from persistence return self.persistenceCapability.refresh().then(function (result) { self.persistPending = false; From 214a843dbaf01c28f3b1ccd904d8f1cc549dfbe4 Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Thu, 2 Jun 2016 11:09:22 -0700 Subject: [PATCH 15/30] [Frontend] New message for copy in-progress dialog fixes #339 --- platform/entanglement/src/actions/CopyAction.js | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/entanglement/src/actions/CopyAction.js b/platform/entanglement/src/actions/CopyAction.js index 2ed9725c41..0c5ab99755 100644 --- a/platform/entanglement/src/actions/CopyAction.js +++ b/platform/entanglement/src/actions/CopyAction.js @@ -81,6 +81,7 @@ define( if (phase.toLowerCase() === 'preparing' && !this.dialog) { this.dialog = this.dialogService.showBlockingMessage({ title: "Preparing to copy objects", + hint: "Do not navigate away from this page or close this browser tab while this message is displayed.", unknownProgress: true, severity: "info" }); From 026ece395631016775a9a05a24a9e13fcb7c6704 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 14:46:50 -0700 Subject: [PATCH 16/30] [Timeline] Provide greater initial width This avoids starting with a scrollable width too small for the initial scroll position that the zoom controller selects. Fixes #817 --- .../features/timeline/src/controllers/TimelineZoomController.js | 2 +- .../timeline/test/controllers/TimelineZoomControllerSpec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 3075460428..6e97f0bd0e 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -122,7 +122,7 @@ define( */ width: function (timestamp) { var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING))); - return Math.max(bounds.width, pixels); + return Math.max(bounds.width * 2, pixels); } }; } diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js index 9e67eecc3f..bf2bc03180 100644 --- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js +++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js @@ -124,7 +124,7 @@ define( var testPixel = mockScope.scroll.width / 4, testMillis = controller.toMillis(testPixel); expect(controller.width(testMillis)) - .toEqual(mockScope.scroll.width); + .not.toBeLessThan(mockScope.scroll.width); }); it("provides a width with some margin past timestamp", function () { From d02f4041b28460d4f4d21973a249c4385c7ec008 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 15:34:32 -0700 Subject: [PATCH 17/30] [Timeline] Update scroll position on timeout Fixes #817 --- platform/features/timeline/bundle.js | 1 + .../src/controllers/TimelineZoomController.js | 12 ++++++++++-- .../test/controllers/TimelineZoomControllerSpec.js | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js index ae7a283fc5..782918e545 100644 --- a/platform/features/timeline/bundle.js +++ b/platform/features/timeline/bundle.js @@ -472,6 +472,7 @@ define([ "implementation": TimelineZoomController, "depends": [ "$scope", + "$timeout", "TIMELINE_ZOOM_CONFIGURATION" ] }, diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 6e97f0bd0e..8e1c440ce3 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -28,11 +28,12 @@ define( * Controls the pan-zoom state of a timeline view. * @constructor */ - function TimelineZoomController($scope, ZOOM_CONFIGURATION) { + function TimelineZoomController($scope, $timeout, 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, + width = tickWidth, bounds = { x: 0, width: tickWidth }; // Default duration in view function toMillis(pixels) { @@ -62,6 +63,12 @@ define( zoomIndex += 1; } bounds.x = toPixels(timespan.getStart()); + + // Physical width may be insufficient for scroll; + // if so, try again on a timeout! + if (bounds.x + bounds.width > width) { + $timeout(initializeZoomFromTimespan.bind(null, timespan)); + } } function initializeZoom() { @@ -122,7 +129,8 @@ define( */ width: function (timestamp) { var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING))); - return Math.max(bounds.width * 2, pixels); + width = Math.max(bounds.width, pixels); + return width; } }; } diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js index bf2bc03180..e037c689d4 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, + mockTimeout, controller; beforeEach(function () { @@ -37,8 +38,10 @@ define( }; mockScope = jasmine.createSpyObj("$scope", ['$watch']); mockScope.commit = jasmine.createSpy('commit'); + mockTimeout = jasmine.createSpy('$timeout'); controller = new TimelineZoomController( mockScope, + mockTimeout, testConfiguration ); }); From 44d6456de195acd2ba4549c0e59234eb5b6cb3b9 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 16:00:09 -0700 Subject: [PATCH 18/30] [Timeline] Set scroll on timeout Whenever timeline zoom controller sets scroll, check to see if there may be a width violation that causes scroll to be reset, and retry on a timeout if so. Fixes #936. --- .../src/controllers/TimelineZoomController.js | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 8e1c440ce3..7aeccf662a 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -34,6 +34,7 @@ define( zoomIndex = Math.floor(zoomLevels.length / 2), tickWidth = ZOOM_CONFIGURATION.width || 200, width = tickWidth, + desiredScroll = 0, bounds = { x: 0, width: tickWidth }; // Default duration in view function toMillis(pixels) { @@ -55,6 +56,15 @@ define( } } + function setScroll() { + bounds.x = desiredScroll; + // Physical width may be insufficient for scroll; + // if so, try again on a timeout! + if (bounds.x + bounds.width > width) { + $timeout(setScroll, 0); + } + } + function initializeZoomFromTimespan(timespan) { var timelineDuration = timespan.getDuration(); zoomIndex = 0; @@ -62,13 +72,8 @@ define( zoomIndex < zoomLevels.length - 1) { zoomIndex += 1; } - bounds.x = toPixels(timespan.getStart()); - - // Physical width may be insufficient for scroll; - // if so, try again on a timeout! - if (bounds.x + bounds.width > width) { - $timeout(initializeZoomFromTimespan.bind(null, timespan)); - } + desiredScroll = toPixels(timespan.getStart()); + setScroll(); } function initializeZoom() { @@ -100,7 +105,9 @@ define( if (arguments.length > 0 && !isNaN(amount)) { var center = this.toMillis(bounds.x + bounds.width / 2); setZoomLevel(zoomIndex + amount); - bounds.x = this.toPixels(center) - bounds.width / 2; + desiredScroll = + this.toPixels(center) - bounds.width / 2; + setScroll(); } return zoomLevels[zoomIndex]; }, From d52bfed1df7dacbdaffa815fa981717d8ff5fb67 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 16:36:09 -0700 Subject: [PATCH 19/30] [Timeline] Always set scroll on timeout ...to allow time for width to increase. --- .../src/controllers/TimelineZoomController.js | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 7aeccf662a..8f0422a7a7 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -33,8 +33,8 @@ define( var zoomLevels = ZOOM_CONFIGURATION.levels || [1000], zoomIndex = Math.floor(zoomLevels.length / 2), tickWidth = ZOOM_CONFIGURATION.width || 200, - width = tickWidth, desiredScroll = 0, + achievedDesiredScroll, bounds = { x: 0, width: tickWidth }; // Default duration in view function toMillis(pixels) { @@ -56,13 +56,13 @@ define( } } - function setScroll() { - bounds.x = desiredScroll; - // Physical width may be insufficient for scroll; - // if so, try again on a timeout! - if (bounds.x + bounds.width > width) { - $timeout(setScroll, 0); - } + function setScroll(x) { + desiredScroll = x; + achievedDesiredScroll = false; + $timeout(function () { + $scope.scroll.x = desiredScroll; + achievedDesiredScroll = true; + }, 0); } function initializeZoomFromTimespan(timespan) { @@ -72,8 +72,7 @@ define( zoomIndex < zoomLevels.length - 1) { zoomIndex += 1; } - desiredScroll = toPixels(timespan.getStart()); - setScroll(); + setScroll(toPixels(timespan.getStart())); } function initializeZoom() { @@ -103,11 +102,11 @@ define( zoom: function (amount) { // Update the zoom level if called with an argument if (arguments.length > 0 && !isNaN(amount)) { + //var x = achievedDesiredScroll ? + // bounds.x : desiredScroll; var center = this.toMillis(bounds.x + bounds.width / 2); setZoomLevel(zoomIndex + amount); - desiredScroll = - this.toPixels(center) - bounds.width / 2; - setScroll(); + setScroll(this.toPixels(center) - bounds.width / 2); } return zoomLevels[zoomIndex]; }, @@ -136,8 +135,7 @@ define( */ width: function (timestamp) { var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING))); - width = Math.max(bounds.width, pixels); - return width; + return Math.max(bounds.width, pixels); } }; } From 86b31bc0403bcf3376997372601615e0945e24bd Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 16:38:11 -0700 Subject: [PATCH 20/30] [Timeline] Simplify scroll-setting --- .../timeline/src/controllers/TimelineZoomController.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 8f0422a7a7..9ce55b3d67 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -33,8 +33,6 @@ define( var zoomLevels = ZOOM_CONFIGURATION.levels || [1000], zoomIndex = Math.floor(zoomLevels.length / 2), tickWidth = ZOOM_CONFIGURATION.width || 200, - desiredScroll = 0, - achievedDesiredScroll, bounds = { x: 0, width: tickWidth }; // Default duration in view function toMillis(pixels) { @@ -57,11 +55,8 @@ define( } function setScroll(x) { - desiredScroll = x; - achievedDesiredScroll = false; $timeout(function () { - $scope.scroll.x = desiredScroll; - achievedDesiredScroll = true; + $scope.scroll.x = x; }, 0); } From 99590d18f7fece48cf82cb7783e85712b0b6f8b2 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 16:40:07 -0700 Subject: [PATCH 21/30] [Timeline] Simplify bounds-tracking --- .../src/controllers/TimelineZoomController.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 9ce55b3d67..d326cf7bbb 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -32,8 +32,7 @@ define( // 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 }; // Default duration in view + tickWidth = ZOOM_CONFIGURATION.width || 200; function toMillis(pixels) { return (pixels / tickWidth) * zoomLevels[zoomIndex]; @@ -63,7 +62,7 @@ define( 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; } @@ -77,9 +76,6 @@ define( } } - $scope.$watch("scroll", function (scroll) { - bounds = scroll; - }); $scope.$watch("domainObject", initializeZoom); return { @@ -97,8 +93,7 @@ define( zoom: function (amount) { // Update the zoom level if called with an argument if (arguments.length > 0 && !isNaN(amount)) { - //var x = achievedDesiredScroll ? - // bounds.x : desiredScroll; + var bounds = $scope.scroll; var center = this.toMillis(bounds.x + bounds.width / 2); setZoomLevel(zoomIndex + amount); setScroll(this.toPixels(center) - bounds.width / 2); @@ -130,7 +125,7 @@ define( */ width: function (timestamp) { var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING))); - return Math.max(bounds.width, pixels); + return Math.max($scope.scroll.width, pixels); } }; } From 23b64951f35bdbcd05b5e948dda19d362c7849fe Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 16:42:09 -0700 Subject: [PATCH 22/30] [Timeline] Update zoom controller spec ...to reflect changes/simplifications for #936. --- .../test/controllers/TimelineZoomControllerSpec.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js index e037c689d4..40ed8c6c61 100644 --- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js +++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js @@ -38,6 +38,7 @@ define( }; mockScope = jasmine.createSpyObj("$scope", ['$watch']); mockScope.commit = jasmine.createSpy('commit'); + mockScope.scroll = { x: 0, width: 1000 }; mockTimeout = jasmine.createSpy('$timeout'); controller = new TimelineZoomController( mockScope, @@ -67,11 +68,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, @@ -112,6 +108,10 @@ define( mockScope.$watch.calls.forEach(function (call) { call.args[1](mockScope[call.args[0]]); }); + + mockTimeout.calls.forEach(function (call) { + call.args[0](); + }); }); it("zooms to fit the timeline", function () { From fa6e8fd5f9feb90b90b5ca930a586e794eb616d7 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 16:49:49 -0700 Subject: [PATCH 23/30] Revert "[Timeline] Update scroll position on timeout" --- platform/features/timeline/bundle.js | 1 - .../src/controllers/TimelineZoomController.js | 12 ++---------- .../test/controllers/TimelineZoomControllerSpec.js | 3 --- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js index 782918e545..ae7a283fc5 100644 --- a/platform/features/timeline/bundle.js +++ b/platform/features/timeline/bundle.js @@ -472,7 +472,6 @@ define([ "implementation": TimelineZoomController, "depends": [ "$scope", - "$timeout", "TIMELINE_ZOOM_CONFIGURATION" ] }, diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 8e1c440ce3..6e97f0bd0e 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -28,12 +28,11 @@ define( * Controls the pan-zoom state of a timeline view. * @constructor */ - function TimelineZoomController($scope, $timeout, ZOOM_CONFIGURATION) { + function TimelineZoomController($scope, 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, - width = tickWidth, bounds = { x: 0, width: tickWidth }; // Default duration in view function toMillis(pixels) { @@ -63,12 +62,6 @@ define( zoomIndex += 1; } bounds.x = toPixels(timespan.getStart()); - - // Physical width may be insufficient for scroll; - // if so, try again on a timeout! - if (bounds.x + bounds.width > width) { - $timeout(initializeZoomFromTimespan.bind(null, timespan)); - } } function initializeZoom() { @@ -129,8 +122,7 @@ define( */ width: function (timestamp) { var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING))); - width = Math.max(bounds.width, pixels); - return width; + return Math.max(bounds.width * 2, pixels); } }; } diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js index e037c689d4..bf2bc03180 100644 --- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js +++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js @@ -28,7 +28,6 @@ define( describe("The timeline zoom state controller", function () { var testConfiguration, mockScope, - mockTimeout, controller; beforeEach(function () { @@ -38,10 +37,8 @@ define( }; mockScope = jasmine.createSpyObj("$scope", ['$watch']); mockScope.commit = jasmine.createSpy('commit'); - mockTimeout = jasmine.createSpy('$timeout'); controller = new TimelineZoomController( mockScope, - mockTimeout, testConfiguration ); }); From 9913fb48f5cf3375f4b096ee7e95cc36a83b2a6d Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 2 Jun 2016 16:54:59 -0700 Subject: [PATCH 24/30] Revert "[Timeline] Provide greater initial width" --- .../features/timeline/src/controllers/TimelineZoomController.js | 2 +- .../timeline/test/controllers/TimelineZoomControllerSpec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index 6e97f0bd0e..3075460428 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -122,7 +122,7 @@ define( */ width: function (timestamp) { var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING))); - return Math.max(bounds.width * 2, pixels); + return Math.max(bounds.width, pixels); } }; } diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js index bf2bc03180..9e67eecc3f 100644 --- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js +++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js @@ -124,7 +124,7 @@ define( var testPixel = mockScope.scroll.width / 4, testMillis = controller.toMillis(testPixel); expect(controller.width(testMillis)) - .not.toBeLessThan(mockScope.scroll.width); + .toEqual(mockScope.scroll.width); }); it("provides a width with some margin past timestamp", function () { From f9c93ca022b8d1b5c8eca08ab337ed9d506009ae Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 6 Jun 2016 09:49:52 -0700 Subject: [PATCH 25/30] [Build] Remove SNAPSHOT status To close sprint Huxley, https://github.com/nasa/openmct/milestones/Huxley --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eb7afd1f70..00b73fda0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openmct", - "version": "0.10.2-SNAPSHOT", + "version": "0.10.2", "description": "The Open MCT core platform", "dependencies": { "express": "^4.13.1", From b0f06a2195fc760adf2ea2f4d92021f550e5c495 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 6 Jun 2016 09:57:09 -0700 Subject: [PATCH 26/30] [Build] Restore SNAPSHOT status ...to open sprint Kress, https://github.com/nasa/openmct/milestones/Kress --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 00b73fda0a..13bfe158dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openmct", - "version": "0.10.2", + "version": "0.10.3-SNAPSHOT", "description": "The Open MCT core platform", "dependencies": { "express": "^4.13.1", From a1b2175801dd7582d7e4bbd268e3ee7cc72cac40 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Tue, 7 Jun 2016 10:02:52 -0700 Subject: [PATCH 27/30] [Timeline] Reduce flicker Reposition scroll bar in Timeline with RAF instead of timeout; this ensures that scroll bar is positioned after the current digest (updating the width) but before the results are rendered (avoiding flicker.) Fixes #997 --- platform/features/timeline/bundle.js | 2 +- .../src/controllers/TimelineZoomController.js | 7 ++++--- .../test/controllers/TimelineZoomControllerSpec.js | 13 ++++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js index 782918e545..d8f8729808 100644 --- a/platform/features/timeline/bundle.js +++ b/platform/features/timeline/bundle.js @@ -472,7 +472,7 @@ define([ "implementation": TimelineZoomController, "depends": [ "$scope", - "$timeout", + "$window", "TIMELINE_ZOOM_CONFIGURATION" ] }, diff --git a/platform/features/timeline/src/controllers/TimelineZoomController.js b/platform/features/timeline/src/controllers/TimelineZoomController.js index d326cf7bbb..620e871d11 100644 --- a/platform/features/timeline/src/controllers/TimelineZoomController.js +++ b/platform/features/timeline/src/controllers/TimelineZoomController.js @@ -28,7 +28,7 @@ define( * Controls the pan-zoom state of a timeline view. * @constructor */ - function TimelineZoomController($scope, $timeout, 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), @@ -54,9 +54,10 @@ define( } function setScroll(x) { - $timeout(function () { + $window.requestAnimationFrame(function () { $scope.scroll.x = x; - }, 0); + $scope.$apply(); + }); } function initializeZoomFromTimespan(timespan) { diff --git a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js index 40ed8c6c61..18ed911671 100644 --- a/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js +++ b/platform/features/timeline/test/controllers/TimelineZoomControllerSpec.js @@ -28,7 +28,7 @@ define( describe("The timeline zoom state controller", function () { var testConfiguration, mockScope, - mockTimeout, + mockWindow, controller; beforeEach(function () { @@ -36,13 +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 }; - mockTimeout = jasmine.createSpy('$timeout'); + mockWindow = { + requestAnimationFrame: jasmine.createSpy('raf') + }; controller = new TimelineZoomController( mockScope, - mockTimeout, + mockWindow, testConfiguration ); }); @@ -109,7 +112,7 @@ define( call.args[1](mockScope[call.args[0]]); }); - mockTimeout.calls.forEach(function (call) { + mockWindow.requestAnimationFrame.calls.forEach(function (call) { call.args[0](); }); }); From 29dd51439da9b7aef1d84be146ca787df24c50f7 Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Wed, 8 Jun 2016 13:32:21 +0100 Subject: [PATCH 28/30] [Date Input] Addressed issues with date selector. Fixes #1000 --- .../res/templates/controls/datetime-field.html | 10 ++++++---- .../src/controllers/DateTimeFieldController.js | 12 +++++++++++- .../general/src/directives/MCTClickElsewhere.js | 4 +++- .../general/test/directives/MCTClickElsewhereSpec.js | 2 ++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/platform/commonUI/general/res/templates/controls/datetime-field.html b/platform/commonUI/general/res/templates/controls/datetime-field.html index 47551fa25b..5f1705bc98 100644 --- a/platform/commonUI/general/res/templates/controls/datetime-field.html +++ b/platform/commonUI/general/res/templates/controls/datetime-field.html @@ -29,10 +29,12 @@ !structure.validate(ngModel[field])), 'picker-icon': structure.format === 'utc' || !structure.format }"> - - + + + +
xMax || y < yMin || y > yMax) { - scope.$eval(attrs.mctClickElsewhere); + scope.$apply(function () { + scope.$eval(attrs.mctClickElsewhere); + }); } } diff --git a/platform/commonUI/general/test/directives/MCTClickElsewhereSpec.js b/platform/commonUI/general/test/directives/MCTClickElsewhereSpec.js index 2e782a1a01..53924b0dd7 100644 --- a/platform/commonUI/general/test/directives/MCTClickElsewhereSpec.js +++ b/platform/commonUI/general/test/directives/MCTClickElsewhereSpec.js @@ -104,6 +104,8 @@ define( }); it("triggers an evaluation of its related Angular expression", function () { + expect(mockScope.$apply).toHaveBeenCalled(); + mockScope.$apply.mostRecentCall.args[0](); expect(mockScope.$eval) .toHaveBeenCalledWith(testAttrs.mctClickElsewhere); }); From acd0fae04048a427f8c5b27cf286bacf261796bf Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Thu, 9 Jun 2016 12:33:09 +0100 Subject: [PATCH 29/30] [Tables] Recalculate column dimensions on resize. Fixes #861 --- platform/features/table/res/templates/mct-table.html | 2 +- .../features/table/src/controllers/MCTTableController.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/features/table/res/templates/mct-table.html b/platform/features/table/res/templates/mct-table.html index 7a18388455..0835b6c48d 100644 --- a/platform/features/table/res/templates/mct-table.html +++ b/platform/features/table/res/templates/mct-table.html @@ -1,4 +1,4 @@ -
+
diff --git a/platform/features/table/src/controllers/MCTTableController.js b/platform/features/table/src/controllers/MCTTableController.js index e4cfa45b23..5ccda6afe1 100644 --- a/platform/features/table/src/controllers/MCTTableController.js +++ b/platform/features/table/src/controllers/MCTTableController.js @@ -76,6 +76,12 @@ define( */ $scope.$on('add:row', this.addRow.bind(this)); $scope.$on('remove:row', this.removeRow.bind(this)); + + /* + * Listen for resize events to trigger recalculation of table width + */ + $scope.resize = this.setElementSizes.bind(this); + } /** From 5152e64895c1065cc6d460dcd5326b7da4e8ed19 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 10 Jun 2016 10:06:05 -0700 Subject: [PATCH 30/30] [Duplicate] Allow copy across spaces Fixes #1007 --- .../src/policies/CrossSpacePolicy.js | 5 +-- .../test/policies/CrossSpacePolicySpec.js | 34 +++++++++---------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/platform/entanglement/src/policies/CrossSpacePolicy.js b/platform/entanglement/src/policies/CrossSpacePolicy.js index 29aab5a484..39d05bd532 100644 --- a/platform/entanglement/src/policies/CrossSpacePolicy.js +++ b/platform/entanglement/src/policies/CrossSpacePolicy.js @@ -24,10 +24,7 @@ define( [], function () { - var DISALLOWED_ACTIONS = [ - "move", - "copy" - ]; + var DISALLOWED_ACTIONS = ["move"]; /** * This policy prevents performing move/copy/link actions across diff --git a/platform/entanglement/test/policies/CrossSpacePolicySpec.js b/platform/entanglement/test/policies/CrossSpacePolicySpec.js index ef09a47619..38bb1f9606 100644 --- a/platform/entanglement/test/policies/CrossSpacePolicySpec.js +++ b/platform/entanglement/test/policies/CrossSpacePolicySpec.js @@ -70,27 +70,25 @@ define( policy = new CrossSpacePolicy(); }); - ['move', 'copy'].forEach(function (key) { - describe("for " + key + " actions", function () { - beforeEach(function () { - testActionMetadata.key = key; - }); + describe("for move actions", function () { + beforeEach(function () { + testActionMetadata.key = 'move'; + }); - it("allows same-space changes", function () { - expect(policy.allow(mockAction, sameSpaceContext)) - .toBe(true); - }); + it("allows same-space changes", function () { + expect(policy.allow(mockAction, sameSpaceContext)) + .toBe(true); + }); - it("disallows cross-space changes", function () { - expect(policy.allow(mockAction, crossSpaceContext)) - .toBe(false); - }); + it("disallows cross-space changes", function () { + expect(policy.allow(mockAction, crossSpaceContext)) + .toBe(false); + }); - it("allows actions with no selectedObject", function () { - expect(policy.allow(mockAction, { - domainObject: makeObject('a') - })).toBe(true); - }); + it("allows actions with no selectedObject", function () { + expect(policy.allow(mockAction, { + domainObject: makeObject('a') + })).toBe(true); }); });