--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cm/media/js/lib/yui/yui_3.10.3/build/datatable-body/datatable-body-debug.js Tue Jul 16 14:29:46 2013 +0200
@@ -0,0 +1,919 @@
+/*
+YUI 3.10.3 (build 2fb5187)
+Copyright 2013 Yahoo! Inc. All rights reserved.
+Licensed under the BSD License.
+http://yuilibrary.com/license/
+*/
+
+YUI.add('datatable-body', function (Y, NAME) {
+
+/**
+View class responsible for rendering the `<tbody>` section of a table. Used as
+the default `bodyView` for `Y.DataTable.Base` and `Y.DataTable` classes.
+
+@module datatable
+@submodule datatable-body
+@since 3.5.0
+**/
+var Lang = Y.Lang,
+ isArray = Lang.isArray,
+ isNumber = Lang.isNumber,
+ isString = Lang.isString,
+ fromTemplate = Lang.sub,
+ htmlEscape = Y.Escape.html,
+ toArray = Y.Array,
+ bind = Y.bind,
+ YObject = Y.Object,
+ valueRegExp = /\{value\}/g;
+
+/**
+View class responsible for rendering the `<tbody>` section of a table. Used as
+the default `bodyView` for `Y.DataTable.Base` and `Y.DataTable` classes.
+
+Translates the provided `modelList` into a rendered `<tbody>` based on the data
+in the constituent Models, altered or ammended by any special column
+configurations.
+
+The `columns` configuration, passed to the constructor, determines which
+columns will be rendered.
+
+The rendering process involves constructing an HTML template for a complete row
+of data, built by concatenating a customized copy of the instance's
+`CELL_TEMPLATE` into the `ROW_TEMPLATE` once for each column. This template is
+then populated with values from each Model in the `modelList`, aggregating a
+complete HTML string of all row and column data. A `<tbody>` Node is then created from the markup and any column `nodeFormatter`s are applied.
+
+Supported properties of the column objects include:
+
+ * `key` - Used to link a column to an attribute in a Model.
+ * `name` - Used for columns that don't relate to an attribute in the Model
+ (`formatter` or `nodeFormatter` only) if the implementer wants a
+ predictable name to refer to in their CSS.
+ * `cellTemplate` - Overrides the instance's `CELL_TEMPLATE` for cells in this
+ column only.
+ * `formatter` - Used to customize or override the content value from the
+ Model. These do not have access to the cell or row Nodes and should
+ return string (HTML) content.
+ * `nodeFormatter` - Used to provide content for a cell as well as perform any
+ custom modifications on the cell or row Node that could not be performed by
+ `formatter`s. Should be used sparingly for better performance.
+ * `emptyCellValue` - String (HTML) value to use if the Model data for a
+ column, or the content generated by a `formatter`, is the empty string,
+ `null`, or `undefined`.
+ * `allowHTML` - Set to `true` if a column value, `formatter`, or
+ `emptyCellValue` can contain HTML. This defaults to `false` to protect
+ against XSS.
+ * `className` - Space delimited CSS classes to add to all `<td>`s in a column.
+
+A column `formatter` can be:
+
+ * a function, as described below.
+ * a string which can be:
+ * the name of a pre-defined formatter function
+ which can be located in the `Y.DataTable.BodyView.Formatters` hash using the
+ value of the `formatter` property as the index.
+ * A template that can use the `{value}` placeholder to include the value
+ for the current cell or the name of any field in the underlaying model
+ also enclosed in curly braces. Any number and type of these placeholders
+ can be used.
+
+Column `formatter`s are passed an object (`o`) with the following properties:
+
+ * `value` - The current value of the column's associated attribute, if any.
+ * `data` - An object map of Model keys to their current values.
+ * `record` - The Model instance.
+ * `column` - The column configuration object for the current column.
+ * `className` - Initially empty string to allow `formatter`s to add CSS
+ classes to the cell's `<td>`.
+ * `rowIndex` - The zero-based row number.
+ * `rowClass` - Initially empty string to allow `formatter`s to add CSS
+ classes to the cell's containing row `<tr>`.
+
+They may return a value or update `o.value` to assign specific HTML content. A
+returned value has higher precedence.
+
+Column `nodeFormatter`s are passed an object (`o`) with the following
+properties:
+
+ * `value` - The current value of the column's associated attribute, if any.
+ * `td` - The `<td>` Node instance.
+ * `cell` - The `<div>` liner Node instance if present, otherwise, the `<td>`.
+ When adding content to the cell, prefer appending into this property.
+ * `data` - An object map of Model keys to their current values.
+ * `record` - The Model instance.
+ * `column` - The column configuration object for the current column.
+ * `rowIndex` - The zero-based row number.
+
+They are expected to inject content into the cell's Node directly, including
+any "empty" cell content. Each `nodeFormatter` will have access through the
+Node API to all cells and rows in the `<tbody>`, but not to the `<table>`, as
+it will not be attached yet.
+
+If a `nodeFormatter` returns `false`, the `o.td` and `o.cell` Nodes will be
+`destroy()`ed to remove them from the Node cache and free up memory. The DOM
+elements will remain as will any content added to them. _It is highly
+advisable to always return `false` from your `nodeFormatter`s_.
+
+@class BodyView
+@namespace DataTable
+@extends View
+@since 3.5.0
+**/
+Y.namespace('DataTable').BodyView = Y.Base.create('tableBody', Y.View, [], {
+ // -- Instance properties -------------------------------------------------
+
+ /**
+ HTML template used to create table cells.
+
+ @property CELL_TEMPLATE
+ @type {HTML}
+ @default '<td {headers} class="{className}">{content}</td>'
+ @since 3.5.0
+ **/
+ CELL_TEMPLATE: '<td {headers} class="{className}">{content}</td>',
+
+ /**
+ CSS class applied to even rows. This is assigned at instantiation.
+
+ For DataTable, this will be `yui3-datatable-even`.
+
+ @property CLASS_EVEN
+ @type {String}
+ @default 'yui3-table-even'
+ @since 3.5.0
+ **/
+ //CLASS_EVEN: null
+
+ /**
+ CSS class applied to odd rows. This is assigned at instantiation.
+
+ When used by DataTable instances, this will be `yui3-datatable-odd`.
+
+ @property CLASS_ODD
+ @type {String}
+ @default 'yui3-table-odd'
+ @since 3.5.0
+ **/
+ //CLASS_ODD: null
+
+ /**
+ HTML template used to create table rows.
+
+ @property ROW_TEMPLATE
+ @type {HTML}
+ @default '<tr id="{rowId}" data-yui3-record="{clientId}" class="{rowClass}">{content}</tr>'
+ @since 3.5.0
+ **/
+ ROW_TEMPLATE : '<tr id="{rowId}" data-yui3-record="{clientId}" class="{rowClass}">{content}</tr>',
+
+ /**
+ The object that serves as the source of truth for column and row data.
+ This property is assigned at instantiation from the `host` property of
+ the configuration object passed to the constructor.
+
+ @property host
+ @type {Object}
+ @default (initially unset)
+ @since 3.5.0
+ **/
+ //TODO: should this be protected?
+ //host: null,
+
+ /**
+ HTML templates used to create the `<tbody>` containing the table rows.
+
+ @property TBODY_TEMPLATE
+ @type {HTML}
+ @default '<tbody class="{className}">{content}</tbody>'
+ @since 3.6.0
+ **/
+ TBODY_TEMPLATE: '<tbody class="{className}"></tbody>',
+
+ // -- Public methods ------------------------------------------------------
+
+ /**
+ Returns the `<td>` Node from the given row and column index. Alternately,
+ the `seed` can be a Node. If so, the nearest ancestor cell is returned.
+ If the `seed` is a cell, it is returned. If there is no cell at the given
+ coordinates, `null` is returned.
+
+ Optionally, include an offset array or string to return a cell near the
+ cell identified by the `seed`. The offset can be an array containing the
+ number of rows to shift followed by the number of columns to shift, or one
+ of "above", "below", "next", or "previous".
+
+ <pre><code>// Previous cell in the previous row
+ var cell = table.getCell(e.target, [-1, -1]);
+
+ // Next cell
+ var cell = table.getCell(e.target, 'next');
+ var cell = table.getCell(e.taregt, [0, 1];</pre></code>
+
+ @method getCell
+ @param {Number[]|Node} seed Array of row and column indexes, or a Node that
+ is either the cell itself or a descendant of one.
+ @param {Number[]|String} [shift] Offset by which to identify the returned
+ cell Node
+ @return {Node}
+ @since 3.5.0
+ **/
+ getCell: function (seed, shift) {
+ var tbody = this.tbodyNode,
+ row, cell, index, rowIndexOffset;
+
+ if (seed && tbody) {
+ if (isArray(seed)) {
+ row = tbody.get('children').item(seed[0]);
+ cell = row && row.get('children').item(seed[1]);
+ } else if (Y.instanceOf(seed, Y.Node)) {
+ cell = seed.ancestor('.' + this.getClassName('cell'), true);
+ }
+
+ if (cell && shift) {
+ rowIndexOffset = tbody.get('firstChild.rowIndex');
+ if (isString(shift)) {
+ // TODO this should be a static object map
+ switch (shift) {
+ case 'above' : shift = [-1, 0]; break;
+ case 'below' : shift = [1, 0]; break;
+ case 'next' : shift = [0, 1]; break;
+ case 'previous': shift = [0, -1]; break;
+ }
+ }
+
+ if (isArray(shift)) {
+ index = cell.get('parentNode.rowIndex') +
+ shift[0] - rowIndexOffset;
+ row = tbody.get('children').item(index);
+
+ index = cell.get('cellIndex') + shift[1];
+ cell = row && row.get('children').item(index);
+ }
+ }
+ }
+
+ return cell || null;
+ },
+
+ /**
+ Returns the generated CSS classname based on the input. If the `host`
+ attribute is configured, it will attempt to relay to its `getClassName`
+ or use its static `NAME` property as a string base.
+
+ If `host` is absent or has neither method nor `NAME`, a CSS classname
+ will be generated using this class's `NAME`.
+
+ @method getClassName
+ @param {String} token* Any number of token strings to assemble the
+ classname from.
+ @return {String}
+ @protected
+ @since 3.5.0
+ **/
+ getClassName: function () {
+ var host = this.host,
+ args;
+
+ if (host && host.getClassName) {
+ return host.getClassName.apply(host, arguments);
+ } else {
+ args = toArray(arguments);
+ args.unshift(this.constructor.NAME);
+ return Y.ClassNameManager.getClassName
+ .apply(Y.ClassNameManager, args);
+ }
+ },
+
+ /**
+ Returns the Model associated to the row Node or id provided. Passing the
+ Node or id for a descendant of the row also works.
+
+ If no Model can be found, `null` is returned.
+
+ @method getRecord
+ @param {String|Node} seed Row Node or `id`, or one for a descendant of a row
+ @return {Model}
+ @since 3.5.0
+ **/
+ getRecord: function (seed) {
+ var modelList = this.get('modelList'),
+ tbody = this.tbodyNode,
+ row = null,
+ record;
+
+ if (tbody) {
+ if (isString(seed)) {
+ seed = tbody.one('#' + seed);
+ }
+
+ if (Y.instanceOf(seed, Y.Node)) {
+ row = seed.ancestor(function (node) {
+ return node.get('parentNode').compareTo(tbody);
+ }, true);
+
+ record = row &&
+ modelList.getByClientId(row.getData('yui3-record'));
+ }
+ }
+
+ return record || null;
+ },
+
+ /**
+ Returns the `<tr>` Node from the given row index, Model, or Model's
+ `clientId`. If the rows haven't been rendered yet, or if the row can't be
+ found by the input, `null` is returned.
+
+ @method getRow
+ @param {Number|String|Model} id Row index, Model instance, or clientId
+ @return {Node}
+ @since 3.5.0
+ **/
+ getRow: function (id) {
+ var tbody = this.tbodyNode,
+ row = null;
+
+ if (tbody) {
+ if (id) {
+ id = this._idMap[id.get ? id.get('clientId') : id] || id;
+ }
+
+ row = isNumber(id) ?
+ tbody.get('children').item(id) :
+ tbody.one('#' + id);
+ }
+
+ return row;
+ },
+
+ /**
+ Creates the table's `<tbody>` content by assembling markup generated by
+ populating the `ROW\_TEMPLATE`, and `CELL\_TEMPLATE` templates with content
+ from the `columns` and `modelList` attributes.
+
+ The rendering process happens in three stages:
+
+ 1. A row template is assembled from the `columns` attribute (see
+ `_createRowTemplate`)
+
+ 2. An HTML string is built up by concatening the application of the data in
+ each Model in the `modelList` to the row template. For cells with
+ `formatter`s, the function is called to generate cell content. Cells
+ with `nodeFormatter`s are ignored. For all other cells, the data value
+ from the Model attribute for the given column key is used. The
+ accumulated row markup is then inserted into the container.
+
+ 3. If any column is configured with a `nodeFormatter`, the `modelList` is
+ iterated again to apply the `nodeFormatter`s.
+
+ Supported properties of the column objects include:
+
+ * `key` - Used to link a column to an attribute in a Model.
+ * `name` - Used for columns that don't relate to an attribute in the Model
+ (`formatter` or `nodeFormatter` only) if the implementer wants a
+ predictable name to refer to in their CSS.
+ * `cellTemplate` - Overrides the instance's `CELL_TEMPLATE` for cells in
+ this column only.
+ * `formatter` - Used to customize or override the content value from the
+ Model. These do not have access to the cell or row Nodes and should
+ return string (HTML) content.
+ * `nodeFormatter` - Used to provide content for a cell as well as perform
+ any custom modifications on the cell or row Node that could not be
+ performed by `formatter`s. Should be used sparingly for better
+ performance.
+ * `emptyCellValue` - String (HTML) value to use if the Model data for a
+ column, or the content generated by a `formatter`, is the empty string,
+ `null`, or `undefined`.
+ * `allowHTML` - Set to `true` if a column value, `formatter`, or
+ `emptyCellValue` can contain HTML. This defaults to `false` to protect
+ against XSS.
+ * `className` - Space delimited CSS classes to add to all `<td>`s in a
+ column.
+
+ Column `formatter`s are passed an object (`o`) with the following
+ properties:
+
+ * `value` - The current value of the column's associated attribute, if
+ any.
+ * `data` - An object map of Model keys to their current values.
+ * `record` - The Model instance.
+ * `column` - The column configuration object for the current column.
+ * `className` - Initially empty string to allow `formatter`s to add CSS
+ classes to the cell's `<td>`.
+ * `rowIndex` - The zero-based row number.
+ * `rowClass` - Initially empty string to allow `formatter`s to add CSS
+ classes to the cell's containing row `<tr>`.
+
+ They may return a value or update `o.value` to assign specific HTML
+ content. A returned value has higher precedence.
+
+ Column `nodeFormatter`s are passed an object (`o`) with the following
+ properties:
+
+ * `value` - The current value of the column's associated attribute, if
+ any.
+ * `td` - The `<td>` Node instance.
+ * `cell` - The `<div>` liner Node instance if present, otherwise, the
+ `<td>`. When adding content to the cell, prefer appending into this
+ property.
+ * `data` - An object map of Model keys to their current values.
+ * `record` - The Model instance.
+ * `column` - The column configuration object for the current column.
+ * `rowIndex` - The zero-based row number.
+
+ They are expected to inject content into the cell's Node directly, including
+ any "empty" cell content. Each `nodeFormatter` will have access through the
+ Node API to all cells and rows in the `<tbody>`, but not to the `<table>`,
+ as it will not be attached yet.
+
+ If a `nodeFormatter` returns `false`, the `o.td` and `o.cell` Nodes will be
+ `destroy()`ed to remove them from the Node cache and free up memory. The
+ DOM elements will remain as will any content added to them. _It is highly
+ advisable to always return `false` from your `nodeFormatter`s_.
+
+ @method render
+ @return {BodyView} The instance
+ @chainable
+ @since 3.5.0
+ **/
+ render: function () {
+ var table = this.get('container'),
+ data = this.get('modelList'),
+ columns = this.get('columns'),
+ tbody = this.tbodyNode ||
+ (this.tbodyNode = this._createTBodyNode());
+
+ // Needed for mutation
+ this._createRowTemplate(columns);
+
+ if (data) {
+ tbody.setHTML(this._createDataHTML(columns));
+
+ this._applyNodeFormatters(tbody, columns);
+ }
+
+ if (tbody.get('parentNode') !== table) {
+ table.appendChild(tbody);
+ }
+
+ this._afterRenderCleanup();
+
+ this.bindUI();
+
+ return this;
+ },
+
+ // -- Protected and private methods ---------------------------------------
+ /**
+ Handles changes in the source's columns attribute. Redraws the table data.
+
+ @method _afterColumnsChange
+ @param {EventFacade} e The `columnsChange` event object
+ @protected
+ @since 3.5.0
+ **/
+ // TODO: Preserve existing DOM
+ // This will involve parsing and comparing the old and new column configs
+ // and reacting to four types of changes:
+ // 1. formatter, nodeFormatter, emptyCellValue changes
+ // 2. column deletions
+ // 3. column additions
+ // 4. column moves (preserve cells)
+ _afterColumnsChange: function () {
+ this.render();
+ },
+
+ /**
+ Handles modelList changes, including additions, deletions, and updates.
+
+ Modifies the existing table DOM accordingly.
+
+ @method _afterDataChange
+ @param {EventFacade} e The `change` event from the ModelList
+ @protected
+ @since 3.5.0
+ **/
+ _afterDataChange: function () {
+ //var type = e.type.slice(e.type.lastIndexOf(':') + 1);
+
+ // TODO: Isolate changes
+ this.render();
+ },
+
+ /**
+ Handles replacement of the modelList.
+
+ Rerenders the `<tbody>` contents.
+
+ @method _afterModelListChange
+ @param {EventFacade} e The `modelListChange` event
+ @protected
+ @since 3.6.0
+ **/
+ _afterModelListChange: function () {
+ var handles = this._eventHandles;
+
+ if (handles.dataChange) {
+ handles.dataChange.detach();
+ delete handles.dataChange;
+ this.bindUI();
+ }
+
+ if (this.tbodyNode) {
+ this.render();
+ }
+ },
+
+ /**
+ Iterates the `modelList`, and calls any `nodeFormatter`s found in the
+ `columns` param on the appropriate cell Nodes in the `tbody`.
+
+ @method _applyNodeFormatters
+ @param {Node} tbody The `<tbody>` Node whose columns to update
+ @param {Object[]} columns The column configurations
+ @protected
+ @since 3.5.0
+ **/
+ _applyNodeFormatters: function (tbody, columns) {
+ var host = this.host,
+ data = this.get('modelList'),
+ formatters = [],
+ linerQuery = '.' + this.getClassName('liner'),
+ rows, i, len;
+
+ // Only iterate the ModelList again if there are nodeFormatters
+ for (i = 0, len = columns.length; i < len; ++i) {
+ if (columns[i].nodeFormatter) {
+ formatters.push(i);
+ }
+ }
+
+ if (data && formatters.length) {
+ rows = tbody.get('childNodes');
+
+ data.each(function (record, index) {
+ var formatterData = {
+ data : record.toJSON(),
+ record : record,
+ rowIndex : index
+ },
+ row = rows.item(index),
+ i, len, col, key, cells, cell, keep;
+
+
+ if (row) {
+ cells = row.get('childNodes');
+ for (i = 0, len = formatters.length; i < len; ++i) {
+ cell = cells.item(formatters[i]);
+
+ if (cell) {
+ col = formatterData.column = columns[formatters[i]];
+ key = col.key || col.id;
+
+ formatterData.value = record.get(key);
+ formatterData.td = cell;
+ formatterData.cell = cell.one(linerQuery) || cell;
+
+ keep = col.nodeFormatter.call(host,formatterData);
+
+ if (keep === false) {
+ // Remove from the Node cache to reduce
+ // memory footprint. This also purges events,
+ // which you shouldn't be scoping to a cell
+ // anyway. You've been warned. Incidentally,
+ // you should always return false. Just sayin.
+ cell.destroy(true);
+ }
+ }
+ }
+ }
+ });
+ }
+ },
+
+ /**
+ Binds event subscriptions from the UI and the host (if assigned).
+
+ @method bindUI
+ @protected
+ @since 3.5.0
+ **/
+ bindUI: function () {
+ var handles = this._eventHandles,
+ modelList = this.get('modelList'),
+ changeEvent = modelList.model.NAME + ':change';
+
+ if (!handles.columnsChange) {
+ handles.columnsChange = this.after('columnsChange',
+ bind('_afterColumnsChange', this));
+ }
+
+ if (modelList && !handles.dataChange) {
+ handles.dataChange = modelList.after(
+ ['add', 'remove', 'reset', changeEvent],
+ bind('_afterDataChange', this));
+ }
+ },
+
+ /**
+ Iterates the `modelList` and applies each Model to the `_rowTemplate`,
+ allowing any column `formatter` or `emptyCellValue` to override cell
+ content for the appropriate column. The aggregated HTML string is
+ returned.
+
+ @method _createDataHTML
+ @param {Object[]} columns The column configurations to customize the
+ generated cell content or class names
+ @return {HTML} The markup for all Models in the `modelList`, each applied
+ to the `_rowTemplate`
+ @protected
+ @since 3.5.0
+ **/
+ _createDataHTML: function (columns) {
+ var data = this.get('modelList'),
+ html = '';
+
+ if (data) {
+ data.each(function (model, index) {
+ html += this._createRowHTML(model, index, columns);
+ }, this);
+ }
+
+ return html;
+ },
+
+ /**
+ Applies the data of a given Model, modified by any column formatters and
+ supplemented by other template values to the instance's `_rowTemplate` (see
+ `_createRowTemplate`). The generated string is then returned.
+
+ The data from Model's attributes is fetched by `toJSON` and this data
+ object is appended with other properties to supply values to {placeholders}
+ in the template. For a template generated from a Model with 'foo' and 'bar'
+ attributes, the data object would end up with the following properties
+ before being used to populate the `_rowTemplate`:
+
+ * `clientID` - From Model, used the assign the `<tr>`'s 'id' attribute.
+ * `foo` - The value to populate the 'foo' column cell content. This
+ value will be the value stored in the Model's `foo` attribute, or the
+ result of the column's `formatter` if assigned. If the value is '',
+ `null`, or `undefined`, and the column's `emptyCellValue` is assigned,
+ that value will be used.
+ * `bar` - Same for the 'bar' column cell content.
+ * `foo-className` - String of CSS classes to apply to the `<td>`.
+ * `bar-className` - Same.
+ * `rowClass` - String of CSS classes to apply to the `<tr>`. This
+ will be the odd/even class per the specified index plus any additional
+ classes assigned by column formatters (via `o.rowClass`).
+
+ Because this object is available to formatters, any additional properties
+ can be added to fill in custom {placeholders} in the `_rowTemplate`.
+
+ @method _createRowHTML
+ @param {Model} model The Model instance to apply to the row template
+ @param {Number} index The index the row will be appearing
+ @param {Object[]} columns The column configurations
+ @return {HTML} The markup for the provided Model, less any `nodeFormatter`s
+ @protected
+ @since 3.5.0
+ **/
+ _createRowHTML: function (model, index, columns) {
+ var data = model.toJSON(),
+ clientId = model.get('clientId'),
+ values = {
+ rowId : this._getRowId(clientId),
+ clientId: clientId,
+ rowClass: (index % 2) ? this.CLASS_ODD : this.CLASS_EVEN
+ },
+ host = this.host || this,
+ i, len, col, token, value, formatterData;
+
+ for (i = 0, len = columns.length; i < len; ++i) {
+ col = columns[i];
+ value = data[col.key];
+ token = col._id || col.key;
+
+ values[token + '-className'] = '';
+
+ if (col._formatterFn) {
+ formatterData = {
+ value : value,
+ data : data,
+ column : col,
+ record : model,
+ className: '',
+ rowClass : '',
+ rowIndex : index
+ };
+
+ // Formatters can either return a value
+ value = col._formatterFn.call(host, formatterData);
+
+ // or update the value property of the data obj passed
+ if (value === undefined) {
+ value = formatterData.value;
+ }
+
+ values[token + '-className'] = formatterData.className;
+ values.rowClass += ' ' + formatterData.rowClass;
+ }
+
+ if (value === undefined || value === null || value === '') {
+ value = col.emptyCellValue || '';
+ }
+
+ values[token] = col.allowHTML ? value : htmlEscape(value);
+
+ values.rowClass = values.rowClass.replace(/\s+/g, ' ');
+ }
+
+ return fromTemplate(this._rowTemplate, values);
+ },
+
+ /**
+ Creates a custom HTML template string for use in generating the markup for
+ individual table rows with {placeholder}s to capture data from the Models
+ in the `modelList` attribute or from column `formatter`s.
+
+ Assigns the `_rowTemplate` property.
+
+ @method _createRowTemplate
+ @param {Object[]} columns Array of column configuration objects
+ @protected
+ @since 3.5.0
+ **/
+ _createRowTemplate: function (columns) {
+ var html = '',
+ cellTemplate = this.CELL_TEMPLATE,
+ F = Y.DataTable.BodyView.Formatters,
+ i, len, col, key, token, headers, tokenValues, formatter;
+
+ for (i = 0, len = columns.length; i < len; ++i) {
+ col = columns[i];
+ key = col.key;
+ token = col._id || key;
+ formatter = col.formatter;
+ // Only include headers if there are more than one
+ headers = (col._headers || []).length > 1 ?
+ 'headers="' + col._headers.join(' ') + '"' : '';
+
+ tokenValues = {
+ content : '{' + token + '}',
+ headers : headers,
+ className: this.getClassName('col', token) + ' ' +
+ (col.className || '') + ' ' +
+ this.getClassName('cell') +
+ ' {' + token + '-className}'
+ };
+ if (formatter) {
+ if (Lang.isFunction(formatter)) {
+ col._formatterFn = formatter;
+ } else if (formatter in F) {
+ col._formatterFn = F[formatter].call(this.host || this, col);
+ } else {
+ tokenValues.content = formatter.replace(valueRegExp, tokenValues.content);
+ }
+ }
+
+ if (col.nodeFormatter) {
+ // Defer all node decoration to the formatter
+ tokenValues.content = '';
+ }
+
+ html += fromTemplate(col.cellTemplate || cellTemplate, tokenValues);
+ }
+
+ this._rowTemplate = fromTemplate(this.ROW_TEMPLATE, {
+ content: html
+ });
+ },
+ /**
+ Cleans up temporary values created during rendering.
+ @method _afterRenderCleanup
+ @private
+ */
+ _afterRenderCleanup: function () {
+ var columns = this.get('columns'),
+ i, len = columns.length;
+
+ for (i = 0;i < len; i+=1) {
+ delete columns[i]._formatterFn;
+ }
+
+ },
+
+ /**
+ Creates the `<tbody>` node that will store the data rows.
+
+ @method _createTBodyNode
+ @return {Node}
+ @protected
+ @since 3.6.0
+ **/
+ _createTBodyNode: function () {
+ return Y.Node.create(fromTemplate(this.TBODY_TEMPLATE, {
+ className: this.getClassName('data')
+ }));
+ },
+
+ /**
+ Destroys the instance.
+
+ @method destructor
+ @protected
+ @since 3.5.0
+ **/
+ destructor: function () {
+ (new Y.EventHandle(YObject.values(this._eventHandles))).detach();
+ },
+
+ /**
+ Holds the event subscriptions needing to be detached when the instance is
+ `destroy()`ed.
+
+ @property _eventHandles
+ @type {Object}
+ @default undefined (initially unset)
+ @protected
+ @since 3.5.0
+ **/
+ //_eventHandles: null,
+
+ /**
+ Returns the row ID associated with a Model's clientId.
+
+ @method _getRowId
+ @param {String} clientId The Model clientId
+ @return {String}
+ @protected
+ **/
+ _getRowId: function (clientId) {
+ return this._idMap[clientId] || (this._idMap[clientId] = Y.guid());
+ },
+
+ /**
+ Map of Model clientIds to row ids.
+
+ @property _idMap
+ @type {Object}
+ @protected
+ **/
+ //_idMap,
+
+ /**
+ Initializes the instance. Reads the following configuration properties in
+ addition to the instance attributes:
+
+ * `columns` - (REQUIRED) The initial column information
+ * `host` - The object to serve as source of truth for column info and
+ for generating class names
+
+ @method initializer
+ @param {Object} config Configuration data
+ @protected
+ @since 3.5.0
+ **/
+ initializer: function (config) {
+ this.host = config.host;
+
+ this._eventHandles = {
+ modelListChange: this.after('modelListChange',
+ bind('_afterModelListChange', this))
+ };
+ this._idMap = {};
+
+ this.CLASS_ODD = this.getClassName('odd');
+ this.CLASS_EVEN = this.getClassName('even');
+
+ }
+
+ /**
+ The HTML template used to create a full row of markup for a single Model in
+ the `modelList` plus any customizations defined in the column
+ configurations.
+
+ @property _rowTemplate
+ @type {HTML}
+ @default (initially unset)
+ @protected
+ @since 3.5.0
+ **/
+ //_rowTemplate: null
+},{
+ /**
+ Hash of formatting functions for cell contents.
+
+ This property can be populated with a hash of formatting functions by the developer
+ or a set of pre-defined functions can be loaded via the `datatable-formatters` module.
+
+ See: [DataTable.BodyView.Formatters](./DataTable.BodyView.Formatters.html)
+ @property Formatters
+ @type Object
+ @since 3.8.0
+ @static
+ **/
+ Formatters: {}
+});
+
+
+}, '3.10.3', {"requires": ["datatable-core", "view", "classnamemanager"]});