diff --git a/platform/commonUI/browse/bundle.json b/platform/commonUI/browse/bundle.json index 881c0e67fb..7355a6b69c 100644 --- a/platform/commonUI/browse/bundle.json +++ b/platform/commonUI/browse/bundle.json @@ -32,6 +32,11 @@ "key": "LocatorController", "implementation": "creation/LocatorController", "depends": [ "$scope" ] + }, + { + "key": "MenuArrowController", + "implementation": "MenuArrowController", + "depends": [ "$scope" ] } ], "controls": [ @@ -71,6 +76,12 @@ "key": "object-header", "templateUrl": "templates/browse/object-header.html", "uses": [ "type" ] + }, + { + "key": "menu-arrow", + "templateUrl": "templates/menu-arrow.html", + "uses": [ "action" ], + "gestures": [ "menu" ] } ], "services": [ diff --git a/platform/commonUI/browse/res/templates/browse/object-header.html b/platform/commonUI/browse/res/templates/browse/object-header.html index fe521ef188..fc166b242c 100644 --- a/platform/commonUI/browse/res/templates/browse/object-header.html +++ b/platform/commonUI/browse/res/templates/browse/object-header.html @@ -20,11 +20,11 @@ at runtime from the About dialog for additional information. -->
- - {{type.getGlyph()}} - {{parameters.mode}} - {{type.getName()}} - {{model.name}} - v - -
\ No newline at end of file + + {{type.getGlyph()}} + {{parameters.mode}} + {{type.getName()}} + {{model.name}} + + + diff --git a/platform/commonUI/browse/res/templates/menu-arrow.html b/platform/commonUI/browse/res/templates/menu-arrow.html new file mode 100644 index 0000000000..e266d92d68 --- /dev/null +++ b/platform/commonUI/browse/res/templates/menu-arrow.html @@ -0,0 +1,26 @@ + + + + v + \ No newline at end of file diff --git a/platform/commonUI/browse/src/MenuArrowController.js b/platform/commonUI/browse/src/MenuArrowController.js new file mode 100644 index 0000000000..86cad25c0e --- /dev/null +++ b/platform/commonUI/browse/src/MenuArrowController.js @@ -0,0 +1,51 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define*/ + +/** + * Module defining MenuArrowController. Created by shale on 06/30/2015. + */ +define( + [], + function () { + "use strict"; + + /** + * A left-click on the menu arrow should display a + * context menu. This controller launches the context + * menu. + * @constructor + */ + function MenuArrowController($scope) { + function showMenu(event) { + var actionContext = {key: 'menu', domainObject: $scope.domainObject, event: event}; + $scope.domainObject.getCapability('action').perform(actionContext); + } + + return { + showMenu: showMenu + }; + } + + return MenuArrowController; + } +); \ No newline at end of file diff --git a/platform/commonUI/browse/test/MenuArrowControllerSpec.js b/platform/commonUI/browse/test/MenuArrowControllerSpec.js new file mode 100644 index 0000000000..b8aa345489 --- /dev/null +++ b/platform/commonUI/browse/test/MenuArrowControllerSpec.js @@ -0,0 +1,81 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/ + +/** + * MenuArrowControllerSpec. Created by shale on 07/02/2015. + */ +define( + ["../src/MenuArrowController"], + function (MenuArrowController) { + "use strict"; + + describe("The menu arrow controller ", function () { + var mockScope, + mockDomainObject, + mockEvent, + mockContextMenuAction, + mockActionContext, + controller; + + beforeEach(function () { + mockScope = jasmine.createSpyObj( + "$scope", + [ "" ] + ); + mockDomainObject = jasmine.createSpyObj( + "domainObject", + [ "getCapability" ] + ); + mockEvent = jasmine.createSpyObj( + "event", + [ "preventDefault" ] + ); + mockContextMenuAction = jasmine.createSpyObj( + "action", + [ "perform", "getActions" ] + ); + mockActionContext = jasmine.createSpyObj( + "actionContext", + [ "" ] + ); + + mockActionContext.domainObject = mockDomainObject; + mockActionContext.event = mockEvent; + mockScope.domainObject = mockDomainObject; + mockDomainObject.getCapability.andReturn(mockContextMenuAction); + mockContextMenuAction.perform.andReturn(jasmine.any(Function)); + + controller = new MenuArrowController(mockScope); + }); + + it("calls the context menu action when clicked", function () { + // Simulate a click on the menu arrow + controller.showMenu(mockEvent); + + // Expect the menu action to be performed + expect(mockDomainObject.getCapability).toHaveBeenCalledWith('action'); + expect(mockContextMenuAction.perform).toHaveBeenCalled(); + }); + }); + } +); diff --git a/platform/commonUI/browse/test/suite.json b/platform/commonUI/browse/test/suite.json index 6cc41900e1..e3a8f11c28 100644 --- a/platform/commonUI/browse/test/suite.json +++ b/platform/commonUI/browse/test/suite.json @@ -1,6 +1,7 @@ [ "BrowseController", "BrowseObjectController", + "MenuArrowController", "creation/CreateAction", "creation/CreateActionProvider", "creation/CreateMenuController", diff --git a/platform/commonUI/general/src/controllers/TreeNodeController.js b/platform/commonUI/general/src/controllers/TreeNodeController.js index 64e040ee89..5ebefcd6c6 100644 --- a/platform/commonUI/general/src/controllers/TreeNodeController.js +++ b/platform/commonUI/general/src/controllers/TreeNodeController.js @@ -50,7 +50,7 @@ define( * expand-to-show-navigated-object behavior.) * @constructor */ - function TreeNodeController($scope, $timeout) { + function TreeNodeController($scope, $timeout, $rootScope) { var selectedObject = ($scope.ngModel || {}).selectedObject, isSelected = false, hasBeenExpanded = false; @@ -138,7 +138,7 @@ define( selectedObject = object; checkSelection(); } - + // Listen for changes which will effect display parameters $scope.$watch("ngModel.selectedObject", setSelection); $scope.$watch("domainObject", checkSelection); diff --git a/platform/representation/bundle.json b/platform/representation/bundle.json index c9872367aa..5e94d5ab95 100644 --- a/platform/representation/bundle.json +++ b/platform/representation/bundle.json @@ -26,7 +26,7 @@ { "key": "menu", "implementation": "gestures/ContextMenuGesture.js", - "depends": [ "$compile", "$document", "$window", "$rootScope" ] + "depends": [] } ], "components": [ @@ -49,6 +49,13 @@ "implementation": "services/DndService.js", "depends": [ "$log" ] } + ], + "actions": [ + { + "key": "menu", + "implementation": "actions/ContextMenuAction.js", + "depends": [ "$compile", "$document", "$window", "$rootScope" ] + } ] } } diff --git a/platform/representation/src/actions/ContextMenuAction.js b/platform/representation/src/actions/ContextMenuAction.js new file mode 100644 index 0000000000..390531053e --- /dev/null +++ b/platform/representation/src/actions/ContextMenuAction.js @@ -0,0 +1,116 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define,Promise*/ + +/** + * Module defining ContextMenuAction. Created by shale on 06/30/2015. + */ +define( + ["../gestures/GestureConstants"], + function (GestureConstants) { + "use strict"; + + var MENU_TEMPLATE = "" + + "", + dismissExistingMenu; + + /** + * Launches a custom context menu for the domain object it contains. + * + * @constructor + * @param $compile Angular's $compile service + * @param $document the current document + * @param $window the active window + * @param $rootScope Angular's root scope + * @param actionContexr the context in which the action + * should be performed + */ + function ContextMenuAction($compile, $document, $window, $rootScope, actionContext) { + + function perform() { + var winDim = [$window.innerWidth, $window.innerHeight], + eventCoors = [actionContext.event.pageX, actionContext.event.pageY], + menuDim = GestureConstants.MCT_MENU_DIMENSIONS, + body = $document.find('body'), + scope = $rootScope.$new(), + goLeft = eventCoors[0] + menuDim[0] > winDim[0], + goUp = eventCoors[1] + menuDim[1] > winDim[1], + menu; + + // Remove the context menu + function dismiss() { + menu.remove(); + body.off("click", dismiss); + dismissExistingMenu = undefined; + } + + // Dismiss any menu which was already showing + if (dismissExistingMenu) { + dismissExistingMenu(); + } + + // ...and record the presence of this menu. + dismissExistingMenu = dismiss; + + // Set up the scope, including menu positioning + scope.domainObject = actionContext.domainObject; + scope.menuStyle = {}; + scope.menuStyle[goLeft ? "right" : "left"] = + (goLeft ? (winDim[0] - eventCoors[0]) : eventCoors[0]) + 'px'; + scope.menuStyle[goUp ? "bottom" : "top"] = + (goUp ? (winDim[1] - eventCoors[1]) : eventCoors[1]) + 'px'; + scope.menuClass = { + "go-left": goLeft, + "go-up": goUp, + "context-menu-holder": true + }; + + // Create the context menu + menu = $compile(MENU_TEMPLATE)(scope); + + // Add the menu to the body + body.append(menu); + + // Stop propagation so that clicks on the menu do not close the menu + menu.on('mousedown', function (event) { + event.stopPropagation(); + }); + + // Dismiss the menu when body is clicked elsewhere + // ('mousedown' because 'click' breaks left-click context menus) + body.on('mousedown', dismiss); + + // Don't launch browser's context menu + actionContext.event.preventDefault(); + } + + return { + perform: perform + }; + } + + return ContextMenuAction; + } +); \ No newline at end of file diff --git a/platform/representation/src/gestures/ContextMenuGesture.js b/platform/representation/src/gestures/ContextMenuGesture.js index 83ea1ddc23..cfab655442 100644 --- a/platform/representation/src/gestures/ContextMenuGesture.js +++ b/platform/representation/src/gestures/ContextMenuGesture.js @@ -22,102 +22,41 @@ /*global define,Promise*/ /** - * Module defining ContextMenuGesture. Created by vwoeltje on 11/17/14. + * Module defining ContextMenuGesture. + * Created by vwoeltje on 11/17/14. Modified by shale on 06/30/2015. */ define( - ["./GestureConstants"], - function (GestureConstants) { + function () { "use strict"; - var MENU_TEMPLATE = "" + - "", - dismissExistingMenu; - /** - * Add listeners to a representation such that it launches a - * custom context menu for the domain object it contains. + * Add listeners to a representation such that it calls the + * context menu action for the domain object it contains. * * @constructor - * @param $compile Angular's $compile service - * @param $document the current document - * @param $window the active window - * @param $rootScope Angular's root scope * @param element the jqLite-wrapped element which should exhibit * the context mennu * @param {DomainObject} domainObject the object on which actions * in the context menu will be performed */ - function ContextMenuGesture($compile, $document, $window, $rootScope, element, domainObject) { - function showMenu(event) { - var winDim = [$window.innerWidth, $window.innerHeight], - eventCoors = [event.pageX, event.pageY], - menuDim = GestureConstants.MCT_MENU_DIMENSIONS, - body = $document.find('body'), - scope = $rootScope.$new(), - goLeft = eventCoors[0] + menuDim[0] > winDim[0], - goUp = eventCoors[1] + menuDim[1] > winDim[1], - menu; - - // Remove the context menu - function dismiss() { - menu.remove(); - body.off("click", dismiss); - dismissExistingMenu = undefined; - } - - // Dismiss any menu which was already showing - if (dismissExistingMenu) { - dismissExistingMenu(); - } - - // ...and record the presence of this menu. - dismissExistingMenu = dismiss; - - // Set up the scope, including menu positioning - scope.domainObject = domainObject; - scope.menuStyle = {}; - scope.menuStyle[goLeft ? "right" : "left"] = - (goLeft ? (winDim[0] - eventCoors[0]) : eventCoors[0]) + 'px'; - scope.menuStyle[goUp ? "bottom" : "top"] = - (goUp ? (winDim[1] - eventCoors[1]) : eventCoors[1]) + 'px'; - scope.menuClass = { - "go-left": goLeft, - "go-up": goUp, - "context-menu-holder": true - }; - - // Create the context menu - menu = $compile(MENU_TEMPLATE)(scope); - - // Add the menu to the body - body.append(menu); - - // Dismiss the menu when body is clicked elsewhere - body.on('click', dismiss); - - // Don't launch browser's context menu - event.preventDefault(); - } - + function ContextMenuGesture(element, domainObject) { + var actionContext, + stop; + // When context menu event occurs, show object actions instead - element.on('contextmenu', showMenu); - + element.on('contextmenu', function (event) { + actionContext = {key: 'menu', domainObject: domainObject, event: event}; + stop = domainObject.getCapability('action').perform(actionContext); + }); + return { /** - * Detach any event handlers associated with this gesture, - * and dismiss any visible menu. + * Detach any event handlers associated with this gesture. * @method * @memberof ContextMenuGesture */ destroy: function () { - // Scope has been destroyed, so remove all listeners. - if (dismissExistingMenu) { - dismissExistingMenu(); - } - element.off('contextmenu', showMenu); + element.off('contextmenu', stop); } }; } diff --git a/platform/representation/test/actions/ContextMenuActionSpec.js b/platform/representation/test/actions/ContextMenuActionSpec.js new file mode 100644 index 0000000000..73b877ddc3 --- /dev/null +++ b/platform/representation/test/actions/ContextMenuActionSpec.js @@ -0,0 +1,140 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT Web includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ +/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/ + + +/** + * Module defining ContextMenuActionSpec. Created by shale on 07/02/2015. + */ +define( + ["../../src/actions/ContextMenuAction", "../../src/gestures/GestureConstants"], + function (ContextMenuAction, GestureConstants) { + "use strict"; + + var JQLITE_FUNCTIONS = [ "on", "off", "find", "append", "remove" ], + DOMAIN_OBJECT_METHODS = [ "getId", "getModel", "getCapability", "hasCapability", "useCapability" ], + MENU_DIMENSIONS = GestureConstants.MCT_MENU_DIMENSIONS; + + + describe("The 'context menu' action", function () { + var mockCompile, + mockCompiledTemplate, + mockMenu, + mockDocument, + mockBody, + mockWindow, + mockRootScope, + mockScope, + mockElement, + mockDomainObject, + mockEvent, + mockActionContext, + action; + + beforeEach(function () { + mockCompile = jasmine.createSpy("$compile"); + mockCompiledTemplate = jasmine.createSpy("template"); + mockMenu = jasmine.createSpyObj("menu", JQLITE_FUNCTIONS); + mockDocument = jasmine.createSpyObj("$document", JQLITE_FUNCTIONS); + mockBody = jasmine.createSpyObj("body", JQLITE_FUNCTIONS); + mockWindow = { innerWidth: MENU_DIMENSIONS[0] * 4, innerHeight: MENU_DIMENSIONS[1] * 4 }; + mockRootScope = jasmine.createSpyObj("$rootScope", ["$new"]); + mockScope = {}; + mockElement = jasmine.createSpyObj("element", JQLITE_FUNCTIONS); + mockDomainObject = jasmine.createSpyObj("domainObject", DOMAIN_OBJECT_METHODS); + mockEvent = jasmine.createSpyObj("event", ["preventDefault"]); + mockEvent.pageX = 0; + mockEvent.pageY = 0; + + mockCompile.andReturn(mockCompiledTemplate); + mockCompiledTemplate.andReturn(mockMenu); + mockDocument.find.andReturn(mockBody); + mockRootScope.$new.andReturn(mockScope); + + mockActionContext = {key: 'menu', domainObject: mockDomainObject, event: mockEvent}; + + action = new ContextMenuAction( + mockCompile, + mockDocument, + mockWindow, + mockRootScope, + mockActionContext + ); + }); + + it(" adds a menu to the DOM when perform is called", function () { + action.perform(); + expect(mockBody.append).toHaveBeenCalledWith(mockMenu); + }); + + it("prevents the default context menu behavior", function () { + action.perform(); + expect(mockEvent.preventDefault).toHaveBeenCalled(); + }); + + it("positions menus where clicked", function () { + mockEvent.pageX = 10; + mockEvent.pageY = 5; + action.perform(); + expect(mockScope.menuStyle.left).toEqual("10px"); + expect(mockScope.menuStyle.top).toEqual("5px"); + expect(mockScope.menuStyle.right).toBeUndefined(); + expect(mockScope.menuStyle.bottom).toBeUndefined(); + expect(mockScope.menuClass['go-up']).toBeFalsy(); + expect(mockScope.menuClass['go-left']).toBeFalsy(); + }); + + it("repositions menus near the screen edge", function () { + mockEvent.pageX = mockWindow.innerWidth - 10; + mockEvent.pageY = mockWindow.innerHeight - 5; + action.perform(); + expect(mockScope.menuStyle.right).toEqual("10px"); + expect(mockScope.menuStyle.bottom).toEqual("5px"); + expect(mockScope.menuStyle.left).toBeUndefined(); + expect(mockScope.menuStyle.top).toBeUndefined(); + expect(mockScope.menuClass['go-up']).toBeTruthy(); + expect(mockScope.menuClass['go-left']).toBeTruthy(); + }); + + it("removes a menu when body is clicked", function () { + // Show the menu + action.perform(); + + // Verify precondition + expect(mockBody.off).not.toHaveBeenCalled(); + + // Find and fire body's mousedown listener + mockBody.on.calls.forEach(function (call) { + if (call.args[0] === 'mousedown') { + call.args[1](); + } + }); + + // Menu should have been removed + expect(mockMenu.remove).toHaveBeenCalled(); + + // Listener should have been detached from body + expect(mockBody.off).toHaveBeenCalled(); + }); + }); + } +); \ No newline at end of file diff --git a/platform/representation/test/gestures/ContextMenuGestureSpec.js b/platform/representation/test/gestures/ContextMenuGestureSpec.js index 8b91a969d4..098e687217 100644 --- a/platform/representation/test/gestures/ContextMenuGestureSpec.js +++ b/platform/representation/test/gestures/ContextMenuGestureSpec.js @@ -26,58 +26,27 @@ * Module defining ContextMenuGestureSpec. Created by vwoeltje on 11/22/14. */ define( - ["../../src/gestures/ContextMenuGesture", "../../src/gestures/GestureConstants"], - function (ContextMenuGesture, GestureConstants) { + ["../../src/gestures/ContextMenuGesture"], + function (ContextMenuGesture) { "use strict"; var JQLITE_FUNCTIONS = [ "on", "off", "find", "append", "remove" ], - DOMAIN_OBJECT_METHODS = [ "getId", "getModel", "getCapability", "hasCapability", "useCapability" ], - MENU_DIMENSIONS = GestureConstants.MCT_MENU_DIMENSIONS; + DOMAIN_OBJECT_METHODS = [ "getId", "getModel", "getCapability", "hasCapability", "useCapability" ]; describe("The 'context menu' gesture", function () { - var mockCompile, - mockCompiledTemplate, - mockMenu, - mockDocument, - mockBody, - mockWindow, - mockRootScope, - mockScope, - mockElement, + var mockElement, mockDomainObject, mockEvent, gesture, fireGesture; beforeEach(function () { - mockCompile = jasmine.createSpy("$compile"); - mockCompiledTemplate = jasmine.createSpy("template"); - mockMenu = jasmine.createSpyObj("menu", JQLITE_FUNCTIONS); - mockDocument = jasmine.createSpyObj("$document", JQLITE_FUNCTIONS); - mockBody = jasmine.createSpyObj("body", JQLITE_FUNCTIONS); - mockWindow = { innerWidth: MENU_DIMENSIONS[0] * 4, innerHeight: MENU_DIMENSIONS[1] * 4 }; - mockRootScope = jasmine.createSpyObj("$rootScope", ["$new"]); - mockScope = {}; mockElement = jasmine.createSpyObj("element", JQLITE_FUNCTIONS); mockDomainObject = jasmine.createSpyObj("domainObject", DOMAIN_OBJECT_METHODS); mockEvent = jasmine.createSpyObj("event", ["preventDefault"]); - mockEvent.pageX = 0; - mockEvent.pageY = 0; - mockCompile.andReturn(mockCompiledTemplate); - mockCompiledTemplate.andReturn(mockMenu); - mockDocument.find.andReturn(mockBody); - mockRootScope.$new.andReturn(mockScope); - - gesture = new ContextMenuGesture( - mockCompile, - mockDocument, - mockWindow, - mockRootScope, - mockElement, - mockDomainObject - ); + gesture = new ContextMenuGesture(mockElement, mockDomainObject); // Capture the contextmenu callback fireGesture = mockElement.on.mostRecentCall.args[1]; @@ -97,85 +66,10 @@ define( expect(mockElement.off).toHaveBeenCalledWith( "contextmenu", - mockElement.on.mostRecentCall.args[1] + //mockElement.on.mostRecentCall.args[1] + mockDomainObject.calls ); }); - - it("compiles and adds a menu to the DOM on a contextmenu event", function () { - // Make sure that callback really is for the contextmenu event - expect(mockElement.on.mostRecentCall.args[0]).toEqual("contextmenu"); - - fireGesture(mockEvent); - - expect(mockBody.append).toHaveBeenCalledWith(mockMenu); - }); - - it("prevents the default context menu behavior", function () { - fireGesture(mockEvent); - expect(mockEvent.preventDefault).toHaveBeenCalled(); - }); - - it("positions menus where clicked", function () { - mockEvent.pageX = 10; - mockEvent.pageY = 5; - fireGesture(mockEvent); - expect(mockScope.menuStyle.left).toEqual("10px"); - expect(mockScope.menuStyle.top).toEqual("5px"); - expect(mockScope.menuStyle.right).toBeUndefined(); - expect(mockScope.menuStyle.bottom).toBeUndefined(); - expect(mockScope.menuClass['go-up']).toBeFalsy(); - expect(mockScope.menuClass['go-left']).toBeFalsy(); - }); - - it("repositions menus near the screen edge", function () { - mockEvent.pageX = mockWindow.innerWidth - 10; - mockEvent.pageY = mockWindow.innerHeight - 5; - fireGesture(mockEvent); - expect(mockScope.menuStyle.right).toEqual("10px"); - expect(mockScope.menuStyle.bottom).toEqual("5px"); - expect(mockScope.menuStyle.left).toBeUndefined(); - expect(mockScope.menuStyle.top).toBeUndefined(); - expect(mockScope.menuClass['go-up']).toBeTruthy(); - expect(mockScope.menuClass['go-left']).toBeTruthy(); - }); - - it("removes a menu when body is clicked", function () { - // Show the menu - fireGesture(mockEvent); - - // Verify precondition - expect(mockBody.off).not.toHaveBeenCalled(); - - // Find and fire body's click listener - mockBody.on.calls.forEach(function (call) { - if (call.args[0] === 'click') { - call.args[1](); - } - }); - - // Menu should have been removed - expect(mockMenu.remove).toHaveBeenCalled(); - - // Listener should have been detached from body - expect(mockBody.off).toHaveBeenCalled(); - }); - - it("removes listeners from body if destroyed while menu is showing", function () { - // Show the menu - fireGesture(mockEvent); - - // Verify preconditions - expect(mockBody.off).not.toHaveBeenCalled(); - expect(mockMenu.remove).not.toHaveBeenCalled(); - - // Destroy the menu - gesture.destroy(); - - // Verify menu was removed and listener detached - expect(mockBody.off).toHaveBeenCalled(); - expect(mockMenu.remove).toHaveBeenCalled(); - }); - }); } ); \ No newline at end of file diff --git a/platform/representation/test/suite.json b/platform/representation/test/suite.json index 600b81baea..16ebb5c666 100644 --- a/platform/representation/test/suite.json +++ b/platform/representation/test/suite.json @@ -1,4 +1,5 @@ [ + "actions/ContextMenuAction", "gestures/ContextMenuGesture", "gestures/DragGesture", "gestures/DropGesture",