Merge remote-tracking branch 'github/master' into open117b

This commit is contained in:
Victor Woeltjen
2015-10-09 09:35:07 -07:00
29 changed files with 774 additions and 537 deletions

View File

@@ -8,6 +8,11 @@
"key": "urlService",
"implementation": "services/UrlService.js",
"depends": [ "$location" ]
},
{
"key": "popupService",
"implementation": "services/PopupService.js",
"depends": [ "$document", "$window" ]
}
],
"runs": [
@@ -128,7 +133,7 @@
{
"key": "mctPopup",
"implementation": "directives/MCTPopup.js",
"depends": [ "$window", "$document", "$compile", "$interval" ]
"depends": [ "$compile", "popupService" ]
},
{
"key": "mctScrollX",

View File

@@ -27,33 +27,36 @@ define(
var TEMPLATE = "<div></div>";
function MCTPopup($window, $document, $compile) {
/**
* The `mct-popup` directive may be used to display elements
* which "pop up" over other parts of the page. Typically, this is
* done in conjunction with an `ng-if` to control the visibility
* of the popup.
*
* Example of usage:
*
* <mct-popup ng-if="someExpr">
* <span>These are the contents of the popup!</span>
* </mct-popup>
*
* @constructor
* @memberof platform/commonUI/general
* @param $compile Angular's $compile service
* @param {platform/commonUI/general.PopupService} popupService
*/
function MCTPopup($compile, popupService) {
function link(scope, element, attrs, ctrl, transclude) {
var body = $document.find('body'),
popup = $compile(TEMPLATE)(scope),
winDim = [$window.innerWidth, $window.innerHeight],
var div = $compile(TEMPLATE)(scope),
rect = element.parent()[0].getBoundingClientRect(),
position = [ rect.left, rect.top ],
isLeft = position[0] <= (winDim[0] / 2),
isTop = position[1] <= (winDim[1] / 2);
popup.css('position', 'absolute');
popup.css(
isLeft ? 'left' : 'right',
(isLeft ? position[0] : (winDim[0] - position[0])) + 'px'
);
popup.css(
isTop ? 'top' : 'bottom',
(isTop ? position[1] : (winDim[1] - position[1])) + 'px'
);
body.append(popup);
popup = popupService.display(div, position);
transclude(function (clone) {
popup.append(clone);
div.append(clone);
});
scope.$on('$destroy', function () {
popup.remove();
popup.dismiss();
});
}

View File

@@ -0,0 +1,89 @@
/*****************************************************************************
* 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*/
define(
function () {
"use strict";
/**
* A popup is an element that has been displayed at a particular
* location within the page.
* @constructor
* @memberof platform/commonUI/general
* @param element the jqLite-wrapped element
* @param {object} styles an object containing key-value pairs
* of styles used to position the element.
*/
function Popup(element, styles) {
this.styles = styles;
this.element = element;
element.css(styles);
}
/**
* Stop showing this popup.
*/
Popup.prototype.dismiss = function () {
this.element.remove();
};
/**
* Check if this popup is positioned such that it appears to the
* left of its original location.
* @returns {boolean} true if the popup goes left
*/
Popup.prototype.goesLeft = function () {
return !this.styles.left;
};
/**
* Check if this popup is positioned such that it appears to the
* right of its original location.
* @returns {boolean} true if the popup goes right
*/
Popup.prototype.goesRight = function () {
return !this.styles.right;
};
/**
* Check if this popup is positioned such that it appears above
* its original location.
* @returns {boolean} true if the popup goes up
*/
Popup.prototype.goesUp = function () {
return !this.styles.top;
};
/**
* Check if this popup is positioned such that it appears below
* its original location.
* @returns {boolean} true if the popup goes down
*/
Popup.prototype.goesDown = function () {
return !this.styles.bottom;
};
return Popup;
}
);

View File

@@ -0,0 +1,127 @@
/*****************************************************************************
* 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*/
define(
['./Popup'],
function (Popup) {
"use strict";
/**
* Displays popup elements at specific positions within the document.
* @memberof platform/commonUI/general
* @constructor
*/
function PopupService($document, $window) {
this.$document = $document;
this.$window = $window;
}
/**
* Options controlling how the popup is displaed.
*
* @typedef PopupOptions
* @memberof platform/commonUI/general
* @property {number} [offsetX] the horizontal distance, in pixels,
* to offset the element in whichever direction it is
* displayed. Defaults to 0.
* @property {number} [offsetY] the vertical distance, in pixels,
* to offset the element in whichever direction it is
* displayed. Defaults to 0.
* @property {number} [marginX] the horizontal position, in pixels,
* after which to prefer to display the element to the left.
* If negative, this is relative to the right edge of the
* page. Defaults to half the window's width.
* @property {number} [marginY] the vertical position, in pixels,
* after which to prefer to display the element upward.
* If negative, this is relative to the right edge of the
* page. Defaults to half the window's height.
* @property {string} [leftClass] class to apply when shifting to the left
* @property {string} [rightClass] class to apply when shifting to the right
* @property {string} [upClass] class to apply when shifting upward
* @property {string} [downClass] class to apply when shifting downward
*/
/**
* Display a popup at a particular location. The location chosen will
* be the corner of the element; the element will be positioned either
* to the left or the right of this point depending on available
* horizontal space, and will similarly be shifted upward or downward
* depending on available vertical space.
*
* @param element the jqLite-wrapped DOM element to pop up
* @param {number[]} position x,y position of the element, in
* pixel coordinates. Negative values are interpreted as
* relative to the right or bottom of the window.
* @param {PopupOptions} [options] additional options to control
* positioning of the popup
* @returns {platform/commonUI/general.Popup} the popup
*/
PopupService.prototype.display = function (element, position, options) {
var $document = this.$document,
$window = this.$window,
body = $document.find('body'),
winDim = [ $window.innerWidth, $window.innerHeight ],
styles = { position: 'absolute' },
margin,
offset,
bubble;
function adjustNegatives(value, index) {
return value < 0 ? (value + winDim[index]) : value;
}
// Defaults
options = options || {};
offset = [
options.offsetX !== undefined ? options.offsetX : 0,
options.offsetY !== undefined ? options.offsetY : 0
];
margin = [ options.marginX, options.marginY ].map(function (m, i) {
return m === undefined ? (winDim[i] / 2) : m;
}).map(adjustNegatives);
position = position.map(adjustNegatives);
if (position[0] > margin[0]) {
styles.right = (winDim[0] - position[0] + offset[0]) + 'px';
} else {
styles.left = (position[0] + offset[0]) + 'px';
}
if (position[1] > margin[1]) {
styles.bottom = (winDim[1] - position[1] + offset[1]) + 'px';
} else {
styles.top = (position[1] + offset[1]) + 'px';
}
// Add the menu to the body
body.append(element);
// Return a function to dismiss the bubble
return new Popup(element, styles);
};
return PopupService;
}
);

View File

@@ -29,15 +29,16 @@ define(
var JQLITE_METHODS = [ "on", "off", "find", "parent", "css", "append" ];
describe("The mct-popup directive", function () {
var testWindow,
mockDocument,
mockCompile,
var mockCompile,
mockPopupService,
mockPopup,
mockScope,
mockElement,
testAttrs,
mockBody,
mockTransclude,
mockParentEl,
mockNewElement,
testRect,
mctPopup;
@@ -50,12 +51,12 @@ define(
}
beforeEach(function () {
testWindow =
{ innerWidth: 600, innerHeight: 300 };
mockDocument =
jasmine.createSpyObj("$document", JQLITE_METHODS);
mockCompile =
jasmine.createSpy("$compile");
mockPopupService =
jasmine.createSpyObj("popupService", ["display"]);
mockPopup =
jasmine.createSpyObj("popup", ["dismiss"]);
mockScope =
jasmine.createSpyObj("$scope", [ "$eval", "$apply", "$on" ]);
mockElement =
@@ -66,6 +67,8 @@ define(
jasmine.createSpy("transclude");
mockParentEl =
jasmine.createSpyObj("parent", ["getBoundingClientRect"]);
mockNewElement =
jasmine.createSpyObj("newElement", JQLITE_METHODS);
testAttrs = {
mctClickElsewhere: "some Angular expression"
@@ -77,15 +80,17 @@ define(
height: 75
};
mockDocument.find.andReturn(mockBody);
mockCompile.andReturn(jasmine.createSpy());
mockCompile().andCallFake(function () {
return jasmine.createSpyObj("newElement", JQLITE_METHODS);
mockCompile.andCallFake(function () {
var mockFn = jasmine.createSpy();
mockFn.andReturn(mockNewElement);
return mockFn;
});
mockElement.parent.andReturn([mockParentEl]);
mockParentEl.getBoundingClientRect.andReturn(testRect);
mockPopupService.display.andReturn(mockPopup);
mctPopup = new MCTPopup(mockCompile, mockPopupService);
mctPopup = new MCTPopup(testWindow, mockDocument, mockCompile);
mctPopup.link(
mockScope,
mockElement,
@@ -99,6 +104,32 @@ define(
expect(mctPopup.restrict).toEqual("E");
});
describe("creates an element which", function () {
it("displays as a popup", function () {
expect(mockPopupService.display).toHaveBeenCalledWith(
mockNewElement,
[ testRect.left, testRect.top ]
);
});
it("displays transcluded content", function () {
var mockClone =
jasmine.createSpyObj('clone', JQLITE_METHODS);
mockTransclude.mostRecentCall.args[0](mockClone);
expect(mockNewElement.append)
.toHaveBeenCalledWith(mockClone);
});
it("is removed when its containing scope is destroyed", function () {
expect(mockPopup.dismiss).not.toHaveBeenCalled();
mockScope.$on.calls.forEach(function (call) {
if (call.args[0] === '$destroy') {
call.args[1]();
}
});
expect(mockPopup.dismiss).toHaveBeenCalled();
});
});
});
}

View File

@@ -0,0 +1,98 @@
/*****************************************************************************
* 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*/
define(
["../../src/services/PopupService"],
function (PopupService) {
'use strict';
describe("PopupService", function () {
var mockDocument,
testWindow,
mockBody,
mockElement,
popupService;
beforeEach(function () {
mockDocument = jasmine.createSpyObj('$document', [ 'find' ]);
testWindow = { innerWidth: 1000, innerHeight: 800 };
mockBody = jasmine.createSpyObj('body', [ 'append' ]);
mockElement = jasmine.createSpyObj('element', [
'css',
'remove'
]);
mockDocument.find.andCallFake(function (query) {
return query === 'body' && mockBody;
});
popupService = new PopupService(mockDocument, testWindow);
});
it("adds elements to the body of the document", function () {
popupService.display(mockElement, [ 0, 0 ]);
expect(mockBody.append).toHaveBeenCalledWith(mockElement);
});
describe("when positioned in appropriate quadrants", function () {
it("orients elements relative to the top-left", function () {
popupService.display(mockElement, [ 25, 50 ]);
expect(mockElement.css).toHaveBeenCalledWith({
position: 'absolute',
left: '25px',
top: '50px'
});
});
it("orients elements relative to the top-right", function () {
popupService.display(mockElement, [ 800, 50 ]);
expect(mockElement.css).toHaveBeenCalledWith({
position: 'absolute',
right: '200px',
top: '50px'
});
});
it("orients elements relative to the bottom-right", function () {
popupService.display(mockElement, [ 800, 650 ]);
expect(mockElement.css).toHaveBeenCalledWith({
position: 'absolute',
right: '200px',
bottom: '150px'
});
});
it("orients elements relative to the bottom-left", function () {
popupService.display(mockElement, [ 120, 650 ]);
expect(mockElement.css).toHaveBeenCalledWith({
position: 'absolute',
left: '120px',
bottom: '150px'
});
});
});
});
}
);

View File

@@ -0,0 +1,74 @@
/*****************************************************************************
* 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*/
define(
["../../src/services/Popup"],
function (Popup) {
'use strict';
describe("Popup", function () {
var mockElement,
testStyles,
popup;
beforeEach(function () {
mockElement =
jasmine.createSpyObj('element', [ 'css', 'remove' ]);
testStyles = { left: '12px', top: '14px' };
popup = new Popup(mockElement, testStyles);
});
it("applies CSS styles when instantiated", function () {
expect(mockElement.css)
.toHaveBeenCalledWith(testStyles);
});
it("reports the orientation of the popup", function () {
var otherStyles = {
right: '12px',
bottom: '14px'
},
otherPopup = new Popup(mockElement, otherStyles);
expect(popup.goesLeft()).toBeFalsy();
expect(popup.goesRight()).toBeTruthy();
expect(popup.goesUp()).toBeFalsy();
expect(popup.goesDown()).toBeTruthy();
expect(otherPopup.goesLeft()).toBeTruthy();
expect(otherPopup.goesRight()).toBeFalsy();
expect(otherPopup.goesUp()).toBeTruthy();
expect(otherPopup.goesDown()).toBeFalsy();
});
it("removes elements when dismissed", function () {
expect(mockElement.remove).not.toHaveBeenCalled();
popup.dismiss();
expect(mockElement.remove).toHaveBeenCalled();
});
});
}
);

View File

@@ -17,6 +17,8 @@
"directives/MCTPopup",
"directives/MCTResize",
"directives/MCTScroll",
"services/Popup",
"services/PopupService",
"services/UrlService",
"StyleSheetLoader"
]

View File

@@ -45,13 +45,12 @@
"implementation": "services/InfoService.js",
"depends": [
"$compile",
"$document",
"$window",
"$rootScope",
"popupService",
"agentService"
]
}
],
],
"constants": [
{
"key": "INFO_HOVER_DELAY",
@@ -66,4 +65,4 @@
}
]
}
}
}

View File

@@ -31,13 +31,19 @@ define({
BUBBLE_TEMPLATE: "<mct-container key=\"bubble\" " +
"bubble-title=\"{{bubbleTitle}}\" " +
"bubble-layout=\"{{bubbleLayout}}\" " +
"class=\"bubble-container\">" +
"<mct-include key=\"bubbleTemplate\" ng-model=\"bubbleModel\">" +
"class=\"bubble-container\">" +
"<mct-include key=\"bubbleTemplate\" " +
"ng-model=\"bubbleModel\">" +
"</mct-include>" +
"</mct-container>",
// Pixel offset for bubble, to align arrow position
BUBBLE_OFFSET: [ 0, -26 ],
// Max width and margins allowed for bubbles; defined in /platform/commonUI/general/res/sass/_constants.scss
BUBBLE_MARGIN_LR: 10,
BUBBLE_MAX_WIDTH: 300
// Options and classes for bubble
BUBBLE_OPTIONS: {
offsetX: 0,
offsetY: -26
},
BUBBLE_MOBILE_POSITION: [ 0, -25 ],
// Max width and margins allowed for bubbles;
// defined in /platform/commonUI/general/res/sass/_constants.scss
BUBBLE_MARGIN_LR: 10,
BUBBLE_MAX_WIDTH: 300
});

View File

@@ -27,18 +27,18 @@ define(
"use strict";
var BUBBLE_TEMPLATE = InfoConstants.BUBBLE_TEMPLATE,
OFFSET = InfoConstants.BUBBLE_OFFSET;
MOBILE_POSITION = InfoConstants.BUBBLE_MOBILE_POSITION,
OPTIONS = InfoConstants.BUBBLE_OPTIONS;
/**
* Displays informative content ("info bubbles") for the user.
* @memberof platform/commonUI/inspect
* @constructor
*/
function InfoService($compile, $document, $window, $rootScope, agentService) {
function InfoService($compile, $rootScope, popupService, agentService) {
this.$compile = $compile;
this.$document = $document;
this.$window = $window;
this.$rootScope = $rootScope;
this.popupService = popupService;
this.agentService = agentService;
}
@@ -55,53 +55,47 @@ define(
*/
InfoService.prototype.display = function (templateKey, title, content, position) {
var $compile = this.$compile,
$document = this.$document,
$window = this.$window,
$rootScope = this.$rootScope,
body = $document.find('body'),
scope = $rootScope.$new(),
winDim = [$window.innerWidth, $window.innerHeight],
bubbleSpaceLR = InfoConstants.BUBBLE_MARGIN_LR + InfoConstants.BUBBLE_MAX_WIDTH,
goLeft = position[0] > (winDim[0] - bubbleSpaceLR),
goUp = position[1] > (winDim[1] / 2),
span = $compile('<span></span>')(scope),
bubbleSpaceLR = InfoConstants.BUBBLE_MARGIN_LR +
InfoConstants.BUBBLE_MAX_WIDTH,
options,
popup,
bubble;
options = Object.create(OPTIONS);
options.marginX = -bubbleSpaceLR;
// On a phone, bubble takes up more screen real estate,
// so position it differently (toward the bottom)
if (this.agentService.isPhone(navigator.userAgent)) {
position = MOBILE_POSITION;
options = {};
}
popup = this.popupService.display(span, position, options);
// Pass model & container parameters into the scope
scope.bubbleModel = content;
scope.bubbleTemplate = templateKey;
scope.bubbleLayout = (goUp ? 'arw-btm' : 'arw-top') + ' ' +
(goLeft ? 'arw-right' : 'arw-left');
scope.bubbleTitle = title;
// Style the bubble according to how it was positioned
scope.bubbleLayout = [
popup.goesUp() ? 'arw-btm' : 'arw-top',
popup.goesLeft() ? 'arw-right' : 'arw-left'
].join(' ');
scope.bubbleLayout = 'arw-top arw-left';
// Create the context menu
// Create the info bubble, now that we know how to
// point the arrow...
bubble = $compile(BUBBLE_TEMPLATE)(scope);
span.append(bubble);
// Position the bubble
bubble.css('position', 'absolute');
if (this.agentService.isPhone(navigator.userAgent)) {
bubble.css('right', '0px');
bubble.css('left', '0px');
bubble.css('top', 'auto');
bubble.css('bottom', '25px');
} else {
if (goLeft) {
bubble.css('right', (winDim[0] - position[0] + OFFSET[0]) + 'px');
} else {
bubble.css('left', position[0] + OFFSET[0] + 'px');
}
if (goUp) {
bubble.css('bottom', (winDim[1] - position[1] + OFFSET[1]) + 'px');
} else {
bubble.css('top', position[1] + OFFSET[1] + 'px');
}
}
// Add the menu to the body
body.append(bubble);
// Return a function to dismiss the bubble
return function () {
bubble.remove();
// Return a function to dismiss the info bubble
return function dismiss() {
popup.dismiss();
scope.$destroy();
};
};

View File

@@ -28,117 +28,85 @@ define(
describe("The info service", function () {
var mockCompile,
mockDocument,
testWindow,
mockRootScope,
mockPopupService,
mockAgentService,
mockCompiledTemplate,
testScope,
mockBody,
mockElement,
mockScope,
mockElements,
mockPopup,
service;
beforeEach(function () {
mockCompile = jasmine.createSpy('$compile');
mockDocument = jasmine.createSpyObj('$document', ['find']);
testWindow = { innerWidth: 1000, innerHeight: 100 };
mockRootScope = jasmine.createSpyObj('$rootScope', ['$new']);
mockAgentService = jasmine.createSpyObj('agentService', ['isMobile', 'isPhone']);
mockCompiledTemplate = jasmine.createSpy('template');
testScope = {};
mockBody = jasmine.createSpyObj('body', ['append']);
mockElement = jasmine.createSpyObj('element', ['css', 'remove']);
mockPopupService = jasmine.createSpyObj(
'popupService',
['display']
);
mockPopup = jasmine.createSpyObj('popup', [
'dismiss',
'goesLeft',
'goesRight',
'goesUp',
'goesDown'
]);
mockDocument.find.andCallFake(function (tag) {
return tag === 'body' ? mockBody : undefined;
mockScope = jasmine.createSpyObj("scope", ["$destroy"]);
mockElements = [];
mockPopupService.display.andReturn(mockPopup);
mockCompile.andCallFake(function () {
var mockCompiledTemplate = jasmine.createSpy('template'),
mockElement = jasmine.createSpyObj('element', [
'css',
'remove',
'append'
]);
mockCompiledTemplate.andReturn(mockElement);
mockElements.push(mockElement);
return mockCompiledTemplate;
});
mockCompile.andReturn(mockCompiledTemplate);
mockCompiledTemplate.andReturn(mockElement);
mockRootScope.$new.andReturn(testScope);
mockRootScope.$new.andReturn(mockScope);
service = new InfoService(
mockCompile,
mockDocument,
testWindow,
mockRootScope,
mockPopupService,
mockAgentService
);
});
it("creates elements and appends them to the body to display", function () {
service.display('', '', {}, [0, 0]);
expect(mockBody.append).toHaveBeenCalledWith(mockElement);
it("creates elements and displays them as popups", function () {
service.display('', '', {}, [123, 456]);
expect(mockPopupService.display).toHaveBeenCalledWith(
mockElements[0],
[ 123, 456 ],
jasmine.any(Object)
);
});
it("provides a function to remove displayed info bubbles", function () {
var fn = service.display('', '', {}, [0, 0]);
expect(mockElement.remove).not.toHaveBeenCalled();
expect(mockPopup.dismiss).not.toHaveBeenCalled();
fn();
expect(mockElement.remove).toHaveBeenCalled();
expect(mockPopup.dismiss).toHaveBeenCalled();
});
describe("depending on mouse position", function () {
// Positioning should vary based on quadrant in window,
// which is 1000 x 100 in this test case.
it("displays from the top-left in the top-left quadrant", function () {
service.display('', '', {}, [250, 25]);
expect(mockElement.css).toHaveBeenCalledWith(
'left',
(250 + InfoConstants.BUBBLE_OFFSET[0]) + 'px'
);
expect(mockElement.css).toHaveBeenCalledWith(
'top',
(25 + InfoConstants.BUBBLE_OFFSET[1]) + 'px'
);
});
it("displays from the top-right in the top-right quadrant", function () {
service.display('', '', {}, [700, 25]);
expect(mockElement.css).toHaveBeenCalledWith(
'right',
(300 + InfoConstants.BUBBLE_OFFSET[0]) + 'px'
);
expect(mockElement.css).toHaveBeenCalledWith(
'top',
(25 + InfoConstants.BUBBLE_OFFSET[1]) + 'px'
);
});
it("displays from the bottom-left in the bottom-left quadrant", function () {
service.display('', '', {}, [250, 70]);
expect(mockElement.css).toHaveBeenCalledWith(
'left',
(250 + InfoConstants.BUBBLE_OFFSET[0]) + 'px'
);
expect(mockElement.css).toHaveBeenCalledWith(
'bottom',
(30 + InfoConstants.BUBBLE_OFFSET[1]) + 'px'
);
});
it("displays from the bottom-right in the bottom-right quadrant", function () {
service.display('', '', {}, [800, 60]);
expect(mockElement.css).toHaveBeenCalledWith(
'right',
(200 + InfoConstants.BUBBLE_OFFSET[0]) + 'px'
);
expect(mockElement.css).toHaveBeenCalledWith(
'bottom',
(40 + InfoConstants.BUBBLE_OFFSET[1]) + 'px'
);
});
it("when on phone device, positioning is always on bottom", function () {
mockAgentService.isPhone.andReturn(true);
service = new InfoService(
mockCompile,
mockDocument,
testWindow,
mockRootScope,
mockAgentService
);
service.display('', '', {}, [0, 0]);
});
it("when on phone device, positions at bottom", function () {
mockAgentService.isPhone.andReturn(true);
service = new InfoService(
mockCompile,
mockRootScope,
mockPopupService,
mockAgentService
);
service.display('', '', {}, [123, 456]);
expect(mockPopupService.display).toHaveBeenCalledWith(
mockElements[0],
[ 0, -25 ],
jasmine.any(Object)
);
});
});