1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file.
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/**
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * @fileoverview This implements a table header.
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen */
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsencr.define('cr.ui.table', function() {
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const TableSplitter = cr.ui.TableSplitter;
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * Creates a new table header.
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @param {Object=} opt_propertyBag Optional properties.
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @constructor
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @extends {HTMLDivElement}
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  var TableHeader = cr.ui.define('div');
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  TableHeader.prototype = {
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    __proto__: HTMLDivElement.prototype,
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    table_: null,
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Initializes the element.
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    decorate: function() {
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.className = 'table-header';
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.headerInner_ = this.ownerDocument.createElement('div');
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.headerInner_.className = 'table-header-inner';
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.appendChild(this.headerInner_);
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Updates table header width. Header width depends on list having a
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * vertical scrollbar.
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updateWidth: function() {
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Header should not span over the vertical scrollbar of the list.
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var list = this.table_.querySelector('list');
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.headerInner_.style.width = list.clientWidth + 'px';
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Resizes columns.
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    resize: function() {
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var cm = this.table_.columnModel;
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var headerCells = this.querySelectorAll('.table-header-cell');
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (headerCells.length != cm.size) {
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.redraw();
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.headerInner_.textContent = '';
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      for (var i = 0; i < cm.size; i++) {
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        headerCells[i].style.width = cm.getWidth(i) + '%';
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.headerInner_.appendChild(headerCells[i]);
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.appendSplitters_();
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Redraws table header.
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    redraw: function() {
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var cm = this.table_.columnModel;
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var dm = this.table_.dataModel;
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.updateWidth();
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.headerInner_.textContent = '';
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (!cm || ! dm) {
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return;
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      for (var i = 0; i < cm.size; i++) {
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var cell = this.ownerDocument.createElement('div');
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cell.style.width = cm.getWidth(i) + '%';
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cell.className = 'table-header-cell';
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cell.addEventListener('click', this.createSortFunction_(i).bind(this));
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        cell.appendChild(this.createHeaderLabel_(i));
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.headerInner_.appendChild(cell);
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this.appendSplitters_();
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Appends column splitters to the table header.
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    appendSplitters_: function() {
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var cm = this.table_.columnModel;
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var leftPercent = 0;
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      for (var i = 0; i < cm.size - 1; i++) {
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        leftPercent += cm.getWidth(i);
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // splitter should use CSS for background image.
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var splitter = new TableSplitter({table: this.table_});
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        splitter.columnIndex = i;
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        var rtl = this.ownerDocument.defaultView.getComputedStyle(this).
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            direction == 'rtl';
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        splitter.style.left = rtl ? 100 - leftPercent + '%' : leftPercent + '%';
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.headerInner_.appendChild(splitter);
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Renders column header. Appends text label and sort arrow if needed.
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * @param {number} index Column index.
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    createHeaderLabel_: function(index) {
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var cm = this.table_.columnModel;
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var dm = this.table_.dataModel;
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var labelDiv = this.ownerDocument.createElement('div');
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      labelDiv.className = 'table-header-label';
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var span = this.ownerDocument.createElement('span');
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      span.textContent = cm.getName(index);
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      var rtl = this.ownerDocument.defaultView.getComputedStyle(this).
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          direction == 'rtl';
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (rtl) {
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        span.style.backgroundPosition = 'left';
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        span.style.paddingRight= '0';
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      } else {
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        span.style.backgroundPosition = 'right';
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        span.style.paddingLeft= '0';
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (dm) {
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (dm.sortStatus.field == cm.getId(index)) {
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          if (dm.sortStatus.direction == 'desc')
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            span.className = 'table-header-sort-image-desc';
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          else
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            span.className = 'table-header-sort-image-asc';
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      labelDiv.appendChild(span);
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return labelDiv;
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /**
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * Creates sort function for given column.
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     * @param {number} index The index of the column to sort by.
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     */
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    createSortFunction_: function(index) {
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return function() {
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        this.table_.sort(index);
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }.bind(this);
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    },
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  /**
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * The table associated with the header.
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   * @type {cr.ui.Table}
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   */
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  cr.defineProperty(TableHeader, 'table');
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return {
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TableHeader: TableHeader
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen});
168