Neues Initialrelease mit IonicMaterial
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-autocomplete.md-THEME_NAME-theme {
|
||||
background: '{{background-50}}'; }
|
||||
md-autocomplete.md-THEME_NAME-theme[disabled] {
|
||||
background: '{{background-100}}'; }
|
||||
md-autocomplete.md-THEME_NAME-theme button md-icon path {
|
||||
fill: '{{background-600}}'; }
|
||||
md-autocomplete.md-THEME_NAME-theme button:after {
|
||||
background: '{{background-600-0.3}}'; }
|
||||
|
||||
.md-autocomplete-suggestions.md-THEME_NAME-theme {
|
||||
background: '{{background-50}}'; }
|
||||
.md-autocomplete-suggestions.md-THEME_NAME-theme li {
|
||||
color: '{{background-900}}'; }
|
||||
.md-autocomplete-suggestions.md-THEME_NAME-theme li .highlight {
|
||||
color: '{{background-600}}'; }
|
||||
.md-autocomplete-suggestions.md-THEME_NAME-theme li:hover, .md-autocomplete-suggestions.md-THEME_NAME-theme li.selected {
|
||||
background: '{{background-200}}'; }
|
||||
6
www/lib/angular-material/modules/js/autocomplete/autocomplete-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/autocomplete/autocomplete-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-autocomplete.md-THEME_NAME-theme,md-autocomplete.md-THEME_NAME-theme[disabled]{background:0 0}md-autocomplete.md-THEME_NAME-theme button md-icon path{fill:'{{background-600}}'}.md-autocomplete-suggestions.md-THEME_NAME-theme,md-autocomplete.md-THEME_NAME-theme button:after{background:0 0}.md-autocomplete-suggestions.md-THEME_NAME-theme li{color:'{{background-900}}'}.md-autocomplete-suggestions.md-THEME_NAME-theme li .highlight{color:'{{background-600}}'}.md-autocomplete-suggestions.md-THEME_NAME-theme li.selected,.md-autocomplete-suggestions.md-THEME_NAME-theme li:hover{background:0 0}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
@-webkit-keyframes md-autocomplete-list-out {
|
||||
0% {
|
||||
-webkit-animation-timing-function: linear;
|
||||
animation-timing-function: linear; }
|
||||
|
||||
50% {
|
||||
opacity: 0;
|
||||
height: 40px;
|
||||
-webkit-animation-timing-function: ease-in;
|
||||
animation-timing-function: ease-in; }
|
||||
|
||||
100% {
|
||||
height: 0;
|
||||
opacity: 0; } }
|
||||
@keyframes md-autocomplete-list-out {
|
||||
0% {
|
||||
-webkit-animation-timing-function: linear;
|
||||
animation-timing-function: linear; }
|
||||
|
||||
50% {
|
||||
opacity: 0;
|
||||
height: 40px;
|
||||
-webkit-animation-timing-function: ease-in;
|
||||
animation-timing-function: ease-in; }
|
||||
|
||||
100% {
|
||||
height: 0;
|
||||
opacity: 0; } }
|
||||
|
||||
@-webkit-keyframes md-autocomplete-list-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out; }
|
||||
|
||||
50% {
|
||||
opacity: 0;
|
||||
height: 40px; }
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
height: 40px; } }
|
||||
|
||||
@keyframes md-autocomplete-list-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
-webkit-animation-timing-function: ease-out;
|
||||
animation-timing-function: ease-out; }
|
||||
|
||||
50% {
|
||||
opacity: 0;
|
||||
height: 40px; }
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
height: 40px; } }
|
||||
|
||||
md-autocomplete {
|
||||
border-radius: 2px;
|
||||
display: block;
|
||||
height: 40px;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
min-width: 190px; }
|
||||
md-autocomplete[disabled] input {
|
||||
cursor: not-allowed; }
|
||||
md-autocomplete[md-floating-label] {
|
||||
padding-bottom: 26px;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
height: auto; }
|
||||
md-autocomplete[md-floating-label] md-input-container {
|
||||
padding-bottom: 0; }
|
||||
md-autocomplete[md-floating-label] md-autocomplete-wrap {
|
||||
height: auto; }
|
||||
md-autocomplete[md-floating-label] button {
|
||||
position: absolute;
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 30px;
|
||||
height: 30px; }
|
||||
md-autocomplete md-autocomplete-wrap {
|
||||
display: block;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
height: 40px; }
|
||||
md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate] {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
transition: none; }
|
||||
md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate] .md-container {
|
||||
transition: none;
|
||||
top: auto;
|
||||
height: 3px; }
|
||||
md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate].ng-enter {
|
||||
transition: opacity 0.15s linear; }
|
||||
md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate].ng-enter.ng-enter-active {
|
||||
opacity: 1; }
|
||||
md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate].ng-leave {
|
||||
transition: opacity 0.15s linear; }
|
||||
md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate].ng-leave.ng-leave-active {
|
||||
opacity: 0; }
|
||||
md-autocomplete input:not(.md-input) {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0 15px;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
height: 40px;
|
||||
outline: none;
|
||||
background: transparent; }
|
||||
md-autocomplete input:not(.md-input)::-ms-clear {
|
||||
display: none; }
|
||||
md-autocomplete button {
|
||||
position: relative;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
background: transparent;
|
||||
margin: auto 5px; }
|
||||
md-autocomplete button:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: -6px;
|
||||
bottom: -6px;
|
||||
left: -6px;
|
||||
border-radius: 50%;
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
opacity: 0;
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); }
|
||||
md-autocomplete button:focus {
|
||||
outline: none; }
|
||||
md-autocomplete button:focus:after {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 1; }
|
||||
md-autocomplete button md-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate3d(-50%, -50%, 0) scale(0.9);
|
||||
transform: translate3d(-50%, -50%, 0) scale(0.9); }
|
||||
md-autocomplete button md-icon path {
|
||||
stroke-width: 0; }
|
||||
md-autocomplete button.ng-enter {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
transition: -webkit-transform 0.15s ease-out;
|
||||
transition: transform 0.15s ease-out; }
|
||||
md-autocomplete button.ng-enter.ng-enter-active {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1); }
|
||||
md-autocomplete button.ng-leave {
|
||||
transition: -webkit-transform 0.15s ease-out;
|
||||
transition: transform 0.15s ease-out; }
|
||||
md-autocomplete button.ng-leave.ng-leave-active {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0); }
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
md-autocomplete input {
|
||||
border: 1px solid #fff; }
|
||||
md-autocomplete li:focus {
|
||||
color: #fff; } }
|
||||
|
||||
.md-autocomplete-suggestions {
|
||||
position: absolute;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
max-height: 225.5px;
|
||||
z-index: 100; }
|
||||
.md-autocomplete-suggestions li {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
padding: 0 15px;
|
||||
line-height: 48px;
|
||||
height: 48px;
|
||||
transition: background 0.15s linear;
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis; }
|
||||
.md-autocomplete-suggestions li.ng-enter, .md-autocomplete-suggestions li.ng-hide-remove {
|
||||
transition: none;
|
||||
-webkit-animation: md-autocomplete-list-in 0.2s;
|
||||
animation: md-autocomplete-list-in 0.2s; }
|
||||
.md-autocomplete-suggestions li.ng-leave, .md-autocomplete-suggestions li.ng-hide-add {
|
||||
transition: none;
|
||||
-webkit-animation: md-autocomplete-list-out 0.2s;
|
||||
animation: md-autocomplete-list-out 0.2s; }
|
||||
.md-autocomplete-suggestions li:focus {
|
||||
outline: none; }
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
md-autocomplete, .md-autocomplete-suggestions {
|
||||
border: 1px solid #fff; } }
|
||||
951
www/lib/angular-material/modules/js/autocomplete/autocomplete.js
vendored
Normal file
951
www/lib/angular-material/modules/js/autocomplete/autocomplete.js
vendored
Normal file
@@ -0,0 +1,951 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.autocomplete
|
||||
*/
|
||||
/*
|
||||
* @see js folder for autocomplete implementation
|
||||
*/
|
||||
angular.module('material.components.autocomplete', [
|
||||
'material.core',
|
||||
'material.components.icon'
|
||||
]);
|
||||
|
||||
angular
|
||||
.module('material.components.autocomplete')
|
||||
.controller('MdAutocompleteCtrl', MdAutocompleteCtrl);
|
||||
|
||||
var ITEM_HEIGHT = 41,
|
||||
MAX_HEIGHT = 5.5 * ITEM_HEIGHT,
|
||||
MENU_PADDING = 8;
|
||||
|
||||
function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $mdTheming, $window,
|
||||
$animate, $rootElement, $attrs) {
|
||||
//-- private variables
|
||||
var ctrl = this,
|
||||
itemParts = $scope.itemsExpr.split(/ in /i),
|
||||
itemExpr = itemParts[1],
|
||||
elements = null,
|
||||
promise = null,
|
||||
cache = {},
|
||||
noBlur = false,
|
||||
selectedItemWatchers = [],
|
||||
hasFocus = false,
|
||||
lastCount = 0;
|
||||
|
||||
//-- public variables with handlers
|
||||
defineProperty('hidden', handleHiddenChange, true);
|
||||
|
||||
//-- public variables
|
||||
ctrl.scope = $scope;
|
||||
ctrl.parent = $scope.$parent;
|
||||
ctrl.itemName = itemParts[0];
|
||||
ctrl.matches = [];
|
||||
ctrl.loading = false;
|
||||
ctrl.hidden = true;
|
||||
ctrl.index = null;
|
||||
ctrl.messages = [];
|
||||
ctrl.id = $mdUtil.nextUid();
|
||||
ctrl.isDisabled = null;
|
||||
ctrl.isRequired = null;
|
||||
|
||||
//-- public methods
|
||||
ctrl.keydown = keydown;
|
||||
ctrl.blur = blur;
|
||||
ctrl.focus = focus;
|
||||
ctrl.clear = clearValue;
|
||||
ctrl.select = select;
|
||||
ctrl.listEnter = onListEnter;
|
||||
ctrl.listLeave = onListLeave;
|
||||
ctrl.mouseUp = onMouseup;
|
||||
ctrl.getCurrentDisplayValue = getCurrentDisplayValue;
|
||||
ctrl.registerSelectedItemWatcher = registerSelectedItemWatcher;
|
||||
ctrl.unregisterSelectedItemWatcher = unregisterSelectedItemWatcher;
|
||||
|
||||
return init();
|
||||
|
||||
//-- initialization methods
|
||||
|
||||
/**
|
||||
* Initialize the controller, setup watchers, gather elements
|
||||
*/
|
||||
function init () {
|
||||
$mdUtil.initOptionalProperties($scope, $attrs, { searchText: null, selectedItem: null } );
|
||||
$mdTheming($element);
|
||||
configureWatchers();
|
||||
$timeout(function () {
|
||||
gatherElements();
|
||||
focusElement();
|
||||
moveDropdown();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the dropdown's position and applies the new styles to the menu element
|
||||
* @returns {*}
|
||||
*/
|
||||
function positionDropdown () {
|
||||
if (!elements) return $timeout(positionDropdown, 0, false);
|
||||
var hrect = elements.wrap.getBoundingClientRect(),
|
||||
vrect = elements.snap.getBoundingClientRect(),
|
||||
root = elements.root.getBoundingClientRect(),
|
||||
top = vrect.bottom - root.top,
|
||||
bot = root.bottom - vrect.top,
|
||||
left = hrect.left - root.left,
|
||||
width = hrect.width,
|
||||
styles = {
|
||||
left: left + 'px',
|
||||
minWidth: width + 'px',
|
||||
maxWidth: Math.max(hrect.right - root.left, root.right - hrect.left) - MENU_PADDING + 'px'
|
||||
};
|
||||
if (top > bot && root.height - hrect.bottom - MENU_PADDING < MAX_HEIGHT) {
|
||||
styles.top = 'auto';
|
||||
styles.bottom = bot + 'px';
|
||||
styles.maxHeight = Math.min(MAX_HEIGHT, hrect.top - root.top - MENU_PADDING) + 'px';
|
||||
} else {
|
||||
styles.top = top + 'px';
|
||||
styles.bottom = 'auto';
|
||||
styles.maxHeight = Math.min(MAX_HEIGHT, root.bottom - hrect.bottom - MENU_PADDING) + 'px';
|
||||
}
|
||||
elements.$.ul.css(styles);
|
||||
$timeout(correctHorizontalAlignment, 0, false);
|
||||
|
||||
/**
|
||||
* Makes sure that the menu doesn't go off of the screen on either side.
|
||||
*/
|
||||
function correctHorizontalAlignment () {
|
||||
var dropdown = elements.ul.getBoundingClientRect(),
|
||||
styles = {};
|
||||
if (dropdown.right > root.right - MENU_PADDING) {
|
||||
styles.left = (hrect.right - dropdown.width) + 'px';
|
||||
}
|
||||
elements.$.ul.css(styles);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the dropdown menu to the body tag in order to avoid z-index and overflow issues.
|
||||
*/
|
||||
function moveDropdown () {
|
||||
if (!elements.$.root.length) return;
|
||||
$mdTheming(elements.$.ul);
|
||||
elements.$.ul.detach();
|
||||
elements.$.root.append(elements.$.ul);
|
||||
if ($animate.pin) $animate.pin(elements.$.ul, $rootElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends focus to the input element.
|
||||
*/
|
||||
function focusElement () {
|
||||
if ($scope.autofocus) elements.input.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up any watchers used by autocomplete
|
||||
*/
|
||||
function configureWatchers () {
|
||||
var wait = parseInt($scope.delay, 10) || 0;
|
||||
$attrs.$observe('disabled', function (value) { ctrl.isDisabled = value; });
|
||||
$attrs.$observe('required', function (value) { ctrl.isRequired = value !== null; });
|
||||
$scope.$watch('searchText', wait ? $mdUtil.debounce(handleSearchText, wait) : handleSearchText);
|
||||
registerSelectedItemWatcher(selectedItemChange);
|
||||
$scope.$watch('selectedItem', handleSelectedItemChange);
|
||||
angular.element($window).on('resize', positionDropdown);
|
||||
$scope.$on('$destroy', cleanup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes any events or leftover elements created by this controller
|
||||
*/
|
||||
function cleanup () {
|
||||
angular.element($window).off('resize', positionDropdown);
|
||||
elements.$.ul.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers all of the elements needed for this controller
|
||||
*/
|
||||
function gatherElements () {
|
||||
elements = {
|
||||
main: $element[0],
|
||||
ul: $element.find('ul')[0],
|
||||
input: $element.find('input')[0],
|
||||
wrap: $element.find('md-autocomplete-wrap')[0],
|
||||
root: document.body
|
||||
};
|
||||
elements.li = elements.ul.getElementsByTagName('li');
|
||||
elements.snap = getSnapTarget();
|
||||
elements.$ = getAngularElements(elements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the element that the menu will base its position on
|
||||
* @returns {*}
|
||||
*/
|
||||
function getSnapTarget () {
|
||||
for (var element = $element; element.length; element = element.parent()) {
|
||||
if (angular.isDefined(element.attr('md-autocomplete-snap'))) return element[0];
|
||||
}
|
||||
return elements.wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gathers angular-wrapped versions of each element
|
||||
* @param elements
|
||||
* @returns {{}}
|
||||
*/
|
||||
function getAngularElements (elements) {
|
||||
var obj = {};
|
||||
for (var key in elements) {
|
||||
obj[key] = angular.element(elements[key]);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
//-- event/change handlers
|
||||
|
||||
/**
|
||||
* Handles changes to the `hidden` property.
|
||||
* @param hidden
|
||||
* @param oldHidden
|
||||
*/
|
||||
function handleHiddenChange (hidden, oldHidden) {
|
||||
if (!hidden && oldHidden) positionDropdown();
|
||||
if (!hidden) {
|
||||
if (elements) $timeout(function () { $mdUtil.disableScrollAround(elements.ul); }, 0, false);
|
||||
} else {
|
||||
$mdUtil.enableScrolling();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When the user mouses over the dropdown menu, ignore blur events.
|
||||
*/
|
||||
function onListEnter () {
|
||||
noBlur = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the user's mouse leaves the menu, blur events may hide the menu again.
|
||||
*/
|
||||
function onListLeave () {
|
||||
noBlur = false;
|
||||
if (!hasFocus) ctrl.hidden = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the mouse button is released, send focus back to the input field.
|
||||
*/
|
||||
function onMouseup () {
|
||||
elements.input.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changes to the selected item.
|
||||
* @param selectedItem
|
||||
* @param previousSelectedItem
|
||||
*/
|
||||
function selectedItemChange (selectedItem, previousSelectedItem) {
|
||||
if (selectedItem) {
|
||||
$scope.searchText = getDisplayValue(selectedItem);
|
||||
}
|
||||
if ($scope.itemChange && selectedItem !== previousSelectedItem)
|
||||
$scope.itemChange(getItemScope(selectedItem));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls any external watchers listening for the selected item. Used in conjunction with
|
||||
* `registerSelectedItemWatcher`.
|
||||
* @param selectedItem
|
||||
* @param previousSelectedItem
|
||||
*/
|
||||
function handleSelectedItemChange(selectedItem, previousSelectedItem) {
|
||||
for (var i = 0; i < selectedItemWatchers.length; ++i) {
|
||||
selectedItemWatchers[i](selectedItem, previousSelectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a function to be called when the selected item changes.
|
||||
* @param cb
|
||||
*/
|
||||
function registerSelectedItemWatcher(cb) {
|
||||
if (selectedItemWatchers.indexOf(cb) == -1) {
|
||||
selectedItemWatchers.push(cb);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a function previously registered for selected item changes.
|
||||
* @param cb
|
||||
*/
|
||||
function unregisterSelectedItemWatcher(cb) {
|
||||
var i = selectedItemWatchers.indexOf(cb);
|
||||
if (i != -1) {
|
||||
selectedItemWatchers.splice(i, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles changes to the searchText property.
|
||||
* @param searchText
|
||||
* @param previousSearchText
|
||||
*/
|
||||
function handleSearchText (searchText, previousSearchText) {
|
||||
ctrl.index = getDefaultIndex();
|
||||
//-- do nothing on init
|
||||
if (searchText === previousSearchText) return;
|
||||
//-- clear selected item if search text no longer matches it
|
||||
if (searchText !== getDisplayValue($scope.selectedItem)) $scope.selectedItem = null;
|
||||
else return;
|
||||
//-- trigger change event if available
|
||||
if ($scope.textChange && searchText !== previousSearchText)
|
||||
$scope.textChange(getItemScope($scope.selectedItem));
|
||||
//-- cancel results if search text is not long enough
|
||||
if (!isMinLengthMet()) {
|
||||
ctrl.loading = false;
|
||||
ctrl.matches = [];
|
||||
ctrl.hidden = shouldHide();
|
||||
updateMessages();
|
||||
} else {
|
||||
handleQuery();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles input blur event, determines if the dropdown should hide.
|
||||
*/
|
||||
function blur () {
|
||||
hasFocus = false;
|
||||
if (!noBlur) ctrl.hidden = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles input focus event, determines if the dropdown should show.
|
||||
*/
|
||||
function focus () {
|
||||
hasFocus = true;
|
||||
//-- if searchText is null, let's force it to be a string
|
||||
if (!angular.isString($scope.searchText)) $scope.searchText = '';
|
||||
if ($scope.minLength > 0) return;
|
||||
ctrl.hidden = shouldHide();
|
||||
if (!ctrl.hidden) handleQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles keyboard input.
|
||||
* @param event
|
||||
*/
|
||||
function keydown (event) {
|
||||
switch (event.keyCode) {
|
||||
case $mdConstant.KEY_CODE.DOWN_ARROW:
|
||||
if (ctrl.loading) return;
|
||||
event.preventDefault();
|
||||
ctrl.index = Math.min(ctrl.index + 1, ctrl.matches.length - 1);
|
||||
updateScroll();
|
||||
updateMessages();
|
||||
break;
|
||||
case $mdConstant.KEY_CODE.UP_ARROW:
|
||||
if (ctrl.loading) return;
|
||||
event.preventDefault();
|
||||
ctrl.index = ctrl.index < 0 ? ctrl.matches.length - 1 : Math.max(0, ctrl.index - 1);
|
||||
updateScroll();
|
||||
updateMessages();
|
||||
break;
|
||||
case $mdConstant.KEY_CODE.TAB:
|
||||
case $mdConstant.KEY_CODE.ENTER:
|
||||
if (ctrl.hidden || ctrl.loading || ctrl.index < 0 || ctrl.matches.length < 1) return;
|
||||
event.preventDefault();
|
||||
select(ctrl.index);
|
||||
break;
|
||||
case $mdConstant.KEY_CODE.ESCAPE:
|
||||
ctrl.matches = [];
|
||||
ctrl.hidden = true;
|
||||
ctrl.index = getDefaultIndex();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
//-- getters
|
||||
|
||||
/**
|
||||
* Returns the minimum length needed to display the dropdown.
|
||||
* @returns {*}
|
||||
*/
|
||||
function getMinLength () {
|
||||
return angular.isNumber($scope.minLength) ? $scope.minLength : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display value for an item.
|
||||
* @param item
|
||||
* @returns {*}
|
||||
*/
|
||||
function getDisplayValue (item) {
|
||||
return (item && $scope.itemText) ? $scope.itemText(getItemScope(item)) : item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the locals object for compiling item templates.
|
||||
* @param item
|
||||
* @returns {{}}
|
||||
*/
|
||||
function getItemScope (item) {
|
||||
if (!item) return;
|
||||
var locals = {};
|
||||
if (ctrl.itemName) locals[ctrl.itemName] = item;
|
||||
return locals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default index based on whether or not autoselect is enabled.
|
||||
* @returns {number}
|
||||
*/
|
||||
function getDefaultIndex () {
|
||||
return $scope.autoselect ? 0 : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the menu should be hidden.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function shouldHide () {
|
||||
if (!isMinLengthMet()) return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the display value of the current item.
|
||||
* @returns {*}
|
||||
*/
|
||||
function getCurrentDisplayValue () {
|
||||
return getDisplayValue(ctrl.matches[ctrl.index]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the minimum length is met by the search text.
|
||||
* @returns {*}
|
||||
*/
|
||||
function isMinLengthMet () {
|
||||
return angular.isDefined($scope.searchText) && $scope.searchText.length >= getMinLength();
|
||||
}
|
||||
|
||||
//-- actions
|
||||
|
||||
/**
|
||||
* Defines a public property with a handler and a default value.
|
||||
* @param key
|
||||
* @param handler
|
||||
* @param value
|
||||
*/
|
||||
function defineProperty (key, handler, value) {
|
||||
Object.defineProperty(ctrl, key, {
|
||||
get: function () { return value; },
|
||||
set: function (newValue) {
|
||||
var oldValue = value;
|
||||
value = newValue;
|
||||
handler(newValue, oldValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the item at the given index.
|
||||
* @param index
|
||||
*/
|
||||
function select (index) {
|
||||
$scope.selectedItem = ctrl.matches[index];
|
||||
ctrl.hidden = true;
|
||||
ctrl.index = 0;
|
||||
ctrl.matches = [];
|
||||
//-- force form to update state for validation
|
||||
$timeout(function () {
|
||||
elements.$.input.controller('ngModel').$setViewValue(getDisplayValue($scope.selectedItem) ||
|
||||
$scope.searchText);
|
||||
ctrl.hidden = true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the searchText value and selected item.
|
||||
*/
|
||||
function clearValue () {
|
||||
$scope.searchText = '';
|
||||
select(-1);
|
||||
|
||||
// Per http://www.w3schools.com/jsref/event_oninput.asp
|
||||
var eventObj = document.createEvent('CustomEvent');
|
||||
eventObj.initCustomEvent('input', true, true, {value: $scope.searchText});
|
||||
elements.input.dispatchEvent(eventObj);
|
||||
|
||||
elements.input.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the results for the provided search text.
|
||||
* @param searchText
|
||||
*/
|
||||
function fetchResults (searchText) {
|
||||
var items = $scope.$parent.$eval(itemExpr),
|
||||
term = searchText.toLowerCase();
|
||||
if (angular.isArray(items)) {
|
||||
handleResults(items);
|
||||
} else if (items) {
|
||||
ctrl.loading = true;
|
||||
if (items.success) items.success(handleResults);
|
||||
if (items.then) items.then(handleResults);
|
||||
if (items.error) items.error(function () { ctrl.loading = false; });
|
||||
}
|
||||
function handleResults (matches) {
|
||||
cache[term] = matches;
|
||||
if (searchText !== $scope.searchText) return; //-- just cache the results if old request
|
||||
ctrl.loading = false;
|
||||
promise = null;
|
||||
ctrl.matches = matches;
|
||||
ctrl.hidden = shouldHide();
|
||||
updateMessages();
|
||||
positionDropdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the ARIA messages
|
||||
*/
|
||||
function updateMessages () {
|
||||
ctrl.messages = [ getCountMessage(), getCurrentDisplayValue() ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ARIA message for how many results match the current query.
|
||||
* @returns {*}
|
||||
*/
|
||||
function getCountMessage () {
|
||||
if (lastCount === ctrl.matches.length) return '';
|
||||
lastCount = ctrl.matches.length;
|
||||
switch (ctrl.matches.length) {
|
||||
case 0: return 'There are no matches available.';
|
||||
case 1: return 'There is 1 match available.';
|
||||
default: return 'There are ' + ctrl.matches.length + ' matches available.';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure that the focused element is within view.
|
||||
*/
|
||||
function updateScroll () {
|
||||
if (!elements.li[ctrl.index]) return;
|
||||
var li = elements.li[ctrl.index],
|
||||
top = li.offsetTop,
|
||||
bot = top + li.offsetHeight,
|
||||
hgt = elements.ul.clientHeight;
|
||||
if (top < elements.ul.scrollTop) {
|
||||
elements.ul.scrollTop = top;
|
||||
} else if (bot > elements.ul.scrollTop + hgt) {
|
||||
elements.ul.scrollTop = bot - hgt;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the query to gather the results for the current searchText. Attempts to return cached
|
||||
* results first, then forwards the process to `fetchResults` if necessary.
|
||||
*/
|
||||
function handleQuery () {
|
||||
var searchText = $scope.searchText,
|
||||
term = searchText.toLowerCase();
|
||||
//-- cancel promise if a promise is in progress
|
||||
if (promise && promise.cancel) {
|
||||
promise.cancel();
|
||||
promise = null;
|
||||
}
|
||||
//-- if results are cached, pull in cached results
|
||||
if (!$scope.noCache && cache[term]) {
|
||||
ctrl.matches = cache[term];
|
||||
updateMessages();
|
||||
} else {
|
||||
fetchResults(searchText);
|
||||
}
|
||||
if (hasFocus) ctrl.hidden = shouldHide();
|
||||
}
|
||||
|
||||
}
|
||||
MdAutocompleteCtrl.$inject = ["$scope", "$element", "$mdUtil", "$mdConstant", "$timeout", "$mdTheming", "$window", "$animate", "$rootElement", "$attrs"];
|
||||
|
||||
angular
|
||||
.module('material.components.autocomplete')
|
||||
.directive('mdAutocomplete', MdAutocomplete);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdAutocomplete
|
||||
* @module material.components.autocomplete
|
||||
*
|
||||
* @description
|
||||
* `<md-autocomplete>` is a special input component with a drop-down of all possible matches to a custom query.
|
||||
* This component allows you to provide real-time suggestions as the user types in the input area.
|
||||
*
|
||||
* To start, you will need to specify the required parameters and provide a template for your results.
|
||||
* The content inside `md-autocomplete` will be treated as a template.
|
||||
*
|
||||
* In more complex cases, you may want to include other content such as a message to display when
|
||||
* no matches were found. You can do this by wrapping your template in `md-item-template` and adding
|
||||
* a tag for `md-not-found`. An example of this is shown below.
|
||||
* ### Validation
|
||||
*
|
||||
* You can use `ng-messages` to include validation the same way that you would normally validate;
|
||||
* however, if you want to replicate a standard input with a floating label, you will have to do the
|
||||
* following:
|
||||
*
|
||||
* - Make sure that your template is wrapped in `md-item-template`
|
||||
* - Add your `ng-messages` code inside of `md-autocomplete`
|
||||
* - Add your validation properties to `md-autocomplete` (ie. `required`)
|
||||
* - Add a `name` to `md-autocomplete` (to be used on the generated `input`)
|
||||
*
|
||||
* There is an example below of how this should look.
|
||||
*
|
||||
*
|
||||
* @param {expression} md-items An expression in the format of `item in items` to iterate over matches for your search.
|
||||
* @param {expression=} md-selected-item-change An expression to be run each time a new item is selected
|
||||
* @param {expression=} md-search-text-change An expression to be run each time the search text updates
|
||||
* @param {string=} md-search-text A model to bind the search query text to
|
||||
* @param {object=} md-selected-item A model to bind the selected item to
|
||||
* @param {string=} md-item-text An expression that will convert your object to a single string.
|
||||
* @param {string=} placeholder Placeholder text that will be forwarded to the input.
|
||||
* @param {boolean=} md-no-cache Disables the internal caching that happens in autocomplete
|
||||
* @param {boolean=} ng-disabled Determines whether or not to disable the input field
|
||||
* @param {number=} md-min-length Specifies the minimum length of text before autocomplete will make suggestions
|
||||
* @param {number=} md-delay Specifies the amount of time (in milliseconds) to wait before looking for results
|
||||
* @param {boolean=} md-autofocus If true, will immediately focus the input element
|
||||
* @param {boolean=} md-autoselect If true, the first item will be selected by default
|
||||
* @param {string=} md-menu-class This will be applied to the dropdown menu for styling
|
||||
* @param {string=} md-floating-label This will add a floating label to autocomplete and wrap it in `md-input-container`
|
||||
*
|
||||
* @usage
|
||||
* ###Basic Example
|
||||
* <hljs lang="html">
|
||||
* <md-autocomplete
|
||||
* md-selected-item="selectedItem"
|
||||
* md-search-text="searchText"
|
||||
* md-items="item in getMatches(searchText)"
|
||||
* md-item-text="item.display">
|
||||
* <span md-highlight-text="searchText">{{item.display}}</span>
|
||||
* </md-autocomplete>
|
||||
* </hljs>
|
||||
*
|
||||
* ###Example with "not found" message
|
||||
* <hljs lang="html">
|
||||
* <md-autocomplete
|
||||
* md-selected-item="selectedItem"
|
||||
* md-search-text="searchText"
|
||||
* md-items="item in getMatches(searchText)"
|
||||
* md-item-text="item.display">
|
||||
* <md-item-template>
|
||||
* <span md-highlight-text="searchText">{{item.display}}</span>
|
||||
* </md-item-template>
|
||||
* <md-not-found>
|
||||
* No matches found.
|
||||
* </md-not-found>
|
||||
* </md-autocomplete>
|
||||
* </hljs>
|
||||
*
|
||||
* In this example, our code utilizes `md-item-template` and `md-not-found` to specify the different
|
||||
* parts that make up our component.
|
||||
*
|
||||
* ### Example with validation
|
||||
* <hljs lang="html">
|
||||
* <form name="autocompleteForm">
|
||||
* <md-autocomplete
|
||||
* required
|
||||
* input-name="autocomplete"
|
||||
* md-selected-item="selectedItem"
|
||||
* md-search-text="searchText"
|
||||
* md-items="item in getMatches(searchText)"
|
||||
* md-item-text="item.display">
|
||||
* <md-item-template>
|
||||
* <span md-highlight-text="searchText">{{item.display}}</span>
|
||||
* </md-item-template>
|
||||
* <div ng-messages="autocompleteForm.autocomplete.$error">
|
||||
* <div ng-message="required">This field is required</div>
|
||||
* </div>
|
||||
* </md-autocomplete>
|
||||
* </form>
|
||||
* </hljs>
|
||||
*
|
||||
* In this example, our code utilizes `md-item-template` and `md-not-found` to specify the different
|
||||
* parts that make up our component.
|
||||
*/
|
||||
|
||||
function MdAutocomplete ($mdTheming, $mdUtil) {
|
||||
return {
|
||||
controller: 'MdAutocompleteCtrl',
|
||||
controllerAs: '$mdAutocompleteCtrl',
|
||||
scope: {
|
||||
inputName: '@mdInputName',
|
||||
inputMinlength: '@mdInputMinlength',
|
||||
inputMaxlength: '@mdInputMaxlength',
|
||||
searchText: '=?mdSearchText',
|
||||
selectedItem: '=?mdSelectedItem',
|
||||
itemsExpr: '@mdItems',
|
||||
itemText: '&mdItemText',
|
||||
placeholder: '@placeholder',
|
||||
noCache: '=?mdNoCache',
|
||||
itemChange: '&?mdSelectedItemChange',
|
||||
textChange: '&?mdSearchTextChange',
|
||||
minLength: '=?mdMinLength',
|
||||
delay: '=?mdDelay',
|
||||
autofocus: '=?mdAutofocus',
|
||||
floatingLabel: '@?mdFloatingLabel',
|
||||
autoselect: '=?mdAutoselect',
|
||||
menuClass: '@?mdMenuClass'
|
||||
},
|
||||
template: function (element, attr) {
|
||||
var noItemsTemplate = getNoItemsTemplate(),
|
||||
itemTemplate = getItemTemplate(),
|
||||
leftover = element.html();
|
||||
return '\
|
||||
<md-autocomplete-wrap\
|
||||
layout="row"\
|
||||
ng-class="{ \'md-whiteframe-z1\': !floatingLabel }"\
|
||||
role="listbox">\
|
||||
' + getInputElement() + '\
|
||||
<md-progress-linear\
|
||||
ng-if="$mdAutocompleteCtrl.loading"\
|
||||
md-mode="indeterminate"></md-progress-linear>\
|
||||
<ul role="presentation"\
|
||||
class="md-autocomplete-suggestions md-whiteframe-z1 {{menuClass || \'\'}}"\
|
||||
id="ul-{{$mdAutocompleteCtrl.id}}"\
|
||||
ng-hide="$mdAutocompleteCtrl.hidden"\
|
||||
ng-mouseenter="$mdAutocompleteCtrl.listEnter()"\
|
||||
ng-mouseleave="$mdAutocompleteCtrl.listLeave()"\
|
||||
ng-mouseup="$mdAutocompleteCtrl.mouseUp()">\
|
||||
<li ng-repeat="(index, item) in $mdAutocompleteCtrl.matches"\
|
||||
ng-class="{ selected: index === $mdAutocompleteCtrl.index }"\
|
||||
ng-click="$mdAutocompleteCtrl.select(index)"\
|
||||
md-autocomplete-list-item="$mdAutocompleteCtrl.itemName">\
|
||||
' + itemTemplate + '\
|
||||
</li>\
|
||||
' + noItemsTemplate + '\
|
||||
</ul>\
|
||||
</md-autocomplete-wrap>\
|
||||
<aria-status\
|
||||
class="md-visually-hidden"\
|
||||
role="status"\
|
||||
aria-live="assertive">\
|
||||
<p ng-repeat="message in $mdAutocompleteCtrl.messages" ng-if="message">{{message}}</p>\
|
||||
</aria-status>';
|
||||
|
||||
function getItemTemplate() {
|
||||
var templateTag = element.find('md-item-template').remove(),
|
||||
html = templateTag.length ? templateTag.html() : element.html();
|
||||
if (!templateTag.length) element.empty();
|
||||
return html;
|
||||
}
|
||||
|
||||
function getNoItemsTemplate() {
|
||||
var templateTag = element.find('md-not-found').remove(),
|
||||
template = templateTag.length ? templateTag.html() : '';
|
||||
return template
|
||||
? '<li ng-if="!$mdAutocompleteCtrl.matches.length && !$mdAutocompleteCtrl.loading\
|
||||
&& !$mdAutocompleteCtrl.hidden"\
|
||||
ng-hide="$mdAutocompleteCtrl.hidden"\
|
||||
md-autocomplete-parent-scope>' + template + '</li>'
|
||||
: '';
|
||||
|
||||
}
|
||||
|
||||
function getInputElement() {
|
||||
if (attr.mdFloatingLabel) {
|
||||
return '\
|
||||
<md-input-container flex ng-if="floatingLabel">\
|
||||
<label>{{floatingLabel}}</label>\
|
||||
<input type="search"\
|
||||
id="fl-input-{{$mdAutocompleteCtrl.id}}"\
|
||||
name="{{inputName}}"\
|
||||
autocomplete="off"\
|
||||
ng-required="isRequired"\
|
||||
ng-minlength="inputMinlength"\
|
||||
ng-maxlength="inputMaxlength"\
|
||||
ng-disabled="$mdAutocompleteCtrl.isDisabled"\
|
||||
ng-model="$mdAutocompleteCtrl.scope.searchText"\
|
||||
ng-keydown="$mdAutocompleteCtrl.keydown($event)"\
|
||||
ng-blur="$mdAutocompleteCtrl.blur()"\
|
||||
ng-focus="$mdAutocompleteCtrl.focus()"\
|
||||
aria-owns="ul-{{$mdAutocompleteCtrl.id}}"\
|
||||
aria-label="{{floatingLabel}}"\
|
||||
aria-autocomplete="list"\
|
||||
aria-haspopup="true"\
|
||||
aria-activedescendant=""\
|
||||
aria-expanded="{{!$mdAutocompleteCtrl.hidden}}"/>\
|
||||
<div md-autocomplete-parent-scope md-autocomplete-replace>' + leftover + '</div>\
|
||||
</md-input-container>';
|
||||
} else {
|
||||
return '\
|
||||
<input flex type="search"\
|
||||
id="input-{{$mdAutocompleteCtrl.id}}"\
|
||||
name="{{inputName}}"\
|
||||
ng-if="!floatingLabel"\
|
||||
autocomplete="off"\
|
||||
ng-required="isRequired"\
|
||||
ng-disabled="$mdAutocompleteCtrl.isDisabled"\
|
||||
ng-model="$mdAutocompleteCtrl.scope.searchText"\
|
||||
ng-keydown="$mdAutocompleteCtrl.keydown($event)"\
|
||||
ng-blur="$mdAutocompleteCtrl.blur()"\
|
||||
ng-focus="$mdAutocompleteCtrl.focus()"\
|
||||
placeholder="{{placeholder}}"\
|
||||
aria-owns="ul-{{$mdAutocompleteCtrl.id}}"\
|
||||
aria-label="{{placeholder}}"\
|
||||
aria-autocomplete="list"\
|
||||
aria-haspopup="true"\
|
||||
aria-activedescendant=""\
|
||||
aria-expanded="{{!$mdAutocompleteCtrl.hidden}}"/>\
|
||||
<button\
|
||||
type="button"\
|
||||
tabindex="-1"\
|
||||
ng-if="$mdAutocompleteCtrl.scope.searchText && !$mdAutocompleteCtrl.isDisabled"\
|
||||
ng-click="$mdAutocompleteCtrl.clear()">\
|
||||
<md-icon md-svg-icon="md-close"></md-icon>\
|
||||
<span class="md-visually-hidden">Clear</span>\
|
||||
</button>\
|
||||
';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
MdAutocomplete.$inject = ["$mdTheming", "$mdUtil"];
|
||||
|
||||
angular
|
||||
.module('material.components.autocomplete')
|
||||
.controller('MdHighlightCtrl', MdHighlightCtrl);
|
||||
|
||||
function MdHighlightCtrl ($scope, $element, $interpolate) {
|
||||
this.init = init;
|
||||
|
||||
return init();
|
||||
|
||||
function init (term) {
|
||||
var unsafeText = $interpolate($element.html())($scope),
|
||||
text = angular.element('<div>').text(unsafeText).html(),
|
||||
flags = $element.attr('md-highlight-flags') || '',
|
||||
watcher = $scope.$watch(term, function (term) {
|
||||
var regex = getRegExp(term, flags),
|
||||
html = text.replace(regex, '<span class="highlight">$&</span>');
|
||||
$element.html(html);
|
||||
});
|
||||
$element.on('$destroy', function () { watcher(); });
|
||||
}
|
||||
|
||||
function sanitize (term) {
|
||||
if (!term) return term;
|
||||
return term.replace(/[\\\^\$\*\+\?\.\(\)\|\{\}\[\]]/g, '\\$&');
|
||||
}
|
||||
|
||||
function getRegExp (text, flags) {
|
||||
var str = '';
|
||||
if (flags.indexOf('^') >= 1) str += '^';
|
||||
str += text;
|
||||
if (flags.indexOf('$') >= 1) str += '$';
|
||||
return new RegExp(sanitize(str), flags.replace(/[\$\^]/g, ''));
|
||||
}
|
||||
}
|
||||
MdHighlightCtrl.$inject = ["$scope", "$element", "$interpolate"];
|
||||
|
||||
angular
|
||||
.module('material.components.autocomplete')
|
||||
.directive('mdHighlightText', MdHighlight);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdHighlightText
|
||||
* @module material.components.autocomplete
|
||||
*
|
||||
* @description
|
||||
* The `md-highlight-text` directive allows you to specify text that should be highlighted within
|
||||
* an element. Highlighted text will be wrapped in `<span class="highlight"></span>` which can
|
||||
* be styled through CSS. Please note that child elements may not be used with this directive.
|
||||
*
|
||||
* @param {string} md-highlight-text A model to be searched for
|
||||
* @param {string=} md-highlight-flags A list of flags (loosely based on JavaScript RexExp flags).
|
||||
* #### **Supported flags**:
|
||||
* - `g`: Find all matches within the provided text
|
||||
* - `i`: Ignore case when searching for matches
|
||||
* - `$`: Only match if the text ends with the search term
|
||||
* - `^`: Only match if the text begins with the search term
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <input placeholder="Enter a search term..." ng-model="searchTerm" type="text" />
|
||||
* <ul>
|
||||
* <li ng-repeat="result in results" md-highlight-text="searchTerm">
|
||||
* {{result.text}}
|
||||
* </li>
|
||||
* </ul>
|
||||
* </hljs>
|
||||
*/
|
||||
|
||||
function MdHighlight () {
|
||||
return {
|
||||
terminal: true,
|
||||
scope: false,
|
||||
controller: 'MdHighlightCtrl',
|
||||
link: function (scope, element, attr, ctrl) {
|
||||
ctrl.init(attr.mdHighlightText);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
angular
|
||||
.module('material.components.autocomplete')
|
||||
.directive('mdAutocompleteListItem', MdAutocompleteListItem);
|
||||
|
||||
function MdAutocompleteListItem ($compile, $mdUtil) {
|
||||
return {
|
||||
terminal: true,
|
||||
link: postLink,
|
||||
scope: false
|
||||
};
|
||||
function postLink (scope, element, attr) {
|
||||
var ctrl = scope.$parent.$mdAutocompleteCtrl,
|
||||
newScope = ctrl.parent.$new(false, ctrl.parent),
|
||||
itemName = ctrl.scope.$eval(attr.mdAutocompleteListItem);
|
||||
newScope[itemName] = scope.item;
|
||||
$compile(element.contents())(newScope);
|
||||
element.attr({
|
||||
role: 'option',
|
||||
id: 'item_' + $mdUtil.nextUid()
|
||||
});
|
||||
}
|
||||
}
|
||||
MdAutocompleteListItem.$inject = ["$compile", "$mdUtil"];
|
||||
|
||||
angular
|
||||
.module('material.components.autocomplete')
|
||||
.directive('mdAutocompleteParentScope', MdAutocompleteParentScope);
|
||||
|
||||
function MdAutocompleteParentScope ($compile, $mdUtil) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
terminal: true,
|
||||
link: postLink,
|
||||
scope: false
|
||||
};
|
||||
function postLink (scope, element, attr) {
|
||||
var ctrl = scope.$parent.$mdAutocompleteCtrl;
|
||||
$compile(element.contents())(ctrl.parent);
|
||||
if (attr.hasOwnProperty('mdAutocompleteReplace')) {
|
||||
element.after(element.contents());
|
||||
element.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
MdAutocompleteParentScope.$inject = ["$compile", "$mdUtil"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/autocomplete/autocomplete.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/autocomplete/autocomplete.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/@-webkit-keyframes md-autocomplete-list-out{0%{-webkit-animation-timing-function:linear;animation-timing-function:linear}50%{opacity:0;height:40px;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{height:0;opacity:0}}@keyframes md-autocomplete-list-out{0%{-webkit-animation-timing-function:linear;animation-timing-function:linear}50%{opacity:0;height:40px;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{height:0;opacity:0}}@-webkit-keyframes md-autocomplete-list-in{0%{opacity:0;height:0;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{opacity:0;height:40px}100%{opacity:1;height:40px}}@keyframes md-autocomplete-list-in{0%{opacity:0;height:0;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{opacity:0;height:40px}100%{opacity:1;height:40px}}md-autocomplete{border-radius:2px;display:block;height:40px;position:relative;overflow:visible;min-width:190px}md-autocomplete[disabled] input{cursor:not-allowed}md-autocomplete[md-floating-label]{padding-bottom:26px;border-radius:0;background:0 0;height:auto}md-autocomplete[md-floating-label] md-input-container{padding-bottom:0}md-autocomplete[md-floating-label] md-autocomplete-wrap{height:auto}md-autocomplete[md-floating-label] button{position:absolute;top:auto;bottom:0;right:0;width:30px;height:30px}md-autocomplete md-autocomplete-wrap{display:block;position:relative;overflow:visible;height:40px}md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate]{position:absolute;bottom:0;left:0;width:100%;height:3px;transition:none}md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate] .md-container{transition:none;top:auto;height:3px}md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate].ng-enter{transition:opacity .15s linear}md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate].ng-enter.ng-enter-active{opacity:1}md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate].ng-leave{transition:opacity .15s linear}md-autocomplete md-autocomplete-wrap md-progress-linear[md-mode=indeterminate].ng-leave.ng-leave-active{opacity:0}md-autocomplete input:not(.md-input){width:100%;box-sizing:border-box;border:none;box-shadow:none;padding:0 15px;font-size:14px;line-height:40px;height:40px;outline:0;background:0 0}md-autocomplete input:not(.md-input)::-ms-clear{display:none}md-autocomplete button{position:relative;line-height:20px;text-align:center;width:30px;height:30px;cursor:pointer;border:none;border-radius:50%;padding:0;font-size:12px;background:0 0;margin:auto 5px}md-autocomplete button:after{content:'';position:absolute;top:-6px;right:-6px;bottom:-6px;left:-6px;border-radius:50%;-webkit-transform:scale(0);transform:scale(0);opacity:0;transition:all .4s cubic-bezier(.25,.8,.25,1)}md-autocomplete button:focus{outline:0}md-autocomplete button:focus:after{-webkit-transform:scale(1);transform:scale(1);opacity:1}md-autocomplete button md-icon{position:absolute;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9)}md-autocomplete button md-icon path{stroke-width:0}md-autocomplete button.ng-enter{-webkit-transform:scale(0);transform:scale(0);transition:-webkit-transform .15s ease-out;transition:transform .15s ease-out}md-autocomplete button.ng-enter.ng-enter-active{-webkit-transform:scale(1);transform:scale(1)}md-autocomplete button.ng-leave{transition:-webkit-transform .15s ease-out;transition:transform .15s ease-out}md-autocomplete button.ng-leave.ng-leave-active{-webkit-transform:scale(0);transform:scale(0)}@media screen and (-ms-high-contrast:active){md-autocomplete input{border:1px solid #fff}md-autocomplete li:focus{color:#fff}}.md-autocomplete-suggestions{position:absolute;margin:0;list-style:none;padding:0;overflow:auto;max-height:225.5px;z-index:100}.md-autocomplete-suggestions li{cursor:pointer;font-size:14px;overflow:hidden;padding:0 15px;line-height:48px;height:48px;transition:background .15s linear;margin:0;white-space:nowrap;text-overflow:ellipsis}.md-autocomplete-suggestions li.ng-enter,.md-autocomplete-suggestions li.ng-hide-remove{transition:none;-webkit-animation:md-autocomplete-list-in .2s;animation:md-autocomplete-list-in .2s}.md-autocomplete-suggestions li.ng-hide-add,.md-autocomplete-suggestions li.ng-leave{transition:none;-webkit-animation:md-autocomplete-list-out .2s;animation:md-autocomplete-list-out .2s}.md-autocomplete-suggestions li:focus{outline:0}@media screen and (-ms-high-contrast:active){.md-autocomplete-suggestions,md-autocomplete{border:1px solid #fff}}
|
||||
7
www/lib/angular-material/modules/js/autocomplete/autocomplete.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/autocomplete/autocomplete.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "angular-material-autocomplete",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0",
|
||||
"angular-material-icon": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-backdrop.md-opaque.md-THEME_NAME-theme {
|
||||
background-color: '{{foreground-4-0.5}}'; }
|
||||
6
www/lib/angular-material/modules/js/backdrop/backdrop-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/backdrop/backdrop-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-backdrop.md-opaque.md-THEME_NAME-theme{background-color:'{{foreground-4-0.5}}'}
|
||||
59
www/lib/angular-material/modules/js/backdrop/backdrop.css
Normal file
59
www/lib/angular-material/modules/js/backdrop/backdrop.css
Normal file
@@ -0,0 +1,59 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-backdrop {
|
||||
z-index: 50;
|
||||
background-color: transparent;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
right: 0; }
|
||||
md-backdrop.md-select-backdrop {
|
||||
z-index: 81; }
|
||||
md-backdrop.md-dialog-backdrop {
|
||||
z-index: 79; }
|
||||
md-backdrop.md-bottom-sheet-backdrop {
|
||||
z-index: 69; }
|
||||
md-backdrop.md-sidenav-backdrop {
|
||||
z-index: 59; }
|
||||
md-backdrop.md-click-catcher {
|
||||
top: 0;
|
||||
position: fixed; }
|
||||
md-backdrop.ng-enter {
|
||||
-webkit-animation: cubic-bezier(0.25, 0.8, 0.25, 1) mdBackdropFadeIn 0.5s both;
|
||||
animation: cubic-bezier(0.25, 0.8, 0.25, 1) mdBackdropFadeIn 0.5s both; }
|
||||
md-backdrop.ng-leave {
|
||||
-webkit-animation: cubic-bezier(0.55, 0, 0.55, 0.2) mdBackdropFadeOut 0.2s both;
|
||||
animation: cubic-bezier(0.55, 0, 0.55, 0.2) mdBackdropFadeOut 0.2s both; }
|
||||
|
||||
@-webkit-keyframes mdBackdropFadeIn {
|
||||
from {
|
||||
opacity: 0; }
|
||||
|
||||
to {
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes mdBackdropFadeIn {
|
||||
from {
|
||||
opacity: 0; }
|
||||
|
||||
to {
|
||||
opacity: 1; } }
|
||||
|
||||
@-webkit-keyframes mdBackdropFadeOut {
|
||||
from {
|
||||
opacity: 1; }
|
||||
|
||||
to {
|
||||
opacity: 0; } }
|
||||
|
||||
@keyframes mdBackdropFadeOut {
|
||||
from {
|
||||
opacity: 1; }
|
||||
|
||||
to {
|
||||
opacity: 0; } }
|
||||
39
www/lib/angular-material/modules/js/backdrop/backdrop.js
vendored
Normal file
39
www/lib/angular-material/modules/js/backdrop/backdrop.js
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
* @ngdoc module
|
||||
* @name material.components.backdrop
|
||||
* @description Backdrop
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdBackdrop
|
||||
* @module material.components.backdrop
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* `<md-backdrop>` is a backdrop element used by other components, such as dialog and bottom sheet.
|
||||
* Apply class `opaque` to make the backdrop use the theme backdrop color.
|
||||
*
|
||||
*/
|
||||
|
||||
angular.module('material.components.backdrop', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdBackdrop', BackdropDirective);
|
||||
|
||||
function BackdropDirective($mdTheming) {
|
||||
return $mdTheming;
|
||||
}
|
||||
BackdropDirective.$inject = ["$mdTheming"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/backdrop/backdrop.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/backdrop/backdrop.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-backdrop{z-index:50;background-color:transparent;position:absolute;height:100%;left:0;right:0}md-backdrop.md-select-backdrop{z-index:81}md-backdrop.md-dialog-backdrop{z-index:79}md-backdrop.md-bottom-sheet-backdrop{z-index:69}md-backdrop.md-sidenav-backdrop{z-index:59}md-backdrop.md-click-catcher{top:0;position:fixed}md-backdrop.ng-enter{-webkit-animation:cubic-bezier(.25,.8,.25,1) mdBackdropFadeIn .5s both;animation:cubic-bezier(.25,.8,.25,1) mdBackdropFadeIn .5s both}md-backdrop.ng-leave{-webkit-animation:cubic-bezier(.55,0,.55,.2) mdBackdropFadeOut .2s both;animation:cubic-bezier(.55,0,.55,.2) mdBackdropFadeOut .2s both}@-webkit-keyframes mdBackdropFadeIn{from{opacity:0}to{opacity:1}}@keyframes mdBackdropFadeIn{from{opacity:0}to{opacity:1}}@-webkit-keyframes mdBackdropFadeOut{from{opacity:1}to{opacity:0}}@keyframes mdBackdropFadeOut{from{opacity:1}to{opacity:0}}
|
||||
7
www/lib/angular-material/modules/js/backdrop/backdrop.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/backdrop/backdrop.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(n,e,i){"use strict";function o(n){return n}e.module("material.components.backdrop",["material.core"]).directive("mdBackdrop",o),o.$inject=["$mdTheming"]}(window,window.angular);
|
||||
7
www/lib/angular-material/modules/js/backdrop/bower.json
Normal file
7
www/lib/angular-material/modules/js/backdrop/bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-backdrop",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-bottom-sheet.md-THEME_NAME-theme {
|
||||
background-color: '{{background-50}}';
|
||||
border-top-color: '{{background-300}}'; }
|
||||
md-bottom-sheet.md-THEME_NAME-theme.md-list md-list-item {
|
||||
color: '{{foreground-1}}'; }
|
||||
md-bottom-sheet.md-THEME_NAME-theme .md-subheader {
|
||||
background-color: '{{background-50}}'; }
|
||||
md-bottom-sheet.md-THEME_NAME-theme .md-subheader {
|
||||
color: '{{foreground-1}}'; }
|
||||
6
www/lib/angular-material/modules/js/bottomSheet/bottomSheet-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/bottomSheet/bottomSheet-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-bottom-sheet.md-THEME_NAME-theme{background-color:'{{background-50}}';border-top-color:'{{background-300}}'}md-bottom-sheet.md-THEME_NAME-theme.md-list md-list-item{color:'{{foreground-1}}'}md-bottom-sheet.md-THEME_NAME-theme .md-subheader{background-color:'{{background-50}}';color:'{{foreground-1}}'}
|
||||
170
www/lib/angular-material/modules/js/bottomSheet/bottomSheet.css
Normal file
170
www/lib/angular-material/modules/js/bottomSheet/bottomSheet.css
Normal file
@@ -0,0 +1,170 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-bottom-sheet {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 8px 16px 88px 16px;
|
||||
z-index: 70;
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid;
|
||||
-webkit-transform: translate3d(0, 80px, 0);
|
||||
transform: translate3d(0, 80px, 0);
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
transition-property: -webkit-transform;
|
||||
transition-property: transform; }
|
||||
md-bottom-sheet.md-has-header {
|
||||
padding-top: 0; }
|
||||
md-bottom-sheet.ng-enter {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate3d(0, 100%, 0);
|
||||
transform: translate3d(0, 100%, 0); }
|
||||
md-bottom-sheet.ng-enter-active {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
-webkit-transform: translate3d(0, 80px, 0) !important;
|
||||
transform: translate3d(0, 80px, 0) !important; }
|
||||
md-bottom-sheet.ng-leave-active {
|
||||
-webkit-transform: translate3d(0, 100%, 0) !important;
|
||||
transform: translate3d(0, 100%, 0) !important;
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); }
|
||||
md-bottom-sheet .md-subheader {
|
||||
background-color: transparent;
|
||||
font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif;
|
||||
line-height: 56px;
|
||||
padding: 0;
|
||||
white-space: nowrap; }
|
||||
md-bottom-sheet md-inline-icon {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
fill: #444; }
|
||||
md-bottom-sheet md-list-item {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
outline: none; }
|
||||
md-bottom-sheet md-list-item:hover {
|
||||
cursor: pointer; }
|
||||
md-bottom-sheet.md-list md-list-item {
|
||||
padding: 0;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
height: 48px; }
|
||||
md-bottom-sheet.md-list md-list-item div.md-icon-container {
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
margin-right: 32px; }
|
||||
md-bottom-sheet.md-grid {
|
||||
padding-left: 24px;
|
||||
padding-right: 24px;
|
||||
padding-top: 0; }
|
||||
md-bottom-sheet.md-grid md-list {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-flex-wrap: wrap;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
transition: all 0.5s;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center; }
|
||||
md-bottom-sheet.md-grid md-list-item {
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
transition: all 0.5s;
|
||||
height: 96px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
/* Mixin for how many grid items to show per row */ }
|
||||
@media screen and (max-width: 600px) {
|
||||
md-bottom-sheet.md-grid md-list-item {
|
||||
-webkit-flex: 1 1 33.33333%;
|
||||
-ms-flex: 1 1 33.33333%;
|
||||
flex: 1 1 33.33333%;
|
||||
max-width: 33.33333%; }
|
||||
md-bottom-sheet.md-grid md-list-item:nth-of-type(3n+1) {
|
||||
-webkit-align-items: flex-start;
|
||||
-ms-flex-align: start;
|
||||
align-items: flex-start; }
|
||||
md-bottom-sheet.md-grid md-list-item:nth-of-type(3n) {
|
||||
-webkit-align-items: flex-end;
|
||||
-ms-flex-align: end;
|
||||
align-items: flex-end; } }
|
||||
@media screen and (min-width: 600px) and (max-width: 960px) {
|
||||
md-bottom-sheet.md-grid md-list-item {
|
||||
-webkit-flex: 1 1 25%;
|
||||
-ms-flex: 1 1 25%;
|
||||
flex: 1 1 25%;
|
||||
max-width: 25%; } }
|
||||
@media screen and (min-width: 960px) and (max-width: 1200px) {
|
||||
md-bottom-sheet.md-grid md-list-item {
|
||||
-webkit-flex: 1 1 16.66667%;
|
||||
-ms-flex: 1 1 16.66667%;
|
||||
flex: 1 1 16.66667%;
|
||||
max-width: 16.66667%; } }
|
||||
@media screen and (min-width: 1200px) {
|
||||
md-bottom-sheet.md-grid md-list-item {
|
||||
-webkit-flex: 1 1 14.28571%;
|
||||
-ms-flex: 1 1 14.28571%;
|
||||
flex: 1 1 14.28571%;
|
||||
max-width: 14.28571%; } }
|
||||
md-bottom-sheet.md-grid md-list-item .md-list-item-content {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
width: 48px;
|
||||
padding-bottom: 16px; }
|
||||
md-bottom-sheet.md-grid md-list-item .md-grid-item-content {
|
||||
border: 1px solid transparent;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
width: 80px; }
|
||||
md-bottom-sheet.md-grid md-list-item .md-icon-container {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
margin: 0 0; }
|
||||
md-bottom-sheet.md-grid md-list-item .md-grid-text {
|
||||
font-weight: 400;
|
||||
line-height: 16px;
|
||||
font-size: 13px;
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
width: 64px;
|
||||
text-align: center;
|
||||
text-transform: none;
|
||||
padding-top: 8px; }
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
md-bottom-sheet {
|
||||
border: 1px solid #fff; } }
|
||||
267
www/lib/angular-material/modules/js/bottomSheet/bottomSheet.js
vendored
Normal file
267
www/lib/angular-material/modules/js/bottomSheet/bottomSheet.js
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.bottomSheet
|
||||
* @description
|
||||
* BottomSheet
|
||||
*/
|
||||
angular.module('material.components.bottomSheet', [
|
||||
'material.core',
|
||||
'material.components.backdrop'
|
||||
])
|
||||
.directive('mdBottomSheet', MdBottomSheetDirective)
|
||||
.provider('$mdBottomSheet', MdBottomSheetProvider);
|
||||
|
||||
function MdBottomSheetDirective() {
|
||||
return {
|
||||
restrict: 'E'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name $mdBottomSheet
|
||||
* @module material.components.bottomSheet
|
||||
*
|
||||
* @description
|
||||
* `$mdBottomSheet` opens a bottom sheet over the app and provides a simple promise API.
|
||||
*
|
||||
* ## Restrictions
|
||||
*
|
||||
* - The bottom sheet's template must have an outer `<md-bottom-sheet>` element.
|
||||
* - Add the `md-grid` class to the bottom sheet for a grid layout.
|
||||
* - Add the `md-list` class to the bottom sheet for a list layout.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <div ng-controller="MyController">
|
||||
* <md-button ng-click="openBottomSheet()">
|
||||
* Open a Bottom Sheet!
|
||||
* </md-button>
|
||||
* </div>
|
||||
* </hljs>
|
||||
* <hljs lang="js">
|
||||
* var app = angular.module('app', ['ngMaterial']);
|
||||
* app.controller('MyController', function($scope, $mdBottomSheet) {
|
||||
* $scope.openBottomSheet = function() {
|
||||
* $mdBottomSheet.show({
|
||||
* template: '<md-bottom-sheet>Hello!</md-bottom-sheet>'
|
||||
* });
|
||||
* };
|
||||
* });
|
||||
* </hljs>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdBottomSheet#show
|
||||
*
|
||||
* @description
|
||||
* Show a bottom sheet with the specified options.
|
||||
*
|
||||
* @param {object} options An options object, with the following properties:
|
||||
*
|
||||
* - `templateUrl` - `{string=}`: The url of an html template file that will
|
||||
* be used as the content of the bottom sheet. Restrictions: the template must
|
||||
* have an outer `md-bottom-sheet` element.
|
||||
* - `template` - `{string=}`: Same as templateUrl, except this is an actual
|
||||
* template string.
|
||||
* - `scope` - `{object=}`: the scope to link the template / controller to. If none is specified, it will create a new child scope.
|
||||
* This scope will be destroyed when the bottom sheet is removed unless `preserveScope` is set to true.
|
||||
* - `preserveScope` - `{boolean=}`: whether to preserve the scope when the element is removed. Default is false
|
||||
* - `controller` - `{string=}`: The controller to associate with this bottom sheet.
|
||||
* - `locals` - `{string=}`: An object containing key/value pairs. The keys will
|
||||
* be used as names of values to inject into the controller. For example,
|
||||
* `locals: {three: 3}` would inject `three` into the controller with the value
|
||||
* of 3.
|
||||
* - `targetEvent` - `{DOMClickEvent=}`: A click's event object. When passed in as an option,
|
||||
* the location of the click will be used as the starting point for the opening animation
|
||||
* of the the dialog.
|
||||
* - `resolve` - `{object=}`: Similar to locals, except it takes promises as values
|
||||
* and the bottom sheet will not open until the promises resolve.
|
||||
* - `controllerAs` - `{string=}`: An alias to assign the controller to on the scope.
|
||||
* - `parent` - `{element=}`: The element to append the bottom sheet to. The `parent` may be a `function`, `string`,
|
||||
* `object`, or null. Defaults to appending to the body of the root element (or the root element) of the application.
|
||||
* e.g. angular.element(document.getElementById('content')) or "#content"
|
||||
* - `disableParentScroll` - `{boolean=}`: Whether to disable scrolling while the bottom sheet is open.
|
||||
* Default true.
|
||||
*
|
||||
* @returns {promise} A promise that can be resolved with `$mdBottomSheet.hide()` or
|
||||
* rejected with `$mdBottomSheet.cancel()`.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdBottomSheet#hide
|
||||
*
|
||||
* @description
|
||||
* Hide the existing bottom sheet and resolve the promise returned from
|
||||
* `$mdBottomSheet.show()`. This call will close the most recently opened/current bottomsheet (if any).
|
||||
*
|
||||
* @param {*=} response An argument for the resolved promise.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdBottomSheet#cancel
|
||||
*
|
||||
* @description
|
||||
* Hide the existing bottom sheet and reject the promise returned from
|
||||
* `$mdBottomSheet.show()`.
|
||||
*
|
||||
* @param {*=} response An argument for the rejected promise.
|
||||
*
|
||||
*/
|
||||
|
||||
function MdBottomSheetProvider($$interimElementProvider) {
|
||||
// how fast we need to flick down to close the sheet, pixels/ms
|
||||
var CLOSING_VELOCITY = 0.5;
|
||||
var PADDING = 80; // same as css
|
||||
|
||||
bottomSheetDefaults.$inject = ["$animate", "$mdConstant", "$mdUtil", "$timeout", "$compile", "$mdTheming", "$mdBottomSheet", "$rootElement", "$mdGesture"];
|
||||
return $$interimElementProvider('$mdBottomSheet')
|
||||
.setDefaults({
|
||||
methods: ['disableParentScroll', 'escapeToClose', 'targetEvent'],
|
||||
options: bottomSheetDefaults
|
||||
});
|
||||
|
||||
/* ngInject */
|
||||
function bottomSheetDefaults($animate, $mdConstant, $mdUtil, $timeout, $compile, $mdTheming, $mdBottomSheet, $rootElement, $mdGesture) {
|
||||
var backdrop;
|
||||
|
||||
return {
|
||||
themable: true,
|
||||
targetEvent: null,
|
||||
onShow: onShow,
|
||||
onRemove: onRemove,
|
||||
escapeToClose: true,
|
||||
disableParentScroll: true
|
||||
};
|
||||
|
||||
|
||||
function onShow(scope, element, options) {
|
||||
|
||||
element = $mdUtil.extractElementByName(element, 'md-bottom-sheet');
|
||||
|
||||
// Add a backdrop that will close on click
|
||||
backdrop = $compile('<md-backdrop class="md-opaque md-bottom-sheet-backdrop">')(scope);
|
||||
backdrop.on('click', function() {
|
||||
$timeout($mdBottomSheet.cancel);
|
||||
});
|
||||
$mdTheming.inherit(backdrop, options.parent);
|
||||
|
||||
$animate.enter(backdrop, options.parent, null);
|
||||
|
||||
var bottomSheet = new BottomSheet(element, options.parent);
|
||||
options.bottomSheet = bottomSheet;
|
||||
|
||||
// Give up focus on calling item
|
||||
options.targetEvent && angular.element(options.targetEvent.target).blur();
|
||||
$mdTheming.inherit(bottomSheet.element, options.parent);
|
||||
|
||||
if (options.disableParentScroll) {
|
||||
options.lastOverflow = options.parent.css('overflow');
|
||||
options.parent.css('overflow', 'hidden');
|
||||
}
|
||||
|
||||
return $animate.enter(bottomSheet.element, options.parent)
|
||||
.then(function() {
|
||||
var focusable = angular.element(
|
||||
element[0].querySelector('button') ||
|
||||
element[0].querySelector('a') ||
|
||||
element[0].querySelector('[ng-click]')
|
||||
);
|
||||
focusable.focus();
|
||||
|
||||
if (options.escapeToClose) {
|
||||
options.rootElementKeyupCallback = function(e) {
|
||||
if (e.keyCode === $mdConstant.KEY_CODE.ESCAPE) {
|
||||
$timeout($mdBottomSheet.cancel);
|
||||
}
|
||||
};
|
||||
$rootElement.on('keyup', options.rootElementKeyupCallback);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function onRemove(scope, element, options) {
|
||||
|
||||
var bottomSheet = options.bottomSheet;
|
||||
|
||||
$animate.leave(backdrop);
|
||||
return $animate.leave(bottomSheet.element).then(function() {
|
||||
if (options.disableParentScroll) {
|
||||
options.parent.css('overflow', options.lastOverflow);
|
||||
delete options.lastOverflow;
|
||||
}
|
||||
|
||||
bottomSheet.cleanup();
|
||||
|
||||
// Restore focus
|
||||
options.targetEvent && angular.element(options.targetEvent.target).focus();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* BottomSheet class to apply bottom-sheet behavior to an element
|
||||
*/
|
||||
function BottomSheet(element, parent) {
|
||||
var deregister = $mdGesture.register(parent, 'drag', { horizontal: false });
|
||||
parent.on('$md.dragstart', onDragStart)
|
||||
.on('$md.drag', onDrag)
|
||||
.on('$md.dragend', onDragEnd);
|
||||
|
||||
return {
|
||||
element: element,
|
||||
cleanup: function cleanup() {
|
||||
deregister();
|
||||
parent.off('$md.dragstart', onDragStart)
|
||||
.off('$md.drag', onDrag)
|
||||
.off('$md.dragend', onDragEnd);
|
||||
}
|
||||
};
|
||||
|
||||
function onDragStart(ev) {
|
||||
// Disable transitions on transform so that it feels fast
|
||||
element.css($mdConstant.CSS.TRANSITION_DURATION, '0ms');
|
||||
}
|
||||
|
||||
function onDrag(ev) {
|
||||
var transform = ev.pointer.distanceY;
|
||||
if (transform < 5) {
|
||||
// Slow down drag when trying to drag up, and stop after PADDING
|
||||
transform = Math.max(-PADDING, transform / 2);
|
||||
}
|
||||
element.css($mdConstant.CSS.TRANSFORM, 'translate3d(0,' + (PADDING + transform) + 'px,0)');
|
||||
}
|
||||
|
||||
function onDragEnd(ev) {
|
||||
if (ev.pointer.distanceY > 0 &&
|
||||
(ev.pointer.distanceY > 20 || Math.abs(ev.pointer.velocityY) > CLOSING_VELOCITY)) {
|
||||
var distanceRemaining = element.prop('offsetHeight') - ev.pointer.distanceY;
|
||||
var transitionDuration = Math.min(distanceRemaining / ev.pointer.velocityY * 0.75, 500);
|
||||
element.css($mdConstant.CSS.TRANSITION_DURATION, transitionDuration + 'ms');
|
||||
$timeout($mdBottomSheet.cancel);
|
||||
} else {
|
||||
element.css($mdConstant.CSS.TRANSITION_DURATION, '');
|
||||
element.css($mdConstant.CSS.TRANSFORM, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
MdBottomSheetProvider.$inject = ["$$interimElementProvider"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/bottomSheet/bottomSheet.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/bottomSheet/bottomSheet.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-bottom-sheet{position:absolute;left:0;right:0;bottom:0;padding:8px 16px 88px;z-index:70;border-top-width:1px;border-top-style:solid;-webkit-transform:translate3d(0,80px,0);transform:translate3d(0,80px,0);transition:all .4s cubic-bezier(.25,.8,.25,1);transition-property:-webkit-transform;transition-property:transform}md-bottom-sheet.md-has-header{padding-top:0}md-bottom-sheet.ng-enter{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}md-bottom-sheet.ng-enter-active{opacity:1;display:block;-webkit-transform:translate3d(0,80px,0)!important;transform:translate3d(0,80px,0)!important}md-bottom-sheet.ng-leave-active{-webkit-transform:translate3d(0,100%,0)!important;transform:translate3d(0,100%,0)!important;transition:all .3s cubic-bezier(.55,0,.55,.2)}md-bottom-sheet .md-subheader{background-color:transparent;font-family:RobotoDraft,Roboto,'Helvetica Neue',sans-serif;line-height:56px;padding:0;white-space:nowrap}md-bottom-sheet md-inline-icon{display:inline-block;height:24px;width:24px;fill:#444}md-bottom-sheet md-list-item{display:-webkit-flex;display:-ms-flexbox;display:flex;outline:0}md-bottom-sheet md-list-item:hover{cursor:pointer}md-bottom-sheet.md-list md-list-item{padding:0;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:48px}md-bottom-sheet.md-list md-list-item div.md-icon-container{display:inline-block;height:24px;margin-right:32px}md-bottom-sheet.md-grid{padding-left:24px;padding-right:24px;padding-top:0}md-bottom-sheet.md-grid md-list{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;transition:all .5s;-webkit-align-items:center;-ms-flex-align:center;align-items:center}md-bottom-sheet.md-grid md-list-item{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-ms-flex-align:center;align-items:center;transition:all .5s;height:96px;margin-top:8px;margin-bottom:8px}@media screen and (max-width:600px){md-bottom-sheet.md-grid md-list-item{-webkit-flex:1 1 33.33333%;-ms-flex:1 1 33.33333%;flex:1 1 33.33333%;max-width:33.33333%}md-bottom-sheet.md-grid md-list-item:nth-of-type(3n+1){-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}md-bottom-sheet.md-grid md-list-item:nth-of-type(3n){-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end}}@media screen and (min-width:600px) and (max-width:960px){md-bottom-sheet.md-grid md-list-item{-webkit-flex:1 1 25%;-ms-flex:1 1 25%;flex:1 1 25%;max-width:25%}}@media screen and (min-width:960px) and (max-width:1200px){md-bottom-sheet.md-grid md-list-item{-webkit-flex:1 1 16.66667%;-ms-flex:1 1 16.66667%;flex:1 1 16.66667%;max-width:16.66667%}}@media screen and (min-width:1200px){md-bottom-sheet.md-grid md-list-item{-webkit-flex:1 1 14.28571%;-ms-flex:1 1 14.28571%;flex:1 1 14.28571%;max-width:14.28571%}}md-bottom-sheet.md-grid md-list-item .md-list-item-content{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-ms-flex-align:center;align-items:center;width:48px;padding-bottom:16px}md-bottom-sheet.md-grid md-list-item .md-grid-item-content{border:1px solid transparent;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-ms-flex-align:center;align-items:center;width:80px}md-bottom-sheet.md-grid md-list-item .md-icon-container{display:inline-block;box-sizing:border-box;height:48px;width:48px;margin:0}md-bottom-sheet.md-grid md-list-item .md-grid-text{font-weight:400;line-height:16px;font-size:13px;margin:0;white-space:nowrap;width:64px;text-align:center;text-transform:none;padding-top:8px}@media screen and (-ms-high-contrast:active){md-bottom-sheet{border:1px solid #fff}}
|
||||
7
www/lib/angular-material/modules/js/bottomSheet/bottomSheet.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/bottomSheet/bottomSheet.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(e,t,n){"use strict";function o(){return{restrict:"E"}}function r(e){function n(e,n,a,l,c,i,s,m,d){function u(o,r,d){r=a.extractElementByName(r,"md-bottom-sheet"),S=c('<md-backdrop class="md-opaque md-bottom-sheet-backdrop">')(o),S.on("click",function(){l(s.cancel)}),i.inherit(S,d.parent),e.enter(S,d.parent,null);var u=new f(r,d.parent);return d.bottomSheet=u,d.targetEvent&&t.element(d.targetEvent.target).blur(),i.inherit(u.element,d.parent),d.disableParentScroll&&(d.lastOverflow=d.parent.css("overflow"),d.parent.css("overflow","hidden")),e.enter(u.element,d.parent).then(function(){var e=t.element(r[0].querySelector("button")||r[0].querySelector("a")||r[0].querySelector("[ng-click]"));e.focus(),d.escapeToClose&&(d.rootElementKeyupCallback=function(e){e.keyCode===n.KEY_CODE.ESCAPE&&l(s.cancel)},m.on("keyup",d.rootElementKeyupCallback))})}function p(n,o,r){var a=r.bottomSheet;return e.leave(S),e.leave(a.element).then(function(){r.disableParentScroll&&(r.parent.css("overflow",r.lastOverflow),delete r.lastOverflow),a.cleanup(),r.targetEvent&&t.element(r.targetEvent.target).focus()})}function f(e,t){function a(t){e.css(n.CSS.TRANSITION_DURATION,"0ms")}function c(t){var o=t.pointer.distanceY;5>o&&(o=Math.max(-r,o/2)),e.css(n.CSS.TRANSFORM,"translate3d(0,"+(r+o)+"px,0)")}function i(t){if(t.pointer.distanceY>0&&(t.pointer.distanceY>20||Math.abs(t.pointer.velocityY)>o)){var r=e.prop("offsetHeight")-t.pointer.distanceY,a=Math.min(r/t.pointer.velocityY*.75,500);e.css(n.CSS.TRANSITION_DURATION,a+"ms"),l(s.cancel)}else e.css(n.CSS.TRANSITION_DURATION,""),e.css(n.CSS.TRANSFORM,"")}var m=d.register(t,"drag",{horizontal:!1});return t.on("$md.dragstart",a).on("$md.drag",c).on("$md.dragend",i),{element:e,cleanup:function(){m(),t.off("$md.dragstart",a).off("$md.drag",c).off("$md.dragend",i)}}}var S;return{themable:!0,targetEvent:null,onShow:u,onRemove:p,escapeToClose:!0,disableParentScroll:!0}}var o=.5,r=80;return n.$inject=["$animate","$mdConstant","$mdUtil","$timeout","$compile","$mdTheming","$mdBottomSheet","$rootElement","$mdGesture"],e("$mdBottomSheet").setDefaults({methods:["disableParentScroll","escapeToClose","targetEvent"],options:n})}t.module("material.components.bottomSheet",["material.core","material.components.backdrop"]).directive("mdBottomSheet",o).provider("$mdBottomSheet",r),r.$inject=["$$interimElementProvider"]}(window,window.angular);
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "angular-material-bottomSheet",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0",
|
||||
"angular-material-backdrop": "0.10.0"
|
||||
}
|
||||
}
|
||||
7
www/lib/angular-material/modules/js/button/bower.json
Normal file
7
www/lib/angular-material/modules/js/button/bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-button",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
a.md-button.md-THEME_NAME-theme, .md-button.md-THEME_NAME-theme {
|
||||
border-radius: 3px; }
|
||||
a.md-button.md-THEME_NAME-theme:not([disabled]):hover, .md-button.md-THEME_NAME-theme:not([disabled]):hover {
|
||||
background-color: '{{background-500-0.2}}'; }
|
||||
a.md-button.md-THEME_NAME-theme:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme:not([disabled]).md-focused {
|
||||
background-color: '{{background-500-0.2}}'; }
|
||||
a.md-button.md-THEME_NAME-theme:not([disabled]).md-icon-button:hover, .md-button.md-THEME_NAME-theme:not([disabled]).md-icon-button:hover {
|
||||
background-color: transparent; }
|
||||
a.md-button.md-THEME_NAME-theme.md-fab, .md-button.md-THEME_NAME-theme.md-fab {
|
||||
border-radius: 50%;
|
||||
background-color: '{{accent-color}}';
|
||||
color: '{{accent-contrast}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-fab md-icon, .md-button.md-THEME_NAME-theme.md-fab md-icon {
|
||||
color: '{{accent-contrast}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]):hover {
|
||||
background-color: '{{accent-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]).md-focused {
|
||||
background-color: '{{accent-A700}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-icon-button, .md-button.md-THEME_NAME-theme.md-icon-button {
|
||||
border-radius: 50%; }
|
||||
a.md-button.md-THEME_NAME-theme.md-primary, .md-button.md-THEME_NAME-theme.md-primary {
|
||||
color: '{{primary-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-primary.md-raised, a.md-button.md-THEME_NAME-theme.md-primary.md-fab, .md-button.md-THEME_NAME-theme.md-primary.md-raised, .md-button.md-THEME_NAME-theme.md-primary.md-fab {
|
||||
color: '{{primary-contrast}}';
|
||||
background-color: '{{primary-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]) md-icon, a.md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]) md-icon {
|
||||
color: '{{primary-contrast}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]):hover, a.md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]):hover {
|
||||
background-color: '{{primary-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]).md-focused, a.md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-primary.md-raised:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-primary.md-fab:not([disabled]).md-focused {
|
||||
background-color: '{{primary-600}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-primary:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-primary:not([disabled]) md-icon {
|
||||
color: '{{primary-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-fab, .md-button.md-THEME_NAME-theme.md-fab {
|
||||
border-radius: 50%;
|
||||
background-color: '{{accent-color}}';
|
||||
color: '{{accent-contrast}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]) .md-icon, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]) .md-icon {
|
||||
color: '{{accent-contrast}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]):hover {
|
||||
background-color: '{{accent-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-fab:not([disabled]).md-focused {
|
||||
background-color: '{{accent-A700}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-raised, .md-button.md-THEME_NAME-theme.md-raised {
|
||||
color: '{{background-contrast}}';
|
||||
background-color: '{{background-50}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-raised:not([disabled]) .md-icon, .md-button.md-THEME_NAME-theme.md-raised:not([disabled]) .md-icon {
|
||||
color: '{{background-contrast}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-raised:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-raised:not([disabled]):hover {
|
||||
background-color: '{{background-50}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-raised:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-raised:not([disabled]).md-focused {
|
||||
background-color: '{{background-200}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-warn, .md-button.md-THEME_NAME-theme.md-warn {
|
||||
color: '{{warn-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-warn.md-raised, a.md-button.md-THEME_NAME-theme.md-warn.md-fab, .md-button.md-THEME_NAME-theme.md-warn.md-raised, .md-button.md-THEME_NAME-theme.md-warn.md-fab {
|
||||
color: '{{warn-contrast}}';
|
||||
background-color: '{{warn-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]) md-icon, a.md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]) md-icon {
|
||||
color: '{{warn-contrast}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]):hover, a.md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]):hover {
|
||||
background-color: '{{warn-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]).md-focused, a.md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-warn.md-raised:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-warn.md-fab:not([disabled]).md-focused {
|
||||
background-color: '{{warn-700}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-warn:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-warn:not([disabled]) md-icon {
|
||||
color: '{{warn-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-accent, .md-button.md-THEME_NAME-theme.md-accent {
|
||||
color: '{{accent-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-accent.md-raised, a.md-button.md-THEME_NAME-theme.md-accent.md-fab, .md-button.md-THEME_NAME-theme.md-accent.md-raised, .md-button.md-THEME_NAME-theme.md-accent.md-fab {
|
||||
color: '{{accent-contrast}}';
|
||||
background-color: '{{accent-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]) md-icon, a.md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]) md-icon {
|
||||
color: '{{accent-contrast}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]):hover, a.md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]):hover, .md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]):hover {
|
||||
background-color: '{{accent-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]).md-focused, a.md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-accent.md-raised:not([disabled]).md-focused, .md-button.md-THEME_NAME-theme.md-accent.md-fab:not([disabled]).md-focused {
|
||||
background-color: '{{accent-700}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-accent:not([disabled]) md-icon, .md-button.md-THEME_NAME-theme.md-accent:not([disabled]) md-icon {
|
||||
color: '{{accent-color}}'; }
|
||||
a.md-button.md-THEME_NAME-theme[disabled], a.md-button.md-THEME_NAME-theme.md-raised[disabled], a.md-button.md-THEME_NAME-theme.md-fab[disabled], a.md-button.md-THEME_NAME-theme.md-accent[disabled], a.md-button.md-THEME_NAME-theme.md-warn[disabled], .md-button.md-THEME_NAME-theme[disabled], .md-button.md-THEME_NAME-theme.md-raised[disabled], .md-button.md-THEME_NAME-theme.md-fab[disabled], .md-button.md-THEME_NAME-theme.md-accent[disabled], .md-button.md-THEME_NAME-theme.md-warn[disabled] {
|
||||
color: '{{foreground-3}}';
|
||||
cursor: not-allowed; }
|
||||
a.md-button.md-THEME_NAME-theme[disabled] md-icon, a.md-button.md-THEME_NAME-theme.md-raised[disabled] md-icon, a.md-button.md-THEME_NAME-theme.md-fab[disabled] md-icon, a.md-button.md-THEME_NAME-theme.md-accent[disabled] md-icon, a.md-button.md-THEME_NAME-theme.md-warn[disabled] md-icon, .md-button.md-THEME_NAME-theme[disabled] md-icon, .md-button.md-THEME_NAME-theme.md-raised[disabled] md-icon, .md-button.md-THEME_NAME-theme.md-fab[disabled] md-icon, .md-button.md-THEME_NAME-theme.md-accent[disabled] md-icon, .md-button.md-THEME_NAME-theme.md-warn[disabled] md-icon {
|
||||
color: '{{foreground-3}}'; }
|
||||
a.md-button.md-THEME_NAME-theme.md-raised[disabled], a.md-button.md-THEME_NAME-theme.md-fab[disabled], .md-button.md-THEME_NAME-theme.md-raised[disabled], .md-button.md-THEME_NAME-theme.md-fab[disabled] {
|
||||
background-color: '{{foreground-4}}'; }
|
||||
a.md-button.md-THEME_NAME-theme[disabled], .md-button.md-THEME_NAME-theme[disabled] {
|
||||
background-color: transparent; }
|
||||
6
www/lib/angular-material/modules/js/button/button-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/button/button-default-theme.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
158
www/lib/angular-material/modules/js/button/button.css
Normal file
158
www/lib/angular-material/modules/js/button/button.css
Normal file
@@ -0,0 +1,158 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
/**
|
||||
* Position a FAB button.
|
||||
*/
|
||||
.md-button {
|
||||
box-sizing: border-box;
|
||||
color: currentColor;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
outline: none;
|
||||
border: 0;
|
||||
display: inline-table;
|
||||
padding: 0 6px;
|
||||
margin: 6px 8px;
|
||||
line-height: 36px;
|
||||
min-height: 36px;
|
||||
background: transparent;
|
||||
white-space: nowrap;
|
||||
min-width: 88px;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
font-style: inherit;
|
||||
font-variant: inherit;
|
||||
font-family: inherit;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: box-shadow 0.4s cubic-bezier(0.25, 0.8, 0.25, 1), background-color 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); }
|
||||
.md-button *, .md-button *:before, .md-button *:after {
|
||||
box-sizing: border-box; }
|
||||
.md-button:focus {
|
||||
outline: none; }
|
||||
.md-button:hover, .md-button:focus {
|
||||
text-decoration: none; }
|
||||
.md-button.ng-hide, .md-button.ng-leave {
|
||||
transition: none; }
|
||||
.md-button.md-cornered {
|
||||
border-radius: 0; }
|
||||
.md-button.md-icon {
|
||||
padding: 0;
|
||||
background: none; }
|
||||
.md-button.md-icon-button {
|
||||
margin: 0 6px;
|
||||
height: 48px;
|
||||
min-width: 0;
|
||||
line-height: 48px;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: 48px;
|
||||
border-radius: 50%; }
|
||||
.md-button.md-icon-button .md-ripple-container {
|
||||
border-radius: 50%;
|
||||
background-clip: padding-box;
|
||||
overflow: hidden;
|
||||
-webkit-mask-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC'); }
|
||||
.md-button.md-fab {
|
||||
z-index: 20;
|
||||
line-height: 56px;
|
||||
min-width: 0;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
vertical-align: middle;
|
||||
border-radius: 50%;
|
||||
background-clip: padding-box;
|
||||
overflow: hidden;
|
||||
transition: 0.2s linear;
|
||||
transition-property: background-color, box-shadow; }
|
||||
.md-button.md-fab.md-fab-bottom-right {
|
||||
top: auto;
|
||||
right: 20px;
|
||||
bottom: 20px;
|
||||
left: auto;
|
||||
position: absolute; }
|
||||
.md-button.md-fab.md-fab-bottom-left {
|
||||
top: auto;
|
||||
right: auto;
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
position: absolute; }
|
||||
.md-button.md-fab.md-fab-top-right {
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
position: absolute; }
|
||||
.md-button.md-fab.md-fab-top-left {
|
||||
top: 20px;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: 20px;
|
||||
position: absolute; }
|
||||
.md-button.md-fab .md-ripple-container {
|
||||
border-radius: 50%;
|
||||
background-clip: padding-box;
|
||||
overflow: hidden;
|
||||
-webkit-mask-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC'); }
|
||||
.md-button.md-fab md-icon {
|
||||
margin-top: 0; }
|
||||
.md-button.md-fab.md-mini {
|
||||
line-height: 40px;
|
||||
width: 40px;
|
||||
height: 40px; }
|
||||
|
||||
.md-toast-open-top .md-button.md-fab-top-left, .md-toast-open-top .md-button.md-fab-top-right {
|
||||
-webkit-transform: translate3d(0, 42px, 0);
|
||||
transform: translate3d(0, 42px, 0); }
|
||||
.md-toast-open-top .md-button.md-fab-top-left:not([disabled]).md-focused, .md-toast-open-top .md-button.md-fab-top-left:not([disabled]):hover, .md-toast-open-top .md-button.md-fab-top-right:not([disabled]).md-focused, .md-toast-open-top .md-button.md-fab-top-right:not([disabled]):hover {
|
||||
-webkit-transform: translate3d(0, 41px, 0);
|
||||
transform: translate3d(0, 41px, 0); }
|
||||
|
||||
.md-toast-open-bottom .md-button.md-fab-bottom-left, .md-toast-open-bottom .md-button.md-fab-bottom-right {
|
||||
-webkit-transform: translate3d(0, -42px, 0);
|
||||
transform: translate3d(0, -42px, 0); }
|
||||
.md-toast-open-bottom .md-button.md-fab-bottom-left:not([disabled]).md-focused, .md-toast-open-bottom .md-button.md-fab-bottom-left:not([disabled]):hover, .md-toast-open-bottom .md-button.md-fab-bottom-right:not([disabled]).md-focused, .md-toast-open-bottom .md-button.md-fab-bottom-right:not([disabled]):hover {
|
||||
-webkit-transform: translate3d(0, -43px, 0);
|
||||
transform: translate3d(0, -43px, 0); }
|
||||
|
||||
.md-button-group {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
width: 100%; }
|
||||
|
||||
.md-button-group > .md-button {
|
||||
-webkit-flex: 1;
|
||||
-ms-flex: 1;
|
||||
flex: 1;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
width: 0;
|
||||
border-width: 1px 0px 1px 1px;
|
||||
border-radius: 0;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap; }
|
||||
.md-button-group > .md-button:first-child {
|
||||
border-radius: 2px 0px 0px 2px; }
|
||||
.md-button-group > .md-button:last-child {
|
||||
border-right-width: 1px;
|
||||
border-radius: 0px 2px 2px 0px; }
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
.md-button.md-raised, .md-button.md-fab {
|
||||
border: 1px solid #fff; } }
|
||||
136
www/lib/angular-material/modules/js/button/button.js
vendored
Normal file
136
www/lib/angular-material/modules/js/button/button.js
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.button
|
||||
* @description
|
||||
*
|
||||
* Button
|
||||
*/
|
||||
angular
|
||||
.module('material.components.button', [ 'material.core' ])
|
||||
.directive('mdButton', MdButtonDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdButton
|
||||
* @module material.components.button
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* `<md-button>` is a button directive with optional ink ripples (default enabled).
|
||||
*
|
||||
* If you supply a `href` or `ng-href` attribute, it will become an `<a>` element. Otherwise, it will
|
||||
* become a `<button>` element. As per the [Material Design specifications](http://www.google.com/design/spec/style/color.html#color-ui-color-application)
|
||||
* the FAB button background is filled with the accent color [by default]. The primary color palette may be used with
|
||||
* the `md-primary` class.
|
||||
*
|
||||
* @param {boolean=} md-no-ink If present, disable ripple ink effects.
|
||||
* @param {expression=} ng-disabled En/Disable based on the expression
|
||||
* @param {string=} md-ripple-size Overrides the default ripple size logic. Options: `full`, `partial`, `auto`
|
||||
* @param {string=} aria-label Adds alternative text to button for accessibility, useful for icon buttons.
|
||||
* If no default text is found, a warning will be logged.
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* Regular buttons:
|
||||
*
|
||||
* <hljs lang="html">
|
||||
* <md-button> Flat Button </md-button>
|
||||
* <md-button href="http://google.com"> Flat link </md-button>
|
||||
* <md-button class="md-raised"> Raised Button </md-button>
|
||||
* <md-button ng-disabled="true"> Disabled Button </md-button>
|
||||
* <md-button>
|
||||
* <md-icon md-svg-src="your/icon.svg"></md-icon>
|
||||
* Register Now
|
||||
* </md-button>
|
||||
* </hljs>
|
||||
*
|
||||
* FAB buttons:
|
||||
*
|
||||
* <hljs lang="html">
|
||||
* <md-button class="md-fab" aria-label="FAB">
|
||||
* <md-icon md-svg-src="your/icon.svg"></md-icon>
|
||||
* </md-button>
|
||||
* <!-- mini-FAB -->
|
||||
* <md-button class="md-fab md-mini" aria-label="Mini FAB">
|
||||
* <md-icon md-svg-src="your/icon.svg"></md-icon>
|
||||
* </md-button>
|
||||
* <!-- Button with SVG Icon -->
|
||||
* <md-button class="md-icon-button" aria-label="Custom Icon Button">
|
||||
* <md-icon md-svg-icon="path/to/your.svg"></md-icon>
|
||||
* </md-button>
|
||||
* </hljs>
|
||||
*/
|
||||
function MdButtonDirective($mdButtonInkRipple, $mdTheming, $mdAria, $timeout) {
|
||||
|
||||
return {
|
||||
restrict: 'EA',
|
||||
replace: true,
|
||||
transclude: true,
|
||||
template: getTemplate,
|
||||
link: postLink
|
||||
};
|
||||
|
||||
function isAnchor(attr) {
|
||||
return angular.isDefined(attr.href) || angular.isDefined(attr.ngHref) || angular.isDefined(attr.ngLink) || angular.isDefined(attr.uiSref);
|
||||
}
|
||||
|
||||
function getTemplate(element, attr) {
|
||||
return isAnchor(attr) ?
|
||||
'<a class="md-button" ng-transclude></a>' :
|
||||
'<button class="md-button" ng-transclude></button>';
|
||||
}
|
||||
|
||||
function postLink(scope, element, attr) {
|
||||
var node = element[0];
|
||||
$mdTheming(element);
|
||||
$mdButtonInkRipple.attach(scope, element);
|
||||
|
||||
var elementHasText = node.textContent.trim();
|
||||
if (!elementHasText) {
|
||||
$mdAria.expect(element, 'aria-label');
|
||||
}
|
||||
|
||||
// For anchor elements, we have to set tabindex manually when the
|
||||
// element is disabled
|
||||
if (isAnchor(attr) && angular.isDefined(attr.ngDisabled) ) {
|
||||
scope.$watch(attr.ngDisabled, function(isDisabled) {
|
||||
element.attr('tabindex', isDisabled ? -1 : 0);
|
||||
});
|
||||
}
|
||||
|
||||
// disabling click event when disabled is true
|
||||
element.on('click', function(e){
|
||||
if (attr.disabled === true) {
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
});
|
||||
|
||||
// restrict focus styles to the keyboard
|
||||
scope.mouseActive = false;
|
||||
element.on('mousedown', function() {
|
||||
scope.mouseActive = true;
|
||||
$timeout(function(){
|
||||
scope.mouseActive = false;
|
||||
}, 100);
|
||||
})
|
||||
.on('focus', function() {
|
||||
if(scope.mouseActive === false) { element.addClass('md-focused'); }
|
||||
})
|
||||
.on('blur', function() { element.removeClass('md-focused'); });
|
||||
}
|
||||
|
||||
}
|
||||
MdButtonDirective.$inject = ["$mdButtonInkRipple", "$mdTheming", "$mdAria", "$timeout"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/button/button.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/button/button.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/.md-button{box-sizing:border-box;color:currentColor;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;outline:0;border:0;display:inline-table;padding:0 6px;margin:6px 8px;line-height:36px;min-height:36px;background:0 0;white-space:nowrap;min-width:88px;text-align:center;text-transform:uppercase;font-weight:500;font-size:14px;font-style:inherit;font-variant:inherit;font-family:inherit;text-decoration:none;cursor:pointer;overflow:hidden;transition:box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1)}.md-button *,.md-button :after,.md-button :before{box-sizing:border-box}.md-button:focus{outline:0}.md-button:focus,.md-button:hover{text-decoration:none}.md-button.ng-hide,.md-button.ng-leave{transition:none}.md-button.md-cornered{border-radius:0}.md-button.md-icon{padding:0;background:0 0}.md-button.md-icon-button{margin:0 6px;height:48px;min-width:0;line-height:48px;padding-left:0;padding-right:0;width:48px;border-radius:50%}.md-button.md-icon-button .md-ripple-container{border-radius:50%;background-clip:padding-box;overflow:hidden;-webkit-mask-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC)}.md-button.md-fab{z-index:20;line-height:56px;min-width:0;width:56px;height:56px;vertical-align:middle;border-radius:50%;background-clip:padding-box;overflow:hidden;transition:.2s linear;transition-property:background-color,box-shadow}.md-button.md-fab.md-fab-bottom-right{top:auto;right:20px;bottom:20px;left:auto;position:absolute}.md-button.md-fab.md-fab-bottom-left{top:auto;right:auto;bottom:20px;left:20px;position:absolute}.md-button.md-fab.md-fab-top-right{top:20px;right:20px;bottom:auto;left:auto;position:absolute}.md-button.md-fab.md-fab-top-left{top:20px;right:auto;bottom:auto;left:20px;position:absolute}.md-button.md-fab .md-ripple-container{border-radius:50%;background-clip:padding-box;overflow:hidden;-webkit-mask-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC)}.md-button.md-fab md-icon{margin-top:0}.md-button.md-fab.md-mini{line-height:40px;width:40px;height:40px}.md-toast-open-top .md-button.md-fab-top-left,.md-toast-open-top .md-button.md-fab-top-right{-webkit-transform:translate3d(0,42px,0);transform:translate3d(0,42px,0)}.md-toast-open-top .md-button.md-fab-top-left:not([disabled]).md-focused,.md-toast-open-top .md-button.md-fab-top-left:not([disabled]):hover,.md-toast-open-top .md-button.md-fab-top-right:not([disabled]).md-focused,.md-toast-open-top .md-button.md-fab-top-right:not([disabled]):hover{-webkit-transform:translate3d(0,41px,0);transform:translate3d(0,41px,0)}.md-toast-open-bottom .md-button.md-fab-bottom-left,.md-toast-open-bottom .md-button.md-fab-bottom-right{-webkit-transform:translate3d(0,-42px,0);transform:translate3d(0,-42px,0)}.md-toast-open-bottom .md-button.md-fab-bottom-left:not([disabled]).md-focused,.md-toast-open-bottom .md-button.md-fab-bottom-left:not([disabled]):hover,.md-toast-open-bottom .md-button.md-fab-bottom-right:not([disabled]).md-focused,.md-toast-open-bottom .md-button.md-fab-bottom-right:not([disabled]):hover{-webkit-transform:translate3d(0,-43px,0);transform:translate3d(0,-43px,0)}.md-button-group{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;width:100%}.md-button-group>.md-button{-webkit-flex:1;-ms-flex:1;flex:1;display:block;overflow:hidden;width:0;border-width:1px 0 1px 1px;border-radius:0;text-align:center;text-overflow:ellipsis;white-space:nowrap}.md-button-group>.md-button:first-child{border-radius:2px 0 0 2px}.md-button-group>.md-button:last-child{border-right-width:1px;border-radius:0 2px 2px 0}@media screen and (-ms-high-contrast:active){.md-button.md-fab,.md-button.md-raised{border:1px solid #fff}}
|
||||
7
www/lib/angular-material/modules/js/button/button.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/button/button.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(n,t,e){"use strict";function i(n,e,i,o){function u(n){return t.isDefined(n.href)||t.isDefined(n.ngHref)||t.isDefined(n.ngLink)||t.isDefined(n.uiSref)}function a(n,t){return u(t)?'<a class="md-button" ng-transclude></a>':'<button class="md-button" ng-transclude></button>'}function c(a,c,s){var d=c[0];e(c),n.attach(a,c);var r=d.textContent.trim();r||i.expect(c,"aria-label"),u(s)&&t.isDefined(s.ngDisabled)&&a.$watch(s.ngDisabled,function(n){c.attr("tabindex",n?-1:0)}),c.on("click",function(n){s.disabled===!0&&(n.preventDefault(),n.stopImmediatePropagation())}),a.mouseActive=!1,c.on("mousedown",function(){a.mouseActive=!0,o(function(){a.mouseActive=!1},100)}).on("focus",function(){a.mouseActive===!1&&c.addClass("md-focused")}).on("blur",function(){c.removeClass("md-focused")})}return{restrict:"EA",replace:!0,transclude:!0,template:a,link:c}}t.module("material.components.button",["material.core"]).directive("mdButton",i),i.$inject=["$mdButtonInkRipple","$mdTheming","$mdAria","$timeout"]}(window,window.angular);
|
||||
7
www/lib/angular-material/modules/js/card/bower.json
Normal file
7
www/lib/angular-material/modules/js/card/bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-card",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-card.md-THEME_NAME-theme {
|
||||
background-color: '{{background-color}}';
|
||||
border-radius: 2px; }
|
||||
md-card.md-THEME_NAME-theme .md-card-image {
|
||||
border-radius: 2px 2px 0 0; }
|
||||
6
www/lib/angular-material/modules/js/card/card-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/card/card-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-card.md-THEME_NAME-theme{background-color:'{{background-color}}';border-radius:2px}md-card.md-THEME_NAME-theme .md-card-image{border-radius:2px 2px 0 0}
|
||||
34
www/lib/angular-material/modules/js/card/card.css
Normal file
34
www/lib/angular-material/modules/js/card/card.css
Normal file
@@ -0,0 +1,34 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-card {
|
||||
box-sizing: border-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
margin: 8px;
|
||||
box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.14), 0px 2px 2px 0px rgba(0, 0, 0, 0.098), 0px 1px 5px 0px rgba(0, 0, 0, 0.084); }
|
||||
md-card > img, md-card > :not(md-card-content) img {
|
||||
width: 100%; }
|
||||
md-card md-card-content {
|
||||
padding: 16px; }
|
||||
md-card .md-actions {
|
||||
margin: 0; }
|
||||
md-card .md-actions .md-button {
|
||||
margin-bottom: 8px;
|
||||
margin-top: 8px;
|
||||
margin-right: 4px;
|
||||
margin-left: 4px; }
|
||||
md-card md-card-footer {
|
||||
padding: 16px; }
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
md-card {
|
||||
border: 1px solid #fff; } }
|
||||
85
www/lib/angular-material/modules/js/card/card.js
vendored
Normal file
85
www/lib/angular-material/modules/js/card/card.js
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.card
|
||||
*
|
||||
* @description
|
||||
* Card components.
|
||||
*/
|
||||
angular.module('material.components.card', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdCard', mdCardDirective);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdCard
|
||||
* @module material.components.card
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-card>` directive is a container element used within `<md-content>` containers.
|
||||
*
|
||||
* An image included as a direct descendant will fill the card's width, while the `<md-card-content>`
|
||||
* container will wrap text content and provide padding. An `<md-card-footer>` element can be
|
||||
* optionally included to put content flush against the bottom edge of the card.
|
||||
*
|
||||
* Action buttons can be included in an element with the `.md-actions` class, also used in `md-dialog`.
|
||||
* You can then position buttons using layout attributes.
|
||||
*
|
||||
* Cards have constant width and variable heights; where the maximum height is limited to what can
|
||||
* fit within a single view on a platform, but it can temporarily expand as needed.
|
||||
*
|
||||
* @usage
|
||||
* ###Card with optional footer
|
||||
* <hljs lang="html">
|
||||
* <md-card>
|
||||
* <img src="card-image.png" class="md-card-image" alt="image caption">
|
||||
* <md-card-content>
|
||||
* <h2>Card headline</h2>
|
||||
* <p>Card content</p>
|
||||
* </md-card-content>
|
||||
* <md-card-footer>
|
||||
* Card footer
|
||||
* </md-card-footer>
|
||||
* </md-card>
|
||||
* </hljs>
|
||||
*
|
||||
* ###Card with actions
|
||||
* <hljs lang="html">
|
||||
* <md-card>
|
||||
* <img src="card-image.png" class="md-card-image" alt="image caption">
|
||||
* <md-card-content>
|
||||
* <h2>Card headline</h2>
|
||||
* <p>Card content</p>
|
||||
* </md-card-content>
|
||||
* <div class="md-actions" layout="row" layout-align="end center">
|
||||
* <md-button>Action 1</md-button>
|
||||
* <md-button>Action 2</md-button>
|
||||
* </div>
|
||||
* </md-card>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function mdCardDirective($mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function($scope, $element, $attr) {
|
||||
$mdTheming($element);
|
||||
}
|
||||
};
|
||||
}
|
||||
mdCardDirective.$inject = ["$mdTheming"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/card/card.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/card/card.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-card{box-sizing:border-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin:8px;box-shadow:0 3px 1px -2px rgba(0,0,0,.14),0 2px 2px 0 rgba(0,0,0,.098),0 1px 5px 0 rgba(0,0,0,.084)}md-card>:not(md-card-content) img,md-card>img{width:100%}md-card md-card-content{padding:16px}md-card .md-actions{margin:0}md-card .md-actions .md-button{margin:8px 4px}md-card md-card-footer{padding:16px}@media screen and (-ms-high-contrast:active){md-card{border:1px solid #fff}}
|
||||
7
www/lib/angular-material/modules/js/card/card.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/card/card.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(n,i,t){"use strict";function e(n){return{restrict:"E",link:function(i,t,e){n(t)}}}i.module("material.components.card",["material.core"]).directive("mdCard",e),e.$inject=["$mdTheming"]}(window,window.angular);
|
||||
7
www/lib/angular-material/modules/js/checkbox/bower.json
Normal file
7
www/lib/angular-material/modules/js/checkbox/bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-checkbox",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-checkbox.md-THEME_NAME-theme .md-ripple {
|
||||
color: '{{accent-600}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme.md-checked .md-ripple {
|
||||
color: '{{background-600}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme.md-checked.md-focused .md-container:before {
|
||||
background-color: '{{accent-color-0.26}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme .md-icon {
|
||||
border-color: '{{foreground-2}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme.md-checked .md-icon {
|
||||
background-color: '{{accent-color-0.87}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme.md-checked .md-icon:after {
|
||||
border-color: '{{background-200}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary .md-ripple {
|
||||
color: '{{primary-600}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-ripple {
|
||||
color: '{{background-600}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary .md-icon {
|
||||
border-color: '{{foreground-2}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-icon {
|
||||
background-color: '{{primary-color-0.87}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked.md-focused .md-container:before {
|
||||
background-color: '{{primary-color-0.26}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-icon:after {
|
||||
border-color: '{{background-200}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn .md-ripple {
|
||||
color: '{{warn-600}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn .md-icon {
|
||||
border-color: '{{foreground-2}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-icon {
|
||||
background-color: '{{warn-color-0.87}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked.md-focused:not([disabled]) .md-container:before {
|
||||
background-color: '{{warn-color-0.26}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-icon:after {
|
||||
border-color: '{{background-200}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme[disabled] .md-icon {
|
||||
border-color: '{{foreground-3}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme[disabled].md-checked .md-icon {
|
||||
background-color: '{{foreground-3}}'; }
|
||||
md-checkbox.md-THEME_NAME-theme[disabled] .md-label {
|
||||
color: '{{foreground-3}}'; }
|
||||
6
www/lib/angular-material/modules/js/checkbox/checkbox-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/checkbox/checkbox-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-checkbox.md-THEME_NAME-theme .md-ripple{color:'{{accent-600}}'}md-checkbox.md-THEME_NAME-theme.md-checked .md-ripple{color:'{{background-600}}'}md-checkbox.md-THEME_NAME-theme.md-checked.md-focused .md-container:before{background-color:'{{accent-color-0.26}}'}md-checkbox.md-THEME_NAME-theme .md-icon{border-color:'{{foreground-2}}'}md-checkbox.md-THEME_NAME-theme.md-checked .md-icon{background-color:'{{accent-color-0.87}}'}md-checkbox.md-THEME_NAME-theme.md-checked .md-icon:after{border-color:'{{background-200}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary .md-ripple{color:'{{primary-600}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-ripple{color:'{{background-600}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary .md-icon{border-color:'{{foreground-2}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-icon{background-color:'{{primary-color-0.87}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked.md-focused .md-container:before{background-color:'{{primary-color-0.26}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-primary.md-checked .md-icon:after{border-color:'{{background-200}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn .md-ripple{color:'{{warn-600}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn .md-icon{border-color:'{{foreground-2}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-icon{background-color:'{{warn-color-0.87}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked.md-focused:not([disabled]) .md-container:before{background-color:'{{warn-color-0.26}}'}md-checkbox.md-THEME_NAME-theme:not([disabled]).md-warn.md-checked .md-icon:after{border-color:'{{background-200}}'}md-checkbox.md-THEME_NAME-theme[disabled] .md-icon{border-color:'{{foreground-3}}'}md-checkbox.md-THEME_NAME-theme[disabled].md-checked .md-icon{background-color:'{{foreground-3}}'}md-checkbox.md-THEME_NAME-theme[disabled] .md-label{color:'{{foreground-3}}'}
|
||||
124
www/lib/angular-material/modules/js/checkbox/checkbox.css
Normal file
124
www/lib/angular-material/modules/js/checkbox/checkbox.css
Normal file
@@ -0,0 +1,124 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-checkbox {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
margin: 8px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
padding-left: 18px;
|
||||
padding-right: 0;
|
||||
position: relative;
|
||||
line-height: 26px;
|
||||
min-width: 18px;
|
||||
min-height: 18px; }
|
||||
html[dir=rtl] md-checkbox {
|
||||
padding-left: 0; }
|
||||
html[dir=rtl] md-checkbox {
|
||||
padding-right: 18px; }
|
||||
md-checkbox *, md-checkbox *:before, md-checkbox *:after {
|
||||
box-sizing: border-box; }
|
||||
md-checkbox.md-focused:not([disabled]) .md-container:before {
|
||||
left: -8px;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
bottom: -8px; }
|
||||
md-checkbox.md-focused:not([disabled]):not(.md-checked) .md-container:before {
|
||||
background-color: rgba(0, 0, 0, 0.12); }
|
||||
md-checkbox .md-container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
display: inline-block;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
-webkit-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
left: 0;
|
||||
right: auto; }
|
||||
html[dir=rtl] md-checkbox .md-container {
|
||||
left: auto; }
|
||||
html[dir=rtl] md-checkbox .md-container {
|
||||
right: 0; }
|
||||
md-checkbox .md-container:before {
|
||||
background-color: transparent;
|
||||
border-radius: 50%;
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
height: auto;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transition: all 0.5s;
|
||||
width: auto; }
|
||||
md-checkbox .md-container:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
right: -10px;
|
||||
bottom: -10px;
|
||||
left: -10px; }
|
||||
md-checkbox .md-container .md-ripple-container {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: auto;
|
||||
left: -15px;
|
||||
top: -15px;
|
||||
right: -15px;
|
||||
bottom: -15px; }
|
||||
md-checkbox .md-icon {
|
||||
transition: 240ms;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-radius: 2px; }
|
||||
md-checkbox.md-checked .md-icon {
|
||||
border: none; }
|
||||
md-checkbox[disabled] {
|
||||
cursor: no-drop; }
|
||||
md-checkbox.md-checked .md-icon:after {
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
top: 2px;
|
||||
display: table;
|
||||
width: 6px;
|
||||
height: 12px;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
content: ''; }
|
||||
md-checkbox .md-label {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
white-space: normal;
|
||||
-webkit-user-select: text;
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text; }
|
||||
md-checkbox .md-label span {
|
||||
margin-left: 10px;
|
||||
margin-right: 0; }
|
||||
html[dir=rtl] md-checkbox .md-label span {
|
||||
margin-left: 0; }
|
||||
html[dir=rtl] md-checkbox .md-label span {
|
||||
margin-right: 10px; }
|
||||
167
www/lib/angular-material/modules/js/checkbox/checkbox.js
vendored
Normal file
167
www/lib/angular-material/modules/js/checkbox/checkbox.js
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.checkbox
|
||||
* @description Checkbox module!
|
||||
*/
|
||||
angular
|
||||
.module('material.components.checkbox', ['material.core'])
|
||||
.directive('mdCheckbox', MdCheckboxDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdCheckbox
|
||||
* @module material.components.checkbox
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The checkbox directive is used like the normal [angular checkbox](https://docs.angularjs.org/api/ng/input/input%5Bcheckbox%5D).
|
||||
*
|
||||
* As per the [material design spec](http://www.google.com/design/spec/style/color.html#color-ui-color-application)
|
||||
* the checkbox is in the accent color by default. The primary color palette may be used with
|
||||
* the `md-primary` class.
|
||||
*
|
||||
* @param {string} ng-model Assignable angular expression to data-bind to.
|
||||
* @param {string=} name Property name of the form under which the control is published.
|
||||
* @param {expression=} ng-true-value The value to which the expression should be set when selected.
|
||||
* @param {expression=} ng-false-value The value to which the expression should be set when not selected.
|
||||
* @param {string=} ng-change Angular expression to be executed when input changes due to user interaction with the input element.
|
||||
* @param {boolean=} md-no-ink Use of attribute indicates use of ripple ink effects
|
||||
* @param {string=} aria-label Adds label to checkbox for accessibility.
|
||||
* Defaults to checkbox's text. If no default text is found, a warning will be logged.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-checkbox ng-model="isChecked" aria-label="Finished?">
|
||||
* Finished ?
|
||||
* </md-checkbox>
|
||||
*
|
||||
* <md-checkbox md-no-ink ng-model="hasInk" aria-label="No Ink Effects">
|
||||
* No Ink Effects
|
||||
* </md-checkbox>
|
||||
*
|
||||
* <md-checkbox ng-disabled="true" ng-model="isDisabled" aria-label="Disabled">
|
||||
* Disabled
|
||||
* </md-checkbox>
|
||||
*
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function MdCheckboxDirective(inputDirective, $mdInkRipple, $mdAria, $mdConstant, $mdTheming, $mdUtil, $timeout) {
|
||||
inputDirective = inputDirective[0];
|
||||
var CHECKED_CSS = 'md-checked';
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
require: '?ngModel',
|
||||
priority:210, // Run before ngAria
|
||||
template:
|
||||
'<div class="md-container" md-ink-ripple md-ink-ripple-checkbox>' +
|
||||
'<div class="md-icon"></div>' +
|
||||
'</div>' +
|
||||
'<div ng-transclude class="md-label"></div>',
|
||||
compile: compile
|
||||
};
|
||||
|
||||
// **********************************************************
|
||||
// Private Methods
|
||||
// **********************************************************
|
||||
|
||||
function compile (tElement, tAttrs) {
|
||||
|
||||
tAttrs.type = 'checkbox';
|
||||
tAttrs.tabindex = tAttrs.tabindex || '0';
|
||||
tElement.attr('role', tAttrs.type);
|
||||
|
||||
return function postLink(scope, element, attr, ngModelCtrl) {
|
||||
ngModelCtrl = ngModelCtrl || $mdUtil.fakeNgModel();
|
||||
$mdTheming(element);
|
||||
|
||||
if (attr.ngChecked) {
|
||||
scope.$watch(
|
||||
scope.$eval.bind(scope, attr.ngChecked),
|
||||
ngModelCtrl.$setViewValue.bind(ngModelCtrl)
|
||||
);
|
||||
}
|
||||
$$watchExpr('ngDisabled', 'tabindex', {
|
||||
true: '-1',
|
||||
false: attr.tabindex
|
||||
});
|
||||
$mdAria.expectWithText(element, 'aria-label');
|
||||
|
||||
// Reuse the original input[type=checkbox] directive from Angular core.
|
||||
// This is a bit hacky as we need our own event listener and own render
|
||||
// function.
|
||||
inputDirective.link.pre(scope, {
|
||||
on: angular.noop,
|
||||
0: {}
|
||||
}, attr, [ngModelCtrl]);
|
||||
|
||||
scope.mouseActive = false;
|
||||
element.on('click', listener)
|
||||
.on('keypress', keypressHandler)
|
||||
.on('mousedown', function() {
|
||||
scope.mouseActive = true;
|
||||
$timeout(function(){
|
||||
scope.mouseActive = false;
|
||||
}, 100);
|
||||
})
|
||||
.on('focus', function() {
|
||||
if(scope.mouseActive === false) { element.addClass('md-focused'); }
|
||||
})
|
||||
.on('blur', function() { element.removeClass('md-focused'); });
|
||||
|
||||
ngModelCtrl.$render = render;
|
||||
|
||||
function $$watchExpr(expr, htmlAttr, valueOpts) {
|
||||
if (attr[expr]) {
|
||||
scope.$watch(attr[expr], function(val) {
|
||||
if (valueOpts[val]) {
|
||||
element.attr(htmlAttr, valueOpts[val]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function keypressHandler(ev) {
|
||||
var keyCode = ev.which || ev.keyCode;
|
||||
if (keyCode === $mdConstant.KEY_CODE.SPACE || keyCode === $mdConstant.KEY_CODE.ENTER) {
|
||||
ev.preventDefault();
|
||||
if (!element.hasClass('md-focused')) { element.addClass('md-focused'); }
|
||||
listener(ev);
|
||||
}
|
||||
}
|
||||
function listener(ev) {
|
||||
if (element[0].hasAttribute('disabled')) return;
|
||||
|
||||
scope.$apply(function() {
|
||||
// Toggle the checkbox value...
|
||||
var viewValue = attr.ngChecked ? attr.checked : !ngModelCtrl.$viewValue;
|
||||
|
||||
ngModelCtrl.$setViewValue( viewValue, ev && ev.type);
|
||||
ngModelCtrl.$render();
|
||||
});
|
||||
}
|
||||
|
||||
function render() {
|
||||
if(ngModelCtrl.$viewValue) {
|
||||
element.addClass(CHECKED_CSS);
|
||||
} else {
|
||||
element.removeClass(CHECKED_CSS);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
MdCheckboxDirective.$inject = ["inputDirective", "$mdInkRipple", "$mdAria", "$mdConstant", "$mdTheming", "$mdUtil", "$timeout"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/checkbox/checkbox.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/checkbox/checkbox.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-checkbox{box-sizing:border-box;display:block;margin:8px;white-space:nowrap;cursor:pointer;outline:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding-left:18px;padding-right:0;position:relative;line-height:26px;min-width:18px;min-height:18px}html[dir=rtl] md-checkbox{padding-left:0;padding-right:18px}md-checkbox *,md-checkbox :after,md-checkbox :before{box-sizing:border-box}md-checkbox.md-focused:not([disabled]) .md-container:before{left:-8px;top:-8px;right:-8px;bottom:-8px}md-checkbox.md-focused:not([disabled]):not(.md-checked) .md-container:before{background-color:rgba(0,0,0,.12)}md-checkbox .md-container{position:absolute;top:50%;display:inline-block;width:18px;height:18px;-webkit-transform:translateY(-50%);transform:translateY(-50%);left:0;right:auto}html[dir=rtl] md-checkbox .md-container{left:auto;right:0}md-checkbox .md-container:before{background-color:transparent;border-radius:50%;content:'';position:absolute;display:block;height:auto;left:0;top:0;right:0;bottom:0;transition:all .5s;width:auto}md-checkbox .md-container:after{content:'';position:absolute;top:-10px;right:-10px;bottom:-10px;left:-10px}md-checkbox .md-container .md-ripple-container{position:absolute;display:block;width:auto;height:auto;left:-15px;top:-15px;right:-15px;bottom:-15px}md-checkbox .md-icon{transition:240ms;position:absolute;top:0;left:0;width:18px;height:18px;border-width:2px;border-style:solid;border-radius:2px}md-checkbox.md-checked .md-icon{border:none}md-checkbox[disabled]{cursor:no-drop}md-checkbox.md-checked .md-icon:after{-webkit-transform:rotate(45deg);transform:rotate(45deg);position:absolute;left:6px;top:2px;display:table;width:6px;height:12px;border-width:2px;border-style:solid;border-top:0;border-left:0;content:''}md-checkbox .md-label{position:relative;display:inline-block;vertical-align:middle;white-space:normal;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}md-checkbox .md-label span{margin-left:10px;margin-right:0}html[dir=rtl] md-checkbox .md-label span{margin-left:0;margin-right:10px}
|
||||
7
www/lib/angular-material/modules/js/checkbox/checkbox.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/checkbox/checkbox.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(e,n,i){"use strict";function t(e,i,t,c,d,o,a){function s(i,s){return s.type="checkbox",s.tabindex=s.tabindex||"0",i.attr("role",s.type),function(i,s,u,l){function m(e,n,t){u[e]&&i.$watch(u[e],function(e){t[e]&&s.attr(n,t[e])})}function f(e){var n=e.which||e.keyCode;(n===c.KEY_CODE.SPACE||n===c.KEY_CODE.ENTER)&&(e.preventDefault(),s.hasClass("md-focused")||s.addClass("md-focused"),p(e))}function p(e){s[0].hasAttribute("disabled")||i.$apply(function(){var n=u.ngChecked?u.checked:!l.$viewValue;l.$setViewValue(n,e&&e.type),l.$render()})}function v(){l.$viewValue?s.addClass(r):s.removeClass(r)}l=l||o.fakeNgModel(),d(s),u.ngChecked&&i.$watch(i.$eval.bind(i,u.ngChecked),l.$setViewValue.bind(l)),m("ngDisabled","tabindex",{"true":"-1","false":u.tabindex}),t.expectWithText(s,"aria-label"),e.link.pre(i,{on:n.noop,0:{}},u,[l]),i.mouseActive=!1,s.on("click",p).on("keypress",f).on("mousedown",function(){i.mouseActive=!0,a(function(){i.mouseActive=!1},100)}).on("focus",function(){i.mouseActive===!1&&s.addClass("md-focused")}).on("blur",function(){s.removeClass("md-focused")}),l.$render=v}}e=e[0];var r="md-checked";return{restrict:"E",transclude:!0,require:"?ngModel",priority:210,template:'<div class="md-container" md-ink-ripple md-ink-ripple-checkbox><div class="md-icon"></div></div><div ng-transclude class="md-label"></div>',compile:s}}n.module("material.components.checkbox",["material.core"]).directive("mdCheckbox",t),t.$inject=["inputDirective","$mdInkRipple","$mdAria","$mdConstant","$mdTheming","$mdUtil","$timeout"]}(window,window.angular);
|
||||
8
www/lib/angular-material/modules/js/chips/bower.json
Normal file
8
www/lib/angular-material/modules/js/chips/bower.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "angular-material-chips",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0",
|
||||
"angular-material-autocomplete": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-chips.md-THEME_NAME-theme .md-chips {
|
||||
box-shadow: 0 1px '{{background-300}}'; }
|
||||
md-chips.md-THEME_NAME-theme .md-chips.md-focused {
|
||||
box-shadow: 0 2px '{{primary-color}}'; }
|
||||
md-chips.md-THEME_NAME-theme .md-chip {
|
||||
background: '{{background-300}}';
|
||||
color: '{{background-800}}'; }
|
||||
md-chips.md-THEME_NAME-theme .md-chip.md-focused {
|
||||
background: '{{primary-color}}';
|
||||
color: '{{primary-contrast}}'; }
|
||||
md-chips.md-THEME_NAME-theme .md-chip.md-focused md-icon {
|
||||
color: '{{primary-contrast}}'; }
|
||||
md-chips.md-THEME_NAME-theme md-chip-remove .md-button md-icon path {
|
||||
fill: '{{background-500}}'; }
|
||||
|
||||
.md-contact-suggestion span.md-contact-email {
|
||||
color: '{{background-400}}'; }
|
||||
6
www/lib/angular-material/modules/js/chips/chips-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/chips/chips-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-chips.md-THEME_NAME-theme .md-chips{box-shadow:0 1px '{{background-300}}'}md-chips.md-THEME_NAME-theme .md-chips.md-focused{box-shadow:0 2px '{{primary-color}}'}md-chips.md-THEME_NAME-theme .md-chip{background:0 0;color:'{{background-800}}'}md-chips.md-THEME_NAME-theme .md-chip.md-focused{background:0 0;color:'{{primary-contrast}}'}md-chips.md-THEME_NAME-theme .md-chip.md-focused md-icon{color:'{{primary-contrast}}'}md-chips.md-THEME_NAME-theme md-chip-remove .md-button md-icon path{fill:'{{background-500}}'}.md-contact-suggestion span.md-contact-email{color:'{{background-400}}'}
|
||||
131
www/lib/angular-material/modules/js/chips/chips.css
Normal file
131
www/lib/angular-material/modules/js/chips/chips.css
Normal file
@@ -0,0 +1,131 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
.md-contact-chips .md-chips .md-chip {
|
||||
padding: 0 8px 0 0; }
|
||||
.md-contact-chips .md-chips .md-chip .md-contact-avatar {
|
||||
float: left; }
|
||||
.md-contact-chips .md-chips .md-chip .md-contact-avatar img {
|
||||
height: 32px;
|
||||
border-radius: 16px; }
|
||||
.md-contact-chips .md-chips .md-chip .md-contact-name {
|
||||
display: inline-block;
|
||||
height: 32px;
|
||||
margin-left: 8px; }
|
||||
|
||||
.md-contact-suggestion {
|
||||
height: 56px; }
|
||||
.md-contact-suggestion img {
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
margin-top: 8px; }
|
||||
.md-contact-suggestion .md-contact-name {
|
||||
margin-left: 8px;
|
||||
width: 120px; }
|
||||
.md-contact-suggestion .md-contact-name, .md-contact-suggestion .md-contact-email {
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; }
|
||||
|
||||
.md-contact-chips-suggestions li {
|
||||
height: 100%; }
|
||||
|
||||
.md-chips {
|
||||
display: block;
|
||||
font-family: RobotoDraft, Roboto, 'Helvetica Neue', sans-serif;
|
||||
font-size: 13px;
|
||||
padding: 0 0 8px 0;
|
||||
vertical-align: middle;
|
||||
cursor: text; }
|
||||
.md-chips:after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both; }
|
||||
.md-chips .md-chip {
|
||||
cursor: default;
|
||||
border-radius: 16px;
|
||||
display: block;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin: 8px 8px 0 0;
|
||||
padding: 0 8px 0 12px;
|
||||
float: left; }
|
||||
.md-chips .md-chip .md-chip-content {
|
||||
display: block;
|
||||
padding-right: 4px;
|
||||
float: left;
|
||||
white-space: nowrap; }
|
||||
.md-chips .md-chip .md-chip-content:focus {
|
||||
outline: none; }
|
||||
.md-chips .md-chip .md-chip-remove-container {
|
||||
display: inline-block;
|
||||
margin-right: -5px; }
|
||||
.md-chips .md-chip .md-chip-remove {
|
||||
text-align: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
position: relative; }
|
||||
.md-chips .md-chip .md-chip-remove md-icon {
|
||||
height: 18px;
|
||||
width: 18px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-transform: translate3d(-50%, -50%, 0);
|
||||
transform: translate3d(-50%, -50%, 0); }
|
||||
.md-chips .md-chip-input-container {
|
||||
display: block;
|
||||
line-height: 32px;
|
||||
margin: 8px 8px 0 0;
|
||||
padding: 0 8px 0 12px;
|
||||
float: left; }
|
||||
.md-chips .md-chip-input-container input:not([type]), .md-chips .md-chip-input-container input[type="email"], .md-chips .md-chip-input-container input[type="number"], .md-chips .md-chip-input-container input[type="tel"], .md-chips .md-chip-input-container input[type="url"], .md-chips .md-chip-input-container input[type="text"] {
|
||||
border: 0;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0; }
|
||||
.md-chips .md-chip-input-container input:not([type]):focus, .md-chips .md-chip-input-container input[type="email"]:focus, .md-chips .md-chip-input-container input[type="number"]:focus, .md-chips .md-chip-input-container input[type="tel"]:focus, .md-chips .md-chip-input-container input[type="url"]:focus, .md-chips .md-chip-input-container input[type="text"]:focus {
|
||||
outline: none; }
|
||||
.md-chips .md-chip-input-container md-autocomplete, .md-chips .md-chip-input-container md-autocomplete-wrap {
|
||||
background: transparent;
|
||||
height: 32px; }
|
||||
.md-chips .md-chip-input-container md-autocomplete md-autocomplete-wrap {
|
||||
box-shadow: none; }
|
||||
.md-chips .md-chip-input-container md-autocomplete input {
|
||||
position: relative; }
|
||||
.md-chips .md-chip-input-container input {
|
||||
border: 0;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
padding: 0; }
|
||||
.md-chips .md-chip-input-container input:focus {
|
||||
outline: none; }
|
||||
.md-chips .md-chip-input-container md-autocomplete, .md-chips .md-chip-input-container md-autocomplete-wrap {
|
||||
height: 32px; }
|
||||
.md-chips .md-chip-input-container md-autocomplete {
|
||||
box-shadow: none; }
|
||||
.md-chips .md-chip-input-container md-autocomplete input {
|
||||
position: relative; }
|
||||
.md-chips .md-chip-input-container:not(:first-child) {
|
||||
margin: 8px 8px 0 0; }
|
||||
.md-chips .md-chip-input-container input {
|
||||
background: transparent;
|
||||
border-width: 0; }
|
||||
.md-chips md-autocomplete button {
|
||||
display: none; }
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
.md-chip-input-container, md-chip {
|
||||
border: 1px solid #fff; }
|
||||
.md-chip-input-container md-autocomplete {
|
||||
border: none; } }
|
||||
949
www/lib/angular-material/modules/js/chips/chips.js
vendored
Normal file
949
www/lib/angular-material/modules/js/chips/chips.js
vendored
Normal file
@@ -0,0 +1,949 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.chips
|
||||
*/
|
||||
/*
|
||||
* @see js folder for chips implementation
|
||||
*/
|
||||
angular.module('material.components.chips', [
|
||||
'material.core',
|
||||
'material.components.autocomplete'
|
||||
]);
|
||||
|
||||
angular
|
||||
.module('material.components.chips')
|
||||
.directive('mdChip', MdChip);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdChip
|
||||
* @module material.components.chips
|
||||
*
|
||||
* @description
|
||||
* `<md-chip>` is a component used within `<md-chips>` and is responsible for rendering individual
|
||||
* chips.
|
||||
*
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-chip>{{$chip}}</md-chip>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
|
||||
// This hint text is hidden within a chip but used by screen readers to
|
||||
// inform the user how they can interact with a chip.
|
||||
var DELETE_HINT_TEMPLATE = '\
|
||||
<span ng-if="!$mdChipsCtrl.readonly" class="md-visually-hidden">\
|
||||
{{$mdChipsCtrl.deleteHint}}\
|
||||
</span>';
|
||||
|
||||
/**
|
||||
* MDChip Directive Definition
|
||||
*
|
||||
* @param $mdTheming
|
||||
* @param $mdInkRipple
|
||||
* ngInject
|
||||
*/
|
||||
function MdChip($mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: '^?mdChips',
|
||||
compile: compile
|
||||
};
|
||||
|
||||
function compile(element, attr) {
|
||||
element.append(DELETE_HINT_TEMPLATE);
|
||||
return function postLink(scope, element, attr, ctrl) {
|
||||
element.addClass('md-chip');
|
||||
$mdTheming(element);
|
||||
|
||||
if (ctrl) angular.element(element[0].querySelector('.md-chip-content'))
|
||||
.on('blur', function () {
|
||||
ctrl.selectedChip = -1;
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
MdChip.$inject = ["$mdTheming"];
|
||||
|
||||
angular
|
||||
.module('material.components.chips')
|
||||
.directive('mdChipRemove', MdChipRemove);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdChipRemove
|
||||
* @module material.components.chips
|
||||
*
|
||||
* @description
|
||||
* `<md-chip-remove>`
|
||||
* Designates an element to be used as the delete button for a chip. This
|
||||
* element is passed as a child of the `md-chips` element.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-chips><button md-chip-remove>DEL</button></md-chips>
|
||||
* </hljs>
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* MdChipRemove Directive Definition.
|
||||
*
|
||||
* @param $compile
|
||||
* @param $timeout
|
||||
* @returns {{restrict: string, require: string[], link: Function, scope: boolean}}
|
||||
* @constructor
|
||||
*/
|
||||
function MdChipRemove ($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
require: '^mdChips',
|
||||
scope: false,
|
||||
link: postLink
|
||||
};
|
||||
|
||||
function postLink(scope, element, attr, ctrl) {
|
||||
element.on('click', function(event) {
|
||||
scope.$apply(function() {
|
||||
ctrl.removeChip(scope.$$replacedScope.$index);
|
||||
});
|
||||
});
|
||||
|
||||
// Child elements aren't available until after a $timeout tick as they are hidden by an
|
||||
// `ng-if`. see http://goo.gl/zIWfuw
|
||||
$timeout(function() {
|
||||
element.attr({ tabindex: -1, ariaHidden: true });
|
||||
element.find('button').attr('tabindex', '-1');
|
||||
});
|
||||
}
|
||||
}
|
||||
MdChipRemove.$inject = ["$timeout"];
|
||||
|
||||
angular
|
||||
.module('material.components.chips')
|
||||
.directive('mdChipTransclude', MdChipTransclude);
|
||||
|
||||
function MdChipTransclude ($compile, $mdUtil) {
|
||||
return {
|
||||
restrict: 'EA',
|
||||
terminal: true,
|
||||
link: link,
|
||||
scope: false
|
||||
};
|
||||
function link (scope, element, attr) {
|
||||
var ctrl = scope.$parent.$mdChipsCtrl,
|
||||
newScope = ctrl.parent.$new(false, ctrl.parent);
|
||||
newScope.$$replacedScope = scope;
|
||||
newScope.$chip = scope.$chip;
|
||||
newScope.$mdChipsCtrl = ctrl;
|
||||
element.html(ctrl.$scope.$eval(attr.mdChipTransclude));
|
||||
$compile(element.contents())(newScope);
|
||||
}
|
||||
}
|
||||
MdChipTransclude.$inject = ["$compile", "$mdUtil"];
|
||||
|
||||
angular
|
||||
.module('material.components.chips')
|
||||
.controller('MdChipsCtrl', MdChipsCtrl);
|
||||
|
||||
/**
|
||||
* Controller for the MdChips component. Responsible for adding to and
|
||||
* removing from the list of chips, marking chips as selected, and binding to
|
||||
* the models of various input components.
|
||||
*
|
||||
* @param $scope
|
||||
* @param $mdConstant
|
||||
* @param $log
|
||||
* @param $element
|
||||
* @constructor
|
||||
*/
|
||||
function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout) {
|
||||
/** @type {$timeout} **/
|
||||
this.$timeout = $timeout;
|
||||
|
||||
/** @type {Object} */
|
||||
this.$mdConstant = $mdConstant;
|
||||
|
||||
/** @type {angular.$scope} */
|
||||
this.$scope = $scope;
|
||||
|
||||
/** @type {angular.$scope} */
|
||||
this.parent = $scope.$parent;
|
||||
|
||||
/** @type {$log} */
|
||||
this.$log = $log;
|
||||
|
||||
/** @type {$element} */
|
||||
this.$element = $element;
|
||||
|
||||
/** @type {angular.NgModelController} */
|
||||
this.ngModelCtrl = null;
|
||||
|
||||
/** @type {angular.NgModelController} */
|
||||
this.userInputNgModelCtrl = null;
|
||||
|
||||
/** @type {Element} */
|
||||
this.userInputElement = null;
|
||||
|
||||
/** @type {Array.<Object>} */
|
||||
this.items = [];
|
||||
|
||||
/** @type {number} */
|
||||
this.selectedChip = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Hidden hint text for how to delete a chip. Used to give context to screen readers.
|
||||
* @type {string}
|
||||
*/
|
||||
this.deleteHint = 'Press delete to remove this chip.';
|
||||
|
||||
/**
|
||||
* Hidden label for the delete button. Used to give context to screen readers.
|
||||
* @type {string}
|
||||
*/
|
||||
this.deleteButtonLabel = 'Remove';
|
||||
|
||||
/**
|
||||
* Model used by the input element.
|
||||
* @type {string}
|
||||
*/
|
||||
this.chipBuffer = '';
|
||||
|
||||
/**
|
||||
* Whether to use the mdOnAppend expression to transform the chip buffer
|
||||
* before appending it to the list.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.useMdOnAppend = false;
|
||||
}
|
||||
MdChipsCtrl.$inject = ["$scope", "$mdConstant", "$log", "$element", "$timeout"];
|
||||
|
||||
/**
|
||||
* Handles the keydown event on the input element: <enter> appends the
|
||||
* buffer to the chip list, while backspace removes the last chip in the list
|
||||
* if the current buffer is empty.
|
||||
* @param event
|
||||
*/
|
||||
MdChipsCtrl.prototype.inputKeydown = function(event) {
|
||||
var chipBuffer = this.getChipBuffer();
|
||||
switch (event.keyCode) {
|
||||
case this.$mdConstant.KEY_CODE.ENTER:
|
||||
if (this.$scope.requireMatch || !chipBuffer) break;
|
||||
event.preventDefault();
|
||||
this.appendChip(chipBuffer);
|
||||
this.resetChipBuffer();
|
||||
break;
|
||||
case this.$mdConstant.KEY_CODE.BACKSPACE:
|
||||
if (chipBuffer) break;
|
||||
event.stopPropagation();
|
||||
if (this.items.length) this.selectAndFocusChipSafe(this.items.length - 1);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the keydown event on the chip elements: backspace removes the selected chip, arrow
|
||||
* keys switch which chips is active
|
||||
* @param event
|
||||
*/
|
||||
MdChipsCtrl.prototype.chipKeydown = function (event) {
|
||||
if (this.getChipBuffer()) return;
|
||||
switch (event.keyCode) {
|
||||
case this.$mdConstant.KEY_CODE.BACKSPACE:
|
||||
case this.$mdConstant.KEY_CODE.DELETE:
|
||||
if (this.selectedChip < 0) return;
|
||||
event.preventDefault();
|
||||
this.removeAndSelectAdjacentChip(this.selectedChip);
|
||||
break;
|
||||
case this.$mdConstant.KEY_CODE.LEFT_ARROW:
|
||||
event.preventDefault();
|
||||
if (this.selectedChip < 0) this.selectedChip = this.items.length;
|
||||
if (this.items.length) this.selectAndFocusChipSafe(this.selectedChip - 1);
|
||||
break;
|
||||
case this.$mdConstant.KEY_CODE.RIGHT_ARROW:
|
||||
event.preventDefault();
|
||||
this.selectAndFocusChipSafe(this.selectedChip + 1);
|
||||
break;
|
||||
case this.$mdConstant.KEY_CODE.ESCAPE:
|
||||
case this.$mdConstant.KEY_CODE.TAB:
|
||||
if (this.selectedChip < 0) return;
|
||||
event.preventDefault();
|
||||
this.onFocus();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the input's placeholder - uses `placeholder` when list is empty and `secondary-placeholder`
|
||||
* when the list is non-empty. If `secondary-placeholder` is not provided, `placeholder` is used
|
||||
* always.
|
||||
*/
|
||||
MdChipsCtrl.prototype.getPlaceholder = function() {
|
||||
// Allow `secondary-placeholder` to be blank.
|
||||
var useSecondary = (this.items.length &&
|
||||
(this.secondaryPlaceholder == '' || this.secondaryPlaceholder));
|
||||
return useSecondary ? this.placeholder : this.secondaryPlaceholder;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes chip at {@code index} and selects the adjacent chip.
|
||||
* @param index
|
||||
*/
|
||||
MdChipsCtrl.prototype.removeAndSelectAdjacentChip = function(index) {
|
||||
var selIndex = this.getAdjacentChipIndex(index);
|
||||
this.removeChip(index);
|
||||
this.$timeout(angular.bind(this, function () {
|
||||
this.selectAndFocusChipSafe(selIndex);
|
||||
}));
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the selected chip index to -1.
|
||||
*/
|
||||
MdChipsCtrl.prototype.resetSelectedChip = function() {
|
||||
this.selectedChip = -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the index of an adjacent chip to select after deletion. Adjacency is
|
||||
* determined as the next chip in the list, unless the target chip is the
|
||||
* last in the list, then it is the chip immediately preceding the target. If
|
||||
* there is only one item in the list, -1 is returned (select none).
|
||||
* The number returned is the index to select AFTER the target has been
|
||||
* removed.
|
||||
* If the current chip is not selected, then -1 is returned to select none.
|
||||
*/
|
||||
MdChipsCtrl.prototype.getAdjacentChipIndex = function(index) {
|
||||
var len = this.items.length - 1;
|
||||
return (len == 0) ? -1 :
|
||||
(index == len) ? index -1 : index;
|
||||
};
|
||||
|
||||
/**
|
||||
* Append the contents of the buffer to the chip list. This method will first
|
||||
* call out to the md-on-append method, if provided
|
||||
* @param newChip
|
||||
*/
|
||||
MdChipsCtrl.prototype.appendChip = function(newChip) {
|
||||
if (this.items.indexOf(newChip) + 1) return;
|
||||
if (this.useMdOnAppend && this.mdOnAppend) {
|
||||
newChip = this.mdOnAppend({'$chip': newChip});
|
||||
}
|
||||
this.items.push(newChip);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets whether to use the md-on-append expression. This expression is
|
||||
* bound to scope and controller in {@code MdChipsDirective} as
|
||||
* {@code mdOnAppend}. Due to the nature of directive scope bindings, the
|
||||
* controller cannot know on its own/from the scope whether an expression was
|
||||
* actually provided.
|
||||
*/
|
||||
MdChipsCtrl.prototype.useMdOnAppendExpression = function() {
|
||||
this.useMdOnAppend = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the input buffer. The input buffer can be the model bound to the
|
||||
* default input item {@code this.chipBuffer}, the {@code selectedItem}
|
||||
* model of an {@code md-autocomplete}, or, through some magic, the model
|
||||
* bound to any inpput or text area element found within a
|
||||
* {@code md-input-container} element.
|
||||
* @return {Object|string}
|
||||
*/
|
||||
MdChipsCtrl.prototype.getChipBuffer = function() {
|
||||
return !this.userInputElement ? this.chipBuffer :
|
||||
this.userInputNgModelCtrl ? this.userInputNgModelCtrl.$viewValue :
|
||||
this.userInputElement[0].value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the input buffer for either the internal input or user provided input element.
|
||||
*/
|
||||
MdChipsCtrl.prototype.resetChipBuffer = function() {
|
||||
if (this.userInputElement) {
|
||||
if (this.userInputNgModelCtrl) {
|
||||
this.userInputNgModelCtrl.$setViewValue('');
|
||||
this.userInputNgModelCtrl.$render();
|
||||
} else {
|
||||
this.userInputElement[0].value = '';
|
||||
}
|
||||
} else {
|
||||
this.chipBuffer = '';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the chip at the given index.
|
||||
* @param index
|
||||
*/
|
||||
MdChipsCtrl.prototype.removeChip = function(index) {
|
||||
this.items.splice(index, 1);
|
||||
};
|
||||
|
||||
MdChipsCtrl.prototype.removeChipAndFocusInput = function (index) {
|
||||
this.removeChip(index);
|
||||
this.onFocus();
|
||||
};
|
||||
/**
|
||||
* Selects the chip at `index`,
|
||||
* @param index
|
||||
*/
|
||||
MdChipsCtrl.prototype.selectAndFocusChipSafe = function(index) {
|
||||
if (!this.items.length) {
|
||||
this.selectChip(-1);
|
||||
this.onFocus();
|
||||
return;
|
||||
}
|
||||
if (index === this.items.length) return this.onFocus();
|
||||
index = Math.max(index, 0);
|
||||
index = Math.min(index, this.items.length - 1);
|
||||
this.selectChip(index);
|
||||
this.focusChip(index);
|
||||
};
|
||||
|
||||
/**
|
||||
* Marks the chip at the given index as selected.
|
||||
* @param index
|
||||
*/
|
||||
MdChipsCtrl.prototype.selectChip = function(index) {
|
||||
if (index >= -1 && index <= this.items.length) {
|
||||
this.selectedChip = index;
|
||||
} else {
|
||||
this.$log.warn('Selected Chip index out of bounds; ignoring.');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Selects the chip at `index` and gives it focus.
|
||||
* @param index
|
||||
*/
|
||||
MdChipsCtrl.prototype.selectAndFocusChip = function(index) {
|
||||
this.selectChip(index);
|
||||
if (index != -1) {
|
||||
this.focusChip(index);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Call `focus()` on the chip at `index`
|
||||
*/
|
||||
MdChipsCtrl.prototype.focusChip = function(index) {
|
||||
this.$element[0].querySelector('md-chip[index="' + index + '"] .md-chip-content').focus();
|
||||
};
|
||||
|
||||
/**
|
||||
* Configures the required interactions with the ngModel Controller.
|
||||
* Specifically, set {@code this.items} to the {@code NgModelCtrl#$viewVale}.
|
||||
* @param ngModelCtrl
|
||||
*/
|
||||
MdChipsCtrl.prototype.configureNgModel = function(ngModelCtrl) {
|
||||
this.ngModelCtrl = ngModelCtrl;
|
||||
|
||||
var self = this;
|
||||
ngModelCtrl.$render = function() {
|
||||
// model is updated. do something.
|
||||
self.items = self.ngModelCtrl.$viewValue;
|
||||
};
|
||||
};
|
||||
|
||||
MdChipsCtrl.prototype.onFocus = function () {
|
||||
var input = this.$element[0].querySelector('input');
|
||||
input && input.focus();
|
||||
this.resetSelectedChip();
|
||||
};
|
||||
|
||||
MdChipsCtrl.prototype.onInputFocus = function () {
|
||||
this.inputHasFocus = true;
|
||||
this.resetSelectedChip();
|
||||
};
|
||||
|
||||
MdChipsCtrl.prototype.onInputBlur = function () {
|
||||
this.inputHasFocus = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configure event bindings on a user-provided input element.
|
||||
* @param inputElement
|
||||
*/
|
||||
MdChipsCtrl.prototype.configureUserInput = function(inputElement) {
|
||||
this.userInputElement = inputElement;
|
||||
|
||||
// Find the NgModelCtrl for the input element
|
||||
var ngModelCtrl = inputElement.controller('ngModel');
|
||||
// `.controller` will look in the parent as well.
|
||||
if (ngModelCtrl != this.ngModelCtrl) {
|
||||
this.userInputNgModelCtrl = ngModelCtrl;
|
||||
}
|
||||
|
||||
// Bind to keydown and focus events of input
|
||||
var scope = this.$scope;
|
||||
var ctrl = this;
|
||||
inputElement
|
||||
.attr({ tabindex: 0 })
|
||||
.on('keydown', function(event) { scope.$apply( angular.bind(ctrl, function() { ctrl.inputKeydown(event); })) })
|
||||
.on('focus', angular.bind(ctrl, ctrl.onInputFocus))
|
||||
.on('blur', angular.bind(ctrl, ctrl.onInputBlur));
|
||||
};
|
||||
|
||||
MdChipsCtrl.prototype.configureAutocomplete = function(ctrl) {
|
||||
|
||||
ctrl.registerSelectedItemWatcher(angular.bind(this, function (item) {
|
||||
if (item) {
|
||||
this.appendChip(item);
|
||||
this.resetChipBuffer();
|
||||
}
|
||||
}));
|
||||
|
||||
this.$element.find('input')
|
||||
.on('focus',angular.bind(this, this.onInputFocus) )
|
||||
.on('blur', angular.bind(this, this.onInputBlur) );
|
||||
};
|
||||
|
||||
MdChipsCtrl.prototype.hasFocus = function () {
|
||||
return this.inputHasFocus || this.selectedChip >= 0;
|
||||
};
|
||||
|
||||
angular
|
||||
.module('material.components.chips')
|
||||
.directive('mdChips', MdChips);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdChips
|
||||
* @module material.components.chips
|
||||
*
|
||||
* @description
|
||||
* `<md-chips>` is an input component for building lists of strings or objects. The list items are
|
||||
* displayed as 'chips'. This component can make use of an `<input>` element or an
|
||||
* `<md-autocomplete>` element.
|
||||
*
|
||||
* <strong>Custom `<md-chip-template>` template</strong>
|
||||
* A custom template may be provided to render the content of each chip. This is achieved by
|
||||
* specifying an `<md-chip-template>` element as a child of `<md-chips>`. Note: Any attributes on
|
||||
* `<md-chip-template>` will be dropped as only the innerHTML is used for the chip template. The
|
||||
* variables `$chip` and `$index` are available in the scope of `<md-chip-template>`, representing
|
||||
* the chip object and its index in the list of chips, respectively.
|
||||
* To override the chip delete control, include an element (ideally a button) with the attribute
|
||||
* `md-chip-remove`. A click listener to remove the chip will be added automatically. The element
|
||||
* is also placed as a sibling to the chip content (on which there are also click listeners) to
|
||||
* avoid a nested ng-click situation.
|
||||
*
|
||||
* <h3> Pending Features </h3>
|
||||
* <ul style="padding-left:20px;">
|
||||
*
|
||||
* <ul>Style
|
||||
* <li>Colours for hover, press states (ripple?).</li>
|
||||
* </ul>
|
||||
*
|
||||
* <ul>List Manipulation
|
||||
* <li>delete item via DEL or backspace keys when selected</li>
|
||||
* </ul>
|
||||
*
|
||||
* <ul>Validation
|
||||
* <li>de-dupe values (or support duplicates, but fix the ng-repeat duplicate key issue)</li>
|
||||
* <li>allow a validation callback</li>
|
||||
* <li>hilighting style for invalid chips</li>
|
||||
* </ul>
|
||||
*
|
||||
* <ul>Item mutation
|
||||
* <li>Support `
|
||||
* <md-chip-edit>` template, show/hide the edit element on tap/click? double tap/double
|
||||
* click?
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <ul>Truncation and Disambiguation (?)
|
||||
* <li>Truncate chip text where possible, but do not truncate entries such that two are
|
||||
* indistinguishable.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <ul>Drag and Drop
|
||||
* <li>Drag and drop chips between related `<md-chips>` elements.
|
||||
* </li>
|
||||
* </ul>
|
||||
* </ul>
|
||||
*
|
||||
* <span style="font-size:.8em;text-align:center">
|
||||
* Warning: This component is a WORK IN PROGRESS. If you use it now,
|
||||
* it will probably break on you in the future.
|
||||
* </span>
|
||||
*
|
||||
* @param {string=|object=} ng-model A model to bind the list of items to
|
||||
* @param {string=} placeholder Placeholder text that will be forwarded to the input.
|
||||
* @param {string=} secondary-placeholder Placeholder text that will be forwarded to the input,
|
||||
* displayed when there is at least on item in the list
|
||||
* @param {boolean=} readonly Disables list manipulation (deleting or adding list items), hiding
|
||||
* the input and delete buttons
|
||||
* @param {expression} md-on-append An expression expected to convert the input string into an
|
||||
* object when adding a chip.
|
||||
* @param {string=} delete-hint A string read by screen readers instructing users that pressing
|
||||
* the delete key will remove the chip.
|
||||
* @param {string=} delete-button-label A label for the delete button. Also hidden and read by
|
||||
* screen readers.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-chips
|
||||
* ng-model="myItems"
|
||||
* placeholder="Add an item"
|
||||
* readonly="isReadOnly">
|
||||
* </md-chips>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
var MD_CHIPS_TEMPLATE = '\
|
||||
<md-chips-wrap\
|
||||
ng-if="!$mdChipsCtrl.readonly || $mdChipsCtrl.items.length > 0"\
|
||||
ng-keydown="$mdChipsCtrl.chipKeydown($event)"\
|
||||
ng-class="{ \'md-focused\': $mdChipsCtrl.hasFocus() }"\
|
||||
class="md-chips">\
|
||||
<md-chip ng-repeat="$chip in $mdChipsCtrl.items"\
|
||||
index="{{$index}}"\
|
||||
ng-class="{\'md-focused\': $mdChipsCtrl.selectedChip == $index}">\
|
||||
<div class="md-chip-content"\
|
||||
tabindex="-1"\
|
||||
aria-hidden="true"\
|
||||
ng-focus="!$mdChipsCtrl.readonly && $mdChipsCtrl.selectChip($index)"\
|
||||
md-chip-transclude="$mdChipsCtrl.chipContentsTemplate"></div>\
|
||||
<div class="md-chip-remove-container"\
|
||||
md-chip-transclude="$mdChipsCtrl.chipRemoveTemplate"></div>\
|
||||
</md-chip>\
|
||||
<div ng-if="!$mdChipsCtrl.readonly && $mdChipsCtrl.ngModelCtrl"\
|
||||
class="md-chip-input-container"\
|
||||
md-chip-transclude="$mdChipsCtrl.chipInputTemplate"></div>\
|
||||
</div>\
|
||||
</md-chips-wrap>';
|
||||
|
||||
var CHIP_INPUT_TEMPLATE = '\
|
||||
<input\
|
||||
tabindex="0"\
|
||||
placeholder="{{$mdChipsCtrl.getPlaceholder()}}"\
|
||||
aria-label="{{$mdChipsCtrl.getPlaceholder()}}"\
|
||||
ng-model="$mdChipsCtrl.chipBuffer"\
|
||||
ng-focus="$mdChipsCtrl.onInputFocus()"\
|
||||
ng-blur="$mdChipsCtrl.onInputBlur()"\
|
||||
ng-keydown="$mdChipsCtrl.inputKeydown($event)">';
|
||||
|
||||
var CHIP_DEFAULT_TEMPLATE = '\
|
||||
<span>{{$chip}}</span>';
|
||||
|
||||
var CHIP_REMOVE_TEMPLATE = '\
|
||||
<button\
|
||||
class="md-chip-remove"\
|
||||
ng-if="!$mdChipsCtrl.readonly"\
|
||||
ng-click="$mdChipsCtrl.removeChipAndFocusInput($$replacedScope.$index)"\
|
||||
type="button"\
|
||||
aria-hidden="true"\
|
||||
tabindex="-1">\
|
||||
<md-icon md-svg-icon="md-close"></md-icon>\
|
||||
<span class="md-visually-hidden">\
|
||||
{{$mdChipsCtrl.deleteButtonLabel}}\
|
||||
</span>\
|
||||
</button>';
|
||||
|
||||
/**
|
||||
* MDChips Directive Definition
|
||||
*/
|
||||
function MdChips ($mdTheming, $mdUtil, $compile, $log, $timeout) {
|
||||
return {
|
||||
template: function(element, attrs) {
|
||||
// Clone the element into an attribute. By prepending the attribute
|
||||
// name with '$', Angular won't write it into the DOM. The cloned
|
||||
// element propagates to the link function via the attrs argument,
|
||||
// where various contained-elements can be consumed.
|
||||
var content = attrs['$mdUserTemplate'] = element.clone();
|
||||
return MD_CHIPS_TEMPLATE;
|
||||
},
|
||||
require: ['mdChips'],
|
||||
restrict: 'E',
|
||||
controller: 'MdChipsCtrl',
|
||||
controllerAs: '$mdChipsCtrl',
|
||||
bindToController: true,
|
||||
compile: compile,
|
||||
scope: {
|
||||
readonly: '=readonly',
|
||||
placeholder: '@',
|
||||
secondaryPlaceholder: '@',
|
||||
mdOnAppend: '&',
|
||||
deleteHint: '@',
|
||||
deleteButtonLabel: '@',
|
||||
requireMatch: '=?mdRequireMatch'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds the final template for `md-chips` and returns the postLink function.
|
||||
*
|
||||
* Building the template involves 3 key components:
|
||||
* static chips
|
||||
* chip template
|
||||
* input control
|
||||
*
|
||||
* If no `ng-model` is provided, only the static chip work needs to be done.
|
||||
*
|
||||
* If no user-passed `md-chip-template` exists, the default template is used. This resulting
|
||||
* template is appended to the chip content element.
|
||||
*
|
||||
* The remove button may be overridden by passing an element with an md-chip-remove attribute.
|
||||
*
|
||||
* If an `input` or `md-autocomplete` element is provided by the caller, it is set aside for
|
||||
* transclusion later. The transclusion happens in `postLink` as the parent scope is required.
|
||||
* If no user input is provided, a default one is appended to the input container node in the
|
||||
* template.
|
||||
*
|
||||
* Static Chips (i.e. `md-chip` elements passed from the caller) are gathered and set aside for
|
||||
* transclusion in the `postLink` function.
|
||||
*
|
||||
*
|
||||
* @param element
|
||||
* @param attr
|
||||
* @returns {Function}
|
||||
*/
|
||||
function compile(element, attr) {
|
||||
// Grab the user template from attr and reset the attribute to null.
|
||||
var userTemplate = attr['$mdUserTemplate'];
|
||||
attr['$mdUserTemplate'] = null;
|
||||
|
||||
// Set the chip remove, chip contents and chip input templates. The link function will put
|
||||
// them on the scope for transclusion later.
|
||||
var chipRemoveTemplate = getTemplateByQuery('md-chips>*[md-chip-remove]') || CHIP_REMOVE_TEMPLATE,
|
||||
chipContentsTemplate = getTemplateByQuery('md-chips>md-chip-template') || CHIP_DEFAULT_TEMPLATE,
|
||||
chipInputTemplate = getTemplateByQuery('md-chips>md-autocomplete')
|
||||
|| getTemplateByQuery('md-chips>input')
|
||||
|| CHIP_INPUT_TEMPLATE,
|
||||
staticChips = userTemplate.find('md-chip');
|
||||
|
||||
// Warn of malformed template. See #2545
|
||||
if (userTemplate[0].querySelector('md-chip-template>*[md-chip-remove]')) {
|
||||
$log.warn('invalid placement of md-chip-remove within md-chip-template.');
|
||||
}
|
||||
|
||||
function getTemplateByQuery (query) {
|
||||
if (!attr.ngModel) return;
|
||||
var element = userTemplate[0].querySelector(query);
|
||||
return element && element.outerHTML;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures controller and transcludes.
|
||||
*/
|
||||
return function postLink(scope, element, attrs, controllers) {
|
||||
|
||||
$mdUtil.initOptionalProperties(scope, attr);
|
||||
|
||||
$mdTheming(element);
|
||||
var mdChipsCtrl = controllers[0];
|
||||
mdChipsCtrl.chipContentsTemplate = chipContentsTemplate;
|
||||
mdChipsCtrl.chipRemoveTemplate = chipRemoveTemplate;
|
||||
mdChipsCtrl.chipInputTemplate = chipInputTemplate;
|
||||
|
||||
element
|
||||
.attr({ ariaHidden: true, tabindex: -1 })
|
||||
.on('focus', function () { mdChipsCtrl.onFocus(); });
|
||||
|
||||
if (attr.ngModel) {
|
||||
mdChipsCtrl.configureNgModel(element.controller('ngModel'));
|
||||
|
||||
// If an `md-on-append` attribute was set, tell the controller to use the expression
|
||||
// when appending chips.
|
||||
if (attrs.mdOnAppend) mdChipsCtrl.useMdOnAppendExpression();
|
||||
|
||||
// The md-autocomplete and input elements won't be compiled until after this directive
|
||||
// is complete (due to their nested nature). Wait a tick before looking for them to
|
||||
// configure the controller.
|
||||
if (chipInputTemplate != CHIP_INPUT_TEMPLATE) {
|
||||
$timeout(function() {
|
||||
if (chipInputTemplate.indexOf('<md-autocomplete') === 0)
|
||||
mdChipsCtrl
|
||||
.configureAutocomplete(element.find('md-autocomplete')
|
||||
.controller('mdAutocomplete'));
|
||||
mdChipsCtrl.configureUserInput(element.find('input'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Compile with the parent's scope and prepend any static chips to the wrapper.
|
||||
if (staticChips.length > 0) {
|
||||
var compiledStaticChips = $compile(staticChips)(scope.$parent);
|
||||
$timeout(function() { element.find('md-chips-wrap').prepend(compiledStaticChips); });
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
MdChips.$inject = ["$mdTheming", "$mdUtil", "$compile", "$log", "$timeout"];
|
||||
|
||||
angular
|
||||
.module('material.components.chips')
|
||||
.controller('MdContactChipsCtrl', MdContactChipsCtrl);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Controller for the MdContactChips component
|
||||
* @constructor
|
||||
*/
|
||||
function MdContactChipsCtrl () {
|
||||
/** @type {Object} */
|
||||
this.selectedItem = null;
|
||||
|
||||
/** @type {string} */
|
||||
this.searchText = '';
|
||||
}
|
||||
|
||||
|
||||
MdContactChipsCtrl.prototype.queryContact = function(searchText) {
|
||||
var results = this.contactQuery({'$query': searchText});
|
||||
return this.filterSelected ?
|
||||
results.filter(angular.bind(this, this.filterSelectedContacts)) : results;
|
||||
};
|
||||
|
||||
|
||||
MdContactChipsCtrl.prototype.filterSelectedContacts = function(contact) {
|
||||
return this.contacts.indexOf(contact) == -1;
|
||||
};
|
||||
|
||||
angular
|
||||
.module('material.components.chips')
|
||||
.directive('mdContactChips', MdContactChips);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdContactChips
|
||||
* @module material.components.chips
|
||||
*
|
||||
* @description
|
||||
* `<md-contact-chips>` is an input component based on `md-chips` and makes use of an
|
||||
* `md-autocomplete` element. The component allows the caller to supply a query expression
|
||||
* which returns a list of possible contacts. The user can select one of these and add it to
|
||||
* the list of chips.
|
||||
*
|
||||
* @param {string=|object=} ng-model A model to bind the list of items to
|
||||
* @param {string=} placeholder Placeholder text that will be forwarded to the input.
|
||||
* @param {string=} secondary-placeholder Placeholder text that will be forwarded to the input,
|
||||
* displayed when there is at least on item in the list
|
||||
* @param {expression} md-contacts An expression expected to return contacts matching the search
|
||||
* test, `$query`.
|
||||
* @param {string} md-contact-name The field name of the contact object representing the
|
||||
* contact's name.
|
||||
* @param {string} md-contact-email The field name of the contact object representing the
|
||||
* contact's email address.
|
||||
* @param {string} md-contact-image The field name of the contact object representing the
|
||||
* contact's image.
|
||||
*
|
||||
*
|
||||
* // The following attribute has been removed but may come back.
|
||||
* @param {expression=} filter-selected Whether to filter selected contacts from the list of
|
||||
* suggestions shown in the autocomplete.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-contact-chips
|
||||
* ng-model="ctrl.contacts"
|
||||
* md-contacts="ctrl.querySearch($query)"
|
||||
* md-contact-name="name"
|
||||
* md-contact-image="image"
|
||||
* md-contact-email="email"
|
||||
* placeholder="To">
|
||||
* </md-contact-chips>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
var MD_CONTACT_CHIPS_TEMPLATE = '\
|
||||
<md-chips class="md-contact-chips"\
|
||||
ng-model="$mdContactChipsCtrl.contacts"\
|
||||
md-require-match="$mdContactChipsCtrl.requireMatch"\
|
||||
md-autocomplete-snap>\
|
||||
<md-autocomplete\
|
||||
md-menu-class="md-contact-chips-suggestions"\
|
||||
md-selected-item="$mdContactChipsCtrl.selectedItem"\
|
||||
md-search-text="$mdContactChipsCtrl.searchText"\
|
||||
md-items="item in $mdContactChipsCtrl.queryContact($mdContactChipsCtrl.searchText)"\
|
||||
md-item-text="$mdContactChipsCtrl.mdContactName"\
|
||||
md-no-cache="true"\
|
||||
md-autoselect\
|
||||
placeholder="{{$mdContactChipsCtrl.contacts.length == 0 ?\
|
||||
$mdContactChipsCtrl.placeholder : $mdContactChipsCtrl.secondaryPlaceholder}}">\
|
||||
<div class="md-contact-suggestion">\
|
||||
<img \
|
||||
ng-src="{{item[$mdContactChipsCtrl.contactImage]}}"\
|
||||
alt="{{item[$mdContactChipsCtrl.contactName]}}" />\
|
||||
<span class="md-contact-name" md-highlight-text="$mdContactChipsCtrl.searchText">\
|
||||
{{item[$mdContactChipsCtrl.contactName]}}\
|
||||
</span>\
|
||||
<span class="md-contact-email" >{{item[$mdContactChipsCtrl.contactEmail]}}</span>\
|
||||
</div>\
|
||||
</md-autocomplete>\
|
||||
<md-chip-template>\
|
||||
<div class="md-contact-avatar">\
|
||||
<img \
|
||||
ng-src="{{$chip[$mdContactChipsCtrl.contactImage]}}"\
|
||||
alt="{{$chip[$mdContactChipsCtrl.contactName]}}" />\
|
||||
</div>\
|
||||
<div class="md-contact-name">\
|
||||
{{$chip[$mdContactChipsCtrl.contactName]}}\
|
||||
</div>\
|
||||
</md-chip-template>\
|
||||
</md-chips>';
|
||||
|
||||
|
||||
/**
|
||||
* MDContactChips Directive Definition
|
||||
*
|
||||
* @param $mdTheming
|
||||
* @returns {*}
|
||||
* ngInject
|
||||
*/
|
||||
function MdContactChips ($mdTheming, $mdUtil) {
|
||||
return {
|
||||
template: function(element, attrs) {
|
||||
return MD_CONTACT_CHIPS_TEMPLATE;
|
||||
},
|
||||
restrict: 'E',
|
||||
controller: 'MdContactChipsCtrl',
|
||||
controllerAs: '$mdContactChipsCtrl',
|
||||
bindToController: true,
|
||||
compile: compile,
|
||||
scope: {
|
||||
contactQuery: '&mdContacts',
|
||||
placeholder: '@',
|
||||
secondaryPlaceholder: '@',
|
||||
contactName: '@mdContactName',
|
||||
contactImage: '@mdContactImage',
|
||||
contactEmail: '@mdContactEmail',
|
||||
contacts: '=ngModel',
|
||||
requireMatch: '=?mdRequireMatch'
|
||||
}
|
||||
};
|
||||
|
||||
function compile(element, attr) {
|
||||
return function postLink(scope, element, attrs, controllers) {
|
||||
|
||||
$mdUtil.initOptionalProperties(scope, attr);
|
||||
$mdTheming(element);
|
||||
|
||||
element.attr('tabindex', '-1');
|
||||
};
|
||||
}
|
||||
}
|
||||
MdContactChips.$inject = ["$mdTheming", "$mdUtil"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/chips/chips.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/chips/chips.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/.md-contact-chips .md-chips .md-chip{padding:0 8px 0 0}.md-contact-chips .md-chips .md-chip .md-contact-avatar{float:left}.md-contact-chips .md-chips .md-chip .md-contact-avatar img{height:32px;border-radius:16px}.md-contact-chips .md-chips .md-chip .md-contact-name{display:inline-block;height:32px;margin-left:8px}.md-contact-suggestion{height:56px}.md-contact-suggestion img{height:40px;border-radius:20px;margin-top:8px}.md-contact-suggestion .md-contact-name{margin-left:8px;width:120px}.md-contact-suggestion .md-contact-email,.md-contact-suggestion .md-contact-name{display:inline-block;overflow:hidden;text-overflow:ellipsis}.md-contact-chips-suggestions li{height:100%}.md-chips{display:block;font-family:RobotoDraft,Roboto,'Helvetica Neue',sans-serif;font-size:13px;padding:0 0 8px;vertical-align:middle;cursor:text}.md-chips:after{content:'';display:table;clear:both}.md-chips .md-chip{cursor:default;border-radius:16px;display:block;height:32px;line-height:32px;margin:8px 8px 0 0;padding:0 8px 0 12px;float:left}.md-chips .md-chip .md-chip-content{display:block;padding-right:4px;float:left;white-space:nowrap}.md-chips .md-chip .md-chip-content:focus{outline:0}.md-chips .md-chip .md-chip-remove-container{display:inline-block;margin-right:-5px}.md-chips .md-chip .md-chip-remove{text-align:center;width:32px;height:32px;min-width:0;padding:0;background:0 0;border:none;box-shadow:none;margin:0;position:relative}.md-chips .md-chip .md-chip-remove md-icon{height:18px;width:18px;position:absolute;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}.md-chips .md-chip-input-container{display:block;line-height:32px;margin:8px 8px 0 0;padding:0 8px 0 12px;float:left}.md-chips .md-chip-input-container input:not([type]),.md-chips .md-chip-input-container input[type=email],.md-chips .md-chip-input-container input[type=number],.md-chips .md-chip-input-container input[type=tel],.md-chips .md-chip-input-container input[type=url],.md-chips .md-chip-input-container input[type=text]{border:0;height:32px;line-height:32px;padding:0}.md-chips .md-chip-input-container input:not([type]):focus,.md-chips .md-chip-input-container input[type=email]:focus,.md-chips .md-chip-input-container input[type=number]:focus,.md-chips .md-chip-input-container input[type=tel]:focus,.md-chips .md-chip-input-container input[type=url]:focus,.md-chips .md-chip-input-container input[type=text]:focus{outline:0}.md-chips .md-chip-input-container md-autocomplete,.md-chips .md-chip-input-container md-autocomplete-wrap{background:0 0}.md-chips .md-chip-input-container md-autocomplete md-autocomplete-wrap{box-shadow:none}.md-chips .md-chip-input-container input{border:0;height:32px;line-height:32px;padding:0}.md-chips .md-chip-input-container input:focus{outline:0}.md-chips .md-chip-input-container md-autocomplete,.md-chips .md-chip-input-container md-autocomplete-wrap{height:32px}.md-chips .md-chip-input-container md-autocomplete{box-shadow:none}.md-chips .md-chip-input-container md-autocomplete input{position:relative}.md-chips .md-chip-input-container:not(:first-child){margin:8px 8px 0 0}.md-chips .md-chip-input-container input{background:0 0;border-width:0}.md-chips md-autocomplete button{display:none}@media screen and (-ms-high-contrast:active){.md-chip-input-container,md-chip{border:1px solid #fff}.md-chip-input-container md-autocomplete{border:none}}
|
||||
7
www/lib/angular-material/modules/js/chips/chips.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/chips/chips.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
www/lib/angular-material/modules/js/content/bower.json
Normal file
7
www/lib/angular-material/modules/js/content/bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-content",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-content.md-THEME_NAME-theme {
|
||||
background-color: '{{background-color}}'; }
|
||||
6
www/lib/angular-material/modules/js/content/content-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/content/content-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-content.md-THEME_NAME-theme{background-color:'{{background-color}}'}
|
||||
20
www/lib/angular-material/modules/js/content/content.css
Normal file
20
www/lib/angular-material/modules/js/content/content.css
Normal file
@@ -0,0 +1,20 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-content {
|
||||
display: block;
|
||||
position: relative;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch; }
|
||||
md-content[md-scroll-y] {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden; }
|
||||
md-content[md-scroll-x] {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden; }
|
||||
md-content.autoScroll {
|
||||
-webkit-overflow-scrolling: auto; }
|
||||
85
www/lib/angular-material/modules/js/content/content.js
vendored
Normal file
85
www/lib/angular-material/modules/js/content/content.js
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.content
|
||||
*
|
||||
* @description
|
||||
* Scrollable content
|
||||
*/
|
||||
angular.module('material.components.content', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdContent', mdContentDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdContent
|
||||
* @module material.components.content
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-content>` directive is a container element useful for scrollable content
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* - Add the `[layout-padding]` attribute to make the content padded.
|
||||
*
|
||||
* <hljs lang="html">
|
||||
* <md-content layout-padding>
|
||||
* Lorem ipsum dolor sit amet, ne quod novum mei.
|
||||
* </md-content>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
|
||||
function mdContentDirective($mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: ['$scope', '$element', ContentController],
|
||||
link: function(scope, element, attr) {
|
||||
var node = element[0];
|
||||
|
||||
$mdTheming(element);
|
||||
scope.$broadcast('$mdContentLoaded', element);
|
||||
|
||||
iosScrollFix(element[0]);
|
||||
}
|
||||
};
|
||||
|
||||
function ContentController($scope, $element) {
|
||||
this.$scope = $scope;
|
||||
this.$element = $element;
|
||||
}
|
||||
}
|
||||
mdContentDirective.$inject = ["$mdTheming"];
|
||||
|
||||
function iosScrollFix(node) {
|
||||
// IOS FIX:
|
||||
// If we scroll where there is no more room for the webview to scroll,
|
||||
// by default the webview itself will scroll up and down, this looks really
|
||||
// bad. So if we are scrolling to the very top or bottom, add/subtract one
|
||||
angular.element(node).on('$md.pressdown', function(ev) {
|
||||
// Only touch events
|
||||
if (ev.pointer.type !== 't') return;
|
||||
// Don't let a child content's touchstart ruin it for us.
|
||||
if (ev.$materialScrollFixed) return;
|
||||
ev.$materialScrollFixed = true;
|
||||
|
||||
if (node.scrollTop === 0) {
|
||||
node.scrollTop = 1;
|
||||
} else if (node.scrollHeight === node.scrollTop + node.offsetHeight) {
|
||||
node.scrollTop -= 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/content/content.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/content/content.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-content{display:block;position:relative;overflow:auto;-webkit-overflow-scrolling:touch}md-content[md-scroll-y]{overflow-y:auto;overflow-x:hidden}md-content[md-scroll-x]{overflow-x:auto;overflow-y:hidden}md-content.autoScroll{-webkit-overflow-scrolling:auto}
|
||||
7
www/lib/angular-material/modules/js/content/content.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/content/content.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(e,t,o){"use strict";function n(e){function t(e,t){this.$scope=e,this.$element=t}return{restrict:"E",controller:["$scope","$element",t],link:function(t,o,n){o[0];e(o),t.$broadcast("$mdContentLoaded",o),i(o[0])}}}function i(e){t.element(e).on("$md.pressdown",function(t){"t"===t.pointer.type&&(t.$materialScrollFixed||(t.$materialScrollFixed=!0,0===e.scrollTop?e.scrollTop=1:e.scrollHeight===e.scrollTop+e.offsetHeight&&(e.scrollTop-=1)))})}t.module("material.components.content",["material.core"]).directive("mdContent",n),n.$inject=["$mdTheming"]}(window,window.angular);
|
||||
8
www/lib/angular-material/modules/js/core/bower.json
Normal file
8
www/lib/angular-material/modules/js/core/bower.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "angular-material-core",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-gestures": "0.10.0",
|
||||
"angular-material-theming": "0.10.0"
|
||||
}
|
||||
}
|
||||
2594
www/lib/angular-material/modules/js/core/core.css
Normal file
2594
www/lib/angular-material/modules/js/core/core.css
Normal file
File diff suppressed because it is too large
Load Diff
3772
www/lib/angular-material/modules/js/core/core.js
vendored
Normal file
3772
www/lib/angular-material/modules/js/core/core.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
www/lib/angular-material/modules/js/core/core.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/core/core.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
10
www/lib/angular-material/modules/js/core/core.min.js
vendored
Normal file
10
www/lib/angular-material/modules/js/core/core.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
www/lib/angular-material/modules/js/core/default-theme.js
vendored
Normal file
4
www/lib/angular-material/modules/js/core/default-theme.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
www/lib/angular-material/modules/js/dialog/bower.json
Normal file
8
www/lib/angular-material/modules/js/dialog/bower.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "angular-material-dialog",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0",
|
||||
"angular-material-backdrop": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-dialog.md-THEME_NAME-theme {
|
||||
border-radius: 4px;
|
||||
background-color: '{{background-color}}'; }
|
||||
md-dialog.md-THEME_NAME-theme.md-content-overflow .md-actions {
|
||||
border-top-color: '{{foreground-4}}'; }
|
||||
6
www/lib/angular-material/modules/js/dialog/dialog-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/dialog/dialog-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-dialog.md-THEME_NAME-theme{border-radius:4px;background-color:'{{background-color}}'}md-dialog.md-THEME_NAME-theme.md-content-overflow .md-actions{border-top-color:'{{foreground-4}}'}
|
||||
111
www/lib/angular-material/modules/js/dialog/dialog.css
Normal file
111
www/lib/angular-material/modules/js/dialog/dialog.css
Normal file
@@ -0,0 +1,111 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
.md-dialog-is-showing {
|
||||
max-height: 100%; }
|
||||
|
||||
.md-dialog-container {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-justify-content: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 80; }
|
||||
|
||||
md-dialog {
|
||||
opacity: 0;
|
||||
min-width: 240px;
|
||||
max-width: 80%;
|
||||
max-height: 80%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 8px 10px -5px rgba(0, 0, 0, 0.14), 0px 16px 24px 2px rgba(0, 0, 0, 0.098), 0px 6px 30px 5px rgba(0, 0, 0, 0.084);
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column; }
|
||||
md-dialog.transition-in {
|
||||
opacity: 1;
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
-webkit-transform: translate3d(0, 0, 0) scale(1);
|
||||
transform: translate3d(0, 0, 0) scale(1); }
|
||||
md-dialog.transition-out {
|
||||
transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
-webkit-transform: translate3d(0, 100%, 0) scale(0.2);
|
||||
transform: translate3d(0, 100%, 0) scale(0.2); }
|
||||
md-dialog > form {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
overflow: auto; }
|
||||
md-dialog md-dialog-content {
|
||||
-webkit-order: 1;
|
||||
-ms-flex-order: 1;
|
||||
order: 1;
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch; }
|
||||
md-dialog md-dialog-content:not([layout=row]) > *:first-child:not(.md-subheader) {
|
||||
margin-top: 0; }
|
||||
md-dialog md-dialog-content:focus {
|
||||
outline: none; }
|
||||
md-dialog md-dialog-content .md-subheader {
|
||||
margin: 0; }
|
||||
md-dialog md-dialog-content .md-subheader.sticky-clone {
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.16); }
|
||||
md-dialog md-dialog-content.sticky-container {
|
||||
padding: 0; }
|
||||
md-dialog md-dialog-content.sticky-container > div {
|
||||
padding: 24px;
|
||||
padding-top: 0; }
|
||||
md-dialog .md-actions {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-order: 2;
|
||||
-ms-flex-order: 2;
|
||||
order: 2;
|
||||
box-sizing: border-box;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-justify-content: flex-end;
|
||||
-ms-flex-pack: end;
|
||||
justify-content: flex-end;
|
||||
margin-bottom: 0;
|
||||
padding-right: 8px;
|
||||
padding-left: 16px;
|
||||
min-height: 52px; }
|
||||
md-dialog .md-actions .md-button {
|
||||
margin-bottom: 8px;
|
||||
margin-left: 8px;
|
||||
margin-right: 0;
|
||||
margin-top: 8px; }
|
||||
md-dialog.md-content-overflow .md-actions {
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid; }
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
md-dialog {
|
||||
border: 1px solid #fff; } }
|
||||
713
www/lib/angular-material/modules/js/dialog/dialog.js
vendored
Normal file
713
www/lib/angular-material/modules/js/dialog/dialog.js
vendored
Normal file
@@ -0,0 +1,713 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.dialog
|
||||
*/
|
||||
angular.module('material.components.dialog', [
|
||||
'material.core',
|
||||
'material.components.backdrop'
|
||||
])
|
||||
.directive('mdDialog', MdDialogDirective)
|
||||
.provider('$mdDialog', MdDialogProvider);
|
||||
|
||||
function MdDialogDirective($$rAF, $mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, element, attr) {
|
||||
$mdTheming(element);
|
||||
$$rAF(function() {
|
||||
var content = element[0].querySelector('md-dialog-content');
|
||||
if (content && content.scrollHeight > content.clientHeight) {
|
||||
element.addClass('md-content-overflow');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
MdDialogDirective.$inject = ["$$rAF", "$mdTheming"];
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name $mdDialog
|
||||
* @module material.components.dialog
|
||||
*
|
||||
* @description
|
||||
* `$mdDialog` opens a dialog over the app to inform users about critical information or require
|
||||
* them to make decisions. There are two approaches for setup: a simple promise API
|
||||
* and regular object syntax.
|
||||
*
|
||||
* ## Restrictions
|
||||
*
|
||||
* - The dialog is always given an isolate scope.
|
||||
* - The dialog's template must have an outer `<md-dialog>` element.
|
||||
* Inside, use an `<md-dialog-content>` element for the dialog's content, and use
|
||||
* an element with class `md-actions` for the dialog's actions.
|
||||
* - Dialogs must cover the entire application to keep interactions inside of them.
|
||||
* Use the `parent` option to change where dialogs are appended.
|
||||
*
|
||||
* ## Sizing
|
||||
* - Complex dialogs can be sized with `flex="percentage"`, i.e. `flex="66"`.
|
||||
* - Default max-width is 80% of the `rootElement` or `parent`.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <div ng-app="demoApp" ng-controller="EmployeeController">
|
||||
* <div>
|
||||
* <md-button ng-click="showAlert()" class="md-raised md-warn">
|
||||
* Employee Alert!
|
||||
* </md-button>
|
||||
* </div>
|
||||
* <div>
|
||||
* <md-button ng-click="showDialog($event)" class="md-raised">
|
||||
* Custom Dialog
|
||||
* </md-button>
|
||||
* </div>
|
||||
* <div>
|
||||
* <md-button ng-click="closeAlert()" ng-disabled="!hasAlert()" class="md-raised">
|
||||
* Close Alert
|
||||
* </md-button>
|
||||
* </div>
|
||||
* <div>
|
||||
* <md-button ng-click="showGreeting($event)" class="md-raised md-primary" >
|
||||
* Greet Employee
|
||||
* </md-button>
|
||||
* </div>
|
||||
* </div>
|
||||
* </hljs>
|
||||
*
|
||||
* ### JavaScript: object syntax
|
||||
* <hljs lang="js">
|
||||
* (function(angular, undefined){
|
||||
* "use strict";
|
||||
*
|
||||
* angular
|
||||
* .module('demoApp', ['ngMaterial'])
|
||||
* .controller('AppCtrl', AppController);
|
||||
*
|
||||
* function AppController($scope, $mdDialog) {
|
||||
* var alert;
|
||||
* $scope.showAlert = showAlert;
|
||||
* $scope.showDialog = showDialog;
|
||||
* $scope.items = [1, 2, 3];
|
||||
*
|
||||
* // Internal method
|
||||
* function showAlert() {
|
||||
* alert = $mdDialog.alert({
|
||||
* title: 'Attention',
|
||||
* content: 'This is an example of how easy dialogs can be!',
|
||||
* ok: 'Close'
|
||||
* });
|
||||
*
|
||||
* $mdDialog
|
||||
* .show( alert )
|
||||
* .finally(function() {
|
||||
* alert = undefined;
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* function showDialog($event) {
|
||||
* var parentEl = angular.element(document.body);
|
||||
* $mdDialog.show({
|
||||
* parent: parentEl,
|
||||
* targetEvent: $event,
|
||||
* template:
|
||||
* '<md-dialog aria-label="List dialog">' +
|
||||
* ' <md-dialog-content>'+
|
||||
* ' <md-list>'+
|
||||
* ' <md-list-item ng-repeat="item in items">'+
|
||||
* ' <p>Number {{item}}</p>' +
|
||||
* ' </md-item>'+
|
||||
* ' </md-list>'+
|
||||
* ' </md-dialog-content>' +
|
||||
* ' <div class="md-actions">' +
|
||||
* ' <md-button ng-click="closeDialog()" class="md-primary">' +
|
||||
* ' Close Dialog' +
|
||||
* ' </md-button>' +
|
||||
* ' </div>' +
|
||||
* '</md-dialog>',
|
||||
* locals: {
|
||||
* items: $scope.items
|
||||
* },
|
||||
* controller: DialogController
|
||||
* });
|
||||
* function DialogController($scope, $mdDialog, items) {
|
||||
* $scope.items = items;
|
||||
* $scope.closeDialog = function() {
|
||||
* $mdDialog.hide();
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* })(angular);
|
||||
* </hljs>
|
||||
*
|
||||
* ### JavaScript: promise API syntax, custom dialog template
|
||||
* <hljs lang="js">
|
||||
* (function(angular, undefined){
|
||||
* "use strict";
|
||||
*
|
||||
* angular
|
||||
* .module('demoApp', ['ngMaterial'])
|
||||
* .controller('EmployeeController', EmployeeEditor)
|
||||
* .controller('GreetingController', GreetingController);
|
||||
*
|
||||
* // Fictitious Employee Editor to show how to use simple and complex dialogs.
|
||||
*
|
||||
* function EmployeeEditor($scope, $mdDialog) {
|
||||
* var alert;
|
||||
*
|
||||
* $scope.showAlert = showAlert;
|
||||
* $scope.closeAlert = closeAlert;
|
||||
* $scope.showGreeting = showCustomGreeting;
|
||||
*
|
||||
* $scope.hasAlert = function() { return !!alert };
|
||||
* $scope.userName = $scope.userName || 'Bobby';
|
||||
*
|
||||
* // Dialog #1 - Show simple alert dialog and cache
|
||||
* // reference to dialog instance
|
||||
*
|
||||
* function showAlert() {
|
||||
* alert = $mdDialog.alert()
|
||||
* .title('Attention, ' + $scope.userName)
|
||||
* .content('This is an example of how easy dialogs can be!')
|
||||
* .ok('Close');
|
||||
*
|
||||
* $mdDialog
|
||||
* .show( alert )
|
||||
* .finally(function() {
|
||||
* alert = undefined;
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* // Close the specified dialog instance and resolve with 'finished' flag
|
||||
* // Normally this is not needed, just use '$mdDialog.hide()' to close
|
||||
* // the most recent dialog popup.
|
||||
*
|
||||
* function closeAlert() {
|
||||
* $mdDialog.hide( alert, "finished" );
|
||||
* alert = undefined;
|
||||
* }
|
||||
*
|
||||
* // Dialog #2 - Demonstrate more complex dialogs construction and popup.
|
||||
*
|
||||
* function showCustomGreeting($event) {
|
||||
* $mdDialog.show({
|
||||
* targetEvent: $event,
|
||||
* template:
|
||||
* '<md-dialog>' +
|
||||
*
|
||||
* ' <md-dialog-content>Hello {{ employee }}!</md-dialog-content>' +
|
||||
*
|
||||
* ' <div class="md-actions">' +
|
||||
* ' <md-button ng-click="closeDialog()" class="md-primary">' +
|
||||
* ' Close Greeting' +
|
||||
* ' </md-button>' +
|
||||
* ' </div>' +
|
||||
* '</md-dialog>',
|
||||
* controller: 'GreetingController',
|
||||
* onComplete: afterShowAnimation,
|
||||
* locals: { employee: $scope.userName }
|
||||
* });
|
||||
*
|
||||
* // When the 'enter' animation finishes...
|
||||
*
|
||||
* function afterShowAnimation(scope, element, options) {
|
||||
* // post-show code here: DOM element focus, etc.
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Dialog #3 - Demonstrate use of ControllerAs and passing $scope to dialog
|
||||
* // Here we used ng-controller="GreetingController as vm" and
|
||||
* // $scope.vm === <controller instance>
|
||||
*
|
||||
* function showCustomGreeting() {
|
||||
*
|
||||
* $mdDialog.show({
|
||||
* clickOutsideToClose: true,
|
||||
*
|
||||
* scope: $scope, // use parent scope in template
|
||||
* preserveScope: true, // do not forget this if use parent scope
|
||||
|
||||
* // Since GreetingController is instantiated with ControllerAs syntax
|
||||
* // AND we are passing the parent '$scope' to the dialog, we MUST
|
||||
* // use 'vm.<xxx>' in the template markup
|
||||
*
|
||||
* template: '<md-dialog>' +
|
||||
* ' <md-dialog-content>' +
|
||||
* ' Hi There {{vm.employee}}' +
|
||||
* ' </md-dialog-content>' +
|
||||
* '</md-dialog>',
|
||||
*
|
||||
* controller: function DialogController($scope, $mdDialog) {
|
||||
* $scope.closeDialog = function() {
|
||||
* $mdDialog.hide();
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* }
|
||||
*
|
||||
* }
|
||||
*
|
||||
* // Greeting controller used with the more complex 'showCustomGreeting()' custom dialog
|
||||
*
|
||||
* function GreetingController($scope, $mdDialog, employee) {
|
||||
* // Assigned from construction <code>locals</code> options...
|
||||
* $scope.employee = employee;
|
||||
*
|
||||
* $scope.closeDialog = function() {
|
||||
* // Easily hides most recent dialog shown...
|
||||
* // no specific instance reference is needed.
|
||||
* $mdDialog.hide();
|
||||
* };
|
||||
* }
|
||||
*
|
||||
* })(angular);
|
||||
* </hljs>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#alert
|
||||
*
|
||||
* @description
|
||||
* Builds a preconfigured dialog with the specified message.
|
||||
*
|
||||
* @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
|
||||
*
|
||||
* - $mdDialogPreset#title(string) - sets title to string
|
||||
* - $mdDialogPreset#content(string) - sets content / message to string
|
||||
* - $mdDialogPreset#ok(string) - sets okay button text to string
|
||||
* - $mdDialogPreset#theme(string) - sets the theme of the dialog
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#confirm
|
||||
*
|
||||
* @description
|
||||
* Builds a preconfigured dialog with the specified message. You can call show and the promise returned
|
||||
* will be resolved only if the user clicks the confirm action on the dialog.
|
||||
*
|
||||
* @returns {obj} an `$mdDialogPreset` with the chainable configuration methods:
|
||||
*
|
||||
* Additionally, it supports the following methods:
|
||||
*
|
||||
* - $mdDialogPreset#title(string) - sets title to string
|
||||
* - $mdDialogPreset#content(string) - sets content / message to string
|
||||
* - $mdDialogPreset#ok(string) - sets okay button text to string
|
||||
* - $mdDialogPreset#cancel(string) - sets cancel button text to string
|
||||
* - $mdDialogPreset#theme(string) - sets the theme of the dialog
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#show
|
||||
*
|
||||
* @description
|
||||
* Show a dialog with the specified options.
|
||||
*
|
||||
* @param {object} optionsOrPreset Either provide an `$mdDialogPreset` returned from `alert()`, and
|
||||
* `confirm()`, or an options object with the following properties:
|
||||
* - `templateUrl` - `{string=}`: The url of a template that will be used as the content
|
||||
* of the dialog.
|
||||
* - `template` - `{string=}`: Same as templateUrl, except this is an actual template string.
|
||||
* - `targetEvent` - `{DOMClickEvent=}`: A click's event object. When passed in as an option,
|
||||
* the location of the click will be used as the starting point for the opening animation
|
||||
* of the the dialog.
|
||||
* - `scope` - `{object=}`: the scope to link the template / controller to. If none is specified,
|
||||
* it will create a new isolate scope.
|
||||
* This scope will be destroyed when the dialog is removed unless `preserveScope` is set to true.
|
||||
* - `preserveScope` - `{boolean=}`: whether to preserve the scope when the element is removed. Default is false
|
||||
* - `disableParentScroll` - `{boolean=}`: Whether to disable scrolling while the dialog is open.
|
||||
* Default true.
|
||||
* - `hasBackdrop` - `{boolean=}`: Whether there should be an opaque backdrop behind the dialog.
|
||||
* Default true.
|
||||
* - `clickOutsideToClose` - `{boolean=}`: Whether the user can click outside the dialog to
|
||||
* close it. Default false.
|
||||
* - `escapeToClose` - `{boolean=}`: Whether the user can press escape to close the dialog.
|
||||
* Default true.
|
||||
* - `focusOnOpen` - `{boolean=}`: An option to override focus behavior on open. Only disable if
|
||||
* focusing some other way, as focus management is required for dialogs to be accessible.
|
||||
* Defaults to true.
|
||||
* - `controller` - `{string=}`: The controller to associate with the dialog. The controller
|
||||
* will be injected with the local `$mdDialog`, which passes along a scope for the dialog.
|
||||
* - `locals` - `{object=}`: An object containing key/value pairs. The keys will be used as names
|
||||
* of values to inject into the controller. For example, `locals: {three: 3}` would inject
|
||||
* `three` into the controller, with the value 3. If `bindToController` is true, they will be
|
||||
* copied to the controller instead.
|
||||
* - `bindToController` - `bool`: bind the locals to the controller, instead of passing them in.
|
||||
* These values will not be available until after initialization.
|
||||
* - `resolve` - `{object=}`: Similar to locals, except it takes promises as values, and the
|
||||
* dialog will not open until all of the promises resolve.
|
||||
* - `controllerAs` - `{string=}`: An alias to assign the controller to on the scope.
|
||||
* - `parent` - `{element=}`: The element to append the dialog to. Defaults to appending
|
||||
* to the root element of the application.
|
||||
* - `onComplete` `{function=}`: Callback function used to announce when the show() action is
|
||||
* finished.
|
||||
*
|
||||
* @returns {promise} A promise that can be resolved with `$mdDialog.hide()` or
|
||||
* rejected with `$mdDialog.cancel()`.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#hide
|
||||
*
|
||||
* @description
|
||||
* Hide an existing dialog and resolve the promise returned from `$mdDialog.show()`.
|
||||
*
|
||||
* @param {*=} response An argument for the resolved promise.
|
||||
*
|
||||
* @returns {promise} A promise that is resolved when the dialog has been closed.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $mdDialog#cancel
|
||||
*
|
||||
* @description
|
||||
* Hide an existing dialog and reject the promise returned from `$mdDialog.show()`.
|
||||
*
|
||||
* @param {*=} response An argument for the rejected promise.
|
||||
*
|
||||
* @returns {promise} A promise that is resolved when the dialog has been closed.
|
||||
*/
|
||||
|
||||
function MdDialogProvider($$interimElementProvider) {
|
||||
|
||||
var alertDialogMethods = ['title', 'content', 'ariaLabel', 'ok'];
|
||||
|
||||
advancedDialogOptions.$inject = ["$mdDialog", "$mdTheming"];
|
||||
dialogDefaultOptions.$inject = ["$mdAria", "$document", "$mdUtil", "$mdConstant", "$mdTheming", "$mdDialog", "$timeout", "$rootElement", "$animate", "$$rAF", "$q"];
|
||||
return $$interimElementProvider('$mdDialog')
|
||||
.setDefaults({
|
||||
methods: ['disableParentScroll', 'hasBackdrop', 'clickOutsideToClose', 'escapeToClose', 'targetEvent', 'parent'],
|
||||
options: dialogDefaultOptions
|
||||
})
|
||||
.addPreset('alert', {
|
||||
methods: ['title', 'content', 'ariaLabel', 'ok', 'theme'],
|
||||
options: advancedDialogOptions
|
||||
})
|
||||
.addPreset('confirm', {
|
||||
methods: ['title', 'content', 'ariaLabel', 'ok', 'cancel', 'theme'],
|
||||
options: advancedDialogOptions
|
||||
});
|
||||
|
||||
/* ngInject */
|
||||
function advancedDialogOptions($mdDialog, $mdTheming) {
|
||||
return {
|
||||
template: [
|
||||
'<md-dialog md-theme="{{ dialog.theme }}" aria-label="{{ dialog.ariaLabel }}">',
|
||||
'<md-dialog-content role="document" tabIndex="-1">',
|
||||
'<h2 class="md-title">{{ dialog.title }}</h2>',
|
||||
'<p>{{ dialog.content }}</p>',
|
||||
'</md-dialog-content>',
|
||||
'<div class="md-actions">',
|
||||
'<md-button ng-if="dialog.$type == \'confirm\'"' +
|
||||
' ng-click="dialog.abort()" class="md-primary">',
|
||||
'{{ dialog.cancel }}',
|
||||
'</md-button>',
|
||||
'<md-button ng-click="dialog.hide()" class="md-primary">',
|
||||
'{{ dialog.ok }}',
|
||||
'</md-button>',
|
||||
'</div>',
|
||||
'</md-dialog>'
|
||||
].join(''),
|
||||
controller: function mdDialogCtrl() {
|
||||
this.hide = function() {
|
||||
$mdDialog.hide(true);
|
||||
};
|
||||
this.abort = function() {
|
||||
$mdDialog.cancel();
|
||||
};
|
||||
},
|
||||
controllerAs: 'dialog',
|
||||
bindToController: true,
|
||||
theme: $mdTheming.defaultTheme()
|
||||
};
|
||||
}
|
||||
|
||||
/* ngInject */
|
||||
function dialogDefaultOptions($mdAria, $document, $mdUtil, $mdConstant, $mdTheming, $mdDialog, $timeout, $rootElement, $animate, $$rAF, $q) {
|
||||
return {
|
||||
hasBackdrop: true,
|
||||
isolateScope: true,
|
||||
onShow: onShow,
|
||||
onRemove: onRemove,
|
||||
clickOutsideToClose: false,
|
||||
escapeToClose: true,
|
||||
targetEvent: null,
|
||||
focusOnOpen: true,
|
||||
disableParentScroll: true,
|
||||
transformTemplate: function(template) {
|
||||
return '<div class="md-dialog-container">' + template + '</div>';
|
||||
}
|
||||
};
|
||||
|
||||
function trapFocus(ev) {
|
||||
var dialog = document.querySelector('md-dialog');
|
||||
|
||||
if (dialog && !dialog.contains(ev.target)) {
|
||||
ev.stopImmediatePropagation();
|
||||
dialog.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// On show method for dialogs
|
||||
function onShow(scope, element, options) {
|
||||
angular.element($document[0].body).addClass('md-dialog-is-showing');
|
||||
element = $mdUtil.extractElementByName(element, 'md-dialog');
|
||||
|
||||
// Incase the user provides a raw dom element, always wrap it in jqLite
|
||||
options.parent = angular.element(options.parent);
|
||||
|
||||
options.popInTarget = angular.element((options.targetEvent || {}).target);
|
||||
var closeButton = findCloseButton();
|
||||
|
||||
if (options.hasBackdrop) {
|
||||
// Fix for IE 10
|
||||
var computeFrom = (options.parent[0] == $document[0].body && $document[0].documentElement
|
||||
&& $document[0].documentElement.scrollTop) ? angular.element($document[0].documentElement) : options.parent;
|
||||
var parentOffset = computeFrom.prop('scrollTop');
|
||||
options.backdrop = angular.element('<md-backdrop class="md-dialog-backdrop md-opaque">');
|
||||
options.backdrop.css('top', parentOffset +'px');
|
||||
$mdTheming.inherit(options.backdrop, options.parent);
|
||||
$animate.enter(options.backdrop, options.parent);
|
||||
element.css('top', parentOffset +'px');
|
||||
}
|
||||
|
||||
var role = 'dialog',
|
||||
elementToFocus = closeButton;
|
||||
|
||||
if (options.$type === 'alert') {
|
||||
role = 'alertdialog';
|
||||
elementToFocus = element.find('md-dialog-content');
|
||||
}
|
||||
|
||||
configureAria(element.find('md-dialog'), role, options);
|
||||
|
||||
document.addEventListener('focus', trapFocus, true);
|
||||
|
||||
if (options.disableParentScroll) {
|
||||
options.lastOverflow = options.parent.css('overflow');
|
||||
options.parent.css('overflow', 'hidden');
|
||||
}
|
||||
|
||||
return dialogPopIn(
|
||||
element,
|
||||
options.parent,
|
||||
options.popInTarget && options.popInTarget.length && options.popInTarget
|
||||
)
|
||||
.then(function() {
|
||||
|
||||
applyAriaToSiblings(element, true);
|
||||
|
||||
if (options.escapeToClose) {
|
||||
options.rootElementKeyupCallback = function(e) {
|
||||
if (e.keyCode === $mdConstant.KEY_CODE.ESCAPE) {
|
||||
$timeout($mdDialog.cancel);
|
||||
}
|
||||
};
|
||||
$rootElement.on('keyup', options.rootElementKeyupCallback);
|
||||
}
|
||||
|
||||
if (options.clickOutsideToClose) {
|
||||
options.dialogClickOutsideCallback = function(ev) {
|
||||
// Only close if we click the flex container outside the backdrop
|
||||
if (ev.target === element[0]) {
|
||||
$timeout($mdDialog.cancel);
|
||||
}
|
||||
};
|
||||
element.on('click', options.dialogClickOutsideCallback);
|
||||
}
|
||||
|
||||
if (options.focusOnOpen) {
|
||||
elementToFocus.focus();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function findCloseButton() {
|
||||
//If no element with class dialog-close, try to find the last
|
||||
//button child in md-actions and assume it is a close button
|
||||
var closeButton = element[0].querySelector('.dialog-close');
|
||||
if (!closeButton) {
|
||||
var actionButtons = element[0].querySelectorAll('.md-actions button');
|
||||
closeButton = actionButtons[ actionButtons.length - 1 ];
|
||||
}
|
||||
return angular.element(closeButton);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// On remove function for all dialogs
|
||||
function onRemove(scope, element, options) {
|
||||
angular.element($document[0].body).removeClass('md-dialog-is-showing');
|
||||
|
||||
if (options.backdrop) {
|
||||
$animate.leave(options.backdrop);
|
||||
}
|
||||
if (options.disableParentScroll) {
|
||||
options.parent.css('overflow', options.lastOverflow);
|
||||
delete options.lastOverflow;
|
||||
}
|
||||
if (options.escapeToClose) {
|
||||
$rootElement.off('keyup', options.rootElementKeyupCallback);
|
||||
}
|
||||
if (options.clickOutsideToClose) {
|
||||
element.off('click', options.dialogClickOutsideCallback);
|
||||
}
|
||||
|
||||
applyAriaToSiblings(element, false);
|
||||
|
||||
document.removeEventListener('focus', trapFocus, true);
|
||||
|
||||
return dialogPopOut(
|
||||
element,
|
||||
options.parent,
|
||||
options.popInTarget && options.popInTarget.length && options.popInTarget
|
||||
).then(function() {
|
||||
element.remove();
|
||||
options.popInTarget && options.popInTarget.focus();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject ARIA-specific attributes appropriate for Dialogs
|
||||
*/
|
||||
function configureAria(element, role, options) {
|
||||
|
||||
element.attr({
|
||||
'role': role,
|
||||
'tabIndex': '-1'
|
||||
});
|
||||
|
||||
var dialogContent = element.find('md-dialog-content');
|
||||
if (dialogContent.length === 0){
|
||||
dialogContent = element;
|
||||
}
|
||||
|
||||
var dialogId = element.attr('id') || ('dialog_' + $mdUtil.nextUid());
|
||||
dialogContent.attr('id', dialogId);
|
||||
element.attr('aria-describedby', dialogId);
|
||||
|
||||
if (options.ariaLabel) {
|
||||
$mdAria.expect(element, 'aria-label', options.ariaLabel);
|
||||
}
|
||||
else {
|
||||
$mdAria.expectAsync(element, 'aria-label', function() {
|
||||
var words = dialogContent.text().split(/\s+/);
|
||||
if (words.length > 3) words = words.slice(0,3).concat('...');
|
||||
return words.join(' ');
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Utility function to filter out raw DOM nodes
|
||||
*/
|
||||
function isNodeOneOf(elem, nodeTypeArray) {
|
||||
if (nodeTypeArray.indexOf(elem.nodeName) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Walk DOM to apply or remove aria-hidden on sibling nodes
|
||||
* and parent sibling nodes
|
||||
*
|
||||
* Prevents screen reader interaction behind modal window
|
||||
* on swipe interfaces
|
||||
*/
|
||||
function applyAriaToSiblings(element, value) {
|
||||
var attribute = 'aria-hidden';
|
||||
|
||||
// get raw DOM node
|
||||
element = element[0];
|
||||
|
||||
function walkDOM(element) {
|
||||
while (element.parentNode) {
|
||||
if (element === document.body) {
|
||||
return;
|
||||
}
|
||||
var children = element.parentNode.children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
// skip over child if it is an ascendant of the dialog
|
||||
// or a script or style tag
|
||||
if (element !== children[i] && !isNodeOneOf(children[i], ['SCRIPT', 'STYLE'])) {
|
||||
children[i].setAttribute(attribute, value);
|
||||
}
|
||||
}
|
||||
|
||||
walkDOM(element = element.parentNode);
|
||||
}
|
||||
}
|
||||
walkDOM(element);
|
||||
}
|
||||
|
||||
function dialogPopIn(container, parentElement, clickElement) {
|
||||
var dialogEl = container.find('md-dialog');
|
||||
|
||||
parentElement.append(container);
|
||||
transformToClickElement(dialogEl, clickElement);
|
||||
|
||||
$$rAF(function() {
|
||||
dialogEl.addClass('transition-in')
|
||||
.css($mdConstant.CSS.TRANSFORM, '');
|
||||
});
|
||||
|
||||
return $mdUtil.transitionEndPromise(dialogEl);
|
||||
}
|
||||
|
||||
function dialogPopOut(container, parentElement, clickElement) {
|
||||
var dialogEl = container.find('md-dialog');
|
||||
|
||||
dialogEl.addClass('transition-out').removeClass('transition-in');
|
||||
transformToClickElement(dialogEl, clickElement);
|
||||
|
||||
return $mdUtil.transitionEndPromise(dialogEl);
|
||||
}
|
||||
|
||||
function transformToClickElement(dialogEl, clickElement) {
|
||||
if (clickElement) {
|
||||
var clickRect = clickElement[0].getBoundingClientRect();
|
||||
var dialogRect = dialogEl[0].getBoundingClientRect();
|
||||
|
||||
var scaleX = Math.min(0.5, clickRect.width / dialogRect.width);
|
||||
var scaleY = Math.min(0.5, clickRect.height / dialogRect.height);
|
||||
|
||||
dialogEl.css($mdConstant.CSS.TRANSFORM, 'translate3d(' +
|
||||
(-dialogRect.left + clickRect.left + clickRect.width/2 - dialogRect.width/2) + 'px,' +
|
||||
(-dialogRect.top + clickRect.top + clickRect.height/2 - dialogRect.height/2) + 'px,' +
|
||||
'0) scale(' + scaleX + ',' + scaleY + ')'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function dialogTransitionEnd(dialogEl) {
|
||||
var deferred = $q.defer();
|
||||
dialogEl.on($mdConstant.CSS.TRANSITIONEND, finished);
|
||||
function finished(ev) {
|
||||
//Make sure this transitionend didn't bubble up from a child
|
||||
if (ev.target === dialogEl[0]) {
|
||||
dialogEl.off($mdConstant.CSS.TRANSITIONEND, finished);
|
||||
deferred.resolve();
|
||||
}
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
MdDialogProvider.$inject = ["$$interimElementProvider"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/dialog/dialog.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/dialog/dialog.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/.md-dialog-is-showing{max-height:100%}.md-dialog-container{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:absolute;top:0;left:0;width:100%;height:100%;z-index:80}md-dialog{opacity:0;min-width:240px;max-width:80%;max-height:80%;position:relative;overflow:hidden;box-shadow:0 8px 10px -5px rgba(0,0,0,.14),0 16px 24px 2px rgba(0,0,0,.098),0 6px 30px 5px rgba(0,0,0,.084);display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}md-dialog.transition-in{opacity:1;transition:all .4s cubic-bezier(.25,.8,.25,1);-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}md-dialog.transition-out{transition:all .4s cubic-bezier(.25,.8,.25,1);-webkit-transform:translate3d(0,100%,0) scale(.2);transform:translate3d(0,100%,0) scale(.2)}md-dialog>form{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto}md-dialog md-dialog-content{-webkit-order:1;-ms-flex-order:1;order:1;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:24px;overflow:auto;-webkit-overflow-scrolling:touch}md-dialog md-dialog-content:not([layout=row])>:first-child:not(.md-subheader){margin-top:0}md-dialog md-dialog-content:focus{outline:0}md-dialog md-dialog-content .md-subheader{margin:0}md-dialog md-dialog-content .md-subheader.sticky-clone{box-shadow:0 2px 4px 0 rgba(0,0,0,.16)}md-dialog md-dialog-content.sticky-container{padding:0}md-dialog md-dialog-content.sticky-container>div{padding:0 24px 24px}md-dialog .md-actions{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-order:2;-ms-flex-order:2;order:2;box-sizing:border-box;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;margin-bottom:0;padding-right:8px;padding-left:16px;min-height:52px}md-dialog .md-actions .md-button{margin:8px 0 8px 8px}md-dialog.md-content-overflow .md-actions{border-top-width:1px;border-top-style:solid}@media screen and (-ms-high-contrast:active){md-dialog{border:1px solid #fff}}
|
||||
7
www/lib/angular-material/modules/js/dialog/dialog.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/dialog/dialog.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
www/lib/angular-material/modules/js/divider/bower.json
Normal file
7
www/lib/angular-material/modules/js/divider/bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-divider",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-divider.md-THEME_NAME-theme {
|
||||
border-top-color: '{{foreground-4}}'; }
|
||||
6
www/lib/angular-material/modules/js/divider/divider-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/divider/divider-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-divider.md-THEME_NAME-theme{border-top-color:'{{foreground-4}}'}
|
||||
14
www/lib/angular-material/modules/js/divider/divider.css
Normal file
14
www/lib/angular-material/modules/js/divider/divider.css
Normal file
@@ -0,0 +1,14 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-divider {
|
||||
display: block;
|
||||
border-top-width: 1px;
|
||||
border-top-style: solid;
|
||||
margin: 0; }
|
||||
md-divider[md-inset] {
|
||||
margin-left: 80px; }
|
||||
46
www/lib/angular-material/modules/js/divider/divider.js
vendored
Normal file
46
www/lib/angular-material/modules/js/divider/divider.js
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.divider
|
||||
* @description Divider module!
|
||||
*/
|
||||
angular.module('material.components.divider', [
|
||||
'material.core'
|
||||
])
|
||||
.directive('mdDivider', MdDividerDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdDivider
|
||||
* @module material.components.divider
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* Dividers group and separate content within lists and page layouts using strong visual and spatial distinctions. This divider is a thin rule, lightweight enough to not distract the user from content.
|
||||
*
|
||||
* @param {boolean=} md-inset Add this attribute to activate the inset divider style.
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-divider></md-divider>
|
||||
*
|
||||
* <md-divider md-inset></md-divider>
|
||||
* </hljs>
|
||||
*
|
||||
*/
|
||||
function MdDividerDirective($mdTheming) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: $mdTheming
|
||||
};
|
||||
}
|
||||
MdDividerDirective.$inject = ["$mdTheming"];
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/divider/divider.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/divider/divider.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-divider{display:block;border-top-width:1px;border-top-style:solid;margin:0}md-divider[md-inset]{margin-left:80px}
|
||||
7
www/lib/angular-material/modules/js/divider/divider.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/divider/divider.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(i,e,n){"use strict";function r(i){return{restrict:"E",link:i}}e.module("material.components.divider",["material.core"]).directive("mdDivider",r),r.$inject=["$mdTheming"]}(window,window.angular);
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-fabActions",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
58
www/lib/angular-material/modules/js/fabActions/fabActions.js
vendored
Normal file
58
www/lib/angular-material/modules/js/fabActions/fabActions.js
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('material.components.fabActions', ['material.core'])
|
||||
.directive('mdFabActions', MdFabActionsDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdFabActions
|
||||
* @module material.components.fabSpeedDial
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-fab-actions>` directive is used inside of a `<md-fab-speed-dial>` or
|
||||
* `<md-fab-toolbar>` directive to mark the an element (or elements) as the actions and setup the
|
||||
* proper event listeners.
|
||||
*
|
||||
* @usage
|
||||
* See the `<md-fab-speed-dial>` or `<md-fab-toolbar>` directives for example usage.
|
||||
*/
|
||||
function MdFabActionsDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
||||
require: ['^?mdFabSpeedDial', '^?mdFabToolbar'],
|
||||
|
||||
link: function(scope, element, attributes, controllers) {
|
||||
// Grab whichever parent controller is used
|
||||
var controller = controllers[0] || controllers[1];
|
||||
|
||||
// Make the children open/close their parent directive
|
||||
if (controller) {
|
||||
angular.forEach(element.children(), function(child) {
|
||||
angular.element(child).on('focus', controller.open);
|
||||
angular.element(child).on('blur', controller.close);
|
||||
});
|
||||
}
|
||||
|
||||
// After setting up the listeners, wrap every child in a new div and add a class that we can
|
||||
// scale/fling independently
|
||||
element.children().wrap('<div class="md-fab-action-item">');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
||||
})(window, window.angular);
|
||||
7
www/lib/angular-material/modules/js/fabActions/fabActions.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/fabActions/fabActions.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(n,e,i){"use strict";!function(){function n(){return{restrict:"E",require:["^?mdFabSpeedDial","^?mdFabToolbar"],link:function(n,i,o,t){var c=t[0]||t[1];c&&e.forEach(i.children(),function(n){e.element(n).on("focus",c.open),e.element(n).on("blur",c.close)}),i.children().wrap('<div class="md-fab-action-item">')}}}e.module("material.components.fabActions",["material.core"]).directive("mdFabActions",n)}()}(window,window.angular);
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "angular-material-fabSpeedDial",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0",
|
||||
"angular-material-fabTrigger": "0.10.0",
|
||||
"angular-material-fabActions": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-fab-speed-dial {
|
||||
position: relative;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
/*
|
||||
* Handle the animations
|
||||
*/ }
|
||||
md-fab-speed-dial .md-css-variables {
|
||||
z-index: 20; }
|
||||
md-fab-speed-dial.md-is-open .md-fab-action-item {
|
||||
visibility: visible; }
|
||||
md-fab-speed-dial md-fab-actions {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
height: 100%; }
|
||||
md-fab-speed-dial md-fab-actions .md-fab-action-item {
|
||||
visibility: hidden;
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); }
|
||||
md-fab-speed-dial.md-down {
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column; }
|
||||
md-fab-speed-dial.md-down md-fab-trigger {
|
||||
-webkit-order: 1;
|
||||
-ms-flex-order: 1;
|
||||
order: 1; }
|
||||
md-fab-speed-dial.md-down md-fab-actions {
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-order: 2;
|
||||
-ms-flex-order: 2;
|
||||
order: 2; }
|
||||
md-fab-speed-dial.md-up {
|
||||
-webkit-flex-direction: column;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column; }
|
||||
md-fab-speed-dial.md-up md-fab-trigger {
|
||||
-webkit-order: 2;
|
||||
-ms-flex-order: 2;
|
||||
order: 2; }
|
||||
md-fab-speed-dial.md-up md-fab-actions {
|
||||
-webkit-flex-direction: column-reverse;
|
||||
-ms-flex-direction: column-reverse;
|
||||
flex-direction: column-reverse;
|
||||
-webkit-order: 1;
|
||||
-ms-flex-order: 1;
|
||||
order: 1; }
|
||||
md-fab-speed-dial.md-left {
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row; }
|
||||
md-fab-speed-dial.md-left md-fab-trigger {
|
||||
-webkit-order: 2;
|
||||
-ms-flex-order: 2;
|
||||
order: 2; }
|
||||
md-fab-speed-dial.md-left md-fab-actions {
|
||||
-webkit-flex-direction: row-reverse;
|
||||
-ms-flex-direction: row-reverse;
|
||||
flex-direction: row-reverse;
|
||||
-webkit-order: 1;
|
||||
-ms-flex-order: 1;
|
||||
order: 1; }
|
||||
md-fab-speed-dial.md-left md-fab-actions .md-fab-action-item {
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); }
|
||||
md-fab-speed-dial.md-right {
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row; }
|
||||
md-fab-speed-dial.md-right md-fab-trigger {
|
||||
-webkit-order: 1;
|
||||
-ms-flex-order: 1;
|
||||
order: 1; }
|
||||
md-fab-speed-dial.md-right md-fab-actions {
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-order: 2;
|
||||
-ms-flex-order: 2;
|
||||
order: 2; }
|
||||
md-fab-speed-dial.md-right md-fab-actions .md-fab-action-item {
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); }
|
||||
md-fab-speed-dial.md-scale .md-fab-action-item {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2);
|
||||
transition-duration: 0.14286s; }
|
||||
235
www/lib/angular-material/modules/js/fabSpeedDial/fabSpeedDial.js
vendored
Normal file
235
www/lib/angular-material/modules/js/fabSpeedDial/fabSpeedDial.js
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('material.components.fabSpeedDial', [
|
||||
'material.core',
|
||||
'material.components.fabTrigger',
|
||||
'material.components.fabActions'
|
||||
])
|
||||
.directive('mdFabSpeedDial', MdFabSpeedDialDirective)
|
||||
.animation('.md-fling', MdFabSpeedDialFlingAnimation)
|
||||
.animation('.md-scale', MdFabSpeedDialScaleAnimation);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdFabSpeedDial
|
||||
* @module material.components.fabSpeedDial
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-fab-speed-dial>` directive is used to present a series of popup elements (usually
|
||||
* `<md-button>`s) for quick access to common actions.
|
||||
*
|
||||
* There are currently two animations available by applying one of the following classes to
|
||||
* the component:
|
||||
*
|
||||
* - `md-fling` - The speed dial items appear from underneath the trigger and move into their
|
||||
* appropriate positions.
|
||||
* - `md-scale` - The speed dial items appear in their proper places by scaling from 0% to 100%.
|
||||
*
|
||||
* @usage
|
||||
* <hljs lang="html">
|
||||
* <md-fab-speed-dial direction="up" class="md-fling">
|
||||
* <md-fab-trigger>
|
||||
* <md-button aria-label="Add..."><md-icon icon="/img/icons/plus.svg"></md-icon></md-button>
|
||||
* </md-fab-trigger>
|
||||
*
|
||||
* <md-fab-actions>
|
||||
* <md-button aria-label="Add User">
|
||||
* <md-icon icon="/img/icons/user.svg"></md-icon>
|
||||
* </md-button>
|
||||
*
|
||||
* <md-button aria-label="Add Group">
|
||||
* <md-icon icon="/img/icons/group.svg"></md-icon>
|
||||
* </md-button>
|
||||
* </md-fab-actions>
|
||||
* </md-fab-speed-dial>
|
||||
* </hljs>
|
||||
*
|
||||
* @param {string=} md-direction From which direction you would like the speed dial to appear
|
||||
* relative to the trigger element.
|
||||
* @param {expression=} md-open Programmatically control whether or not the speed-dial is visible.
|
||||
*/
|
||||
function MdFabSpeedDialDirective() {
|
||||
FabSpeedDialController.$inject = ["$scope", "$element", "$animate"];
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
||||
scope: {
|
||||
direction: '@?mdDirection',
|
||||
isOpen: '=?mdOpen'
|
||||
},
|
||||
|
||||
bindToController: true,
|
||||
controller: FabSpeedDialController,
|
||||
controllerAs: 'vm',
|
||||
|
||||
link: FabSpeedDialLink
|
||||
};
|
||||
|
||||
function FabSpeedDialLink(scope, element) {
|
||||
// Prepend an element to hold our CSS variables so we can use them in the animations below
|
||||
element.prepend('<div class="md-css-variables"></div>');
|
||||
}
|
||||
|
||||
function FabSpeedDialController($scope, $element, $animate) {
|
||||
var vm = this;
|
||||
|
||||
// Define our open/close functions
|
||||
// Note: Used by fabTrigger and fabActions directives
|
||||
vm.open = function() {
|
||||
$scope.$apply('vm.isOpen = true');
|
||||
};
|
||||
|
||||
vm.close = function() {
|
||||
$scope.$apply('vm.isOpen = false');
|
||||
};
|
||||
|
||||
setupDefaults();
|
||||
setupListeners();
|
||||
setupWatchers();
|
||||
|
||||
// Set our default variables
|
||||
function setupDefaults() {
|
||||
// Set the default direction to 'down' if none is specified
|
||||
vm.direction = vm.direction || 'down';
|
||||
|
||||
// Set the default to be closed
|
||||
vm.isOpen = vm.isOpen || false;
|
||||
}
|
||||
|
||||
// Setup our event listeners
|
||||
function setupListeners() {
|
||||
$element.on('mouseenter', vm.open);
|
||||
$element.on('mouseleave', vm.close);
|
||||
}
|
||||
|
||||
// Setup our watchers
|
||||
function setupWatchers() {
|
||||
// Watch for changes to the direction and update classes/attributes
|
||||
$scope.$watch('vm.direction', function(newDir, oldDir) {
|
||||
// Add the appropriate classes so we can target the direction in the CSS
|
||||
$animate.removeClass($element, 'md-' + oldDir);
|
||||
$animate.addClass($element, 'md-' + newDir);
|
||||
});
|
||||
|
||||
|
||||
// Watch for changes to md-open
|
||||
$scope.$watch('vm.isOpen', function(isOpen) {
|
||||
var toAdd = isOpen ? 'md-is-open' : '';
|
||||
var toRemove = isOpen ? '' : 'md-is-open';
|
||||
|
||||
$animate.setClass($element, toAdd, toRemove);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function MdFabSpeedDialFlingAnimation() {
|
||||
function runAnimation(element) {
|
||||
var el = element[0];
|
||||
var ctrl = element.controller('mdFabSpeedDial');
|
||||
var items = el.querySelectorAll('.md-fab-action-item');
|
||||
|
||||
// Grab our element which stores CSS variables
|
||||
var variablesElement = el.querySelector('.md-css-variables');
|
||||
|
||||
// Setup JS variables based on our CSS variables
|
||||
var startZIndex = variablesElement.style.zIndex;
|
||||
|
||||
// Always reset the items to their natural position/state
|
||||
angular.forEach(items, function(item, index) {
|
||||
var styles = item.style;
|
||||
|
||||
styles.transform = '';
|
||||
styles.transitionDelay = '';
|
||||
styles.opacity = 1;
|
||||
|
||||
// Make the items closest to the trigger have the highest z-index
|
||||
item.style.zIndex = (items.length - index) + startZIndex;
|
||||
});
|
||||
|
||||
// If the control is closed, hide the items behind the trigger
|
||||
if (!ctrl.isOpen) {
|
||||
angular.forEach(items, function(item, index) {
|
||||
var newPosition, axis;
|
||||
|
||||
switch (ctrl.direction) {
|
||||
case 'up':
|
||||
newPosition = item.scrollHeight * (index + 1);
|
||||
axis = 'Y';
|
||||
break;
|
||||
case 'down':
|
||||
newPosition = -item.scrollHeight * (index + 1);
|
||||
axis = 'Y';
|
||||
break;
|
||||
case 'left':
|
||||
newPosition = item.scrollWidth * (index + 1);
|
||||
axis = 'X';
|
||||
break;
|
||||
case 'right':
|
||||
newPosition = -item.scrollWidth * (index + 1);
|
||||
axis = 'X';
|
||||
break;
|
||||
}
|
||||
|
||||
item.style.transform = 'translate' + axis + '(' + newPosition + 'px)';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
addClass: function(element, className, done) {
|
||||
if (element.hasClass('md-fling')) {
|
||||
runAnimation(element);
|
||||
}
|
||||
},
|
||||
removeClass: function(element, className, done) {
|
||||
runAnimation(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function MdFabSpeedDialScaleAnimation() {
|
||||
var delay = 65;
|
||||
|
||||
function runAnimation(element) {
|
||||
var el = element[0];
|
||||
var ctrl = element.controller('mdFabSpeedDial');
|
||||
var items = el.querySelectorAll('.md-fab-action-item');
|
||||
|
||||
// Always reset the items to their natural position/state
|
||||
angular.forEach(items, function(item, index) {
|
||||
var styles = item.style,
|
||||
offsetDelay = index * delay;
|
||||
|
||||
styles.opacity = ctrl.isOpen ? 1 : 0;
|
||||
styles.transform = ctrl.isOpen ? 'scale(1)' : 'scale(0)';
|
||||
styles.transitionDelay = (ctrl.isOpen ? offsetDelay : (items.length - offsetDelay)) + 'ms';
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
addClass: function(element, className, done) {
|
||||
runAnimation(element);
|
||||
},
|
||||
|
||||
removeClass: function(element, className, done) {
|
||||
runAnimation(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/fabSpeedDial/fabSpeedDial.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/fabSpeedDial/fabSpeedDial.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-fab-speed-dial{position:relative;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}md-fab-speed-dial .md-css-variables{z-index:20}md-fab-speed-dial.md-is-open .md-fab-action-item{visibility:visible}md-fab-speed-dial md-fab-actions{display:-webkit-flex;display:-ms-flexbox;display:flex;height:100%}md-fab-speed-dial md-fab-actions .md-fab-action-item{visibility:hidden;transition:all .3s cubic-bezier(.55,0,.55,.2)}md-fab-speed-dial.md-down{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}md-fab-speed-dial.md-down md-fab-trigger{-webkit-order:1;-ms-flex-order:1;order:1}md-fab-speed-dial.md-down md-fab-actions{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-order:2;-ms-flex-order:2;order:2}md-fab-speed-dial.md-up{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}md-fab-speed-dial.md-up md-fab-trigger{-webkit-order:2;-ms-flex-order:2;order:2}md-fab-speed-dial.md-up md-fab-actions{-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse;-webkit-order:1;-ms-flex-order:1;order:1}md-fab-speed-dial.md-left{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}md-fab-speed-dial.md-left md-fab-trigger{-webkit-order:2;-ms-flex-order:2;order:2}md-fab-speed-dial.md-left md-fab-actions{-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-order:1;-ms-flex-order:1;order:1}md-fab-speed-dial.md-left md-fab-actions .md-fab-action-item{transition:all .3s cubic-bezier(.55,0,.55,.2)}md-fab-speed-dial.md-right{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}md-fab-speed-dial.md-right md-fab-trigger{-webkit-order:1;-ms-flex-order:1;order:1}md-fab-speed-dial.md-right md-fab-actions{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-order:2;-ms-flex-order:2;order:2}md-fab-speed-dial.md-right md-fab-actions .md-fab-action-item{transition:all .3s cubic-bezier(.55,0,.55,.2)}md-fab-speed-dial.md-scale .md-fab-action-item{opacity:0;-webkit-transform:scale(0);transform:scale(0);transition:all .3s cubic-bezier(.55,0,.55,.2);transition-duration:.14286s}
|
||||
7
www/lib/angular-material/modules/js/fabSpeedDial/fabSpeedDial.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/fabSpeedDial/fabSpeedDial.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(n,e,i){"use strict";!function(){function n(){function n(n,e){e.prepend('<div class="md-css-variables"></div>')}function e(n,e,i){function t(){s.direction=s.direction||"down",s.isOpen=s.isOpen||!1}function o(){e.on("mouseenter",s.open),e.on("mouseleave",s.close)}function a(){n.$watch("vm.direction",function(n,t){i.removeClass(e,"md-"+t),i.addClass(e,"md-"+n)}),n.$watch("vm.isOpen",function(n){var t=n?"md-is-open":"",o=n?"":"md-is-open";i.setClass(e,t,o)})}var s=this;s.open=function(){n.$apply("vm.isOpen = true")},s.close=function(){n.$apply("vm.isOpen = false")},t(),o(),a()}return e.$inject=["$scope","$element","$animate"],{restrict:"E",scope:{direction:"@?mdDirection",isOpen:"=?mdOpen"},bindToController:!0,controller:e,controllerAs:"vm",link:n}}function i(){function n(n){var i=n[0],t=n.controller("mdFabSpeedDial"),o=i.querySelectorAll(".md-fab-action-item"),a=i.querySelector(".md-css-variables"),s=a.style.zIndex;e.forEach(o,function(n,e){var i=n.style;i.transform="",i.transitionDelay="",i.opacity=1,n.style.zIndex=o.length-e+s}),t.isOpen||e.forEach(o,function(n,e){var i,o;switch(t.direction){case"up":i=n.scrollHeight*(e+1),o="Y";break;case"down":i=-n.scrollHeight*(e+1),o="Y";break;case"left":i=n.scrollWidth*(e+1),o="X";break;case"right":i=-n.scrollWidth*(e+1),o="X"}n.style.transform="translate"+o+"("+i+"px)"})}return{addClass:function(e,i,t){e.hasClass("md-fling")&&n(e)},removeClass:function(e,i,t){n(e)}}}function t(){function n(n){var t=n[0],o=n.controller("mdFabSpeedDial"),a=t.querySelectorAll(".md-fab-action-item");e.forEach(a,function(n,e){var t=n.style,s=e*i;t.opacity=o.isOpen?1:0,t.transform=o.isOpen?"scale(1)":"scale(0)",t.transitionDelay=(o.isOpen?s:a.length-s)+"ms"})}var i=65;return{addClass:function(e,i,t){n(e)},removeClass:function(e,i,t){n(e)}}}e.module("material.components.fabSpeedDial",["material.core","material.components.fabTrigger","material.components.fabActions"]).directive("mdFabSpeedDial",n).animation(".md-fling",i).animation(".md-scale",t)}()}(window,window.angular);
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "angular-material-fabToolbar",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0",
|
||||
"angular-material-fabTrigger": "0.10.0",
|
||||
"angular-material-fabActions": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-fab-toolbar {
|
||||
display: block;
|
||||
/*
|
||||
* Closed styling
|
||||
*/
|
||||
/*
|
||||
* Hover styling
|
||||
*/ }
|
||||
md-fab-toolbar .md-fab-toolbar-wrapper {
|
||||
display: block;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 6.8rem; }
|
||||
md-fab-toolbar md-fab-trigger {
|
||||
position: absolute;
|
||||
z-index: 20; }
|
||||
md-fab-toolbar md-fab-trigger button {
|
||||
overflow: visible !important; }
|
||||
md-fab-toolbar md-fab-trigger .md-fab-toolbar-background {
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 21;
|
||||
opacity: 1;
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2); }
|
||||
md-fab-toolbar md-fab-trigger md-icon {
|
||||
position: relative;
|
||||
z-index: 22;
|
||||
opacity: 1;
|
||||
transition: all 200ms ease-in; }
|
||||
md-fab-toolbar.md-left md-fab-trigger {
|
||||
left: 0; }
|
||||
md-fab-toolbar.md-left .md-toolbar-tools {
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row; }
|
||||
md-fab-toolbar.md-right md-fab-trigger {
|
||||
right: 0; }
|
||||
md-fab-toolbar.md-right .md-toolbar-tools {
|
||||
-webkit-flex-direction: row-reverse;
|
||||
-ms-flex-direction: row-reverse;
|
||||
flex-direction: row-reverse; }
|
||||
md-fab-toolbar.md-right .md-toolbar-tools > .md-button:first-child {
|
||||
margin-left: 0.6rem; }
|
||||
md-fab-toolbar.md-right .md-toolbar-tools > .md-button:first-child {
|
||||
margin-right: -0.8rem; }
|
||||
md-fab-toolbar.md-right .md-toolbar-tools > .md-button:last-child {
|
||||
margin-right: 8px; }
|
||||
md-fab-toolbar md-toolbar {
|
||||
background-color: transparent !important;
|
||||
z-index: 23; }
|
||||
md-fab-toolbar md-toolbar .md-toolbar-tools {
|
||||
padding: 0 20px;
|
||||
margin-top: 3px; }
|
||||
md-fab-toolbar md-toolbar .md-fab-action-item {
|
||||
opacity: 0;
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
transition: all 0.3s cubic-bezier(0.55, 0, 0.55, 0.2);
|
||||
transition-duration: 0.15s; }
|
||||
md-fab-toolbar.md-is-open md-fab-trigger > button {
|
||||
box-shadow: none; }
|
||||
md-fab-toolbar.md-is-open md-fab-trigger > button md-icon {
|
||||
opacity: 0; }
|
||||
md-fab-toolbar.md-is-open .md-fab-action-item {
|
||||
opacity: 1;
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1); }
|
||||
217
www/lib/angular-material/modules/js/fabToolbar/fabToolbar.js
vendored
Normal file
217
www/lib/angular-material/modules/js/fabToolbar/fabToolbar.js
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('material.components.fabToolbar', [
|
||||
'material.core',
|
||||
'material.components.fabTrigger',
|
||||
'material.components.fabActions'
|
||||
])
|
||||
.directive('mdFabToolbar', MdFabToolbarDirective)
|
||||
.animation('.md-fab-toolbar', MdFabToolbarAnimation);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdFabToolbar
|
||||
* @module material.components.fabToolbar
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
*
|
||||
* The `<md-fab-toolbar>` directive is used present a toolbar of elements (usually `<md-button>`s)
|
||||
* for quick access to common actions when a floating action button is activated (via hover or
|
||||
* keyboard navigation).
|
||||
*
|
||||
* @usage
|
||||
*
|
||||
* <hljs lang="html">
|
||||
* <md-fab-toolbar>
|
||||
* <md-fab-trigger>
|
||||
* <md-button aria-label="Add..."><md-icon icon="/img/icons/plus.svg"></md-icon></md-button>
|
||||
* </md-fab-trigger>
|
||||
*
|
||||
* <md-fab-actions>
|
||||
* <md-button aria-label="Add User">
|
||||
* <md-icon icon="/img/icons/user.svg"></md-icon>
|
||||
* </md-button>
|
||||
*
|
||||
* <md-button aria-label="Add Group">
|
||||
* <md-icon icon="/img/icons/group.svg"></md-icon>
|
||||
* </md-button>
|
||||
* </md-fab-actions>
|
||||
* </md-fab-toolbar>
|
||||
* </hljs>
|
||||
*
|
||||
* @param {expression=} md-open Programmatically control whether or not the toolbar is visible.
|
||||
*/
|
||||
function MdFabToolbarDirective() {
|
||||
FabToolbarController.$inject = ["$scope", "$element", "$animate"];
|
||||
return {
|
||||
restrict: 'E',
|
||||
transclude: true,
|
||||
template:
|
||||
'<div class="md-fab-toolbar-wrapper">' +
|
||||
' <div class="md-fab-toolbar-content" ng-transclude></div>' +
|
||||
'</div>',
|
||||
|
||||
scope: {
|
||||
isOpen: '=?mdOpen'
|
||||
},
|
||||
|
||||
bindToController: true,
|
||||
controller: FabToolbarController,
|
||||
controllerAs: 'vm',
|
||||
|
||||
link: link
|
||||
};
|
||||
|
||||
function FabToolbarController($scope, $element, $animate) {
|
||||
var vm = this;
|
||||
|
||||
// Set the default to be closed
|
||||
vm.isOpen = vm.isOpen || false;
|
||||
|
||||
vm.open = function() {
|
||||
vm.isOpen = true;
|
||||
$scope.$apply();
|
||||
};
|
||||
|
||||
vm.close = function() {
|
||||
vm.isOpen = false;
|
||||
$scope.$apply();
|
||||
};
|
||||
|
||||
// Add our class so we can trigger the animation on start
|
||||
$element.addClass('md-fab-toolbar');
|
||||
|
||||
// Setup some mouse events so the hover effect can be triggered
|
||||
// anywhere over the toolbar
|
||||
$element.on('mouseenter', vm.open);
|
||||
$element.on('mouseleave', vm.close);
|
||||
|
||||
// Watch for changes to md-open and toggle our class
|
||||
$scope.$watch('vm.isOpen', function(isOpen) {
|
||||
var toAdd = isOpen ? 'md-is-open' : '';
|
||||
var toRemove = isOpen ? '' : 'md-is-open';
|
||||
|
||||
$animate.setClass($element, toAdd, toRemove);
|
||||
});
|
||||
}
|
||||
|
||||
function link(scope, element, attributes) {
|
||||
// Don't allow focus on the trigger
|
||||
element.find('md-fab-trigger').find('button').attr('tabindex', '-1');
|
||||
|
||||
// Prepend the background element to the trigger's button
|
||||
element.find('md-fab-trigger').find('button')
|
||||
.prepend('<div class="md-fab-toolbar-background"></div>');
|
||||
}
|
||||
}
|
||||
|
||||
function MdFabToolbarAnimation() {
|
||||
var originalIconDelay;
|
||||
|
||||
function runAnimation(element, className, done) {
|
||||
var el = element[0];
|
||||
var ctrl = element.controller('mdFabToolbar');
|
||||
|
||||
// Grab the relevant child elements
|
||||
var backgroundElement = el.querySelector('.md-fab-toolbar-background');
|
||||
var triggerElement = el.querySelector('md-fab-trigger button');
|
||||
var iconElement = el.querySelector('md-fab-trigger button md-icon');
|
||||
var actions = element.find('md-fab-actions').children();
|
||||
|
||||
// If we have both elements, use them to position the new background
|
||||
if (triggerElement && backgroundElement) {
|
||||
// Get our variables
|
||||
var color = window.getComputedStyle(triggerElement).getPropertyValue('background-color');
|
||||
var width = el.offsetWidth;
|
||||
var height = el.offsetHeight;
|
||||
|
||||
// Make a square
|
||||
var scale = width * 2;
|
||||
|
||||
// Set some basic styles no matter what animation we're doing
|
||||
backgroundElement.style.backgroundColor = color;
|
||||
backgroundElement.style.borderRadius = width + 'px';
|
||||
|
||||
// If we're open
|
||||
if (ctrl.isOpen) {
|
||||
|
||||
// Set the width/height to take up the full toolbar width
|
||||
backgroundElement.style.width = scale + 'px';
|
||||
backgroundElement.style.height = scale + 'px';
|
||||
|
||||
// Set the top/left to move up/left (or right) by the scale width/height
|
||||
backgroundElement.style.top = -(scale / 2) + 'px';
|
||||
|
||||
if (element.hasClass('md-left')) {
|
||||
backgroundElement.style.left = -(scale / 2) + 'px';
|
||||
backgroundElement.style.right = null;
|
||||
}
|
||||
|
||||
if (element.hasClass('md-right')) {
|
||||
backgroundElement.style.right = -(scale / 2) + 'px';
|
||||
backgroundElement.style.left = null;
|
||||
}
|
||||
|
||||
// Set the next close animation to have the proper delays
|
||||
backgroundElement.style.transitionDelay = '0ms';
|
||||
iconElement.style.transitionDelay = '.3s';
|
||||
|
||||
// Apply a transition delay to actions
|
||||
angular.forEach(actions, function(action, index) {
|
||||
action.style.transitionDelay = (actions.length - index) * 25 + 'ms';
|
||||
});
|
||||
} else {
|
||||
// Otherwise, set the width/height to the trigger's width/height
|
||||
backgroundElement.style.width = triggerElement.offsetWidth + 'px';
|
||||
backgroundElement.style.height = triggerElement.offsetHeight + 'px';
|
||||
|
||||
// Reset the position
|
||||
backgroundElement.style.top = '0px';
|
||||
|
||||
if (element.hasClass('md-left')) {
|
||||
backgroundElement.style.left = '0px';
|
||||
backgroundElement.style.right = null;
|
||||
}
|
||||
|
||||
if (element.hasClass('md-right')) {
|
||||
backgroundElement.style.right = '0px';
|
||||
backgroundElement.style.left = null;
|
||||
}
|
||||
|
||||
// Set the next open animation to have the proper delays
|
||||
backgroundElement.style.transitionDelay = '200ms';
|
||||
iconElement.style.transitionDelay = '0ms';
|
||||
|
||||
// Apply a transition delay to actions
|
||||
angular.forEach(actions, function(action, index) {
|
||||
action.style.transitionDelay = (index * 25) + 'ms';
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
addClass: function(element, className, done) {
|
||||
runAnimation(element, className, done);
|
||||
},
|
||||
|
||||
removeClass: function(element, className, done) {
|
||||
runAnimation(element, className, done);
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/fabToolbar/fabToolbar.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/fabToolbar/fabToolbar.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-fab-toolbar{display:block}md-fab-toolbar .md-fab-toolbar-wrapper{display:block;position:relative;overflow:hidden;height:6.8rem}md-fab-toolbar md-fab-trigger{position:absolute;z-index:20}md-fab-toolbar md-fab-trigger button{overflow:visible!important}md-fab-toolbar md-fab-trigger .md-fab-toolbar-background{display:block;position:absolute;z-index:21;opacity:1;transition:all .3s cubic-bezier(.55,0,.55,.2)}md-fab-toolbar md-fab-trigger md-icon{position:relative;z-index:22;opacity:1;transition:all 200ms ease-in}md-fab-toolbar.md-left md-fab-trigger{left:0}md-fab-toolbar.md-left .md-toolbar-tools{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row}md-fab-toolbar.md-right md-fab-trigger{right:0}md-fab-toolbar.md-right .md-toolbar-tools{-webkit-flex-direction:row-reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}md-fab-toolbar.md-right .md-toolbar-tools>.md-button:first-child{margin-left:.6rem;margin-right:-.8rem}md-fab-toolbar.md-right .md-toolbar-tools>.md-button:last-child{margin-right:8px}md-fab-toolbar md-toolbar{background-color:transparent!important;z-index:23}md-fab-toolbar md-toolbar .md-toolbar-tools{padding:0 20px;margin-top:3px}md-fab-toolbar md-toolbar .md-fab-action-item{opacity:0;-webkit-transform:scale(0);transform:scale(0);transition:all .3s cubic-bezier(.55,0,.55,.2);transition-duration:.15s}md-fab-toolbar.md-is-open md-fab-trigger>button{box-shadow:none}md-fab-toolbar.md-is-open md-fab-trigger>button md-icon{opacity:0}md-fab-toolbar.md-is-open .md-fab-action-item{opacity:1;-webkit-transform:scale(1);transform:scale(1)}
|
||||
7
www/lib/angular-material/modules/js/fabToolbar/fabToolbar.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/fabToolbar/fabToolbar.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(t,e,n){"use strict";!function(){function n(){function t(t,e,n){var o=this;o.isOpen=o.isOpen||!1,o.open=function(){o.isOpen=!0,t.$apply()},o.close=function(){o.isOpen=!1,t.$apply()},e.addClass("md-fab-toolbar"),e.on("mouseenter",o.open),e.on("mouseleave",o.close),t.$watch("vm.isOpen",function(t){var o=t?"md-is-open":"",l=t?"":"md-is-open";n.setClass(e,o,l)})}function e(t,e,n){e.find("md-fab-trigger").find("button").attr("tabindex","-1"),e.find("md-fab-trigger").find("button").prepend('<div class="md-fab-toolbar-background"></div>')}return t.$inject=["$scope","$element","$animate"],{restrict:"E",transclude:!0,template:'<div class="md-fab-toolbar-wrapper"> <div class="md-fab-toolbar-content" ng-transclude></div></div>',scope:{isOpen:"=?mdOpen"},bindToController:!0,controller:t,controllerAs:"vm",link:e}}function o(){function n(n,o,l){var s=n[0],a=n.controller("mdFabToolbar"),i=s.querySelector(".md-fab-toolbar-background"),r=s.querySelector("md-fab-trigger button"),d=s.querySelector("md-fab-trigger button md-icon"),c=n.find("md-fab-actions").children();if(r&&i){var f=t.getComputedStyle(r).getPropertyValue("background-color"),m=s.offsetWidth,p=(s.offsetHeight,2*m);i.style.backgroundColor=f,i.style.borderRadius=m+"px",a.isOpen?(i.style.width=p+"px",i.style.height=p+"px",i.style.top=-(p/2)+"px",n.hasClass("md-left")&&(i.style.left=-(p/2)+"px",i.style.right=null),n.hasClass("md-right")&&(i.style.right=-(p/2)+"px",i.style.left=null),i.style.transitionDelay="0ms",d.style.transitionDelay=".3s",e.forEach(c,function(t,e){t.style.transitionDelay=25*(c.length-e)+"ms"})):(i.style.width=r.offsetWidth+"px",i.style.height=r.offsetHeight+"px",i.style.top="0px",n.hasClass("md-left")&&(i.style.left="0px",i.style.right=null),n.hasClass("md-right")&&(i.style.right="0px",i.style.left=null),i.style.transitionDelay="200ms",d.style.transitionDelay="0ms",e.forEach(c,function(t,e){t.style.transitionDelay=25*e+"ms"}))}}return{addClass:function(t,e,o){n(t,e,o)},removeClass:function(t,e,o){n(t,e,o)}}}e.module("material.components.fabToolbar",["material.core","material.components.fabTrigger","material.components.fabActions"]).directive("mdFabToolbar",n).animation(".md-fab-toolbar",o)}()}(window,window.angular);
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-fabTrigger",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
55
www/lib/angular-material/modules/js/fabTrigger/fabTrigger.js
vendored
Normal file
55
www/lib/angular-material/modules/js/fabTrigger/fabTrigger.js
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('material.components.fabTrigger', [ 'material.core' ])
|
||||
.directive('mdFabTrigger', MdFabTriggerDirective);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdFabTrigger
|
||||
* @module material.components.fabSpeedDial
|
||||
*
|
||||
* @restrict E
|
||||
*
|
||||
* @description
|
||||
* The `<md-fab-trigger>` directive is used inside of a `<md-fab-speed-dial>` or
|
||||
* `<md-fab-toolbar>` directive to mark the an element (or elements) as the trigger and setup the
|
||||
* proper event listeners.
|
||||
*
|
||||
* @usage
|
||||
* See the `<md-fab-speed-dial>` or `<md-fab-toolbar>` directives for example usage.
|
||||
*/
|
||||
function MdFabTriggerDirective() {
|
||||
return {
|
||||
restrict: 'E',
|
||||
|
||||
require: ['^?mdFabSpeedDial', '^?mdFabToolbar'],
|
||||
|
||||
link: function(scope, element, attributes, controllers) {
|
||||
// Grab whichever parent controller is used
|
||||
var controller = controllers[0] || controllers[1];
|
||||
|
||||
// Make the children open/close their parent directive
|
||||
if (controller) {
|
||||
angular.forEach(element.children(), function(child) {
|
||||
angular.element(child).on('focus', controller.open);
|
||||
angular.element(child).on('blur', controller.close);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
})(window, window.angular);
|
||||
7
www/lib/angular-material/modules/js/fabTrigger/fabTrigger.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/fabTrigger/fabTrigger.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
!function(e,n,r){"use strict";!function(){function e(){return{restrict:"E",require:["^?mdFabSpeedDial","^?mdFabToolbar"],link:function(e,r,i,o){var t=o[0]||o[1];t&&n.forEach(r.children(),function(e){n.element(e).on("focus",t.open),n.element(e).on("blur",t.close)})}}}n.module("material.components.fabTrigger",["material.core"]).directive("mdFabTrigger",e)}()}(window,window.angular);
|
||||
7
www/lib/angular-material/modules/js/gridList/bower.json
Normal file
7
www/lib/angular-material/modules/js/gridList/bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-gridList",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
68
www/lib/angular-material/modules/js/gridList/gridList.css
Normal file
68
www/lib/angular-material/modules/js/gridList/gridList.css
Normal file
@@ -0,0 +1,68 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-grid-list {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: relative; }
|
||||
md-grid-list *, md-grid-list *:before, md-grid-list *:after {
|
||||
box-sizing: border-box; }
|
||||
md-grid-list md-grid-tile {
|
||||
display: block;
|
||||
position: absolute; }
|
||||
md-grid-list md-grid-tile figure {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
-webkit-justify-content: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
margin: 0; }
|
||||
md-grid-list md-grid-tile md-grid-tile-header, md-grid-list md-grid-tile md-grid-tile-footer {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
color: #fff;
|
||||
background: rgba(0, 0, 0, 0.18);
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0; }
|
||||
md-grid-list md-grid-tile md-grid-tile-header h3, md-grid-list md-grid-tile md-grid-tile-header h4, md-grid-list md-grid-tile md-grid-tile-footer h3, md-grid-list md-grid-tile md-grid-tile-footer h4 {
|
||||
font-weight: 400;
|
||||
margin: 0 0 0 16px; }
|
||||
md-grid-list md-grid-tile md-grid-tile-header h3, md-grid-list md-grid-tile md-grid-tile-footer h3 {
|
||||
font-size: 14px; }
|
||||
md-grid-list md-grid-tile md-grid-tile-header h4, md-grid-list md-grid-tile md-grid-tile-footer h4 {
|
||||
font-size: 12px; }
|
||||
md-grid-list md-grid-tile md-grid-tile-header {
|
||||
top: 0; }
|
||||
md-grid-list md-grid-tile md-grid-tile-footer {
|
||||
bottom: 0; }
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
md-grid-tile {
|
||||
border: 1px solid #fff; }
|
||||
md-grid-tile-footer {
|
||||
border-top: 1px solid #fff; } }
|
||||
763
www/lib/angular-material/modules/js/gridList/gridList.js
vendored
Normal file
763
www/lib/angular-material/modules/js/gridList/gridList.js
vendored
Normal file
@@ -0,0 +1,763 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
(function( window, angular, undefined ){
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name material.components.gridList
|
||||
*/
|
||||
angular.module('material.components.gridList', ['material.core'])
|
||||
.directive('mdGridList', GridListDirective)
|
||||
.directive('mdGridTile', GridTileDirective)
|
||||
.directive('mdGridTileFooter', GridTileCaptionDirective)
|
||||
.directive('mdGridTileHeader', GridTileCaptionDirective)
|
||||
.factory('$mdGridLayout', GridLayoutFactory);
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdGridList
|
||||
* @module material.components.gridList
|
||||
* @restrict E
|
||||
* @description
|
||||
* Grid lists are an alternative to standard list views. Grid lists are distinct
|
||||
* from grids used for layouts and other visual presentations.
|
||||
*
|
||||
* A grid list is best suited to presenting a homogenous data type, typically
|
||||
* images, and is optimized for visual comprehension and differentiating between
|
||||
* like data types.
|
||||
*
|
||||
* A grid list is a continuous element consisting of tessellated, regular
|
||||
* subdivisions called cells that contain tiles (`md-grid-tile`).
|
||||
*
|
||||
* <img src="//material-design.storage.googleapis.com/publish/v_2/material_ext_publish/0Bx4BSt6jniD7OVlEaXZ5YmU1Xzg/components_grids_usage2.png"
|
||||
* style="width: 300px; height: auto; margin-right: 16px;" alt="Concept of grid explained visually">
|
||||
* <img src="//material-design.storage.googleapis.com/publish/v_2/material_ext_publish/0Bx4BSt6jniD7VGhsOE5idWlJWXM/components_grids_usage3.png"
|
||||
* style="width: 300px; height: auto;" alt="Grid concepts legend">
|
||||
*
|
||||
* Cells are arrayed vertically and horizontally within the grid.
|
||||
*
|
||||
* Tiles hold content and can span one or more cells vertically or horizontally.
|
||||
*
|
||||
* ### Responsive Attributes
|
||||
*
|
||||
* The `md-grid-list` directive supports "responsive" attributes, which allow
|
||||
* different `md-cols`, `md-gutter` and `md-row-height` values depending on the
|
||||
* currently matching media query (as defined in `$mdConstant.MEDIA`).
|
||||
*
|
||||
* In order to set a responsive attribute, first define the fallback value with
|
||||
* the standard attribute name, then add additional attributes with the
|
||||
* following convention: `{base-attribute-name}-{media-query-name}="{value}"`
|
||||
* (ie. `md-cols-lg="8"`)
|
||||
*
|
||||
* @param {number} md-cols Number of columns in the grid.
|
||||
* @param {string} md-row-height One of
|
||||
* <ul>
|
||||
* <li>CSS length - Fixed height rows (eg. `8px` or `1rem`)</li>
|
||||
* <li>`{width}:{height}` - Ratio of width to height (eg.
|
||||
* `md-row-height="16:9"`)</li>
|
||||
* <li>`"fit"` - Height will be determined by subdividing the available
|
||||
* height by the number of rows</li>
|
||||
* </ul>
|
||||
* @param {string=} md-gutter The amount of space between tiles in CSS units
|
||||
* (default 1px)
|
||||
* @param {expression=} md-on-layout Expression to evaluate after layout. Event
|
||||
* object is available as `$event`, and contains performance information.
|
||||
*
|
||||
* @usage
|
||||
* Basic:
|
||||
* <hljs lang="html">
|
||||
* <md-grid-list md-cols="5" md-gutter="1em" md-row-height="4:3">
|
||||
* <md-grid-tile></md-grid-tile>
|
||||
* </md-grid-list>
|
||||
* </hljs>
|
||||
*
|
||||
* Fixed-height rows:
|
||||
* <hljs lang="html">
|
||||
* <md-grid-list md-cols="4" md-row-height="200px" ...>
|
||||
* <md-grid-tile></md-grid-tile>
|
||||
* </md-grid-list>
|
||||
* </hljs>
|
||||
*
|
||||
* Fit rows:
|
||||
* <hljs lang="html">
|
||||
* <md-grid-list md-cols="4" md-row-height="fit" style="height: 400px;" ...>
|
||||
* <md-grid-tile></md-grid-tile>
|
||||
* </md-grid-list>
|
||||
* </hljs>
|
||||
*
|
||||
* Using responsive attributes:
|
||||
* <hljs lang="html">
|
||||
* <md-grid-list
|
||||
* md-cols-sm="2"
|
||||
* md-cols-md="4"
|
||||
* md-cols-lg="8"
|
||||
* md-cols-gt-lg="12"
|
||||
* ...>
|
||||
* <md-grid-tile></md-grid-tile>
|
||||
* </md-grid-list>
|
||||
* </hljs>
|
||||
*/
|
||||
function GridListDirective($interpolate, $mdConstant, $mdGridLayout, $mdMedia) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
controller: GridListController,
|
||||
scope: {
|
||||
mdOnLayout: '&'
|
||||
},
|
||||
link: postLink
|
||||
};
|
||||
|
||||
function postLink(scope, element, attrs, ctrl) {
|
||||
// Apply semantics
|
||||
element.attr('role', 'list');
|
||||
|
||||
// Provide the controller with a way to trigger layouts.
|
||||
ctrl.layoutDelegate = layoutDelegate;
|
||||
|
||||
var invalidateLayout = angular.bind(ctrl, ctrl.invalidateLayout),
|
||||
unwatchAttrs = watchMedia();
|
||||
scope.$on('$destroy', unwatchMedia);
|
||||
|
||||
/**
|
||||
* Watches for changes in media, invalidating layout as necessary.
|
||||
*/
|
||||
function watchMedia() {
|
||||
for (var mediaName in $mdConstant.MEDIA) {
|
||||
$mdMedia(mediaName); // initialize
|
||||
$mdMedia.getQuery($mdConstant.MEDIA[mediaName])
|
||||
.addListener(invalidateLayout);
|
||||
}
|
||||
return $mdMedia.watchResponsiveAttributes(
|
||||
['md-cols', 'md-row-height'], attrs, layoutIfMediaMatch);
|
||||
}
|
||||
|
||||
function unwatchMedia() {
|
||||
ctrl.layoutDelegate = angular.noop;
|
||||
|
||||
unwatchAttrs();
|
||||
for (var mediaName in $mdConstant.MEDIA) {
|
||||
$mdMedia.getQuery($mdConstant.MEDIA[mediaName])
|
||||
.removeListener(invalidateLayout);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs grid layout if the provided mediaName matches the currently
|
||||
* active media type.
|
||||
*/
|
||||
function layoutIfMediaMatch(mediaName) {
|
||||
if (mediaName == null) {
|
||||
// TODO(shyndman): It would be nice to only layout if we have
|
||||
// instances of attributes using this media type
|
||||
ctrl.invalidateLayout();
|
||||
} else if ($mdMedia(mediaName)) {
|
||||
ctrl.invalidateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
var lastLayoutProps;
|
||||
|
||||
/**
|
||||
* Invokes the layout engine, and uses its results to lay out our
|
||||
* tile elements.
|
||||
*
|
||||
* @param {boolean} tilesInvalidated Whether tiles have been
|
||||
* added/removed/moved since the last layout. This is to avoid situations
|
||||
* where tiles are replaced with properties identical to their removed
|
||||
* counterparts.
|
||||
*/
|
||||
function layoutDelegate(tilesInvalidated) {
|
||||
var tiles = getTileElements();
|
||||
var props = {
|
||||
tileSpans: getTileSpans(tiles),
|
||||
colCount: getColumnCount(),
|
||||
rowMode: getRowMode(),
|
||||
rowHeight: getRowHeight(),
|
||||
gutter: getGutter()
|
||||
};
|
||||
|
||||
if (!tilesInvalidated && angular.equals(props, lastLayoutProps)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var performance =
|
||||
$mdGridLayout(props.colCount, props.tileSpans, tiles)
|
||||
.map(function(tilePositions, rowCount) {
|
||||
return {
|
||||
grid: {
|
||||
element: element,
|
||||
style: getGridStyle(props.colCount, rowCount,
|
||||
props.gutter, props.rowMode, props.rowHeight)
|
||||
},
|
||||
tiles: tilePositions.map(function(ps, i) {
|
||||
return {
|
||||
element: angular.element(tiles[i]),
|
||||
style: getTileStyle(ps.position, ps.spans,
|
||||
props.colCount, props.rowCount,
|
||||
props.gutter, props.rowMode, props.rowHeight)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.reflow()
|
||||
.performance();
|
||||
|
||||
// Report layout
|
||||
scope.mdOnLayout({
|
||||
$event: {
|
||||
performance: performance
|
||||
}
|
||||
});
|
||||
|
||||
lastLayoutProps = props;
|
||||
}
|
||||
|
||||
// Use $interpolate to do some simple string interpolation as a convenience.
|
||||
|
||||
var startSymbol = $interpolate.startSymbol();
|
||||
var endSymbol = $interpolate.endSymbol();
|
||||
|
||||
// Returns an expression wrapped in the interpolator's start and end symbols.
|
||||
function expr(exprStr) {
|
||||
return startSymbol + exprStr + endSymbol;
|
||||
}
|
||||
|
||||
// The amount of space a single 1x1 tile would take up (either width or height), used as
|
||||
// a basis for other calculations. This consists of taking the base size percent (as would be
|
||||
// if evenly dividing the size between cells), and then subtracting the size of one gutter.
|
||||
// However, since there are no gutters on the edges, each tile only uses a fration
|
||||
// (gutterShare = numGutters / numCells) of the gutter size. (Imagine having one gutter per
|
||||
// tile, and then breaking up the extra gutter on the edge evenly among the cells).
|
||||
var UNIT = $interpolate(expr('share') + '% - (' + expr('gutter') + ' * ' + expr('gutterShare') + ')');
|
||||
|
||||
// The horizontal or vertical position of a tile, e.g., the 'top' or 'left' property value.
|
||||
// The position comes the size of a 1x1 tile plus gutter for each previous tile in the
|
||||
// row/column (offset).
|
||||
var POSITION = $interpolate('calc((' + expr('unit') + ' + ' + expr('gutter') + ') * ' + expr('offset') + ')');
|
||||
|
||||
// The actual size of a tile, e.g., width or height, taking rowSpan or colSpan into account.
|
||||
// This is computed by multiplying the base unit by the rowSpan/colSpan, and then adding back
|
||||
// in the space that the gutter would normally have used (which was already accounted for in
|
||||
// the base unit calculation).
|
||||
var DIMENSION = $interpolate('calc((' + expr('unit') + ') * ' + expr('span') + ' + (' + expr('span') + ' - 1) * ' + expr('gutter') + ')');
|
||||
|
||||
/**
|
||||
* Gets the styles applied to a tile element described by the given parameters.
|
||||
* @param {{row: number, col: number}} position The row and column indices of the tile.
|
||||
* @param {{row: number, col: number}} spans The rowSpan and colSpan of the tile.
|
||||
* @param {number} colCount The number of columns.
|
||||
* @param {number} rowCount The number of rows.
|
||||
* @param {string} gutter The amount of space between tiles. This will be something like
|
||||
* '5px' or '2em'.
|
||||
* @param {string} rowMode The row height mode. Can be one of:
|
||||
* 'fixed': all rows have a fixed size, given by rowHeight,
|
||||
* 'ratio': row height defined as a ratio to width, or
|
||||
* 'fit': fit to the grid-list element height, divinding evenly among rows.
|
||||
* @param {string|number} rowHeight The height of a row. This is only used for 'fixed' mode and
|
||||
* for 'ratio' mode. For 'ratio' mode, this is the *ratio* of width-to-height (e.g., 0.75).
|
||||
* @returns {Object} Map of CSS properties to be applied to the style element. Will define
|
||||
* values for top, left, width, height, marginTop, and paddingTop.
|
||||
*/
|
||||
function getTileStyle(position, spans, colCount, rowCount, gutter, rowMode, rowHeight) {
|
||||
// TODO(shyndman): There are style caching opportunities here.
|
||||
|
||||
// Percent of the available horizontal space that one column takes up.
|
||||
var hShare = (1 / colCount) * 100;
|
||||
|
||||
// Fraction of the gutter size that each column takes up.
|
||||
var hGutterShare = (colCount - 1) / colCount;
|
||||
|
||||
// Base horizontal size of a column.
|
||||
var hUnit = UNIT({share: hShare, gutterShare: hGutterShare, gutter: gutter});
|
||||
|
||||
// The width and horizontal position of each tile is always calculated the same way, but the
|
||||
// height and vertical position depends on the rowMode.
|
||||
var style = {
|
||||
left: POSITION({ unit: hUnit, offset: position.col, gutter: gutter }),
|
||||
width: DIMENSION({ unit: hUnit, span: spans.col, gutter: gutter }),
|
||||
// resets
|
||||
paddingTop: '',
|
||||
marginTop: '',
|
||||
top: '',
|
||||
height: ''
|
||||
};
|
||||
|
||||
switch (rowMode) {
|
||||
case 'fixed':
|
||||
// In fixed mode, simply use the given rowHeight.
|
||||
style.top = POSITION({ unit: rowHeight, offset: position.row, gutter: gutter });
|
||||
style.height = DIMENSION({ unit: rowHeight, span: spans.row, gutter: gutter });
|
||||
break;
|
||||
|
||||
case 'ratio':
|
||||
// Percent of the available vertical space that one row takes up. Here, rowHeight holds
|
||||
// the ratio value. For example, if the width:height ratio is 4:3, rowHeight = 1.333.
|
||||
var vShare = hShare / rowHeight;
|
||||
|
||||
// Base veritcal size of a row.
|
||||
var vUnit = UNIT({ share: vShare, gutterShare: hGutterShare, gutter: gutter });
|
||||
|
||||
// padidngTop and marginTop are used to maintain the given aspect ratio, as
|
||||
// a percentage-based value for these properties is applied to the *width* of the
|
||||
// containing block. See http://www.w3.org/TR/CSS2/box.html#margin-properties
|
||||
style.paddingTop = DIMENSION({ unit: vUnit, span: spans.row, gutter: gutter});
|
||||
style.marginTop = POSITION({ unit: vUnit, offset: position.row, gutter: gutter });
|
||||
break;
|
||||
|
||||
case 'fit':
|
||||
// Fraction of the gutter size that each column takes up.
|
||||
var vGutterShare = (rowCount - 1) / rowCount;
|
||||
|
||||
// Percent of the available vertical space that one row takes up.
|
||||
var vShare = (1 / rowCount) * 100;
|
||||
|
||||
// Base vertical size of a row.
|
||||
var vUnit = UNIT({share: vShare, gutterShare: vGutterShare, gutter: gutter});
|
||||
|
||||
style.top = POSITION({unit: vUnit, offset: position.row, gutter: gutter});
|
||||
style.height = DIMENSION({unit: vUnit, span: spans.row, gutter: gutter});
|
||||
break;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
function getGridStyle(colCount, rowCount, gutter, rowMode, rowHeight) {
|
||||
var style = {
|
||||
height: '',
|
||||
paddingBottom: ''
|
||||
};
|
||||
|
||||
switch(rowMode) {
|
||||
case 'fixed':
|
||||
style.height = DIMENSION({ unit: rowHeight, span: rowCount, gutter: gutter });
|
||||
break;
|
||||
|
||||
case 'ratio':
|
||||
// rowHeight is width / height
|
||||
var hGutterShare = colCount === 1 ? 0 : (colCount - 1) / colCount,
|
||||
hShare = (1 / colCount) * 100,
|
||||
vShare = hShare * (1 / rowHeight),
|
||||
vUnit = UNIT({ share: vShare, gutterShare: hGutterShare, gutter: gutter });
|
||||
|
||||
style.paddingBottom = DIMENSION({ unit: vUnit, span: rowCount, gutter: gutter});
|
||||
break;
|
||||
|
||||
case 'fit':
|
||||
// noop, as the height is user set
|
||||
break;
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
|
||||
function getTileElements() {
|
||||
return [].filter.call(element.children(), function(ele) {
|
||||
return ele.tagName == 'MD-GRID-TILE';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of objects containing the rowspan and colspan for each tile.
|
||||
* @returns {Array<{row: number, col: number}>}
|
||||
*/
|
||||
function getTileSpans(tileElements) {
|
||||
return [].map.call(tileElements, function(ele) {
|
||||
var ctrl = angular.element(ele).controller('mdGridTile');
|
||||
return {
|
||||
row: parseInt(
|
||||
$mdMedia.getResponsiveAttribute(ctrl.$attrs, 'md-rowspan'), 10) || 1,
|
||||
col: parseInt(
|
||||
$mdMedia.getResponsiveAttribute(ctrl.$attrs, 'md-colspan'), 10) || 1
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getColumnCount() {
|
||||
var colCount = parseInt($mdMedia.getResponsiveAttribute(attrs, 'md-cols'), 10);
|
||||
if (isNaN(colCount)) {
|
||||
throw 'md-grid-list: md-cols attribute was not found, or contained a non-numeric value';
|
||||
}
|
||||
return colCount;
|
||||
}
|
||||
|
||||
function getGutter() {
|
||||
return applyDefaultUnit($mdMedia.getResponsiveAttribute(attrs, 'md-gutter') || 1);
|
||||
}
|
||||
|
||||
function getRowHeight() {
|
||||
var rowHeight = $mdMedia.getResponsiveAttribute(attrs, 'md-row-height');
|
||||
switch (getRowMode()) {
|
||||
case 'fixed':
|
||||
return applyDefaultUnit(rowHeight);
|
||||
case 'ratio':
|
||||
var whRatio = rowHeight.split(':');
|
||||
return parseFloat(whRatio[0]) / parseFloat(whRatio[1]);
|
||||
case 'fit':
|
||||
return 0; // N/A
|
||||
}
|
||||
}
|
||||
|
||||
function getRowMode() {
|
||||
var rowHeight = $mdMedia.getResponsiveAttribute(attrs, 'md-row-height');
|
||||
if (rowHeight == 'fit') {
|
||||
return 'fit';
|
||||
} else if (rowHeight.indexOf(':') !== -1) {
|
||||
return 'ratio';
|
||||
} else {
|
||||
return 'fixed';
|
||||
}
|
||||
}
|
||||
|
||||
function applyDefaultUnit(val) {
|
||||
return /\D$/.test(val) ? val : val + 'px';
|
||||
}
|
||||
}
|
||||
}
|
||||
GridListDirective.$inject = ["$interpolate", "$mdConstant", "$mdGridLayout", "$mdMedia"];
|
||||
|
||||
/* ngInject */
|
||||
function GridListController($timeout) {
|
||||
this.layoutInvalidated = false;
|
||||
this.tilesInvalidated = false;
|
||||
this.$timeout_ = $timeout;
|
||||
this.layoutDelegate = angular.noop;
|
||||
}
|
||||
GridListController.$inject = ["$timeout"];
|
||||
|
||||
GridListController.prototype = {
|
||||
invalidateTiles: function() {
|
||||
this.tilesInvalidated = true;
|
||||
this.invalidateLayout();
|
||||
},
|
||||
|
||||
invalidateLayout: function() {
|
||||
if (this.layoutInvalidated) {
|
||||
return;
|
||||
}
|
||||
this.layoutInvalidated = true;
|
||||
this.$timeout_(angular.bind(this, this.layout));
|
||||
},
|
||||
|
||||
layout: function() {
|
||||
try {
|
||||
this.layoutDelegate(this.tilesInvalidated);
|
||||
} finally {
|
||||
this.layoutInvalidated = false;
|
||||
this.tilesInvalidated = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* ngInject */
|
||||
function GridLayoutFactory($mdUtil) {
|
||||
var defaultAnimator = GridTileAnimator;
|
||||
|
||||
/**
|
||||
* Set the reflow animator callback
|
||||
*/
|
||||
GridLayout.animateWith = function(customAnimator) {
|
||||
defaultAnimator = !angular.isFunction(customAnimator) ? GridTileAnimator : customAnimator;
|
||||
};
|
||||
|
||||
return GridLayout;
|
||||
|
||||
/**
|
||||
* Publish layout function
|
||||
*/
|
||||
function GridLayout(colCount, tileSpans) {
|
||||
var self, layoutInfo, gridStyles, layoutTime, mapTime, reflowTime;
|
||||
|
||||
layoutTime = $mdUtil.time(function() {
|
||||
layoutInfo = calculateGridFor(colCount, tileSpans);
|
||||
});
|
||||
|
||||
return self = {
|
||||
|
||||
/**
|
||||
* An array of objects describing each tile's position in the grid.
|
||||
*/
|
||||
layoutInfo: function() {
|
||||
return layoutInfo;
|
||||
},
|
||||
|
||||
/**
|
||||
* Maps grid positioning to an element and a set of styles using the
|
||||
* provided updateFn.
|
||||
*/
|
||||
map: function(updateFn) {
|
||||
mapTime = $mdUtil.time(function() {
|
||||
var info = self.layoutInfo();
|
||||
gridStyles = updateFn(info.positioning, info.rowCount);
|
||||
});
|
||||
return self;
|
||||
},
|
||||
|
||||
/**
|
||||
* Default animator simply sets the element.css( <styles> ). An alternate
|
||||
* animator can be provided as an argument. The function has the following
|
||||
* signature:
|
||||
*
|
||||
* function({grid: {element: JQLite, style: Object}, tiles: Array<{element: JQLite, style: Object}>)
|
||||
*/
|
||||
reflow: function(animatorFn) {
|
||||
reflowTime = $mdUtil.time(function() {
|
||||
var animator = animatorFn || defaultAnimator;
|
||||
animator(gridStyles.grid, gridStyles.tiles);
|
||||
});
|
||||
return self;
|
||||
},
|
||||
|
||||
/**
|
||||
* Timing for the most recent layout run.
|
||||
*/
|
||||
performance: function() {
|
||||
return {
|
||||
tileCount: tileSpans.length,
|
||||
layoutTime: layoutTime,
|
||||
mapTime: mapTime,
|
||||
reflowTime: reflowTime,
|
||||
totalTime: layoutTime + mapTime + reflowTime
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Gridlist animator simple sets the css for each element;
|
||||
* NOTE: any transitions effects must be manually set in the CSS.
|
||||
* e.g.
|
||||
*
|
||||
* md-grid-tile {
|
||||
* transition: all 700ms ease-out 50ms;
|
||||
* }
|
||||
*
|
||||
*/
|
||||
function GridTileAnimator(grid, tiles) {
|
||||
grid.element.css(grid.style);
|
||||
tiles.forEach(function(t) {
|
||||
t.element.css(t.style);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the positions of tiles.
|
||||
*
|
||||
* The algorithm works as follows:
|
||||
* An Array<Number> with length colCount (spaceTracker) keeps track of
|
||||
* available tiling positions, where elements of value 0 represents an
|
||||
* empty position. Space for a tile is reserved by finding a sequence of
|
||||
* 0s with length <= than the tile's colspan. When such a space has been
|
||||
* found, the occupied tile positions are incremented by the tile's
|
||||
* rowspan value, as these positions have become unavailable for that
|
||||
* many rows.
|
||||
*
|
||||
* If the end of a row has been reached without finding space for the
|
||||
* tile, spaceTracker's elements are each decremented by 1 to a minimum
|
||||
* of 0. Rows are searched in this fashion until space is found.
|
||||
*/
|
||||
function calculateGridFor(colCount, tileSpans) {
|
||||
var curCol = 0,
|
||||
curRow = 0,
|
||||
spaceTracker = newSpaceTracker();
|
||||
|
||||
return {
|
||||
positioning: tileSpans.map(function(spans, i) {
|
||||
return {
|
||||
spans: spans,
|
||||
position: reserveSpace(spans, i)
|
||||
};
|
||||
}),
|
||||
rowCount: curRow + Math.max.apply(Math, spaceTracker)
|
||||
};
|
||||
|
||||
function reserveSpace(spans, i) {
|
||||
if (spans.col > colCount) {
|
||||
throw 'md-grid-list: Tile at position ' + i + ' has a colspan ' +
|
||||
'(' + spans.col + ') that exceeds the column count ' +
|
||||
'(' + colCount + ')';
|
||||
}
|
||||
|
||||
var start = 0,
|
||||
end = 0;
|
||||
|
||||
// TODO(shyndman): This loop isn't strictly necessary if you can
|
||||
// determine the minimum number of rows before a space opens up. To do
|
||||
// this, recognize that you've iterated across an entire row looking for
|
||||
// space, and if so fast-forward by the minimum rowSpan count. Repeat
|
||||
// until the required space opens up.
|
||||
while (end - start < spans.col) {
|
||||
if (curCol >= colCount) {
|
||||
nextRow();
|
||||
continue;
|
||||
}
|
||||
|
||||
start = spaceTracker.indexOf(0, curCol);
|
||||
if (start === -1 || (end = findEnd(start + 1)) === -1) {
|
||||
start = end = 0;
|
||||
nextRow();
|
||||
continue;
|
||||
}
|
||||
|
||||
curCol = end + 1;
|
||||
}
|
||||
|
||||
adjustRow(start, spans.col, spans.row);
|
||||
curCol = start + spans.col;
|
||||
|
||||
return {
|
||||
col: start,
|
||||
row: curRow
|
||||
};
|
||||
}
|
||||
|
||||
function nextRow() {
|
||||
curCol = 0;
|
||||
curRow++;
|
||||
adjustRow(0, colCount, -1); // Decrement row spans by one
|
||||
}
|
||||
|
||||
function adjustRow(from, cols, by) {
|
||||
for (var i = from; i < from + cols; i++) {
|
||||
spaceTracker[i] = Math.max(spaceTracker[i] + by, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function findEnd(start) {
|
||||
var i;
|
||||
for (i = start; i < spaceTracker.length; i++) {
|
||||
if (spaceTracker[i] !== 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (i === spaceTracker.length) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
function newSpaceTracker() {
|
||||
var tracker = [];
|
||||
for (var i = 0; i < colCount; i++) {
|
||||
tracker.push(0);
|
||||
}
|
||||
return tracker;
|
||||
}
|
||||
}
|
||||
}
|
||||
GridLayoutFactory.$inject = ["$mdUtil"];
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name mdGridTile
|
||||
* @module material.components.gridList
|
||||
* @restrict E
|
||||
* @description
|
||||
* Tiles contain the content of an `md-grid-list`. They span one or more grid
|
||||
* cells vertically or horizontally, and use `md-grid-tile-{footer,header}` to
|
||||
* display secondary content.
|
||||
*
|
||||
* ### Responsive Attributes
|
||||
*
|
||||
* The `md-grid-tile` directive supports "responsive" attributes, which allow
|
||||
* different `md-rowspan` and `md-colspan` values depending on the currently
|
||||
* matching media query (as defined in `$mdConstant.MEDIA`).
|
||||
*
|
||||
* In order to set a responsive attribute, first define the fallback value with
|
||||
* the standard attribute name, then add additional attributes with the
|
||||
* following convention: `{base-attribute-name}-{media-query-name}="{value}"`
|
||||
* (ie. `md-colspan-sm="4"`)
|
||||
*
|
||||
* @param {number=} md-colspan The number of columns to span (default 1). Cannot
|
||||
* exceed the number of columns in the grid. Supports interpolation.
|
||||
* @param {number=} md-rowspan The number of rows to span (default 1). Supports
|
||||
* interpolation.
|
||||
*
|
||||
* @usage
|
||||
* With header:
|
||||
* <hljs lang="html">
|
||||
* <md-grid-tile>
|
||||
* <md-grid-tile-header>
|
||||
* <h3>This is a header</h3>
|
||||
* </md-grid-tile-header>
|
||||
* </md-grid-tile>
|
||||
* </hljs>
|
||||
*
|
||||
* With footer:
|
||||
* <hljs lang="html">
|
||||
* <md-grid-tile>
|
||||
* <md-grid-tile-footer>
|
||||
* <h3>This is a footer</h3>
|
||||
* </md-grid-tile-footer>
|
||||
* </md-grid-tile>
|
||||
* </hljs>
|
||||
*
|
||||
* Spanning multiple rows/columns:
|
||||
* <hljs lang="html">
|
||||
* <md-grid-tile md-colspan="2" md-rowspan="3">
|
||||
* </md-grid-tile>
|
||||
* </hljs>
|
||||
*
|
||||
* Responsive attributes:
|
||||
* <hljs lang="html">
|
||||
* <md-grid-tile md-colspan="1" md-colspan-sm="3" md-colspan-md="5">
|
||||
* </md-grid-tile>
|
||||
* </hljs>
|
||||
*/
|
||||
function GridTileDirective($mdMedia) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
require: '^mdGridList',
|
||||
template: '<figure ng-transclude></figure>',
|
||||
transclude: true,
|
||||
scope: {},
|
||||
// Simple controller that exposes attributes to the grid directive
|
||||
controller: ["$attrs", function($attrs) {
|
||||
this.$attrs = $attrs;
|
||||
}],
|
||||
link: postLink
|
||||
};
|
||||
|
||||
function postLink(scope, element, attrs, gridCtrl) {
|
||||
// Apply semantics
|
||||
element.attr('role', 'listitem');
|
||||
|
||||
// If our colspan or rowspan changes, trigger a layout
|
||||
var unwatchAttrs = $mdMedia.watchResponsiveAttributes(['md-colspan', 'md-rowspan'],
|
||||
attrs, angular.bind(gridCtrl, gridCtrl.invalidateLayout));
|
||||
|
||||
// Tile registration/deregistration
|
||||
gridCtrl.invalidateTiles();
|
||||
scope.$on('$destroy', function() {
|
||||
unwatchAttrs();
|
||||
gridCtrl.invalidateLayout();
|
||||
});
|
||||
|
||||
if (angular.isDefined(scope.$parent.$index)) {
|
||||
scope.$watch(function() { return scope.$parent.$index; },
|
||||
function indexChanged(newIdx, oldIdx) {
|
||||
if (newIdx === oldIdx) {
|
||||
return;
|
||||
}
|
||||
gridCtrl.invalidateTiles();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
GridTileDirective.$inject = ["$mdMedia"];
|
||||
|
||||
|
||||
function GridTileCaptionDirective() {
|
||||
return {
|
||||
template: '<figcaption ng-transclude></figcaption>',
|
||||
transclude: true
|
||||
};
|
||||
}
|
||||
|
||||
})(window, window.angular);
|
||||
6
www/lib/angular-material/modules/js/gridList/gridList.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/gridList/gridList.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-grid-list{box-sizing:border-box;display:block;position:relative}md-grid-list *,md-grid-list :after,md-grid-list :before{box-sizing:border-box}md-grid-list md-grid-tile{display:block;position:absolute}md-grid-list md-grid-tile figure{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;height:100%;position:absolute;top:0;right:0;bottom:0;left:0;padding:0;margin:0}md-grid-list md-grid-tile md-grid-tile-footer,md-grid-list md-grid-tile md-grid-tile-header{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-ms-flex-align:center;align-items:center;height:48px;color:#fff;background:rgba(0,0,0,.18);overflow:hidden;position:absolute;left:0;right:0}md-grid-list md-grid-tile md-grid-tile-footer h3,md-grid-list md-grid-tile md-grid-tile-footer h4,md-grid-list md-grid-tile md-grid-tile-header h3,md-grid-list md-grid-tile md-grid-tile-header h4{font-weight:400;margin:0 0 0 16px}md-grid-list md-grid-tile md-grid-tile-footer h3,md-grid-list md-grid-tile md-grid-tile-header h3{font-size:14px}md-grid-list md-grid-tile md-grid-tile-footer h4,md-grid-list md-grid-tile md-grid-tile-header h4{font-size:12px}md-grid-list md-grid-tile md-grid-tile-header{top:0}md-grid-list md-grid-tile md-grid-tile-footer{bottom:0}@media screen and (-ms-high-contrast:active){md-grid-tile{border:1px solid #fff}md-grid-tile-footer{border-top:1px solid #fff}}
|
||||
7
www/lib/angular-material/modules/js/gridList/gridList.min.js
vendored
Normal file
7
www/lib/angular-material/modules/js/gridList/gridList.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
7
www/lib/angular-material/modules/js/icon/bower.json
Normal file
7
www/lib/angular-material/modules/js/icon/bower.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "angular-material-icon",
|
||||
"version": "0.10.0",
|
||||
"dependencies": {
|
||||
"angular-material-core": "0.10.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/
|
||||
/* mixin definition ; sets LTR and RTL within the same style call */
|
||||
md-icon.md-THEME_NAME-theme {
|
||||
color: '{{foreground-2}}'; }
|
||||
md-icon.md-THEME_NAME-theme.md-primary {
|
||||
color: '{{primary-color}}'; }
|
||||
md-icon.md-THEME_NAME-theme.md-accent {
|
||||
color: '{{accent-color}}'; }
|
||||
md-icon.md-THEME_NAME-theme.md-warn {
|
||||
color: '{{warn-color}}'; }
|
||||
6
www/lib/angular-material/modules/js/icon/icon-default-theme.min.css
vendored
Normal file
6
www/lib/angular-material/modules/js/icon/icon-default-theme.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
* Angular Material Design
|
||||
* https://github.com/angular/material
|
||||
* @license MIT
|
||||
* v0.10.0
|
||||
*/md-icon.md-THEME_NAME-theme{color:'{{foreground-2}}'}md-icon.md-THEME_NAME-theme.md-primary{color:'{{primary-color}}'}md-icon.md-THEME_NAME-theme.md-accent{color:'{{accent-color}}'}md-icon.md-THEME_NAME-theme.md-warn{color:'{{warn-color}}'}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user