aboutsummaryrefslogtreecommitdiffstats
path: root/vnfmarket/src/main/webapp/common/thirdparty/angular-material/modules/closure/gridList/gridList.js
diff options
context:
space:
mode:
Diffstat (limited to 'vnfmarket/src/main/webapp/common/thirdparty/angular-material/modules/closure/gridList/gridList.js')
-rw-r--r--vnfmarket/src/main/webapp/common/thirdparty/angular-material/modules/closure/gridList/gridList.js774
1 files changed, 774 insertions, 0 deletions
diff --git a/vnfmarket/src/main/webapp/common/thirdparty/angular-material/modules/closure/gridList/gridList.js b/vnfmarket/src/main/webapp/common/thirdparty/angular-material/modules/closure/gridList/gridList.js
new file mode 100644
index 00000000..3adbd271
--- /dev/null
+++ b/vnfmarket/src/main/webapp/common/thirdparty/angular-material/modules/closure/gridList/gridList.js
@@ -0,0 +1,774 @@
+/*!
+ * Angular Material Design
+ * https://github.com/angular/material
+ * @license MIT
+ * v1.1.3
+ */
+goog.provide('ngmaterial.components.gridList');
+goog.require('ngmaterial.core');
+/**
+ * @ngdoc module
+ * @name material.components.gridList
+ */
+GridListController['$inject'] = ["$mdUtil"];
+GridLayoutFactory['$inject'] = ["$mdUtil"];
+GridListDirective['$inject'] = ["$interpolate", "$mdConstant", "$mdGridLayout", "$mdMedia"];
+GridTileDirective['$inject'] = ["$mdMedia"];
+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.
+ *
+ * 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) {
+ element.addClass('_md'); // private md component indicator for styling
+
+ // 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', 'md-gutter'], 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, 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 = {};
+
+ switch(rowMode) {
+ case 'fixed':
+ style.height = DIMENSION({ unit: rowHeight, span: rowCount, gutter: gutter });
+ style.paddingBottom = '';
+ 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.height = '';
+ 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' && !ele.$$mdDestroyed;
+ });
+ }
+
+ /**
+ * 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');
+ if (!rowHeight) {
+ throw 'md-grid-list: md-row-height attribute was not found';
+ }
+
+ 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) {
+ throw 'md-grid-list: md-row-height attribute was not found';
+ }
+
+ 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';
+ }
+ }
+}
+
+/* ngInject */
+function GridListController($mdUtil) {
+ this.layoutInvalidated = false;
+ this.tilesInvalidated = false;
+ this.$timeout_ = $mdUtil.nextTick;
+ this.layoutDelegate = angular.noop;
+}
+
+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;
+ }
+ }
+}
+
+/**
+ * @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.
+ *
+ * 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() {
+ // Mark the tile as destroyed so it is no longer considered in layout,
+ // even if the DOM element sticks around (like during a leave animation)
+ element[0].$$mdDestroyed = true;
+ 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();
+ });
+ }
+ }
+}
+
+
+function GridTileCaptionDirective() {
+ return {
+ template: '<figcaption ng-transclude></figcaption>',
+ transclude: true
+ };
+}
+
+ngmaterial.components.gridList = angular.module("material.components.gridList"); \ No newline at end of file