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

Resolve conflicts to complete merge of #477

Conflicts:
	platform/commonUI/general/bundle.json
	platform/commonUI/themes/espresso/res/css/theme-espresso.css
	platform/commonUI/themes/snow/res/css/theme-snow.css
This commit is contained in:
Victor Woeltjen
2016-01-27 12:53:46 -08:00
225 changed files with 10800 additions and 5816 deletions

View File

@@ -0,0 +1,492 @@
/*****************************************************************************
* 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([
"./src/services/UrlService",
"./src/services/PopupService",
"./src/StyleSheetLoader",
"./src/UnsupportedBrowserWarning",
"./src/controllers/TimeRangeController",
"./src/controllers/DateTimePickerController",
"./src/controllers/DateTimeFieldController",
"./src/controllers/TreeNodeController",
"./src/controllers/ActionGroupController",
"./src/controllers/ToggleController",
"./src/controllers/ContextMenuController",
"./src/controllers/ClickAwayController",
"./src/controllers/ViewSwitcherController",
"./src/controllers/BottomBarController",
"./src/controllers/GetterSetterController",
"./src/controllers/SelectorController",
"./src/controllers/ObjectInspectorController",
"./src/controllers/BannerController",
"./src/directives/MCTContainer",
"./src/directives/MCTDrag",
"./src/directives/MCTClickElsewhere",
"./src/directives/MCTResize",
"./src/directives/MCTPopup",
"./src/directives/MCTScroll",
"./src/directives/MCTSplitPane",
"./src/directives/MCTSplitter",
'legacyRegistry'
], function (
UrlService,
PopupService,
StyleSheetLoader,
UnsupportedBrowserWarning,
TimeRangeController,
DateTimePickerController,
DateTimeFieldController,
TreeNodeController,
ActionGroupController,
ToggleController,
ContextMenuController,
ClickAwayController,
ViewSwitcherController,
BottomBarController,
GetterSetterController,
SelectorController,
ObjectInspectorController,
BannerController,
MCTContainer,
MCTDrag,
MCTClickElsewhere,
MCTResize,
MCTPopup,
MCTScroll,
MCTSplitPane,
MCTSplitter,
legacyRegistry
) {
"use strict";
legacyRegistry.register("platform/commonUI/general", {
"name": "General UI elements",
"description": "General UI elements, meant to be reused across modes",
"resources": "res",
"extensions": {
"services": [
{
"key": "urlService",
"implementation": UrlService,
"depends": [
"$location"
]
},
{
"key": "popupService",
"implementation": PopupService,
"depends": [
"$document",
"$window"
]
}
],
"runs": [
{
"implementation": StyleSheetLoader,
"depends": [
"stylesheets[]",
"$document",
"THEME"
]
},
{
"implementation": UnsupportedBrowserWarning,
"depends": [
"notificationService",
"agentService"
]
}
],
"filters": [
{
"implementation": "filters/ReverseFilter.js",
"key": "reverse"
}
],
"stylesheets": [
{
"stylesheetUrl": "css/normalize.min.css",
"priority": "mandatory"
}
],
"templates": [
{
"key": "bottombar",
"templateUrl": "templates/bottombar.html"
},
{
"key": "action-button",
"templateUrl": "templates/controls/action-button.html"
},
{
"key": "input-filter",
"templateUrl": "templates/controls/input-filter.html"
},
{
"key": "indicator",
"templateUrl": "templates/indicator.html"
},
{
"key": "message-banner",
"templateUrl": "templates/message-banner.html"
},
{
"key": "progress-bar",
"templateUrl": "templates/progress-bar.html"
},
{
"key": "time-controller",
"templateUrl": "templates/controls/time-controller.html"
}
],
"controllers": [
{
"key": "TimeRangeController",
"implementation": TimeRangeController,
"depends": [
"$scope",
"formatService",
"DEFAULT_TIME_FORMAT",
"now"
]
},
{
"key": "DateTimePickerController",
"implementation": DateTimePickerController,
"depends": [
"$scope",
"now"
]
},
{
"key": "DateTimeFieldController",
"implementation": DateTimeFieldController,
"depends": [
"$scope",
"formatService",
"DEFAULT_TIME_FORMAT"
]
},
{
"key": "TreeNodeController",
"implementation": TreeNodeController,
"depends": [
"$scope",
"$timeout",
"navigationService"
]
},
{
"key": "ActionGroupController",
"implementation": ActionGroupController,
"depends": [
"$scope"
]
},
{
"key": "ToggleController",
"implementation": ToggleController
},
{
"key": "ContextMenuController",
"implementation": ContextMenuController,
"depends": [
"$scope"
]
},
{
"key": "ClickAwayController",
"implementation": ClickAwayController,
"depends": [
"$scope",
"$document"
]
},
{
"key": "ViewSwitcherController",
"implementation": ViewSwitcherController,
"depends": [
"$scope",
"$timeout"
]
},
{
"key": "BottomBarController",
"implementation": BottomBarController,
"depends": [
"indicators[]"
]
},
{
"key": "GetterSetterController",
"implementation": GetterSetterController,
"depends": [
"$scope"
]
},
{
"key": "SelectorController",
"implementation": SelectorController,
"depends": [
"objectService",
"$scope"
]
},
{
"key": "ObjectInspectorController",
"implementation": ObjectInspectorController,
"depends": [
"$scope",
"objectService"
]
},
{
"key": "BannerController",
"implementation": BannerController,
"depends": [
"$scope",
"notificationService",
"dialogService"
]
}
],
"directives": [
{
"key": "mctContainer",
"implementation": MCTContainer,
"depends": [
"containers[]"
]
},
{
"key": "mctDrag",
"implementation": MCTDrag,
"depends": [
"$document"
]
},
{
"key": "mctClickElsewhere",
"implementation": MCTClickElsewhere,
"depends": [
"$document"
]
},
{
"key": "mctResize",
"implementation": MCTResize,
"depends": [
"$timeout"
]
},
{
"key": "mctPopup",
"implementation": MCTPopup,
"depends": [
"$compile",
"popupService"
]
},
{
"key": "mctScrollX",
"implementation": MCTScroll,
"depends": [
"$parse",
"MCT_SCROLL_X_PROPERTY",
"MCT_SCROLL_X_ATTRIBUTE"
]
},
{
"key": "mctScrollY",
"implementation": MCTScroll,
"depends": [
"$parse",
"MCT_SCROLL_Y_PROPERTY",
"MCT_SCROLL_Y_ATTRIBUTE"
]
},
{
"key": "mctSplitPane",
"implementation": MCTSplitPane,
"depends": [
"$parse",
"$log",
"$interval"
]
},
{
"key": "mctSplitter",
"implementation": MCTSplitter
}
],
"constants": [
{
"key": "MCT_SCROLL_X_PROPERTY",
"value": "scrollLeft"
},
{
"key": "MCT_SCROLL_X_ATTRIBUTE",
"value": "mctScrollX"
},
{
"key": "MCT_SCROLL_Y_PROPERTY",
"value": "scrollTop"
},
{
"key": "MCT_SCROLL_Y_ATTRIBUTE",
"value": "mctScrollY"
},
{
"key": "THEME",
"value": "unspecified",
"priority": "fallback"
}
],
"containers": [
{
"key": "accordion",
"templateUrl": "templates/containers/accordion.html",
"attributes": [
"label"
]
}
],
"representations": [
{
"key": "tree",
"templateUrl": "templates/subtree.html",
"uses": [
"composition"
],
"type": "root",
"priority": "preferred"
},
{
"key": "tree",
"templateUrl": "templates/tree.html"
},
{
"key": "subtree",
"templateUrl": "templates/subtree.html",
"uses": [
"composition"
]
},
{
"key": "tree-node",
"templateUrl": "templates/tree-node.html",
"uses": [
"action"
]
},
{
"key": "label",
"templateUrl": "templates/label.html",
"uses": [
"type",
"location"
],
"gestures": [
"drag",
"menu",
"info"
]
},
{
"key": "node",
"templateUrl": "templates/label.html",
"uses": [
"type"
],
"gestures": [
"drag",
"menu"
]
},
{
"key": "action-group",
"templateUrl": "templates/controls/action-group.html",
"uses": [
"action"
]
},
{
"key": "context-menu",
"templateUrl": "templates/menu/context-menu.html",
"uses": [
"action"
]
},
{
"key": "switcher",
"templateUrl": "templates/controls/switcher.html",
"uses": [
"view"
]
},
{
"key": "object-inspector",
"templateUrl": "templates/object-inspector.html"
}
],
"controls": [
{
"key": "selector",
"templateUrl": "templates/controls/selector.html"
},
{
"key": "datetime-picker",
"templateUrl": "templates/controls/datetime-picker.html"
},
{
"key": "datetime-field",
"templateUrl": "templates/controls/datetime-field.html"
}
],
"licenses": [
{
"name": "Modernizr",
"version": "2.6.2",
"description": "Browser/device capability finding",
"author": "Faruk Ateş",
"website": "http://modernizr.com",
"copyright": "Copyright (c) 20092015",
"license": "license-mit",
"link": "http://modernizr.com/license/"
},
{
"name": "Normalize.css",
"version": "1.1.2",
"description": "Browser style normalization",
"author": "Nicolas Gallagher, Jonathan Neal",
"website": "http://necolas.github.io/normalize.css/",
"copyright": "Copyright (c) Nicolas Gallagher and Jonathan Neal",
"license": "license-mit",
"link": "https://github.com/necolas/normalize.css/blob/v1.1.2/LICENSE.md"
}
]
}
});
});

View File

@@ -1,308 +0,0 @@
{
"name": "General UI elements",
"description": "General UI elements, meant to be reused across modes",
"resources": "res",
"extensions": {
"services": [
{
"key": "urlService",
"implementation": "services/UrlService.js",
"depends": [ "$location" ]
},
{
"key": "popupService",
"implementation": "services/PopupService.js",
"depends": [ "$document", "$window" ]
}
],
"runs": [
{
"implementation": "StyleSheetLoader.js",
"depends": [ "stylesheets[]", "$document", "THEME" ]
},
{
"implementation": "UnsupportedBrowserWarning.js",
"depends": [ "notificationService", "agentService" ]
}
],
"filters": [
{
"implementation": "filters/ReverseFilter.js",
"key": "reverse"
}
],
"stylesheets": [
{
"stylesheetUrl": "css/normalize.min.css",
"priority": "mandatory"
}
],
"templates": [
{
"key": "bottombar",
"templateUrl": "templates/bottombar.html"
},
{
"key": "action-button",
"templateUrl": "templates/controls/action-button.html"
},
{
"key": "input-filter",
"templateUrl": "templates/controls/input-filter.html"
},
{
"key": "indicator",
"templateUrl": "templates/indicator.html"
},
{
"key": "message-banner",
"templateUrl": "templates/message-banner.html"
},
{
"key": "progress-bar",
"templateUrl": "templates/progress-bar.html"
},
{
"key": "time-controller",
"templateUrl": "templates/controls/time-controller.html"
}
],
"controllers": [
{
"key": "TimeRangeController",
"implementation": "controllers/TimeRangeController.js",
"depends": [ "$scope", "formatService", "DEFAULT_TIME_FORMAT", "now" ]
},
{
"key": "DateTimePickerController",
"implementation": "controllers/DateTimePickerController.js",
"depends": [ "$scope", "now" ]
},
{
"key": "DateTimeFieldController",
"implementation": "controllers/DateTimeFieldController.js",
"depends": [ "$scope", "formatService", "DEFAULT_TIME_FORMAT" ]
},
{
"key": "TreeNodeController",
"implementation": "controllers/TreeNodeController.js",
"depends": [ "$scope", "$timeout" ]
},
{
"key": "ActionGroupController",
"implementation": "controllers/ActionGroupController.js",
"depends": [ "$scope" ]
},
{
"key": "ToggleController",
"implementation": "controllers/ToggleController.js"
},
{
"key": "ContextMenuController",
"implementation": "controllers/ContextMenuController.js",
"depends": [ "$scope" ]
},
{
"key": "ClickAwayController",
"implementation": "controllers/ClickAwayController.js",
"depends": [ "$scope", "$document" ]
},
{
"key": "ViewSwitcherController",
"implementation": "controllers/ViewSwitcherController.js",
"depends": [ "$scope", "$timeout" ]
},
{
"key": "BottomBarController",
"implementation": "controllers/BottomBarController.js",
"depends": [ "indicators[]" ]
},
{
"key": "GetterSetterController",
"implementation": "controllers/GetterSetterController.js",
"depends": [ "$scope" ]
},
{
"key": "SelectorController",
"implementation": "controllers/SelectorController.js",
"depends": [ "objectService", "$scope" ]
},
{
"key": "ObjectInspectorController",
"implementation": "controllers/ObjectInspectorController.js",
"depends": [ "$scope", "objectService" ]
},
{
"key": "BannerController",
"implementation": "controllers/BannerController.js",
"depends": ["$scope", "notificationService", "dialogService"]
}
],
"directives": [
{
"key": "mctContainer",
"implementation": "directives/MCTContainer.js",
"depends": [ "containers[]" ]
},
{
"key": "mctDrag",
"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": [ "$compile", "popupService" ]
},
{
"key": "mctScrollX",
"implementation": "directives/MCTScroll.js",
"depends": [ "$parse", "MCT_SCROLL_X_PROPERTY", "MCT_SCROLL_X_ATTRIBUTE" ]
},
{
"key": "mctScrollY",
"implementation": "directives/MCTScroll.js",
"depends": [ "$parse", "MCT_SCROLL_Y_PROPERTY", "MCT_SCROLL_Y_ATTRIBUTE" ]
},
{
"key": "mctSplitPane",
"implementation": "directives/MCTSplitPane.js",
"depends": [ "$parse", "$log", "$interval" ]
},
{
"key": "mctSplitter",
"implementation": "directives/MCTSplitter.js"
}
],
"constants": [
{
"key": "MCT_SCROLL_X_PROPERTY",
"value": "scrollLeft"
},
{
"key": "MCT_SCROLL_X_ATTRIBUTE",
"value": "mctScrollX"
},
{
"key": "MCT_SCROLL_Y_PROPERTY",
"value": "scrollTop"
},
{
"key": "MCT_SCROLL_Y_ATTRIBUTE",
"value": "mctScrollY"
},
{
"key": "THEME",
"value": "unspecified",
"priority": "fallback"
}
],
"containers": [
{
"key": "accordion",
"templateUrl": "templates/containers/accordion.html",
"attributes": [ "label" ]
}
],
"representations": [
{
"key": "tree",
"templateUrl": "templates/subtree.html",
"uses": [ "composition" ],
"type": "root",
"priority": "preferred"
},
{
"key": "tree",
"templateUrl": "templates/tree.html"
},
{
"key": "subtree",
"templateUrl": "templates/subtree.html",
"uses": [ "composition" ]
},
{
"key": "tree-node",
"templateUrl": "templates/tree-node.html",
"uses": [ "action" ]
},
{
"key": "label",
"templateUrl": "templates/label.html",
"uses": [ "type", "location" ],
"gestures": [ "drag", "menu", "info" ]
},
{
"key": "node",
"templateUrl": "templates/label.html",
"uses": [ "type" ],
"gestures": [ "drag", "menu" ]
},
{
"key": "action-group",
"templateUrl": "templates/controls/action-group.html",
"uses": [ "action" ]
},
{
"key": "context-menu",
"templateUrl": "templates/menu/context-menu.html",
"uses": [ "action" ]
},
{
"key": "switcher",
"templateUrl": "templates/controls/switcher.html",
"uses": [ "view" ]
},
{
"key": "object-inspector",
"templateUrl": "templates/object-inspector.html"
}
],
"controls": [
{
"key": "selector",
"templateUrl": "templates/controls/selector.html"
},
{
"key": "datetime-picker",
"templateUrl": "templates/controls/datetime-picker.html"
},
{
"key": "datetime-field",
"templateUrl": "templates/controls/datetime-field.html"
}
],
"licenses": [
{
"name": "Modernizr",
"version": "2.6.2",
"description": "Browser/device capability finding",
"author": "Faruk Ateş",
"website": "http://modernizr.com",
"copyright": "Copyright (c) 20092015",
"license": "license-mit",
"link": "http://modernizr.com/license/"
},
{
"name": "Normalize.css",
"version": "1.1.2",
"description": "Browser style normalization",
"author": "Nicolas Gallagher, Jonathan Neal",
"website": "http://necolas.github.io/normalize.css/",
"copyright": "Copyright (c) Nicolas Gallagher and Jonathan Neal",
"license": "license-mit",
"link": "https://github.com/necolas/normalize.css/blob/v1.1.2/LICENSE.md"
}
]
}
}

View File

@@ -47,14 +47,11 @@ a.disabled {
@include animation-name(pulse, 0.2);
}
@include keyframes(pulse) {
0% { opacity: 0.5; }
100% { opacity: 1; }
}
@mixin pulse($dur: 500ms, $iteration: infinite) {
//@include customKeyframes(pulse, 0.2);
@mixin pulse($dur: 500ms, $iteration: infinite, $opacity0: 0.5, $opacity100: 1) {
@include keyframes(pulse) {
0% { opacity: $opacity0; }
100% { opacity: $opacity100; }
}
@include animation-name(pulse);
@include animation-duration($dur);
@include animation-direction(alternate);
@@ -62,6 +59,19 @@ a.disabled {
@include animation-timing-function(ease-in-out);
}
@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); }
}
@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);
}
.pulse {
@include pulse(750ms);
}

View File

@@ -121,7 +121,12 @@ mct-container {
text-align: center;
}
.scrolling {
.ellipsis {
@include ellipsize();
}
.scrolling,
.scroll {
overflow: auto;
}

View File

@@ -35,7 +35,6 @@
}
&.icon {
color: $colorKey;
//position: relative;
font-size: inherit;
&.alert {
color: $colorAlert;
@@ -81,14 +80,11 @@
}
.t-item-icon {
// Used in grid-item.html, tree-item, inspector location, more?
// Used in grid-item.html, tree-item, inspector location
@extend .ui-symbol;
@extend .icon;
line-height: normal; // This is Ok for the symbolsfont
position: relative;
.t-item-icon-glyph {
position: absolute;
}
&.l-icon-link {
.t-item-icon-glyph {
&:before {
@@ -103,4 +99,4 @@
}
}
}
}
}

View File

@@ -23,7 +23,7 @@
.l-inspect,
.l-inspect table tr td {
font-size: 0.7rem;
font-size: 0.75rem;
}
.l-inspect {
@@ -31,6 +31,9 @@
background: $colorInspectorBg;
color: $colorInspectorFg;
line-height: 140%;
.flex-elem.holder:not(:last-child) { margin-bottom: $interiorMargin; }
.pane-header {
color: pushBack($colorInspectorFg, 20%);
font-size: 0.8rem;
@@ -43,6 +46,16 @@
vertical-align: bottom;
}
}
.split-layout {
.split-pane-component.pane {
&.bottom {
height: 30%;
min-height: 20%;
max-height: 80%;
}
}
}
ul {
@include box-sizing(border-box);
@@ -118,4 +131,34 @@
width: 4px;
}
}
}
.holder-elements {
.current-elements {
position: relative;
.tree-item {
.t-object-label {
// Elements pool is a flat list, so don't indent items.
font-size: 0.75rem;
left: 0;
}
}
}
}
}
.l-inspect {
.splitter-inspect-panel,
.split-pane-component.pane.bottom {
@include trans-prop-nice(opacity, 250ms); // Not working as desired currently; entire inspector seems to be destroyed and recreated when switching into and out of edit mode.
opacity: 0;
pointer-events: none;
}
}
.s-status-editing .l-inspect {
.location-item { pointer-events: none; }
.splitter-inspect-panel,
.split-pane-component.pane.bottom {
opacity: 1;
pointer-events: inherit;
}
}

View File

@@ -64,6 +64,12 @@
}
}
@mixin trans-prop-nice-resize($t: 0.5s, $tf: ease-in-out) {
@include transition-property(height, width, top, right, bottom, left, opacity);
@include transition-duration($t);
@include transition-timing-function($tf);
}
@mixin trans-prop-nice-resize-h($dur: 500ms, $delay: 0) {
@include transition-property(height, bottom, top);
@include transition-duration($dur);
@@ -309,11 +315,11 @@
}
}
@mixin input-base($bg: $colorBodyBg, $fg: $colorBodyFg) {
@mixin input-base($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.6) 0 1px 3px) {
@include appearance(none);
@include border-radius($controlCr);
@include box-sizing(border-box);
@include box-shadow(inset rgba(black, 0.4) 0 1px 3px);
@include box-shadow(inset $shdw);
background: $bg;
border: none;
color: $fg;
@@ -323,7 +329,7 @@
}
}
@mixin nice-input($bg: $colorBodyBg, $fg: $colorBodyFg) {
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg) {
@include input-base($bg, $fg);
padding: 0 $interiorMarginSm;
}

View File

@@ -44,10 +44,6 @@ mct-representation {
$spinD: 0;
@include spinner($spinBW);
content: "";
display: block;
position: absolute;
left: 50%;
top: 50%;
padding: 30%;
width: $spinD;
height: $spinD;
@@ -64,6 +60,6 @@ mct-representation {
}
}
.selected mct-representation.s-status-pending .t-object-label .t-item-icon:before {
border-color: rgba($colorItemTreeSelectedFg, 0.25);
border-top-color: rgba($colorItemTreeSelectedFg, 1.0);
border-color: rgba($colorItemTreeSelectedFg, 0.25) !important;
border-top-color: rgba($colorItemTreeSelectedFg, 1.0) !important;
}

View File

@@ -35,6 +35,7 @@ $pad: $interiorMargin * $baseRatio;
@include box-sizing(border-box);
padding: 0 $pad;
font-size: 0.7rem;
vertical-align: top;
.icon {
font-size: 0.8rem;
@@ -70,6 +71,18 @@ $pad: $interiorMargin * $baseRatio;
&.pause-play {
}
&.t-save:before {
content:'\e612';
font-family: symbolsfont;
margin-right: $interiorMarginSm;
}
&.t-cancel {
.title-label { display: none; }
&:before {
content:'\78';
font-family: symbolsfont;
}
}
&.pause-play {
.icon:before {

View File

@@ -6,10 +6,6 @@
}
}
.l-time-controller-visible {
}
mct-include.l-time-controller {
$minW: 500px;
$knobHOffset: 0px;
@@ -22,10 +18,10 @@ mct-include.l-time-controller {
$r2H: nth($ueTimeControlH,2);
$r3H: nth($ueTimeControlH,3);
@include absPosDefault();
//@include absPosDefault();
//@include test();
display: block;
top: auto;
//top: auto;
height: $r1H + $r2H + $r3H + ($interiorMargin * 2);
min-width: $minW;
font-size: 0.8rem;

View File

@@ -19,8 +19,10 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
.s-status-editing .l-object-wrapper,
.edit-main {
// .s-status-editing .l-object-wrapper is relevant to New Edit Mode;
// .edit-main is legacy for old edit mode.
$handleD: 15px;
$cr: 5px;
.edit-corner,
@@ -92,12 +94,10 @@
}
}
.frame.child-frame.panel {
&:hover {
@include boxShdwLarge();
border-color: $colorKey;
//z-index: 2;
.view-switcher {
opacity: 1;
}

View File

@@ -31,7 +31,6 @@
}
.form {
// @include test(orange);
color: $colorFormText;
.form-section {
position: relative;
@@ -112,12 +111,8 @@
.selector-list {
// Used in create overlay to display tree view
@include nice-input($colorInputBg, $colorInputFg);
@include nice-input();
$h: 150px;
//@include border-radius($basicCr);
//@include box-sizing(border-box);
//background: rgba(black, 0.2);
//padding: $interiorMargin;
position: relative;
height: $h;
// max-width: 50%;
@@ -162,13 +157,9 @@ label.form-control.checkbox {
}
}
input[type="text"] {
@include nice-input($colorInputBg, $colorInputFg);
&.filter {
&.ng-dirty {
// background: red;
}
}
input[type="text"],
input[type="search"] {
@include nice-input();
&.numeric {
text-align: right;
}
@@ -176,7 +167,6 @@ input[type="text"] {
textarea {
@include nice-textarea($colorInputBg, $colorInputFg);
// font-size: 0.9em;
position: absolute;
height: 100%;
width: 100%;

View File

@@ -21,20 +21,7 @@
*****************************************************************************/
.filter,
.t-filter {
input.filter,
input.t-filter-input {
@include subdued-input();
}
input.t-filter-input {
height: $formInputH;
width: 200px;
&:not(.ng-dirty) {
// TO-DO: Update compass install to support this
// @include input-placeholder {
// color: rgba(#fff, 0.3);
// font-style: italic;
// }
}
&:not(.ng-dirty) + .t-a-clear {
display: none;
}
@@ -76,13 +63,6 @@
background-color: $colorKey;
}
}
// &:not(ng-dirty)
}
.l-filter {
// Holds an input and a clear button
display:inline-block;
position: relative;
}
.top-bar {
@@ -100,4 +80,75 @@
.icon-filter {
font-size: 1.4em;
}
}
.l-filter {
$iconEdgeM: 4px;
$iconD: $formInputH - ($iconEdgeM * 2);
// Adds a magnifying glass before, holds an input and a clear button
display: inline-block;
position: relative;
input[type="search"] {
padding: 2px ($iconD + $interiorMargin);
}
.clear-icon,
.menu-icon,
&:before {
@include box-sizing(border-box);
display: inline-block;
line-height: inherit;
position: absolute;
top: 50%;
@include transform(translateY(-50%));
z-index: 1;
}
&:before {
// Magnify glass icon
content:'\4d';
left: $interiorMargin;
@include trans-prop-nice(color, 250ms);
pointer-events: none;
}
.clear-icon {
right: $iconEdgeM;
// Icon is visible only when there is text input
visibility: hidden;
opacity: 0;
&.show {
visibility: visible;
opacity: 1;
}
&:hover {
color: pullForward($colorInputIcon, 10%);
}
}
}
.s-filter {
input[type="search"] {
@include input-base();
}
.clear-icon,
.menu-icon,
&:before {
color: $colorInputIcon;
cursor: pointer;
font-family: symbolsfont;
@include trans-prop-nice((opacity, color), 150ms);
}
// Make icon lighten when hovering over search bar
&:hover:before {
color: pullForward($colorInputIcon, 10%);
}
.clear-icon {
// 'x' in circle icon
&:before {
content: '\e607';
}
}
}

View File

@@ -25,6 +25,7 @@
margin: 0 0 2px 0; // Needed to avoid dropshadow from being clipped by parent containers
}
padding: 0 $interiorMargin;
overflow: hidden;
position: relative;
line-height: $formInputH;
select {
@@ -35,7 +36,7 @@
cursor: pointer;
border: none !important;
padding: 4px 25px 2px 0px;
width: 120%;
width: 130%;
option {
margin: $interiorMargin 0; // Firefox
}

View File

@@ -20,62 +20,37 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
@include keyframes(rotation) {
0% { transform: rotate(0deg); }
100% { transform: rotate(359deg); }
100% { @include transform(rotate(360deg)); }
}
@mixin spinner($b: 5px) {
@include keyframes(rotateCentered) {
0% { @include transform(translateX(-50%) translateY(-50%) rotate(0deg)); }
100% { @include transform(translateX(-50%) translateY(-50%) rotate(359deg)); }
}
@include animation-name(rotateCentered);
@include keyframes(rotation-centered) {
0% { @include transform(translate(-50%, -50%) rotate(0deg)); }
100% { @include transform(translate(-50%, -50%) rotate(360deg)); }
}
@mixin spinner($b: 5px, $c: $colorKey) {
@include transform-origin(center);
@include animation-name(rotation-centered);
@include animation-duration(0.5s);
@include animation-iteration-count(infinite);
@include animation-timing-function(linear);
@include transform-origin(center);
border-style: solid;
border-width: $b;
@include border-radius(100%);
}
@mixin wait-spinner2($b: 5px, $c: $colorAlt1) {
@include spinner($b);
@include box-sizing(border-box);
border-color: rgba($c, 0.25);
border-top-color: rgba($c, 1.0);
border-style: solid;
border-width: $b;
display: block;
position: absolute;
height: 0; width: 0;
padding: 7%;
left: 50%; top: 50%;
}
@mixin wait-spinner($b: 5px, $c: $colorAlt1) {
display: block;
position: absolute;
-webkit-animation: rotation .6s infinite linear;
-moz-animation: rotation .6s infinite linear;
-o-animation: rotation .6s infinite linear;
animation: rotation .6s infinite linear;
border-color: rgba($c, 0.25);
border-top-color: rgba($c, 1.0);
border-style: solid;
border-width: $b;
@include border-radius(100%);
}
.t-wait-spinner,
.wait-spinner {
$d: 5%;
@include wait-spinner(0.5em, $colorKey);
top: 50%; left: 50%;
@include spinner(0.5em, $colorKey);
height: auto; width: auto;
padding: $d; // Will size object based on parent container WIDTH
pointer-events: none;
margin-top: $d / -1;
margin-left: $d / -1;
z-index: 2;
&.inline {
display: inline-block !important;
@@ -85,46 +60,15 @@
}
}
.l-wait-spinner-holder {
pointer-events: none;
position: absolute;
&.align-left {
.t-wait-spinner {
left: 0;
margin-left: 0;
}
}
&.full-size {
display: inline-block;
height: 100%; width: 100%;
.t-wait-spinner {
top: 0;
margin-top: 0;
padding: 30%;
}
}
}
.treeview .wait-spinner {
// Only used in subtree.html, which I don't think this is actually being used
$d: 10px;
@include wait-spinner(0.25em, $colorKey);
height: $d; width: $d;
margin: 0 !important;
padding: 0 !important;
top: 2px; left: 0;
}
.wait-spinner.sm {
$d: 13px;
@include wait-spinner(0.25em, $colorKey);
height: $d; width: $d;
margin-left: 0 !important;
margin-top: 0 !important;
padding: 0 !important;
top: 0; left: 0;
}
.loading {
// Can be applied to any block element with height and width
pointer-events: none;
@@ -133,7 +77,8 @@
content: '';
}
&:before {
@include wait-spinner2(5px, $colorLoadingFg);
@include spinner(5px, $colorLoadingFg);
padding: 5%;
z-index: 10;
}
&:after {
@@ -146,5 +91,4 @@
padding: $menuLineH / 4;
border-width: 2px;
}
}

View File

@@ -27,7 +27,6 @@
}
.item {
&.grid-item {
//div { @include test() }
$d: $ueBrowseGridItemLg;
$iconMargin: 40px;
$iconD: ($d - ($iconMargin * 2)) * 0.85;
@@ -53,7 +52,6 @@
}
}
.contents {
//@include test(red);
$m: $interiorMarginLg;
top: $m; right: $m; bottom: $m; left: $m;
}
@@ -83,19 +81,21 @@
.item-main {
$h: $ueBrowseGridItemLg;
$lh: $h * 0.8;
//top: $ueBrowseGridItemTopBarH; bottom: $ueBrowseGridItemBottomBarH; //
line-height: $lh;
z-index: 1;
.item-type,
.t-item-icon {
//@include test();
@include transform(translateX(-50%) translateY(-55%));
position: absolute;
top: 50%; left: 50%;
//height: $iconD; width: $iconD;
font-size: $iconD * 0.95; //6em;
//line-height: normal;
//text-align: center;
font-size: $iconD * 0.95;
&.l-icon-link {
.t-item-icon-glyph {
&:before {
@include transform(scale(0.25));
}
}
}
}
.item-open {
@include trans-prop-nice("opacity", $transTime);

View File

@@ -102,7 +102,7 @@
}
.object-browse-bar {
left: 45px !important;
margin-left: 45px;
.context-available {
opacity: 1 !important;
}

View File

@@ -33,7 +33,22 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
width: 100%;
height: 100%;
.gl-plot-local-controls {
@include trans-prop-nice(opacity, 150ms);
opacity: 0;
pointer-events: none;
}
.gl-plot-display-area,
.gl-plot-axis-area {
&:hover .gl-plot-local-controls {
opacity: 1;
pointer-events: inherit;
}
}
.gl-plot-axis-area {
//@include test();
position: absolute;
&.gl-plot-x {
top: auto;
@@ -114,15 +129,17 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
.gl-plot-x-options,
.gl-plot-y-options {
$h: 32px;
$h: 24px;
position: absolute;
height: auto;
height: $h;
min-height: $h;
z-index: 2;
}
.gl-plot-x-options {
top: $interiorMargin;
@include transform(translateX(-50%));
bottom: 0;
left: 50%;
}
.gl-plot-y-options {
@@ -132,6 +149,12 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
left: $yLabelW + $interiorMargin * 2;
}
.t-plot-display-controls {
position: absolute;
top: $interiorMargin;
right: $interiorMargin;
}
.gl-plot-hash {
position: absolute;
border: 0 $colorPlotHash $stylePlotHash;

View File

@@ -149,3 +149,32 @@ mct-representation {
border-color: rgba($colorItemTreeSelectedFg, 0.25);
border-top-color: rgba($colorItemTreeSelectedFg, 1.0);
}
.tree .s-status-editing,
.search-results .s-status-editing {
// Item is being edited
.tree-item,
.search-result-item {
background: $colorItemTreeEditingBg;
pointer-events: none;
&:before {
// Pencil icon
@extend .ui-symbol;
@include pulse($dur: 1s, $opacity0: 0.25);
color: $colorItemTreeEditingFg;
content: '\70';
margin-right: $interiorMarginSm;
}
.t-object-label {
.t-item-icon,
.t-title-label {
color: $colorItemTreeEditingFg;
@include text-shadow(none);
}
.t-title-label {
font-style: italic;
}
}
.view-control, + .tree-item-subtree { display: none; }
}
}

View File

@@ -25,6 +25,7 @@
&.child-frame.panel {
background: $colorBodyBg;
border: 1px solid $bc;
z-index: 0; // Needed to prevent child-frame controls from showing through when another child-frame is above
&:hover {
border-color: lighten($bc, 10%);
}

View File

@@ -77,38 +77,38 @@
}
}
// from _bottom-bar.scss
.ue-bottom-bar {
@include absPosDefault(0);// New status bar design
top: auto;
height: $ueFooterH;
line-height: $ueFooterH - ($interiorMargin * 2);
background: $colorFooterBg;
color: lighten($colorBodyBg, 30%);
font-size: .7rem;
.status-holder {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
@include ellipsize();
right: 120px;
text-transform: uppercase;
z-index: 1;
}
.app-logo {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
cursor: pointer;
left: auto;
width: $ueAppLogoW;
z-index: 2;
&.logo-openmctweb {
background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center;
}
}
}
.ue-bottom-bar {
@include absPosDefault(0);// New status bar design
top: auto;
height: $ueFooterH;
line-height: $ueFooterH - ($interiorMargin * 2);
background: $colorFooterBg;
color: lighten($colorBodyBg, 30%);
font-size: .7rem;
.status-holder {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
@include ellipsize();
right: 120px;
text-transform: uppercase;
z-index: 1;
}
.app-logo {
@include box-sizing(border-box);
@include absPosDefault($interiorMargin);
cursor: pointer;
left: auto;
width: $ueAppLogoW;
z-index: 2;
&.logo-openmctweb {
background: url($dirImgs + 'logo-openmctweb.svg') no-repeat center center;
}
}
}
}
.edit-mode {
// Old edit mode
.split-layout {
.split-pane-component.pane.right {
width: 15%;
@@ -132,7 +132,7 @@
.primary-pane {
// Need to lift up this pane to ensure that 'collapsed' panes don't block user interactions
z-index: 2;
z-index: 4;
}
.mini-tab-icon.toggle-pane {
@@ -172,7 +172,7 @@
&.toggle-inspect.anchor-right {
right: $bodyMargin;
&:after {
content: '\e615'; // e615: Crosshair icon; was e608: Info "i" icon
content: '\e615'; // Eye icon
}
&.collapsed {
right: $interiorMargin;
@@ -197,6 +197,16 @@
right: 0;
bottom: $bodyMargin;
left: $bodyMargin;
.create-btn-holder {
&.s-status-editing {
display: none;
& + .search-holder .search-bar {
// .search-holder is adjacent sibling to .create-btn-holder
// Add right margin when create button is hidden, to make room for the collapse pane 'x' button
margin-right: $interiorMarginLg * 2;
}
}
}
}
.holder.holder-object-and-inspector {
@@ -208,25 +218,50 @@
top: $bodyMargin;
bottom: $bodyMargin;
}
.holder-inspector-elements {
.holder-inspector {
top: $bodyMargin;
bottom: $bodyMargin;
left: $bodyMargin;
right: $bodyMargin;
}
.holder-elements {
top: 0;
bottom: $bodyMargin;
left: $bodyMargin;
right: $bodyMargin;
}
}
}
.object-holder {
@include absPosDefault(0, auto);
top: $ueTopBarH + $interiorMarginLg;
&.l-controls-visible {
&.l-time-controller-visible {
bottom: nth($ueTimeControlH,1) + nth($ueTimeControlH,2) +nth($ueTimeControlH,3) + ($interiorMargin * 3);
}
.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,
@@ -247,7 +282,6 @@
/***************************************************** OBJECT BROWSE BAR */
.object-browse-bar {
@include absPosDefault(0, visible); // Must use visible to avoid hiding view switcher menu
@include box-sizing(border-box);
height: $ueTopBarH;
line-height: $ueTopBarH;
@@ -255,15 +289,13 @@
.left {
padding-right: $interiorMarginLg;
.l-back {
.l-back:not(.s-status-editing) {
margin-right: $interiorMarginLg;
}
}
}
// When the tree is hidden, these are the
// classes used for the left menu and the
// right representation.
// When the tree is hidden, these are the classes used for the left menu and the right representation.
.pane-tree-hidden {
// Sets the left tree menu when the tree is hidden.
.tree-holder,
@@ -299,9 +331,6 @@
.pane-inspect-hidden {
.l-object-and-inspector {
.t-inspect {
z-index: 1 !important; // Move down so that primary pane elements are clickable
}
.l-inspect,
.splitter-inspect {
opacity: 0;
@@ -345,3 +374,22 @@
min-width: 200px; // Needed for nice display when primary pane is constrained severely via splitters
}
}
.s-status-editing {
.l-object-wrapper {
@include pulseBorder($colorEditAreaFg, $dur: 1s, $opacity0: 0.3);
@include border-radius($controlCr);
background-color: $colorEditAreaBg;
border-color: $colorEditAreaFg;
border-width: 2px;
border-style: dotted;
.l-object-wrapper-inner {
@include absPosDefault(3px, hidden);
}
.l-edit-controls {
height: $ueEditToolBarH + $interiorMargin;
margin-bottom: $interiorMargin;
opacity: 1;
}
}
}

View File

@@ -20,7 +20,9 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
.tool-bar {
border-bottom: 1px solid $colorInteriorBorder;
&.btn-bar {
white-space: nowrap;
}
.l-control-group {
height: $btnToolbarH;
}

View File

@@ -46,8 +46,7 @@
.edit-mode {
.top-bar {
.buttons-main {
// background: red;
// width: 600px;
// Old edit mode
white-space: nowrap;
&.abs {
bottom: auto;

View File

@@ -24,7 +24,11 @@
<input type="text"
ng-model="textValue"
ng-blur="restoreTextValue(); ngBlur()"
ng-class="{ error: textInvalid }">
ng-class="{
error: textInvalid ||
(structure.validate &&
!structure.validate(ngModel[field]))
}">
</input>
<a class="ui-symbol icon icon-calendar"
ng-if="structure.format === 'utc' || !structure.format"

View File

@@ -20,15 +20,13 @@
at runtime from the About dialog for additional information.
-->
<!-- look at action-button for example -->
<span class="t-filter l-filter"
<span class="t-filter l-filter s-filter"
ng-controller="GetterSetterController">
<input type="search"
class="t-filter-input"
ng-model="getterSetter.value"
placeholder="Filter..."/>
<a class="ui-symbol t-a-clear s-a-clear"
ng-show="getterSetter.value !== ''"
ng-model="getterSetter.value"/>
<a class="clear-icon"
ng-class="{show: !(getterSetter.value === '' || getterSetter.value === undefined)}"
ng-click="getterSetter.value = ''">
x
</a>
</span>

View File

@@ -25,7 +25,7 @@
<span class="l-time-range-inputs-elem ui-symbol type-icon">&#x43;</span>
<span class="l-time-range-input">
<mct-control key="'datetime-field'"
structure="{ format: parameters.format }"
structure="{ format: parameters.format, validate: validateStart }"
ng-model="formModel"
ng-blur="updateBoundsFromForm()"
field="'start'"
@@ -37,7 +37,7 @@
<span class="l-time-range-input" ng-controller="ToggleController as t2">
<mct-control key="'datetime-field'"
structure="{ format: parameters.format }"
structure="{ format: parameters.format, validate: validateEnd }"
ng-model="formModel"
ng-blur="updateBoundsFromForm()"
field="'end'"

View File

@@ -20,44 +20,61 @@
at runtime from the About dialog for additional information.
-->
<span class="l-inspect" ng-controller="ObjectInspectorController as controller">
<div class="abs holder holder-inspector-elements l-flex-col">
<div class="pane-header flex-elem">Inspection</div>
<ul class="flex-elem grows vscroll">
<li>
<em>Properties</em>
<div class="inspector-properties"
ng-repeat="data in metadata"
ng-class="{ first:$index === 0 }">
<div class="label">{{ data.name }}</div>
<div class="value">{{ data.value }}</div>
<div ng-controller="PaneController as modelPaneEdit">
<mct-split-pane class='abs contents split-layout' anchor='bottom'>
<div class="split-pane-component pane top">
<div class="abs holder holder-inspector l-flex-col">
<div class="pane-header flex-elem">Inspection</div>
<ul class="flex-elem grows vscroll">
<li>
<em>Properties</em>
<div class="inspector-properties"
ng-repeat="data in metadata"
ng-class="{ first:$index === 0 }">
<div class="label">{{ data.name }}</div>
<div class="value">{{ data.value }}</div>
</div>
</li>
<li ng-if="contextutalParents.length > 0">
<em title="The location of this linked object.">Location</em>
<span class="inspector-location"
ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item">
</mct-representation>
</span>
</li>
<li ng-if="primaryParents.length > 0">
<em title="The location of the original object that this was linked from.">Original Location</em>
<span class="inspector-location"
ng-repeat="parent in primaryParents"
ng-class="{ last:($index + 1) === primaryParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item">
</mct-representation>
</span>
</li>
</ul>
</div><!--/ holder-inspector -->
</div><!--/ split-pane-component -->
<mct-splitter class="splitter-inspect-panel mobile-hide"></mct-splitter>
<div class="split-pane-component pane bottom">
<div class="abs holder holder-elements l-flex-col">
<em class="flex-elem">Elements</em>
<mct-representation
key="'edit-elements'"
mct-object="domainObject"
class="flex-elem holder grows vscroll current-elements">
</mct-representation>
</div>
</div>
</li>
<li ng-if="contextutalParents.length > 0">
<em title="The location of this linked object.">Location</em>
<span class="inspector-location"
ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item rep-object-label">
</mct-representation>
</span>
</li>
<li ng-if="primaryParents.length > 0">
<em title="The location of the original object that this was linked from.">Original Location</em>
<span class="inspector-location"
ng-repeat="parent in primaryParents"
ng-class="{ last:($index + 1) === primaryParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-model="ngModel"
ng-click="ngModel.selectedObject = parent"
class="location-item rep-object-label">
</mct-representation>
</span>
</li>
</ul>
</div>
</mct-split-pane>
</div><!--/ PaneController -->
</span>

View File

@@ -35,6 +35,7 @@
class="rep-object-label"
key="'label'"
mct-object="domainObject"
parameters="{suppressMenuOnEdit: true}"
ng-click="treeNode.select()"
>
</mct-representation>

View File

@@ -43,7 +43,7 @@ define(
function TimeRangeController($scope, formatService, defaultFormat, now) {
var tickCount = 2,
innerMinimumSpan = 1000, // 1 second
outerMinimumSpan = 1000 * 60 * 60, // 1 hour
outerMinimumSpan = 1000, // 1 second
initialDragValue,
formatter = formatService.getFormat(defaultFormat);
@@ -185,13 +185,6 @@ define(
function updateOuterStart(t) {
var ngModel = $scope.ngModel;
ngModel.outer.start = t;
ngModel.outer.end = Math.max(
ngModel.outer.start + outerMinimumSpan,
ngModel.outer.end
);
ngModel.inner.start =
Math.max(ngModel.outer.start, ngModel.inner.start);
ngModel.inner.end = Math.max(
@@ -207,13 +200,6 @@ define(
function updateOuterEnd(t) {
var ngModel = $scope.ngModel;
ngModel.outer.end = t;
ngModel.outer.start = Math.min(
ngModel.outer.end - outerMinimumSpan,
ngModel.outer.start
);
ngModel.inner.end =
Math.min(ngModel.outer.end, ngModel.inner.end);
ngModel.inner.start = Math.min(
@@ -233,11 +219,20 @@ define(
}
function updateBoundsFromForm() {
$scope.ngModel = $scope.ngModel || {};
$scope.ngModel.outer = {
start: $scope.formModel.start,
end: $scope.formModel.end
};
var start = $scope.formModel.start,
end = $scope.formModel.end;
if (end >= start + outerMinimumSpan) {
$scope.ngModel = $scope.ngModel || {};
$scope.ngModel.outer = { start: start, end: end };
}
}
function validateStart(startValue) {
return startValue <= $scope.formModel.end - outerMinimumSpan;
}
function validateEnd(endValue) {
return endValue >= $scope.formModel.start + outerMinimumSpan;
}
$scope.startLeftDrag = startLeftDrag;
@@ -249,6 +244,9 @@ define(
$scope.updateBoundsFromForm = updateBoundsFromForm;
$scope.validateStart = validateStart;
$scope.validateEnd = validateEnd;
$scope.ticks = [];
// Initialize scope to defaults

View File

@@ -91,6 +91,24 @@ define(
.toHaveBeenCalledWith("ngModel", jasmine.any(Function));
});
it("exposes start time validator", function () {
var testValue = 42000000;
mockScope.formModel = { end: testValue };
expect(mockScope.validateStart(testValue + 1))
.toBe(false);
expect(mockScope.validateStart(testValue - 60 * 60 * 1000 - 1))
.toBe(true);
});
it("exposes end time validator", function () {
var testValue = 42000000;
mockScope.formModel = { start: testValue };
expect(mockScope.validateEnd(testValue - 1))
.toBe(false);
expect(mockScope.validateEnd(testValue + 60 * 60 * 1000 + 1))
.toBe(true);
});
describe("when changes are made via form entry", function () {
beforeEach(function () {
mockScope.ngModel = {
@@ -194,26 +212,6 @@ define(
fireWatchCollection("ngModel", mockScope.ngModel);
});
it("enforces a minimum outer span", function () {
mockScope.ngModel.outer.end =
mockScope.ngModel.outer.start - DAY * 100;
fireWatch(
"ngModel.outer.end",
mockScope.ngModel.outer.end
);
expect(mockScope.ngModel.outer.end)
.toBeGreaterThan(mockScope.ngModel.outer.start);
mockScope.ngModel.outer.start =
mockScope.ngModel.outer.end + DAY * 100;
fireWatch(
"ngModel.outer.start",
mockScope.ngModel.outer.start
);
expect(mockScope.ngModel.outer.end)
.toBeGreaterThan(mockScope.ngModel.outer.start);
});
it("enforces a minimum inner span when outer span changes", function () {
mockScope.ngModel.outer.end =
mockScope.ngModel.outer.start - DAY * 100;