(fix) updates for new packages

This commit is contained in:
Ludovic Marcotte committed 2015-08-21 13:40:07 -04:00
1 parent 91e4c2cefc
commit 0a8834193f
24 files changed
+679 -361

No files matched your search

+288 -78
View File
@@ -2,7 +2,7 @@
* Angular Material Design
* https://github.com/angular/material
* @license MIT
* v0.10.1-master-8c71d0c
* v0.10.1-master-c9f2b9f
*/
(function( window, angular, undefined ){
"use strict";
@@ -892,6 +892,22 @@ function UtilFactory($document, $timeout, $compile, $rootScope, $$mdAnimate, $in
return $mdUtil.now() - start;
},
/**
* Create an implicit getter that caches its `getter()`
* lookup value
*/
valueOnUse : function (scope, key, getter) {
var value = null, args = Array.prototype.slice.call(arguments);
var params = (args.length > 3) ? args.slice(3) : [ ];
Object.defineProperty(scope, key, {
get: function () {
if (value === null) value = getter.apply(scope, params);
return value;
}
});
},
/**
* Get a unique ID.
*
@@ -1347,6 +1363,12 @@ mdCompilerService.$inject = ["$q", "$http", "$injector", "$compile", "$controlle
*/
var pointer, lastPointer, forceSkipClickHijack = false;
/**
* The position of the most recent click if that click was on a label element.
* @type {{x: number, y: number}?}
*/
var lastLabelClickPos = null;
// Used to attach event listeners once when multiple ng-apps are running.
var isInitialized = false;
@@ -1790,9 +1812,16 @@ mdCompilerService.$inject = ["$q", "$http", "$injector", "$compile", "$controlle
*/
document.addEventListener('click', function clickHijacker(ev) {
var isKeyClick = ev.clientX === 0 && ev.clientY === 0;
if (!isKeyClick && !ev.$material && !ev.isIonicTap) {
if (!isKeyClick && !ev.$material && !ev.isIonicTap
&& !isInputEventFromLabelClick(ev)) {
ev.preventDefault();
ev.stopPropagation();
lastLabelClickPos = null;
} else {
lastLabelClickPos = null;
if (ev.target.tagName.toLowerCase() == 'label') {
lastLabelClickPos = {x: ev.x, y: ev.y};
}
}
}, true);
@@ -1913,6 +1942,28 @@ mdCompilerService.$inject = ["$q", "$http", "$injector", "$compile", "$controlle
return ev && pointer && ev.type.charAt(0) === pointer.type;
}
/**
* Gets whether the given event is an input event that was caused by clicking on an
* associated label element.
*
* This is necessary because the browser will, upon clicking on a label element, fire an
* *extra* click event on its associated input (if any). mdGesture is able to flag the label
* click as with `$material` correctly, but not the second input click.
*
* In order to determine whether an input event is from a label click, we compare the (x, y) for
* the event to the (x, y) for the most recent label click (which is cleared whenever a non-label
* click occurs). Unfortunately, there are no event properties that tie the input and the label
* together (such as relatedTarget).
*
* @param {MouseEvent} event
* @returns {boolean}
*/
function isInputEventFromLabelClick(event) {
return lastLabelClickPos
&& lastLabelClickPos.x == event.x
&& lastLabelClickPos.y == event.y;
}
/*
* Update the given pointer based upon the given DOMEvent.
* Distance, velocity, direction, duration, etc
@@ -2876,12 +2927,13 @@ function InkRippleCtrl ($scope, $element, rippleOptions, $window, $timeout, $mdU
this.options = rippleOptions;
this.mousedown = false;
this.ripples = [];
this.container = null;
this.color = null;
this.background = null;
this.timeout = null; // Stores a reference to the most-recent ripple timeout
this.lastRipple = null;
$mdUtil.valueOnUse(this, 'container', this.createContainer);
$mdUtil.valueOnUse(this, 'color', this.getColor, 1);
$mdUtil.valueOnUse(this, 'background', this.getColor, 0.5);
// attach method for unit tests
($element.controller('mdInkRipple') || {}).createRipple = angular.bind(this, this.createRipple);
@@ -3015,10 +3067,6 @@ InkRippleCtrl.prototype.clearTimeout = function () {
* @param top
*/
InkRippleCtrl.prototype.createRipple = function (left, top) {
if (!this.container) this.container = this.createContainer();
if (!this.color) this.color = this.getColor();
if (!this.background) this.background = this.getColor(0.5);
var ctrl = this;
var ripple = angular.element('<div class="md-ripple"></div>');
var width = this.$element.prop('clientWidth');
@@ -3173,8 +3221,8 @@ angular.module('material.core.theming.palette', [])
'A400': '#ff1744',
'A700': '#d50000',
'contrastDefaultColor': 'light',
'contrastDarkColors': '50 100 200 300 400 A100',
'contrastStrongLightColors': '500 600 700 A200 A400 A700'
'contrastDarkColors': '50 100 200 300 A100',
'contrastStrongLightColors': '400 500 600 700 A200 A400 A700'
},
'pink': {
'50': '#fce4ec',
@@ -3192,7 +3240,7 @@ angular.module('material.core.theming.palette', [])
'A400': '#f50057',
'A700': '#c51162',
'contrastDefaultColor': 'light',
'contrastDarkColors': '50 100 200 300 400 A100',
'contrastDarkColors': '50 100 200 A100',
'contrastStrongLightColors': '500 600 A200 A400 A700'
},
'purple': {
@@ -3268,7 +3316,7 @@ angular.module('material.core.theming.palette', [])
'A400': '#2979ff',
'A700': '#2962ff',
'contrastDefaultColor': 'light',
'contrastDarkColors': '100 200 300 400 A100',
'contrastDarkColors': '50 100 200 300 400 A100',
'contrastStrongLightColors': '500 600 700 A200 A400 A700'
},
'light-blue': {
@@ -3287,8 +3335,8 @@ angular.module('material.core.theming.palette', [])
'A400': '#00b0ff',
'A700': '#0091ea',
'contrastDefaultColor': 'dark',
'contrastLightColors': '500 600 700 800 900 A700',
'contrastStrongLightColors': '500 600 700 800 A700'
'contrastLightColors': '600 700 800 900 A700',
'contrastStrongLightColors': '600 700 800 A700'
},
'cyan': {
'50': '#e0f7fa',
@@ -3306,8 +3354,8 @@ angular.module('material.core.theming.palette', [])
'A400': '#00e5ff',
'A700': '#00b8d4',
'contrastDefaultColor': 'dark',
'contrastLightColors': '500 600 700 800 900',
'contrastStrongLightColors': '500 600 700 800'
'contrastLightColors': '700 800 900',
'contrastStrongLightColors': '700 800 900'
},
'teal': {
'50': '#e0f2f1',
@@ -3344,8 +3392,8 @@ angular.module('material.core.theming.palette', [])
'A400': '#00e676',
'A700': '#00c853',
'contrastDefaultColor': 'dark',
'contrastLightColors': '500 600 700 800 900',
'contrastStrongLightColors': '500 600 700'
'contrastLightColors': '600 700 800 900',
'contrastStrongLightColors': '600 700'
},
'light-green': {
'50': '#f1f8e9',
@@ -3363,8 +3411,8 @@ angular.module('material.core.theming.palette', [])
'A400': '#76ff03',
'A700': '#64dd17',
'contrastDefaultColor': 'dark',
'contrastLightColors': '800 900',
'contrastStrongLightColors': '800 900'
'contrastLightColors': '700 800 900',
'contrastStrongLightColors': '700 800 900'
},
'lime': {
'50': '#f9fbe7',
@@ -5387,7 +5435,7 @@ angular
* </hljs>
*
*/
function MdCheckboxDirective(inputDirective, $mdInkRipple, $mdAria, $mdConstant, $mdTheming, $mdUtil, $timeout) {
function MdCheckboxDirective(inputDirective, $mdAria, $mdConstant, $mdTheming, $mdUtil, $timeout) {
inputDirective = inputDirective[0];
var CHECKED_CSS = 'md-checked';
@@ -5494,7 +5542,7 @@ function MdCheckboxDirective(inputDirective, $mdInkRipple, $mdAria, $mdConstant,
};
}
}
MdCheckboxDirective.$inject = ["inputDirective", "$mdInkRipple", "$mdAria", "$mdConstant", "$mdTheming", "$mdUtil", "$timeout"];
MdCheckboxDirective.$inject = ["inputDirective", "$mdAria", "$mdConstant", "$mdTheming", "$mdUtil", "$timeout"];
})();
(function(){
@@ -5953,7 +6001,7 @@ function iosScrollFix(node) {
* @param {Date=} opt_date
*/
CalendarCtrl.prototype.focus = function(opt_date) {
var date = opt_date || this.selectedDate;
var date = opt_date || this.selectedDate || this.today;
var previousFocus = this.calendarElement.querySelector('.md-focus');
if (previousFocus) {
@@ -6114,7 +6162,7 @@ function iosScrollFix(node) {
// of repeated items that are linked, and then those elements have their bindings updataed.
// Since the months are not generated by bindings, we simply regenerate the entire thing
// when the binding (offset) changes.
scope.$watch(function() { return monthCtrl.offset }, function(offset, oldOffset) {
scope.$watch(function() { return monthCtrl.offset; }, function(offset, oldOffset) {
if (offset != oldOffset) {
monthCtrl.generateContent();
}
@@ -6143,11 +6191,11 @@ function iosScrollFix(node) {
this.calendarCtrl = null;
/**
* Number of months from the start of the month "items"
* that the currently rendered month occurs.
* Number of months from the start of the month "items" that the currently rendered month
* occurs. Set via angular data binding.
* @type {number}
*/
this.offset = 0;
this.offset;
/**
* Date cell to focus after appending the month to the document.
@@ -6479,7 +6527,7 @@ function iosScrollFix(node) {
* @returns {string}
*/
function defaultFormatDate(date) {
return date.toLocaleDateString();
return date ? date.toLocaleDateString() : '';
}
/**
@@ -6609,6 +6657,7 @@ function iosScrollFix(node) {
* @module material.components.datepicker
*
* @param {Date} ng-model The component's model. Expects a JavaScript Date object.
* @param {expression=} ng-change Expression evaluated when the model value changes.
* @param {boolean=} disabled Whether the datepicker is disabled.
*
* @description
@@ -6637,7 +6686,8 @@ function iosScrollFix(node) {
'ng-class="{\'md-datepicker-focused\': ctrl.isFocused}">' +
'<input class="md-datepicker-input" aria-haspopup="true" ' +
'ng-focus="ctrl.setFocused(true)" ng-blur="ctrl.setFocused(false)">' +
'<md-button md-no-ink class="md-datepicker-triangle-button md-icon-button" ' +
'<md-button type="button" md-no-ink ' +
'class="md-datepicker-triangle-button md-icon-button" ' +
'ng-click="ctrl.openCalendarPane($event)" ' +
'aria-label="{{::ctrl.dateLocale.msgOpenCalendar}}">' +
'<div class="md-datepicker-expand-triangle"></div>' +
@@ -6646,7 +6696,9 @@ function iosScrollFix(node) {
// This pane will be detached from here and re-attached to the document body.
'<div class="md-datepicker-calendar-pane md-whiteframe-z1">' +
'<div class="md-datepicker-input-mask"></div>' +
'<div class="md-datepicker-input-mask">' +
'<div class="md-datepicker-input-mask-opaque"></div>' +
'</div>' +
'<div class="md-datepicker-calendar">' +
'<md-calendar role="dialog" aria-label="{{::ctrl.dateLocale.msgCalendar}}" ' +
'ng-model="ctrl.date" ng-if="ctrl.isCalendarOpen"></md-calendar>' +
@@ -6720,6 +6772,12 @@ function iosScrollFix(node) {
/** @type {HTMLElement} Calendar icon button. */
this.calendarButton = $element[0].querySelector('.md-datepicker-button');
/**
* Element covering everything but the input in the top of the floating calendar pane.
* @type {HTMLElement}
*/
this.inputMask = $element[0].querySelector('.md-datepicker-input-mask-opaque');
/** @final {!angular.JQLite} */
this.$element = $element;
@@ -6765,7 +6823,7 @@ function iosScrollFix(node) {
this.installPropertyInterceptors();
this.attachChangeListeners();
this.attachInterationListeners();
this.attachInteractionListeners();
var self = this;
$scope.$on('$destroy', function() {
@@ -6799,18 +6857,22 @@ function iosScrollFix(node) {
self.$scope.$on('md-calendar-change', function(event, date) {
self.ngModelCtrl.$setViewValue(date);
self.date = date;
self.inputElement.value = self.dateLocale.formatDate(date);
self.closeCalendarPane();
self.resizeInputElement();
self.inputContainer.classList.remove(INVALID_CLASS);
});
self.inputElement.addEventListener('input', angular.bind(self, self.resizeInputElement));
var ngElement = angular.element(self.inputElement);
ngElement.on('input', angular.bind(self, self.resizeInputElement));
// TODO(chenmike): Add ability for users to specify this interval.
self.inputElement.addEventListener('input', self.$mdUtil.debounce(self.handleInputEvent,
ngElement.on('input', self.$mdUtil.debounce(self.handleInputEvent,
DEFAULT_DEBOUNCE_INTERVAL, self));
};
/** Attach event listeners for user interaction. */
DatePickerCtrl.prototype.attachInterationListeners = function() {
DatePickerCtrl.prototype.attachInteractionListeners = function() {
var self = this;
var $scope = this.$scope;
var keyCodes = this.$mdConstant.KEY_CODE;
@@ -6845,7 +6907,7 @@ function iosScrollFix(node) {
Object.defineProperty(this, 'placeholder', {
get: function() { return self.inputElement.placeholder; },
set: function(value) { self.inputElement.placeholder = value; }
set: function(value) { self.inputElement.placeholder = value || ''; }
});
};
@@ -6878,7 +6940,6 @@ function iosScrollFix(node) {
this.ngModelCtrl.$setViewValue(parsedDate);
this.date = parsedDate;
this.inputContainer.classList.remove(INVALID_CLASS);
this.$scope.$apply();
} else {
// If there's an input string, it's an invalid date.
this.inputContainer.classList.toggle(INVALID_CLASS, inputString);
@@ -6897,6 +6958,12 @@ function iosScrollFix(node) {
calendarPane.style.top = (elementRect.top - bodyRect.top) + 'px';
document.body.appendChild(this.calendarPane);
// The top of the calendar pane is a transparent box that shows the text input underneath.
// Since the pane is flowing, though, the page underneath the pane *adjacent* to the input is
// also shown unless we cover it up. The inputMask does this by filling up the remaining space
// based on the width of the input.
this.inputMask.style.left = elementRect.width + 'px';
// Add CSS class after one frame to trigger open animation.
this.$$rAF(function() {
calendarPane.classList.add('md-pane-open');
@@ -6908,9 +6975,11 @@ function iosScrollFix(node) {
this.$element.removeClass('md-datepicker-open');
this.calendarPane.classList.remove('md-pane-open');
// Use native DOM removal because we do not want any of the angular state of this element
// to be disposed.
this.calendarPane.parentNode.removeChild(this.calendarPane);
if (this.calendarPane.parentNode) {
// Use native DOM removal because we do not want any of the angular state of this element
// to be disposed.
this.calendarPane.parentNode.removeChild(this.calendarPane);
}
};
/**
@@ -7182,7 +7251,7 @@ function iosScrollFix(node) {
* @return {boolean} Whether the date is a valid Date.
*/
function isValidDate(date) {
return date !== null && date.getTime && !isNaN(date.getTime());
return date != null && date.getTime && !isNaN(date.getTime());
}
/**
@@ -8746,7 +8815,7 @@ MdDividerDirective.$inject = ["$mdTheming"];
'</div>',
scope: {
direction: '=?mdDirection',
direction: '@?mdDirection',
isOpen: '=?mdOpen'
},
@@ -10662,6 +10731,7 @@ function inputTextareaDirective($mdUtil, $window, $mdAria) {
function postLink(scope, element, attr, ctrls) {
var containerCtrl = ctrls[0];
var hasNgModel = !!ctrls[1];
var ngModelCtrl = ctrls[1] || $mdUtil.fakeNgModel();
var isReadonly = angular.isDefined(attr.readonly);
@@ -10684,6 +10754,13 @@ function inputTextareaDirective($mdUtil, $window, $mdAria) {
setupTextarea();
}
// If the input doesn't have an ngModel, it may have a static value. For that case,
// we have to do one initial check to determine if the container should be in the
// "has a value" state.
if (!hasNgModel) {
inputCheckValue();
}
var isErrorGetter = containerCtrl.isErrorGetter || function() {
return ngModelCtrl.$invalid && ngModelCtrl.$touched;
};
@@ -11311,7 +11388,7 @@ angular.module('material.components.menu', [
*
*/
function MenuDirective($mdMenu) {
function MenuDirective() {
var INVALID_PREFIX = 'Invalid HTML for md-menu: ';
return {
restrict: 'E',
@@ -11352,7 +11429,6 @@ function MenuDirective($mdMenu) {
}
}
MenuDirective.$inject = ["$mdMenu"];
function MenuController($mdMenu, $attrs, $element, $scope) {
var menuContainer;
@@ -13114,7 +13190,7 @@ function OptionDirective($mdButtonInkRipple, $mdUtil) {
if (angular.isDefined(attr.ngValue)) {
scope.$watch(attr.ngValue, setOptionValue);
} else if (angular.isDefined(attr.value)) {
setOptionValue(attr.value);
setOptionValue(isNaN(attr.value) ? attr.value : Number(attr.value));
} else {
scope.$watch(function() {
return element.text();
@@ -13564,6 +13640,7 @@ function SelectProvider($$interimElementProvider) {
function checkCloseMenu(ev) {
if (ev && ( ev.type == 'mouseup') && (ev.currentTarget != dropDown[0])) return;
if ( mouseOnScrollbar() ) return;
if (!selectCtrl.isMultiple) {
opts.restoreFocus = true;
@@ -13572,6 +13649,23 @@ function SelectProvider($$interimElementProvider) {
$mdSelect.hide(selectCtrl.ngModel.$viewValue);
}, true);
}
/**
* check if the mouseup event was on a scrollbar
*/
function mouseOnScrollbar() {
var clickOnScrollbar = false;
if(ev.currentTarget.children.length > 0) {
var child = ev.currentTarget.children[0];
var hasScrollbar = child.scrollHeight > child.clientHeight;
if (hasScrollbar && child.children.length > 0) {
var relPosX = ev.pageX - ev.currentTarget.getBoundingClientRect().left;
if(relPosX > child.children[0].offsetWidth)
clickOnScrollbar = true;
}
}
return clickOnScrollbar;
}
}
}
@@ -14945,46 +15039,57 @@ angular.module('material.components.subheader', [
* </hljs>
*/
function MdSubheaderDirective($mdSticky, $compile, $mdTheming) {
function MdSubheaderDirective($mdSticky, $compile, $mdTheming, $mdUtil) {
return {
restrict: 'E',
replace: true,
transclude: true,
template:
'<h2 class="md-subheader">' +
'<div class="md-subheader-inner">' +
'<span class="md-subheader-content"></span>' +
'</div>' +
'</h2>',
compile: function(element, attr, transclude) {
return function postLink(scope, element, attr) {
$mdTheming(element);
var outerHTML = element[0].outerHTML;
template: (
'<h2 class="md-subheader">' +
' <div class="md-subheader-inner">' +
' <span class="md-subheader-content"></span>' +
' </div>' +
'</h2>'
),
link: function postLink(scope, element, attr, controllers, transclude) {
$mdTheming(element);
var outerHTML = element[0].outerHTML;
function getContent(el) {
return angular.element(el[0].querySelector('.md-subheader-content'));
}
function getContent(el) {
return angular.element(el[0].querySelector('.md-subheader-content'));
}
// Transclude the user-given contents of the subheader
// the conventional way.
// Transclude the user-given contents of the subheader
// the conventional way.
transclude(scope, function(clone) {
getContent(element).append(clone);
});
// Create another clone, that uses the outer and inner contents
// of the element, that will be 'stickied' as the user scrolls.
if (!element.hasClass('md-no-sticky')) {
transclude(scope, function(clone) {
getContent(element).append(clone);
});
// If the user adds an ng-if or ng-repeat directly to the md-subheader element, the
// compiled clone below will only be a comment tag (since they replace their elements with
// a comment) which cannot be properly passed to the $mdSticky; so we wrap it in our own
// DIV to ensure we have something $mdSticky can use
var wrapperHtml = '<div class="md-subheader-wrapper">' + outerHTML + '</div>';
var stickyClone = $compile(wrapperHtml)(scope);
// Create another clone, that uses the outer and inner contents
// of the element, that will be 'stickied' as the user scrolls.
if (!element.hasClass('md-no-sticky')) {
transclude(scope, function(clone) {
var stickyClone = $compile(angular.element(outerHTML))(scope);
// Append the sticky
$mdSticky(scope, element, stickyClone);
// Delay initialization until after any `ng-if`/`ng-repeat`/etc has finished before
// attempting to create the clone
$mdUtil.nextTick(function() {
getContent(stickyClone).append(clone);
$mdSticky(scope, element, stickyClone);
});
}
};
});
}
}
};
}
}
MdSubheaderDirective.$inject = ["$mdSticky", "$compile", "$mdTheming"];
MdSubheaderDirective.$inject = ["$mdSticky", "$compile", "$mdTheming", "$mdUtil"];
})();
(function(){
@@ -15822,7 +15927,25 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe
function bindEvents () {
var mouseActive = false;
var enterHandler = function() {
var ngWindow = angular.element($window);
// Store whether the element was focused when the window loses focus.
var windowBlurHandler = function() {
elementFocusedOnWindowBlur = document.activeElement === parent[0];
};
var elementFocusedOnWindowBlur = false;
ngWindow.on('blur', windowBlurHandler);
scope.$on('$destroy', function() {
ngWindow.off('blur', windowBlurHandler);
});
var enterHandler = function(e) {
// Prevent the tooltip from showing when the window is receiving focus.
if (e.type === 'focus' && elementFocusedOnWindowBlur) {
elementFocusedOnWindowBlur = false;
return;
}
parent.on('blur mouseleave touchend touchcancel', leaveHandler );
setVisible(true);
};
@@ -16271,6 +16394,15 @@ VirtualRepeatContainerController.prototype.handleScroll_ = function() {
* @param {string=} md-extra-name Evaluates to an additional name to which
* the current iterated item can be assigned on the repeated scope. (Needed
* for use in md-autocomplete).
* @param {boolean=} md-on-demand When present, treats the md-virtual-repeat argument
* as an object that can fetch rows rather than an array.
* NOTE: This object must implement the following interface with two (2) methods:
* getItemAtIndex: function(index) -> item at that index or null if it is not yet
* loaded (It should start downloading the item in that case).
* getLength: function() -> number The data legnth to which the repeater container
* should be sized. Ideally, when the count is known, this method should return it.
* Otherwise, return a higher number than the currently loaded items to produce an
* infinite-scroll behavior.
*/
function VirtualRepeatDirective($parse) {
return {
@@ -16305,12 +16437,16 @@ function VirtualRepeatController($scope, $element, $attrs, $browser, $document,
this.$document = $document;
this.$$rAF = $$rAF;
/** @type {boolean} Whether we are in on-demand mode. */
this.onDemand = $attrs.hasOwnProperty('mdOnDemand');
/** @type {!Function} Backup reference to $browser.$$checkUrlChange */
this.browserCheckUrlChange = $browser.$$checkUrlChange;
/** @type {number} Most recent starting repeat index (based on scroll offset) */
this.newStartIndex = 0;
/** @type {number} Most recent ending repeat index (based on scroll offset) */
this.newEndIndex = 0;
/** @type {number} Most recent end visible index (based on scroll offset) */
this.newVisibleEnd = 0;
/** @type {number} Previous starting repeat index (based on scroll offset) */
this.startIndex = 0;
/** @type {number} Previous ending repeat index (based on scroll offset) */
@@ -16365,10 +16501,12 @@ VirtualRepeatController.prototype.link_ =
this.container = container;
this.transclude = transclude;
this.repeatName = repeatName;
this.repeatListExpression = repeatListExpression;
this.rawRepeatListExpression = repeatListExpression;
this.extraName = extraName;
this.sized = false;
this.repeatListExpression = angular.bind(this, this.repeatListExpression_);
this.container.register(this);
};
@@ -16396,6 +16534,25 @@ VirtualRepeatController.prototype.readItemSize_ = function() {
};
/**
* Returns the user-specified repeat list, transforming it into an array-like
* object in the case of infinite scroll/dynamic load mode.
* @param {!angular.Scope} The scope.
* @return {!Array|!Object} An array or array-like object for iteration.
*/
VirtualRepeatController.prototype.repeatListExpression_ = function(scope) {
var repeatList = this.rawRepeatListExpression(scope);
if (this.onDemand && repeatList) {
var virtualList = new VirtualRepeatModelArrayLike(repeatList);
virtualList.$$includeIndexes(this.newStartIndex, this.newVisibleEnd);
return virtualList;
} else {
return repeatList;
}
};
/**
* Called by the container. Informs us that the containers scroll or size has
* changed.
@@ -16429,6 +16586,9 @@ VirtualRepeatController.prototype.containerUpdated = function() {
if (this.newStartIndex !== this.startIndex ||
this.newEndIndex !== this.endIndex ||
this.container.getScrollOffset() > this.container.getScrollSize()) {
if (this.items instanceof VirtualRepeatModelArrayLike) {
this.items.$$includeIndexes(this.newStartIndex, this.newEndIndex);
}
this.virtualRepeatUpdate_(this.items, this.items);
}
};
@@ -16465,7 +16625,7 @@ VirtualRepeatController.prototype.virtualRepeatUpdate_ = function(items, oldItem
}
this.items = items;
if (items !== oldItems) {
if (items !== oldItems || lengthChanged) {
this.updateIndexes_();
}
@@ -16646,10 +16806,59 @@ VirtualRepeatController.prototype.updateIndexes_ = function() {
this.newStartIndex = Math.max(0, Math.min(
itemsLength - containerLength,
Math.floor(this.container.getScrollOffset() / this.itemSize)));
this.newEndIndex = Math.min(itemsLength, this.newStartIndex + containerLength + NUM_EXTRA);
this.newVisibleEnd = this.newStartIndex + containerLength + NUM_EXTRA;
this.newEndIndex = Math.min(itemsLength, this.newVisibleEnd);
this.newStartIndex = Math.max(0, this.newStartIndex - NUM_EXTRA);
};
/**
* This VirtualRepeatModelArrayLike class enforces the interface requirements
* for infinite scrolling within a mdVirtualRepeatContainer. An object with this
* interface must implement the following interface with two (2) methods:
*
* getItemAtIndex: function(index) -> item at that index or null if it is not yet
* loaded (It should start downloading the item in that case).
*
* getLength: function() -> number The data legnth to which the repeater container
* should be sized. Ideally, when the count is known, this method should return it.
* Otherwise, return a higher number than the currently loaded items to produce an
* infinite-scroll behavior.
*
* @usage
* <hljs lang="html">
* <md-virtual-repeat-container md-orient-horizontal>
* <div md-virtual-repeat="i in items" md-on-demand>
* Hello {{i}}!
* </div>
* </md-virtual-repeat-container>
* </hljs>
*
*/
function VirtualRepeatModelArrayLike(model) {
if (!angular.isFunction(model.getItemAtIndex) ||
!angular.isFunction(model.getLength)) {
throw Error('When md-on-demand is enabled, the Object passed to md-virtual-repeat must implement ' +
'functions getItemAtIndex() and getLength() ');
}
this.model = model;
}
VirtualRepeatModelArrayLike.prototype.$$includeIndexes = function(start, end) {
for (var i = start; i < end; i++) {
if (!this.hasOwnProperty(i)) {
this[i] = this.model.getItemAtIndex(i);
}
}
this.length = this.model.getLength();
};
function abstractMethod() {
throw Error('Non-overridden abstract method called.');
}
})();
(function(){
"use strict";
@@ -17857,6 +18066,7 @@ function MdChipTransclude ($compile) {
newScope = ctrl.parent.$new(false, ctrl.parent);
newScope.$$replacedScope = scope;
newScope.$chip = scope.$chip;
newScope.$index = scope.$index;
newScope.$mdChipsCtrl = ctrl;
var newHtml = ctrl.$scope.$eval(attr.mdChipTransclude);
@@ -19906,7 +20116,7 @@ MdTabsTemplate.$inject = ["$compile", "$mdUtil"];
})();
(function(){
angular.module("material.core").constant("$MD_THEME_CSS", "/* mixin definition ; sets LTR and RTL within the same style call *//** * Position a FAB button. */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}}'; }md-backdrop { background-color: '{{background-900-0.0}}'; } md-backdrop.md-opaque.md-THEME_NAME-theme { background-color: '{{background-900-0.48}}'; } md-backdrop.md-opaque.md-THEME_NAME-theme.ng-enter { background-color: '{{background-900-0.0}}'; } md-backdrop.md-opaque.md-THEME_NAME-theme.ng-enter.md-opaque.md-THEME_NAME-theme.ng-enter-active { background-color: '{{background-900-0.48}}'; } md-backdrop.md-opaque.md-THEME_NAME-theme.ng-leave.md-opaque.md-THEME_NAME-theme.ng-leave-active { background-color: '{{background-900-0.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}}'; } md-bottom-sheet.md-THEME_NAME-theme .md-subheader { color: '{{foreground-1}}'; }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 { 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-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 { 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-THEMLine truncated
angular.module("material.core").constant("$MD_THEME_CSS", "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}}'; }md-backdrop { background-color: '{{background-900-0.0}}'; } md-backdrop.md-opaque.md-THEME_NAME-theme { background-color: '{{background-900-0.48}}'; } md-backdrop.md-opaque.md-THEME_NAME-theme.ng-enter { background-color: '{{background-900-0.0}}'; } md-backdrop.md-opaque.md-THEME_NAME-theme.ng-enter.md-opaque.md-THEME_NAME-theme.ng-enter-active { background-color: '{{background-900-0.48}}'; } md-backdrop.md-opaque.md-THEME_NAME-theme.ng-leave.md-opaque.md-THEME_NAME-theme.ng-leave-active { background-color: '{{background-900-0.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}}'; } md-bottom-sheet.md-THEME_NAME-theme .md-subheader { color: '{{foreground-1}}'; }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 { 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-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 { 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]):hoLine truncated
})();