Merge branch 'open1515' into open115

This commit is contained in:
Victor Woeltjen
2015-09-23 16:05:09 -07:00
42 changed files with 2477 additions and 177 deletions

View File

@ -45,6 +45,16 @@
}
],
"controllers": [
{
"key": "TimeRangeController",
"implementation": "controllers/TimeRangeController.js",
"depends": [ "$scope", "now" ]
},
{
"key": "DateTimePickerController",
"implementation": "controllers/DateTimePickerController.js",
"depends": [ "$scope", "now" ]
},
{
"key": "TreeNodeController",
"implementation": "controllers/TreeNodeController.js",
@ -105,11 +115,21 @@
"implementation": "directives/MCTDrag.js",
"depends": [ "$document" ]
},
{
"key": "mctClickElsewhere",
"implementation": "directives/MCTClickElsewhere.js",
"depends": [ "$document" ]
},
{
"key": "mctResize",
"implementation": "directives/MCTResize.js",
"depends": [ "$timeout" ]
},
{
"key": "mctPopup",
"implementation": "directives/MCTPopup.js",
"depends": [ "$window", "$document", "$compile", "$interval" ]
},
{
"key": "mctScrollX",
"implementation": "directives/MCTScroll.js",
@ -213,6 +233,10 @@
{
"key": "selector",
"templateUrl": "templates/controls/selector.html"
},
{
"key": "datetime-picker",
"templateUrl": "templates/controls/datetime-picker.html"
}
],
"licenses": [

View File

@ -0,0 +1,61 @@
<!--
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.
-->
<div ng-controller="DateTimePickerController">
<div style="vertical-align: top; display: inline-block">
<div style="text-align: center;">
<a ng-click="changeMonth(-1)">&lt;</a>
{{month}} {{year}}
<a ng-click="changeMonth(1)">&gt;</a>
</div>
<div>
<table>
<tr>
<th ng-repeat="day in ['Su','Mo','Tu','We','Th','Fr','Sa']">
{{day}}
</th>
</tr>
<tr ng-repeat="row in table">
<td style="text-align: center;"
ng-repeat="cell in row"
ng-click="select(cell)"
ng-class='{
disabled: !isSelectable(cell),
test: isSelected(cell)
}'>
<div>{{cell.day}}</div>
<div style="font-size: 80%">{{cell.dayOfYear}}</div>
</td>
</tr>
</table>
</div>
</div>
<div style="vertical-align: top; display: inline-block"
ng-repeat="key in ['hours', 'minutes', 'seconds']"
ng-if="options[key]">
<div>{{nameFor(key)}}</div>
<select size="10"
ng-model="time[key]"
ng-options="i for i in optionsFor(key)">
</select>
</div>
</div>

View File

@ -1,69 +1,96 @@
<!--
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.
NOTES
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.
Ticks:
The thinking is to divide whatever the current time span is by 5,
and assign values accordingly to 5 statically-positioned ticks. So the tick x-position is a static percentage
of the total width available, and the labels change dynamically. This is consistent
with our current approach to the time axis of plots.
I'm keeping the number of ticks low so that when the view portal gets narrow,
the tick labels won't collide with each other. For extra credit, add/remove ticks as the user resizes the view area.
Note: this eval needs to be based on the whatever is containing the
time-controller component, not the whole browser window.
Range indicator and slider knobs:
The left and right properties used in .slider .range-holder and the .knobs are
CSS offsets from the left and right of their respective containers. You
may want or need to calculate those positions as pure offsets from the start datetime
(or left, as it were) and set them as left properties. No problem if so, but
we'll need to tweak the CSS tiny bit to get the center of the knobs to line up
properly on the range left and right bounds.
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.
-->
<div ng-init="
notes = 'Temporarily using an array to populate ticks so I can see what I\'m doing';
ticks = [
'00:00',
'00:30',
'01:00',
'01:30',
'02:00'
];
"></div>
<div class="l-time-controller" ng-controller="TimeRangeController">
<div class="l-time-range-inputs-holder">
Start: {{startOuterText}}
<span ng-controller="ToggleController as t">
<a class="ui-symbol" ng-click="t.toggle()">p</a>
<mct-popup ng-if="t.isActive()">
<div style="background: #222;"
mct-click-elsewhere="t.setState(false)">
<mct-control key="'datetime-picker'"
ng-model="ngModel.outer"
field="'start'"
options="{ hours: true }">
</mct-control>
</div>
</mct-popup>
</span>
<div class="l-time-controller">
<div class="l-time-range-inputs-holder">
Start: <input type="date" />
End: <input type="date" />
</div>
End: {{endOuterText}}
<span ng-controller="ToggleController as t2">
<a class="ui-symbol" ng-click="t2.toggle()">p</a>
<mct-popup ng-if="t2.isActive()">
<div style="background: #222;"
mct-click-elsewhere="t2.setState(false)">
<mct-control key="'datetime-picker'"
ng-model="ngModel.outer"
field="'end'"
options="{ hours: true }">
</mct-control>
</div>
</mct-popup>
</span>
<div class="l-time-range-slider-holder">
<div class="l-time-range-slider">
<div class="slider">
<div class="slot range-holder">
<div class="range" style="left: 0%; right: 30%;"></div>
</div>
<div class="knob knob-l" style="left: 0%;">
<div class="range-value">05/22 14:46</div>
</div>
<div class="knob knob-r" style="right: 30%;">
<div class="range-value">07/22 01:21</div>
</div>
</div>
</div>
</div>
<div class="l-time-range-ticks-holder">
<div class="l-time-range-ticks">
<div
ng-repeat="tick in ticks"
ng-style="{ left: $index * 25 + '%' }"
class="tick tick-x"
>
<span class="l-time-range-tick-label">{{tick}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="l-time-range-slider-holder">
<div class="l-time-range-slider">
<div class="slider"
mct-resize="spanWidth = bounds.width">
<div class="slot range-holder">
<div class="range"
mct-drag-down="startMiddleDrag()"
mct-drag="middleDrag(delta[0])"
ng-style="{ left: startInnerPct, right: endInnerPct}">
</div>
</div>
<div class="knob knob-l"
mct-drag-down="startLeftDrag()"
mct-drag="leftDrag(delta[0])"
ng-style="{ left: startInnerPct }">
<div class="range-value">{{startInnerText}}</div>
</div>
<div class="knob knob-r"
mct-drag-down="startRightDrag()"
mct-drag="rightDrag(delta[0])"
ng-style="{ right: endInnerPct }">
<div class="range-value">{{endInnerText}}</div>
</div>
</div>
</div>
</div>
<div class="l-time-range-ticks-holder">
<div class="l-time-range-ticks">
<div
ng-repeat="tick in ticks"
ng-style="{ left: $index * (100 / (ticks.length - 1)) + '%' }"
class="tick tick-x"
>
<span class="l-time-range-tick-label">{{tick}}</span>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,202 @@
/*****************************************************************************
* 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*/
define(
[ 'moment' ],
function (moment) {
'use strict';
var TIME_NAMES = {
'hours': "Hour",
'minutes': "Minute",
'seconds': "Second"
},
MONTHS = moment.months(),
TIME_OPTIONS = (function makeRanges() {
var arr = [];
while (arr.length < 60) {
arr.push(arr.length);
}
return {
hours: arr.slice(0, 24),
minutes: arr,
seconds: arr
};
}());
/**
* Controller to support the date-time picker.
*
* Adds/uses the following properties in scope:
* * `year`: Year being displayed in picker
* * `month`: Month being displayed
* * `table`: Table being displayed; array of arrays of
* * `day`: Day of month
* * `dayOfYear`: Day of year
* * `month`: Month associated with the day
* * `year`: Year associated with the day.
* * `date`: Date chosen
* * `year`: Year selected
* * `month`: Month selected (0-indexed)
* * `day`: Day of month selected
* * `time`: Chosen time (hours/minutes/seconds)
* * `hours`: Hours chosen
* * `minutes`: Minutes chosen
* * `seconds`: Seconds chosen
*
* Months are zero-indexed, day-of-months are one-indexed.
*/
function DateTimePickerController($scope, now) {
var year,
month, // For picker state, not model state
interacted = false;
function generateTable() {
var m = moment.utc({ year: year, month: month }).day(0),
table = [],
row,
col;
for (row = 0; row < 6; row += 1) {
table.push([]);
for (col = 0; col < 7; col += 1) {
table[row].push({
year: m.year(),
month: m.month(),
day: m.date(),
dayOfYear: m.dayOfYear()
});
m.add(1, 'days'); // Next day!
}
}
return table;
}
function updateScopeForMonth() {
$scope.month = MONTHS[month];
$scope.year = year;
$scope.table = generateTable();
}
function updateFromModel(ngModel) {
var m;
m = moment.utc(ngModel);
$scope.date = {
year: m.year(),
month: m.month(),
day: m.date()
};
$scope.time = {
hours: m.hour(),
minutes: m.minute(),
seconds: m.second()
};
//window.alert($scope.date.day + " " + ngModel);
// Zoom to that date in the picker, but
// only if the user hasn't interacted with it yet.
if (!interacted) {
year = m.year();
month = m.month();
updateScopeForMonth();
}
}
function updateFromView() {
var m = moment.utc({
year: $scope.date.year,
month: $scope.date.month,
day: $scope.date.day,
hour: $scope.time.hours,
minute: $scope.time.minutes,
second: $scope.time.seconds
});
$scope.ngModel[$scope.field] = m.valueOf();
}
$scope.isSelectable = function (cell) {
return cell.month === month;
};
$scope.isSelected = function (cell) {
var date = $scope.date || {};
return cell.day === date.day &&
cell.month === date.month &&
cell.year === date.year;
};
$scope.select = function (cell) {
$scope.date = $scope.date || {};
$scope.date.month = cell.month;
$scope.date.year = cell.year;
$scope.date.day = cell.day;
updateFromView();
};
$scope.dateEquals = function (d1, d2) {
return d1.year === d2.year &&
d1.month === d2.month &&
d1.day === d2.day;
};
$scope.changeMonth = function (delta) {
month += delta;
if (month > 11) {
month = 0;
year += 1;
}
if (month < 0) {
month = 11;
year -= 1;
}
interacted = true;
updateScopeForMonth();
};
$scope.nameFor = function (key) {
return TIME_NAMES[key];
};
$scope.optionsFor = function (key) {
return TIME_OPTIONS[key];
};
updateScopeForMonth();
// Ensure some useful default
$scope.ngModel[$scope.field] =
$scope.ngModel[$scope.field] === undefined ?
now() : $scope.ngModel[$scope.field];
$scope.$watch('ngModel[field]', updateFromModel);
$scope.$watchCollection('date', updateFromView);
$scope.$watchCollection('time', updateFromView);
}
return DateTimePickerController;
}
);

View File

@ -0,0 +1,224 @@
/*****************************************************************************
* 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*/
define(
['moment'],
function (moment) {
"use strict";
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss";
/**
* @memberof platform/commonUI/general
* @constructor
*/
function TimeConductorController($scope, now) {
var tickCount = 2,
initialDragValue;
function formatTimestamp(ts) {
return moment.utc(ts).format(DATE_FORMAT);
}
// From 0.0-1.0 to "0%"-"1%"
function toPercent(p) {
return (100 * p) + "%";
}
function updateTicks() {
var i, p, ts, start, end, span;
end = $scope.ngModel.outer.end;
start = $scope.ngModel.outer.start;
span = end - start;
$scope.ticks = [];
for (i = 0; i < tickCount; i += 1) {
p = i / (tickCount - 1);
ts = p * span + start;
$scope.ticks.push(formatTimestamp(ts));
}
}
function updateSpanWidth(w) {
// Space about 100px apart
tickCount = Math.max(Math.floor(w / 100), 2);
updateTicks();
}
function updateViewForInnerSpanFromModel(ngModel) {
var span = ngModel.outer.end - ngModel.outer.start;
// Expose readable dates for the knobs
$scope.startInnerText = formatTimestamp(ngModel.inner.start);
$scope.endInnerText = formatTimestamp(ngModel.inner.end);
// And positions for the knobs
$scope.startInnerPct =
toPercent((ngModel.inner.start - ngModel.outer.start) / span);
$scope.endInnerPct =
toPercent((ngModel.outer.end - ngModel.inner.end) / span);
}
function defaultBounds() {
var t = now();
return {
start: t - 24 * 3600 * 1000, // One day
end: t
};
}
function copyBounds(bounds) {
return { start: bounds.start, end: bounds.end };
}
function updateViewFromModel(ngModel) {
var t = now();
ngModel = ngModel || {};
ngModel.outer = ngModel.outer || defaultBounds();
ngModel.inner = ngModel.inner || copyBounds(ngModel.outer);
// First, dates for the date pickers for outer bounds
$scope.startOuterDate = new Date(ngModel.outer.start);
$scope.endOuterDate = new Date(ngModel.outer.end);
// Then various updates for the inner span
updateViewForInnerSpanFromModel(ngModel);
// Stick it back is scope (in case we just set defaults)
$scope.ngModel = ngModel;
updateTicks();
}
function startLeftDrag() {
initialDragValue = $scope.ngModel.inner.start;
}
function startRightDrag() {
initialDragValue = $scope.ngModel.inner.end;
}
function startMiddleDrag() {
initialDragValue = {
start: $scope.ngModel.inner.start,
end: $scope.ngModel.inner.end
};
}
function toMillis(pixels) {
var span = $scope.ngModel.outer.end - $scope.ngModel.outer.start;
return (pixels / $scope.spanWidth) * span;
}
function clamp(value, low, high) {
return Math.max(low, Math.min(high, value));
}
function leftDrag(pixels) {
var delta = toMillis(pixels);
$scope.ngModel.inner.start = clamp(
initialDragValue + delta,
$scope.ngModel.outer.start,
$scope.ngModel.inner.end
);
updateViewFromModel($scope.ngModel);
}
function rightDrag(pixels) {
var delta = toMillis(pixels);
$scope.ngModel.inner.end = clamp(
initialDragValue + delta,
$scope.ngModel.inner.start,
$scope.ngModel.outer.end
);
updateViewFromModel($scope.ngModel);
}
function middleDrag(pixels) {
var delta = toMillis(pixels),
edge = delta < 0 ? 'start' : 'end',
opposite = delta < 0 ? 'end' : 'start';
// Adjust the position of the edge in the direction of drag
$scope.ngModel.inner[edge] = clamp(
initialDragValue[edge] + delta,
$scope.ngModel.outer.start,
$scope.ngModel.outer.end
);
// Adjust opposite knob to maintain span
$scope.ngModel.inner[opposite] = $scope.ngModel.inner[edge] +
initialDragValue[opposite] - initialDragValue[edge];
updateViewFromModel($scope.ngModel);
}
function updateOuterStart(t) {
var ngModel = $scope.ngModel;
ngModel.outer.end =
Math.max(ngModel.outer.start, ngModel.outer.end);
ngModel.inner.start =
Math.max(ngModel.outer.start, ngModel.inner.start);
ngModel.inner.end =
Math.max(ngModel.outer.start, ngModel.inner.end);
$scope.startOuterText = formatTimestamp(t);
updateViewForInnerSpanFromModel(ngModel);
}
function updateOuterEnd(t) {
var ngModel = $scope.ngModel;
ngModel.outer.start =
Math.min(ngModel.outer.end, ngModel.outer.start);
ngModel.inner.start =
Math.min(ngModel.outer.end, ngModel.inner.start);
ngModel.inner.end =
Math.min(ngModel.outer.end, ngModel.inner.end);
$scope.endOuterText = formatTimestamp(t);
updateViewForInnerSpanFromModel(ngModel);
}
$scope.startLeftDrag = startLeftDrag;
$scope.startRightDrag = startRightDrag;
$scope.startMiddleDrag = startMiddleDrag;
$scope.leftDrag = leftDrag;
$scope.rightDrag = rightDrag;
$scope.middleDrag = middleDrag;
$scope.state = false;
$scope.ticks = [];
// Initialize scope to defaults
updateViewFromModel($scope.ngModel);
$scope.$watchCollection("ngModel", updateViewFromModel);
$scope.$watch("spanWidth", updateSpanWidth);
$scope.$watch("ngModel.outer.start", updateOuterStart);
$scope.$watch("ngModel.outer.end", updateOuterEnd);
}
return TimeConductorController;
}
);

View File

@ -0,0 +1,77 @@
/*****************************************************************************
* 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";
/**
* The `mct-click-elsewhere` directive will evaluate its
* associated expression whenever a `mousedown` occurs anywhere
* outside of the element that has the `mct-click-elsewhere`
* directive attached. This is useful for dismissing popups
* and the like.
*/
function MCTClickElsewhere($document) {
// Link; install event handlers.
function link(scope, element, attrs) {
// Keep a reference to the body, to attach/detach
// mouse event handlers; mousedown and mouseup cannot
// only be attached to the element being linked, as the
// mouse may leave this element during the drag.
var body = $document.find('body');
function clickBody(event) {
var x = event.clientX,
y = event.clientY,
rect = element[0].getBoundingClientRect(),
xMin = rect.left,
xMax = xMin + rect.width,
yMin = rect.top,
yMax = yMin + rect.height;
if (x < xMin || x > xMax || y < yMin || y > yMax) {
scope.$eval(attrs.mctClickElsewhere);
}
}
body.on("mousedown", clickBody);
scope.$on("$destroy", function () {
body.off("mousedown", clickBody);
});
}
return {
// mct-drag only makes sense as an attribute
restrict: "A",
// Link function, to install event handlers
link: link
};
}
return MCTClickElsewhere;
}
);

View File

@ -0,0 +1,70 @@
/*****************************************************************************
* 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';
var TEMPLATE = "<div></div>";
function MCTPopup($window, $document, $compile) {
function link(scope, element, attrs, ctrl, transclude) {
var body = $document.find('body'),
popup = $compile(TEMPLATE)(scope),
winDim = [$window.innerWidth, $window.innerHeight],
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);
transclude(function (clone) {
popup.append(clone);
});
scope.$on('$destroy', function () {
popup.remove();
});
}
return {
restrict: "E",
transclude: true,
link: link,
scope: {}
};
}
return MCTPopup;
}
);

View File

@ -0,0 +1,63 @@
/*****************************************************************************
* 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/controllers/DateTimePickerController"],
function (DateTimePickerController) {
"use strict";
describe("The DateTimePickerController", function () {
var mockScope,
mockNow,
controller;
function fireWatch(expr, value) {
mockScope.$watch.calls.forEach(function (call) {
if (call.args[0] === expr) {
call.args[1](value);
}
});
}
beforeEach(function () {
mockScope = jasmine.createSpyObj(
"$scope",
[ "$apply", "$watch", "$watchCollection" ]
);
mockScope.ngModel = {};
mockScope.field = "testField";
mockNow = jasmine.createSpy('now');
controller = new DateTimePickerController(mockScope, mockNow);
});
it("watches the model that was passed in", function () {
expect(mockScope.$watch).toHaveBeenCalledWith(
"ngModel[field]",
jasmine.any(Function)
);
});
});
}
);

View File

@ -0,0 +1,67 @@
/*****************************************************************************
* 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/controllers/TimeRangeController"],
function (TimeRangeController) {
"use strict";
describe("The TimeRangeController", function () {
var mockScope,
mockNow,
controller;
function fireWatch(expr, value) {
mockScope.$watch.calls.forEach(function (call) {
if (call.args[0] === expr) {
call.args[1](value);
}
});
}
function fireWatchCollection(expr, value) {
mockScope.$watchCollection.calls.forEach(function (call) {
if (call.args[0] === expr) {
call.args[1](value);
}
});
}
beforeEach(function () {
mockScope = jasmine.createSpyObj(
"$scope",
[ "$apply", "$watch", "$watchCollection" ]
);
mockNow = jasmine.createSpy('now');
controller = new TimeRangeController(mockScope, mockNow);
});
it("watches the model that was passed in", function () {
expect(mockScope.$watchCollection)
.toHaveBeenCalledWith("ngModel", jasmine.any(Function));
});
});
}
);

View File

@ -0,0 +1,84 @@
/*****************************************************************************
* 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,describe,it,expect,beforeEach,jasmine*/
define(
["../../src/directives/MCTClickElsewhere"],
function (MCTClickElsewhere) {
"use strict";
var JQLITE_METHODS = [ "on", "off", "find", "parent" ];
describe("The mct-click-elsewhere directive", function () {
var mockDocument,
mockScope,
mockElement,
testAttrs,
mockBody,
mockParentEl,
testRect,
mctClickElsewhere;
function testEvent(x, y) {
return {
pageX: x,
pageY: y,
preventDefault: jasmine.createSpy("preventDefault")
};
}
beforeEach(function () {
mockDocument =
jasmine.createSpyObj("$document", JQLITE_METHODS);
mockScope =
jasmine.createSpyObj("$scope", [ "$eval", "$apply", "$on" ]);
mockElement =
jasmine.createSpyObj("element", JQLITE_METHODS);
mockBody =
jasmine.createSpyObj("body", JQLITE_METHODS);
mockParentEl =
jasmine.createSpyObj("parent", ["getBoundingClientRect"]);
testAttrs = {
mctClickElsewhere: "some Angular expression"
};
testRect = {
left: 20,
top: 42,
width: 60,
height: 75
};
mockDocument.find.andReturn(mockBody);
mctClickElsewhere = new MCTClickElsewhere(mockDocument);
mctClickElsewhere.link(mockScope, mockElement, testAttrs);
});
it("is valid as an attribute", function () {
expect(mctClickElsewhere.restrict).toEqual("A");
});
});
}
);

View File

@ -0,0 +1,105 @@
/*****************************************************************************
* 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,describe,it,expect,beforeEach,jasmine*/
define(
["../../src/directives/MCTPopup"],
function (MCTPopup) {
"use strict";
var JQLITE_METHODS = [ "on", "off", "find", "parent", "css", "append" ];
describe("The mct-popup directive", function () {
var testWindow,
mockDocument,
mockCompile,
mockScope,
mockElement,
testAttrs,
mockBody,
mockTransclude,
mockParentEl,
testRect,
mctPopup;
function testEvent(x, y) {
return {
pageX: x,
pageY: y,
preventDefault: jasmine.createSpy("preventDefault")
};
}
beforeEach(function () {
testWindow =
{ innerWidth: 600, innerHeight: 300 };
mockDocument =
jasmine.createSpyObj("$document", JQLITE_METHODS);
mockCompile =
jasmine.createSpy("$compile");
mockScope =
jasmine.createSpyObj("$scope", [ "$eval", "$apply", "$on" ]);
mockElement =
jasmine.createSpyObj("element", JQLITE_METHODS);
mockBody =
jasmine.createSpyObj("body", JQLITE_METHODS);
mockTransclude =
jasmine.createSpy("transclude");
mockParentEl =
jasmine.createSpyObj("parent", ["getBoundingClientRect"]);
testAttrs = {
mctClickElsewhere: "some Angular expression"
};
testRect = {
left: 20,
top: 42,
width: 60,
height: 75
};
mockDocument.find.andReturn(mockBody);
mockCompile.andReturn(jasmine.createSpy());
mockCompile().andCallFake(function () {
return jasmine.createSpyObj("newElement", JQLITE_METHODS);
});
mockElement.parent.andReturn([mockParentEl]);
mockParentEl.getBoundingClientRect.andReturn(testRect);
mctPopup = new MCTPopup(testWindow, mockDocument, mockCompile);
mctPopup.link(
mockScope,
mockElement,
testAttrs,
null,
mockTransclude
);
});
it("is valid as an element", function () {
expect(mctPopup.restrict).toEqual("E");
});
});
}
);

View File

@ -3,14 +3,18 @@
"controllers/BottomBarController",
"controllers/ClickAwayController",
"controllers/ContextMenuController",
"controllers/DateTimePickerController",
"controllers/GetterSetterController",
"controllers/SelectorController",
"controllers/SplitPaneController",
"controllers/TimeRangeController",
"controllers/ToggleController",
"controllers/TreeNodeController",
"controllers/ViewSwitcherController",
"directives/MCTClickElsewhere",
"directives/MCTContainer",
"directives/MCTDrag",
"directives/MCTPopup",
"directives/MCTResize",
"directives/MCTScroll",
"services/UrlService",