/hippo/src/main/webapp/yui/datatable/datatable-debug.js

http://hdbc.googlecode.com/ · JavaScript · 2037 lines · 887 code · 216 blank · 934 comment · 195 complexity · 9d7b699ff8ed1b88a66ad4840e2ef2c3 MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. Copyright (c) 2009, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.net/yui/license.txt
  5. version: 2.7.0
  6. */
  7. /**
  8. * Mechanism to execute a series of callbacks in a non-blocking queue. Each callback is executed via setTimout unless configured with a negative timeout, in which case it is run in blocking mode in the same execution thread as the previous callback. Callbacks can be function references or object literals with the following keys:
  9. * <ul>
  10. * <li><code>method</code> - {Function} REQUIRED the callback function.</li>
  11. * <li><code>scope</code> - {Object} the scope from which to execute the callback. Default is the global window scope.</li>
  12. * <li><code>argument</code> - {Array} parameters to be passed to method as individual arguments.</li>
  13. * <li><code>timeout</code> - {number} millisecond delay to wait after previous callback completion before executing this callback. Negative values cause immediate blocking execution. Default 0.</li>
  14. * <li><code>until</code> - {Function} boolean function executed before each iteration. Return true to indicate completion and proceed to the next callback.</li>
  15. * <li><code>iterations</code> - {Number} number of times to execute the callback before proceeding to the next callback in the chain. Incompatible with <code>until</code>.</li>
  16. * </ul>
  17. *
  18. * @namespace YAHOO.util
  19. * @class Chain
  20. * @constructor
  21. * @param callback* {Function|Object} Any number of callbacks to initialize the queue
  22. */
  23. YAHOO.util.Chain = function () {
  24. /**
  25. * The callback queue
  26. * @property q
  27. * @type {Array}
  28. * @private
  29. */
  30. this.q = [].slice.call(arguments);
  31. /**
  32. * Event fired when the callback queue is emptied via execution (not via
  33. * a call to chain.stop().
  34. * @event end
  35. */
  36. this.createEvent('end');
  37. };
  38. YAHOO.util.Chain.prototype = {
  39. /**
  40. * Timeout id used to pause or stop execution and indicate the execution state of the Chain. 0 indicates paused or stopped, -1 indicates blocking execution, and any positive number indicates non-blocking execution.
  41. * @property id
  42. * @type {number}
  43. * @private
  44. */
  45. id : 0,
  46. /**
  47. * Begin executing the chain, or resume execution from the last paused position.
  48. * @method run
  49. * @return {Chain} the Chain instance
  50. */
  51. run : function () {
  52. // Grab the first callback in the queue
  53. var c = this.q[0],
  54. fn;
  55. // If there is no callback in the queue or the Chain is currently
  56. // in an execution mode, return
  57. if (!c) {
  58. this.fireEvent('end');
  59. return this;
  60. } else if (this.id) {
  61. return this;
  62. }
  63. fn = c.method || c;
  64. if (typeof fn === 'function') {
  65. var o = c.scope || {},
  66. args = c.argument || [],
  67. ms = c.timeout || 0,
  68. me = this;
  69. if (!(args instanceof Array)) {
  70. args = [args];
  71. }
  72. // Execute immediately if the callback timeout is negative.
  73. if (ms < 0) {
  74. this.id = ms;
  75. if (c.until) {
  76. for (;!c.until();) {
  77. // Execute the callback from scope, with argument
  78. fn.apply(o,args);
  79. }
  80. } else if (c.iterations) {
  81. for (;c.iterations-- > 0;) {
  82. fn.apply(o,args);
  83. }
  84. } else {
  85. fn.apply(o,args);
  86. }
  87. this.q.shift();
  88. this.id = 0;
  89. return this.run();
  90. } else {
  91. // If the until condition is set, check if we're done
  92. if (c.until) {
  93. if (c.until()) {
  94. // Shift this callback from the queue and execute the next
  95. // callback
  96. this.q.shift();
  97. return this.run();
  98. }
  99. // Otherwise if either iterations is not set or we're
  100. // executing the last iteration, shift callback from the queue
  101. } else if (!c.iterations || !--c.iterations) {
  102. this.q.shift();
  103. }
  104. // Otherwise set to execute after the configured timeout
  105. this.id = setTimeout(function () {
  106. // Execute the callback from scope, with argument
  107. fn.apply(o,args);
  108. // Check if the Chain was not paused from inside the callback
  109. if (me.id) {
  110. // Indicate ready to run state
  111. me.id = 0;
  112. // Start the fun all over again
  113. me.run();
  114. }
  115. },ms);
  116. }
  117. }
  118. return this;
  119. },
  120. /**
  121. * Add a callback to the end of the queue
  122. * @method add
  123. * @param c {Function|Object} the callback function ref or object literal
  124. * @return {Chain} the Chain instance
  125. */
  126. add : function (c) {
  127. this.q.push(c);
  128. return this;
  129. },
  130. /**
  131. * Pause the execution of the Chain after the current execution of the
  132. * current callback completes. If called interstitially, clears the
  133. * timeout for the pending callback. Paused Chains can be restarted with
  134. * chain.run()
  135. * @method pause
  136. * @return {Chain} the Chain instance
  137. */
  138. pause: function () {
  139. clearTimeout(this.id);
  140. this.id = 0;
  141. return this;
  142. },
  143. /**
  144. * Stop and clear the Chain's queue after the current execution of the
  145. * current callback completes.
  146. * @method stop
  147. * @return {Chain} the Chain instance
  148. */
  149. stop : function () {
  150. this.pause();
  151. this.q = [];
  152. return this;
  153. }
  154. };
  155. YAHOO.lang.augmentProto(YAHOO.util.Chain,YAHOO.util.EventProvider);
  156. /****************************************************************************/
  157. /****************************************************************************/
  158. /****************************************************************************/
  159. /**
  160. * The ColumnSet class defines and manages a DataTable's Columns,
  161. * including nested hierarchies and access to individual Column instances.
  162. *
  163. * @namespace YAHOO.widget
  164. * @class ColumnSet
  165. * @uses YAHOO.util.EventProvider
  166. * @constructor
  167. * @param aDefinitions {Object[]} Array of object literals that define cells in
  168. * the THEAD.
  169. */
  170. YAHOO.widget.ColumnSet = function(aDefinitions) {
  171. this._sId = "yui-cs" + YAHOO.widget.ColumnSet._nCount;
  172. // First clone the defs
  173. aDefinitions = YAHOO.widget.DataTable._cloneObject(aDefinitions);
  174. this._init(aDefinitions);
  175. YAHOO.widget.ColumnSet._nCount++;
  176. YAHOO.log("ColumnSet initialized", "info", this.toString());
  177. };
  178. /////////////////////////////////////////////////////////////////////////////
  179. //
  180. // Private member variables
  181. //
  182. /////////////////////////////////////////////////////////////////////////////
  183. /**
  184. * Internal class variable to index multiple ColumnSet instances.
  185. *
  186. * @property ColumnSet._nCount
  187. * @type Number
  188. * @private
  189. * @static
  190. */
  191. YAHOO.widget.ColumnSet._nCount = 0;
  192. YAHOO.widget.ColumnSet.prototype = {
  193. /**
  194. * Unique instance name.
  195. *
  196. * @property _sId
  197. * @type String
  198. * @private
  199. */
  200. _sId : null,
  201. /**
  202. * Array of object literal Column definitions passed to the constructor.
  203. *
  204. * @property _aDefinitions
  205. * @type Object[]
  206. * @private
  207. */
  208. _aDefinitions : null,
  209. /////////////////////////////////////////////////////////////////////////////
  210. //
  211. // Public member variables
  212. //
  213. /////////////////////////////////////////////////////////////////////////////
  214. /**
  215. * Top-down tree representation of Column hierarchy.
  216. *
  217. * @property tree
  218. * @type YAHOO.widget.Column[]
  219. */
  220. tree : null,
  221. /**
  222. * Flattened representation of all Columns.
  223. *
  224. * @property flat
  225. * @type YAHOO.widget.Column[]
  226. * @default []
  227. */
  228. flat : null,
  229. /**
  230. * Array of Columns that map one-to-one to a table column.
  231. *
  232. * @property keys
  233. * @type YAHOO.widget.Column[]
  234. * @default []
  235. */
  236. keys : null,
  237. /**
  238. * ID index of nested parent hierarchies for HEADERS accessibility attribute.
  239. *
  240. * @property headers
  241. * @type String[]
  242. * @default []
  243. */
  244. headers : null,
  245. /////////////////////////////////////////////////////////////////////////////
  246. //
  247. // Private methods
  248. //
  249. /////////////////////////////////////////////////////////////////////////////
  250. /**
  251. * Initializes ColumnSet instance with data from Column definitions.
  252. *
  253. * @method _init
  254. * @param aDefinitions {Object[]} Array of object literals that define cells in
  255. * the THEAD .
  256. * @private
  257. */
  258. _init : function(aDefinitions) {
  259. // DOM tree representation of all Columns
  260. var tree = [];
  261. // Flat representation of all Columns
  262. var flat = [];
  263. // Flat representation of only Columns that are meant to display data
  264. var keys = [];
  265. // Array of HEADERS attribute values for all keys in the "keys" array
  266. var headers = [];
  267. // Tracks current node list depth being tracked
  268. var nodeDepth = -1;
  269. // Internal recursive function to define Column instances
  270. var parseColumns = function(nodeList, parent) {
  271. // One level down
  272. nodeDepth++;
  273. // Create corresponding tree node if not already there for this depth
  274. if(!tree[nodeDepth]) {
  275. tree[nodeDepth] = [];
  276. }
  277. // Parse each node at this depth for attributes and any children
  278. for(var j=0; j<nodeList.length; j++) {
  279. var currentNode = nodeList[j];
  280. // Instantiate a new Column for each node
  281. var oColumn = new YAHOO.widget.Column(currentNode);
  282. // Cross-reference Column ID back to the original object literal definition
  283. currentNode.yuiColumnId = oColumn._sId;
  284. // Add the new Column to the flat list
  285. flat.push(oColumn);
  286. // Assign its parent as an attribute, if applicable
  287. if(parent) {
  288. oColumn._oParent = parent;
  289. }
  290. // The Column has descendants
  291. if(YAHOO.lang.isArray(currentNode.children)) {
  292. oColumn.children = currentNode.children;
  293. // Determine COLSPAN value for this Column
  294. var terminalChildNodes = 0;
  295. var countTerminalChildNodes = function(ancestor) {
  296. var descendants = ancestor.children;
  297. // Drill down each branch and count terminal nodes
  298. for(var k=0; k<descendants.length; k++) {
  299. // Keep drilling down
  300. if(YAHOO.lang.isArray(descendants[k].children)) {
  301. countTerminalChildNodes(descendants[k]);
  302. }
  303. // Reached branch terminus
  304. else {
  305. terminalChildNodes++;
  306. }
  307. }
  308. };
  309. countTerminalChildNodes(currentNode);
  310. oColumn._nColspan = terminalChildNodes;
  311. // Cascade certain properties to children if not defined on their own
  312. var currentChildren = currentNode.children;
  313. for(var k=0; k<currentChildren.length; k++) {
  314. var child = currentChildren[k];
  315. if(oColumn.className && (child.className === undefined)) {
  316. child.className = oColumn.className;
  317. }
  318. if(oColumn.editor && (child.editor === undefined)) {
  319. child.editor = oColumn.editor;
  320. }
  321. //TODO: Deprecated
  322. if(oColumn.editorOptions && (child.editorOptions === undefined)) {
  323. child.editorOptions = oColumn.editorOptions;
  324. }
  325. if(oColumn.formatter && (child.formatter === undefined)) {
  326. child.formatter = oColumn.formatter;
  327. }
  328. if(oColumn.resizeable && (child.resizeable === undefined)) {
  329. child.resizeable = oColumn.resizeable;
  330. }
  331. if(oColumn.sortable && (child.sortable === undefined)) {
  332. child.sortable = oColumn.sortable;
  333. }
  334. if(oColumn.hidden) {
  335. child.hidden = true;
  336. }
  337. if(oColumn.width && (child.width === undefined)) {
  338. child.width = oColumn.width;
  339. }
  340. if(oColumn.minWidth && (child.minWidth === undefined)) {
  341. child.minWidth = oColumn.minWidth;
  342. }
  343. if(oColumn.maxAutoWidth && (child.maxAutoWidth === undefined)) {
  344. child.maxAutoWidth = oColumn.maxAutoWidth;
  345. }
  346. // Backward compatibility
  347. if(oColumn.type && (child.type === undefined)) {
  348. child.type = oColumn.type;
  349. }
  350. if(oColumn.type && !oColumn.formatter) {
  351. YAHOO.log("The property type has been" +
  352. " deprecated in favor of formatter", "warn", oColumn.toString());
  353. oColumn.formatter = oColumn.type;
  354. }
  355. if(oColumn.text && !YAHOO.lang.isValue(oColumn.label)) {
  356. YAHOO.log("The property text has been" +
  357. " deprecated in favor of label", "warn", oColumn.toString());
  358. oColumn.label = oColumn.text;
  359. }
  360. if(oColumn.parser) {
  361. YAHOO.log("The property parser is no longer supported",
  362. "warn", this.toString());
  363. }
  364. if(oColumn.sortOptions && ((oColumn.sortOptions.ascFunction) ||
  365. (oColumn.sortOptions.descFunction))) {
  366. YAHOO.log("The properties sortOptions.ascFunction and " +
  367. " sortOptions.descFunction have been deprecated in favor " +
  368. " of sortOptions.sortFunction", "warn", oColumn.toString());
  369. }
  370. }
  371. // The children themselves must also be parsed for Column instances
  372. if(!tree[nodeDepth+1]) {
  373. tree[nodeDepth+1] = [];
  374. }
  375. parseColumns(currentChildren, oColumn);
  376. }
  377. // This Column does not have any children
  378. else {
  379. oColumn._nKeyIndex = keys.length;
  380. oColumn._nColspan = 1;
  381. keys.push(oColumn);
  382. }
  383. // Add the Column to the top-down tree
  384. tree[nodeDepth].push(oColumn);
  385. }
  386. nodeDepth--;
  387. };
  388. // Parse out Column instances from the array of object literals
  389. if(YAHOO.lang.isArray(aDefinitions)) {
  390. parseColumns(aDefinitions);
  391. // Store the array
  392. this._aDefinitions = aDefinitions;
  393. }
  394. else {
  395. YAHOO.log("Could not initialize ColumnSet due to invalid definitions","error");
  396. return null;
  397. }
  398. var i;
  399. // Determine ROWSPAN value for each Column in the tree
  400. var parseTreeForRowspan = function(tree) {
  401. var maxRowDepth = 1;
  402. var currentRow;
  403. var currentColumn;
  404. // Calculate the max depth of descendants for this row
  405. var countMaxRowDepth = function(row, tmpRowDepth) {
  406. tmpRowDepth = tmpRowDepth || 1;
  407. for(var n=0; n<row.length; n++) {
  408. var col = row[n];
  409. // Column has children, so keep counting
  410. if(YAHOO.lang.isArray(col.children)) {
  411. tmpRowDepth++;
  412. countMaxRowDepth(col.children, tmpRowDepth);
  413. tmpRowDepth--;
  414. }
  415. // No children, is it the max depth?
  416. else {
  417. if(tmpRowDepth > maxRowDepth) {
  418. maxRowDepth = tmpRowDepth;
  419. }
  420. }
  421. }
  422. };
  423. // Count max row depth for each row
  424. for(var m=0; m<tree.length; m++) {
  425. currentRow = tree[m];
  426. countMaxRowDepth(currentRow);
  427. // Assign the right ROWSPAN values to each Column in the row
  428. for(var p=0; p<currentRow.length; p++) {
  429. currentColumn = currentRow[p];
  430. if(!YAHOO.lang.isArray(currentColumn.children)) {
  431. currentColumn._nRowspan = maxRowDepth;
  432. }
  433. else {
  434. currentColumn._nRowspan = 1;
  435. }
  436. }
  437. // Reset counter for next row
  438. maxRowDepth = 1;
  439. }
  440. };
  441. parseTreeForRowspan(tree);
  442. // Store tree index values
  443. for(i=0; i<tree[0].length; i++) {
  444. tree[0][i]._nTreeIndex = i;
  445. }
  446. // Store header relationships in an array for HEADERS attribute
  447. var recurseAncestorsForHeaders = function(i, oColumn) {
  448. headers[i].push(oColumn.getSanitizedKey());
  449. if(oColumn._oParent) {
  450. recurseAncestorsForHeaders(i, oColumn._oParent);
  451. }
  452. };
  453. for(i=0; i<keys.length; i++) {
  454. headers[i] = [];
  455. recurseAncestorsForHeaders(i, keys[i]);
  456. headers[i] = headers[i].reverse();
  457. }
  458. // Save to the ColumnSet instance
  459. this.tree = tree;
  460. this.flat = flat;
  461. this.keys = keys;
  462. this.headers = headers;
  463. },
  464. /////////////////////////////////////////////////////////////////////////////
  465. //
  466. // Public methods
  467. //
  468. /////////////////////////////////////////////////////////////////////////////
  469. /**
  470. * Returns unique name of the ColumnSet instance.
  471. *
  472. * @method getId
  473. * @return {String} Unique name of the ColumnSet instance.
  474. */
  475. getId : function() {
  476. return this._sId;
  477. },
  478. /**
  479. * ColumnSet instance name, for logging.
  480. *
  481. * @method toString
  482. * @return {String} Unique name of the ColumnSet instance.
  483. */
  484. toString : function() {
  485. return "ColumnSet instance " + this._sId;
  486. },
  487. /**
  488. * Public accessor to the definitions array.
  489. *
  490. * @method getDefinitions
  491. * @return {Object[]} Array of object literal Column definitions.
  492. */
  493. getDefinitions : function() {
  494. var aDefinitions = this._aDefinitions;
  495. // Internal recursive function to define Column instances
  496. var parseColumns = function(nodeList, oSelf) {
  497. // Parse each node at this depth for attributes and any children
  498. for(var j=0; j<nodeList.length; j++) {
  499. var currentNode = nodeList[j];
  500. // Get the Column for each node
  501. var oColumn = oSelf.getColumnById(currentNode.yuiColumnId);
  502. if(oColumn) {
  503. // Update the current values
  504. var oDefinition = oColumn.getDefinition();
  505. for(var name in oDefinition) {
  506. if(YAHOO.lang.hasOwnProperty(oDefinition, name)) {
  507. currentNode[name] = oDefinition[name];
  508. }
  509. }
  510. }
  511. // The Column has descendants
  512. if(YAHOO.lang.isArray(currentNode.children)) {
  513. // The children themselves must also be parsed for Column instances
  514. parseColumns(currentNode.children, oSelf);
  515. }
  516. }
  517. };
  518. parseColumns(aDefinitions, this);
  519. this._aDefinitions = aDefinitions;
  520. return aDefinitions;
  521. },
  522. /**
  523. * Returns Column instance with given ID.
  524. *
  525. * @method getColumnById
  526. * @param column {String} Column ID.
  527. * @return {YAHOO.widget.Column} Column instance.
  528. */
  529. getColumnById : function(column) {
  530. if(YAHOO.lang.isString(column)) {
  531. var allColumns = this.flat;
  532. for(var i=allColumns.length-1; i>-1; i--) {
  533. if(allColumns[i]._sId === column) {
  534. return allColumns[i];
  535. }
  536. }
  537. }
  538. return null;
  539. },
  540. /**
  541. * Returns Column instance with given key or ColumnSet key index.
  542. *
  543. * @method getColumn
  544. * @param column {String | Number} Column key or ColumnSet key index.
  545. * @return {YAHOO.widget.Column} Column instance.
  546. */
  547. getColumn : function(column) {
  548. if(YAHOO.lang.isNumber(column) && this.keys[column]) {
  549. return this.keys[column];
  550. }
  551. else if(YAHOO.lang.isString(column)) {
  552. var allColumns = this.flat;
  553. var aColumns = [];
  554. for(var i=0; i<allColumns.length; i++) {
  555. if(allColumns[i].key === column) {
  556. aColumns.push(allColumns[i]);
  557. }
  558. }
  559. if(aColumns.length === 1) {
  560. return aColumns[0];
  561. }
  562. else if(aColumns.length > 1) {
  563. return aColumns;
  564. }
  565. }
  566. return null;
  567. },
  568. /**
  569. * Public accessor returns array of given Column's desendants (if any), including itself.
  570. *
  571. * @method getDescendants
  572. * @parem {YAHOO.widget.Column} Column instance.
  573. * @return {Array} Array including the Column itself and all descendants (if any).
  574. */
  575. getDescendants : function(oColumn) {
  576. var oSelf = this;
  577. var allDescendants = [];
  578. var i;
  579. // Recursive function to loop thru all children
  580. var parse = function(oParent) {
  581. allDescendants.push(oParent);
  582. // This Column has children
  583. if(oParent.children) {
  584. for(i=0; i<oParent.children.length; i++) {
  585. parse(oSelf.getColumn(oParent.children[i].key));
  586. }
  587. }
  588. };
  589. parse(oColumn);
  590. return allDescendants;
  591. }
  592. };
  593. /****************************************************************************/
  594. /****************************************************************************/
  595. /****************************************************************************/
  596. /**
  597. * The Column class defines and manages attributes of DataTable Columns
  598. *
  599. * @namespace YAHOO.widget
  600. * @class Column
  601. * @constructor
  602. * @param oConfigs {Object} Object literal of definitions.
  603. */
  604. YAHOO.widget.Column = function(oConfigs) {
  605. this._sId = "yui-col" + YAHOO.widget.Column._nCount;
  606. // Object literal defines Column attributes
  607. if(oConfigs && YAHOO.lang.isObject(oConfigs)) {
  608. for(var sConfig in oConfigs) {
  609. if(sConfig) {
  610. this[sConfig] = oConfigs[sConfig];
  611. }
  612. }
  613. }
  614. // Assign a key if not found
  615. if(!YAHOO.lang.isValue(this.key)) {
  616. this.key = "yui-dt-col" + YAHOO.widget.Column._nCount;
  617. }
  618. // Assign a field if not found, defaults to key
  619. if(!YAHOO.lang.isValue(this.field)) {
  620. this.field = this.key;
  621. }
  622. // Increment counter
  623. YAHOO.widget.Column._nCount++;
  624. // Backward compatibility
  625. if(this.width && !YAHOO.lang.isNumber(this.width)) {
  626. this.width = null;
  627. YAHOO.log("The Column property width must be a number", "warn", this.toString());
  628. }
  629. if(this.editor && YAHOO.lang.isString(this.editor)) {
  630. this.editor = new YAHOO.widget.CellEditor(this.editor, this.editorOptions);
  631. YAHOO.log("The Column property editor must be an instance of YAHOO.widget.CellEditor", "warn", this.toString());
  632. }
  633. };
  634. /////////////////////////////////////////////////////////////////////////////
  635. //
  636. // Private member variables
  637. //
  638. /////////////////////////////////////////////////////////////////////////////
  639. YAHOO.lang.augmentObject(YAHOO.widget.Column, {
  640. /**
  641. * Internal class variable to index multiple Column instances.
  642. *
  643. * @property Column._nCount
  644. * @type Number
  645. * @private
  646. * @static
  647. */
  648. _nCount : 0,
  649. formatCheckbox : function(elCell, oRecord, oColumn, oData) {
  650. YAHOO.log("The method YAHOO.widget.Column.formatCheckbox() has been" +
  651. " deprecated in favor of YAHOO.widget.DataTable.formatCheckbox()", "warn",
  652. "YAHOO.widget.Column.formatCheckbox");
  653. YAHOO.widget.DataTable.formatCheckbox(elCell, oRecord, oColumn, oData);
  654. },
  655. formatCurrency : function(elCell, oRecord, oColumn, oData) {
  656. YAHOO.log("The method YAHOO.widget.Column.formatCurrency() has been" +
  657. " deprecated in favor of YAHOO.widget.DataTable.formatCurrency()", "warn",
  658. "YAHOO.widget.Column.formatCurrency");
  659. YAHOO.widget.DataTable.formatCurrency(elCell, oRecord, oColumn, oData);
  660. },
  661. formatDate : function(elCell, oRecord, oColumn, oData) {
  662. YAHOO.log("The method YAHOO.widget.Column.formatDate() has been" +
  663. " deprecated in favor of YAHOO.widget.DataTable.formatDate()", "warn",
  664. "YAHOO.widget.Column.formatDate");
  665. YAHOO.widget.DataTable.formatDate(elCell, oRecord, oColumn, oData);
  666. },
  667. formatEmail : function(elCell, oRecord, oColumn, oData) {
  668. YAHOO.log("The method YAHOO.widget.Column.formatEmail() has been" +
  669. " deprecated in favor of YAHOO.widget.DataTable.formatEmail()", "warn",
  670. "YAHOO.widget.Column.formatEmail");
  671. YAHOO.widget.DataTable.formatEmail(elCell, oRecord, oColumn, oData);
  672. },
  673. formatLink : function(elCell, oRecord, oColumn, oData) {
  674. YAHOO.log("The method YAHOO.widget.Column.formatLink() has been" +
  675. " deprecated in favor of YAHOO.widget.DataTable.formatLink()", "warn",
  676. "YAHOO.widget.Column.formatLink");
  677. YAHOO.widget.DataTable.formatLink(elCell, oRecord, oColumn, oData);
  678. },
  679. formatNumber : function(elCell, oRecord, oColumn, oData) {
  680. YAHOO.log("The method YAHOO.widget.Column.formatNumber() has been" +
  681. " deprecated in favor of YAHOO.widget.DataTable.formatNumber()", "warn",
  682. "YAHOO.widget.Column.formatNumber");
  683. YAHOO.widget.DataTable.formatNumber(elCell, oRecord, oColumn, oData);
  684. },
  685. formatSelect : function(elCell, oRecord, oColumn, oData) {
  686. YAHOO.log("The method YAHOO.widget.Column.formatSelect() has been" +
  687. " deprecated in favor of YAHOO.widget.DataTable.formatDropdown()", "warn",
  688. "YAHOO.widget.Column.formatSelect");
  689. YAHOO.widget.DataTable.formatDropdown(elCell, oRecord, oColumn, oData);
  690. }
  691. });
  692. YAHOO.widget.Column.prototype = {
  693. /**
  694. * Unique String identifier assigned at instantiation.
  695. *
  696. * @property _sId
  697. * @type String
  698. * @private
  699. */
  700. _sId : null,
  701. /**
  702. * Reference to Column's current position index within its ColumnSet's keys
  703. * array, if applicable. This property only applies to non-nested and bottom-
  704. * level child Columns.
  705. *
  706. * @property _nKeyIndex
  707. * @type Number
  708. * @private
  709. */
  710. _nKeyIndex : null,
  711. /**
  712. * Reference to Column's current position index within its ColumnSet's tree
  713. * array, if applicable. This property only applies to non-nested and top-
  714. * level parent Columns.
  715. *
  716. * @property _nTreeIndex
  717. * @type Number
  718. * @private
  719. */
  720. _nTreeIndex : null,
  721. /**
  722. * Number of table cells the Column spans.
  723. *
  724. * @property _nColspan
  725. * @type Number
  726. * @private
  727. */
  728. _nColspan : 1,
  729. /**
  730. * Number of table rows the Column spans.
  731. *
  732. * @property _nRowspan
  733. * @type Number
  734. * @private
  735. */
  736. _nRowspan : 1,
  737. /**
  738. * Column's parent Column instance, or null.
  739. *
  740. * @property _oParent
  741. * @type YAHOO.widget.Column
  742. * @private
  743. */
  744. _oParent : null,
  745. /**
  746. * The DOM reference to the associated TH element.
  747. *
  748. * @property _elTh
  749. * @type HTMLElement
  750. * @private
  751. */
  752. _elTh : null,
  753. /**
  754. * The DOM reference to the associated TH element's liner DIV element.
  755. *
  756. * @property _elThLiner
  757. * @type HTMLElement
  758. * @private
  759. */
  760. _elThLiner : null,
  761. /**
  762. * The DOM reference to the associated TH element's label SPAN element.
  763. *
  764. * @property _elThLabel
  765. * @type HTMLElement
  766. * @private
  767. */
  768. _elThLabel : null,
  769. /**
  770. * The DOM reference to the associated resizerelement (if any).
  771. *
  772. * @property _elResizer
  773. * @type HTMLElement
  774. * @private
  775. */
  776. _elResizer : null,
  777. /**
  778. * Internal width tracker.
  779. *
  780. * @property _nWidth
  781. * @type Number
  782. * @private
  783. */
  784. _nWidth : null,
  785. /**
  786. * For unreg() purposes, a reference to the Column's DragDrop instance.
  787. *
  788. * @property _dd
  789. * @type YAHOO.util.DragDrop
  790. * @private
  791. */
  792. _dd : null,
  793. /**
  794. * For unreg() purposes, a reference to the Column resizer's DragDrop instance.
  795. *
  796. * @property _ddResizer
  797. * @type YAHOO.util.DragDrop
  798. * @private
  799. */
  800. _ddResizer : null,
  801. /////////////////////////////////////////////////////////////////////////////
  802. //
  803. // Public member variables
  804. //
  805. /////////////////////////////////////////////////////////////////////////////
  806. /**
  807. * Unique name, required.
  808. *
  809. * @property key
  810. * @type String
  811. */
  812. key : null,
  813. /**
  814. * Associated database field, or null.
  815. *
  816. * @property field
  817. * @type String
  818. */
  819. field : null,
  820. /**
  821. * Text or HTML for display as Column's label in the TH element.
  822. *
  823. * @property label
  824. * @type String
  825. */
  826. label : null,
  827. /**
  828. * Column head cell ABBR for accessibility.
  829. *
  830. * @property abbr
  831. * @type String
  832. */
  833. abbr : null,
  834. /**
  835. * Array of object literals that define children (nested headers) of a Column.
  836. *
  837. * @property children
  838. * @type Object[]
  839. */
  840. children : null,
  841. /**
  842. * Column width (in pixels).
  843. *
  844. * @property width
  845. * @type Number
  846. */
  847. width : null,
  848. /**
  849. * Minimum Column width (in pixels).
  850. *
  851. * @property minWidth
  852. * @type Number
  853. * @default null
  854. */
  855. minWidth : null,
  856. /**
  857. * When a width is not defined for a Column, maxAutoWidth defines an upper
  858. * limit that the Column should be auto-sized to. If resizeable is enabled,
  859. * users may still resize to a greater width. Most useful for Columns intended
  860. * to hold long unbroken, unwrapped Strings, such as URLs, to prevent very
  861. * wide Columns from disrupting visual readability by inducing truncation.
  862. *
  863. * @property maxAutoWidth
  864. * @type Number
  865. * @default null
  866. */
  867. maxAutoWidth : null,
  868. /**
  869. * True if Column is in hidden state.
  870. *
  871. * @property hidden
  872. * @type Boolean
  873. * @default false
  874. */
  875. hidden : false,
  876. /**
  877. * True if Column is in selected state.
  878. *
  879. * @property selected
  880. * @type Boolean
  881. * @default false
  882. */
  883. selected : false,
  884. /**
  885. * Custom CSS class or array of classes to be applied to every cell in the Column.
  886. *
  887. * @property className
  888. * @type String || String[]
  889. */
  890. className : null,
  891. /**
  892. * Defines a format function.
  893. *
  894. * @property formatter
  895. * @type String || HTMLFunction
  896. */
  897. formatter : null,
  898. /**
  899. * Config passed to YAHOO.util.Number.format() by the 'currency' Column formatter.
  900. *
  901. * @property currencyOptions
  902. * @type Object
  903. * @default null
  904. */
  905. currencyOptions : null,
  906. /**
  907. * Config passed to YAHOO.util.Date.format() by the 'date' Column formatter.
  908. *
  909. * @property dateOptions
  910. * @type Object
  911. * @default null
  912. */
  913. dateOptions : null,
  914. /**
  915. * A CellEditor instance, otherwise Column is not editable.
  916. *
  917. * @property editor
  918. * @type YAHOO.widget.CellEditor
  919. */
  920. editor : null,
  921. /**
  922. * True if Column is resizeable, false otherwise. The Drag & Drop Utility is
  923. * required to enable this feature. Only bottom-level and non-nested Columns are
  924. * resizeble.
  925. *
  926. * @property resizeable
  927. * @type Boolean
  928. * @default false
  929. */
  930. resizeable : false,
  931. /**
  932. * True if Column is sortable, false otherwise.
  933. *
  934. * @property sortable
  935. * @type Boolean
  936. * @default false
  937. */
  938. sortable : false,
  939. /**
  940. * @property sortOptions.defaultOrder
  941. * @deprecated Use sortOptions.defaultDir.
  942. */
  943. /**
  944. * Default sort direction for Column: YAHOO.widget.DataTable.CLASS_ASC or YAHOO.widget.DataTable.CLASS_DESC.
  945. *
  946. * @property sortOptions.defaultDir
  947. * @type String
  948. * @default null
  949. */
  950. /**
  951. * Custom field to sort on.
  952. *
  953. * @property sortOptions.field
  954. * @type String
  955. * @default null
  956. */
  957. /**
  958. * Custom sort handler.
  959. *
  960. * @property sortOptions.sortFunction
  961. * @type Function
  962. * @default null
  963. */
  964. sortOptions : null,
  965. /////////////////////////////////////////////////////////////////////////////
  966. //
  967. // Public methods
  968. //
  969. /////////////////////////////////////////////////////////////////////////////
  970. /**
  971. * Returns unique ID string.
  972. *
  973. * @method getId
  974. * @return {String} Unique ID string.
  975. */
  976. getId : function() {
  977. return this._sId;
  978. },
  979. /**
  980. * Column instance name, for logging.
  981. *
  982. * @method toString
  983. * @return {String} Column's unique name.
  984. */
  985. toString : function() {
  986. return "Column instance " + this._sId;
  987. },
  988. /**
  989. * Returns object literal definition.
  990. *
  991. * @method getDefinition
  992. * @return {Object} Object literal definition.
  993. */
  994. getDefinition : function() {
  995. var oDefinition = {};
  996. // Update the definition
  997. oDefinition.abbr = this.abbr;
  998. oDefinition.className = this.className;
  999. oDefinition.editor = this.editor;
  1000. oDefinition.editorOptions = this.editorOptions; //TODO: deprecated
  1001. oDefinition.field = this.field;
  1002. oDefinition.formatter = this.formatter;
  1003. oDefinition.hidden = this.hidden;
  1004. oDefinition.key = this.key;
  1005. oDefinition.label = this.label;
  1006. oDefinition.minWidth = this.minWidth;
  1007. oDefinition.maxAutoWidth = this.maxAutoWidth;
  1008. oDefinition.resizeable = this.resizeable;
  1009. oDefinition.selected = this.selected;
  1010. oDefinition.sortable = this.sortable;
  1011. oDefinition.sortOptions = this.sortOptions;
  1012. oDefinition.width = this.width;
  1013. return oDefinition;
  1014. },
  1015. /**
  1016. * Returns unique Column key.
  1017. *
  1018. * @method getKey
  1019. * @return {String} Column key.
  1020. */
  1021. getKey : function() {
  1022. return this.key;
  1023. },
  1024. /**
  1025. * Returns field.
  1026. *
  1027. * @method getField
  1028. * @return {String} Column field.
  1029. */
  1030. getField : function() {
  1031. return this.field;
  1032. },
  1033. /**
  1034. * Returns Column key which has been sanitized for DOM (class and ID) usage
  1035. * starts with letter, contains only letters, numbers, hyphen, or period.
  1036. *
  1037. * @method getSanitizedKey
  1038. * @return {String} Sanitized Column key.
  1039. */
  1040. getSanitizedKey : function() {
  1041. return this.getKey().replace(/[^\w\-]/g,"");
  1042. },
  1043. /**
  1044. * Public accessor returns Column's current position index within its
  1045. * ColumnSet's keys array, if applicable. Only non-nested and bottom-level
  1046. * child Columns will return a value.
  1047. *
  1048. * @method getKeyIndex
  1049. * @return {Number} Position index, or null.
  1050. */
  1051. getKeyIndex : function() {
  1052. return this._nKeyIndex;
  1053. },
  1054. /**
  1055. * Public accessor returns Column's current position index within its
  1056. * ColumnSet's tree array, if applicable. Only non-nested and top-level parent
  1057. * Columns will return a value;
  1058. *
  1059. * @method getTreeIndex
  1060. * @return {Number} Position index, or null.
  1061. */
  1062. getTreeIndex : function() {
  1063. return this._nTreeIndex;
  1064. },
  1065. /**
  1066. * Public accessor returns Column's parent instance if any, or null otherwise.
  1067. *
  1068. * @method getParent
  1069. * @return {YAHOO.widget.Column} Column's parent instance.
  1070. */
  1071. getParent : function() {
  1072. return this._oParent;
  1073. },
  1074. /**
  1075. * Public accessor returns Column's calculated COLSPAN value.
  1076. *
  1077. * @method getColspan
  1078. * @return {Number} Column's COLSPAN value.
  1079. */
  1080. getColspan : function() {
  1081. return this._nColspan;
  1082. },
  1083. // Backward compatibility
  1084. getColSpan : function() {
  1085. YAHOO.log("The method getColSpan() has been" +
  1086. " deprecated in favor of getColspan()", "warn", this.toString());
  1087. return this.getColspan();
  1088. },
  1089. /**
  1090. * Public accessor returns Column's calculated ROWSPAN value.
  1091. *
  1092. * @method getRowspan
  1093. * @return {Number} Column's ROWSPAN value.
  1094. */
  1095. getRowspan : function() {
  1096. return this._nRowspan;
  1097. },
  1098. /**
  1099. * Returns DOM reference to the key TH element.
  1100. *
  1101. * @method getThEl
  1102. * @return {HTMLElement} TH element.
  1103. */
  1104. getThEl : function() {
  1105. return this._elTh;
  1106. },
  1107. /**
  1108. * Returns DOM reference to the TH's liner DIV element. Introduced since
  1109. * resizeable Columns may have an extra resizer liner, making the DIV liner
  1110. * not reliably the TH element's first child.
  1111. *
  1112. * @method getThLInerEl
  1113. * @return {HTMLElement} TH element.
  1114. */
  1115. getThLinerEl : function() {
  1116. return this._elThLiner;
  1117. },
  1118. /**
  1119. * Returns DOM reference to the resizer element, or null.
  1120. *
  1121. * @method getResizerEl
  1122. * @return {HTMLElement} DIV element.
  1123. */
  1124. getResizerEl : function() {
  1125. return this._elResizer;
  1126. },
  1127. // Backward compatibility
  1128. /**
  1129. * @method getColEl
  1130. * @deprecated Use getThEl
  1131. */
  1132. getColEl : function() {
  1133. YAHOO.log("The method getColEl() has been" +
  1134. " deprecated in favor of getThEl()", "warn",
  1135. this.toString());
  1136. return this.getThEl();
  1137. },
  1138. getIndex : function() {
  1139. YAHOO.log("The method getIndex() has been" +
  1140. " deprecated in favor of getKeyIndex()", "warn",
  1141. this.toString());
  1142. return this.getKeyIndex();
  1143. },
  1144. format : function() {
  1145. YAHOO.log("The method format() has been deprecated in favor of the " +
  1146. "DataTable method formatCell()", "error", this.toString());
  1147. }
  1148. };
  1149. /****************************************************************************/
  1150. /****************************************************************************/
  1151. /****************************************************************************/
  1152. /**
  1153. * Sort static utility to support Column sorting.
  1154. *
  1155. * @namespace YAHOO.util
  1156. * @class Sort
  1157. * @static
  1158. */
  1159. YAHOO.util.Sort = {
  1160. /////////////////////////////////////////////////////////////////////////////
  1161. //
  1162. // Public methods
  1163. //
  1164. /////////////////////////////////////////////////////////////////////////////
  1165. /**
  1166. * Comparator function for simple case-insensitive string sorting.
  1167. *
  1168. * @method compare
  1169. * @param a {Object} First sort argument.
  1170. * @param b {Object} Second sort argument.
  1171. * @param desc {Boolean} True if sort direction is descending, false if
  1172. * sort direction is ascending.
  1173. */
  1174. compare: function(a, b, desc) {
  1175. if((a === null) || (typeof a == "undefined")) {
  1176. if((b === null) || (typeof b == "undefined")) {
  1177. return 0;
  1178. }
  1179. else {
  1180. return 1;
  1181. }
  1182. }
  1183. else if((b === null) || (typeof b == "undefined")) {
  1184. return -1;
  1185. }
  1186. if(a.constructor == String) {
  1187. a = a.toLowerCase();
  1188. }
  1189. if(b.constructor == String) {
  1190. b = b.toLowerCase();
  1191. }
  1192. if(a < b) {
  1193. return (desc) ? 1 : -1;
  1194. }
  1195. else if (a > b) {
  1196. return (desc) ? -1 : 1;
  1197. }
  1198. else {
  1199. return 0;
  1200. }
  1201. }
  1202. };
  1203. /****************************************************************************/
  1204. /****************************************************************************/
  1205. /****************************************************************************/
  1206. /**
  1207. * ColumnDD subclasses DragDrop to support rearrangeable Columns.
  1208. *
  1209. * @namespace YAHOO.util
  1210. * @class ColumnDD
  1211. * @extends YAHOO.util.DDProxy
  1212. * @constructor
  1213. * @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
  1214. * @param oColumn {YAHOO.widget.Column} Column instance.
  1215. * @param elTh {HTMLElement} TH element reference.
  1216. * @param elTarget {HTMLElement} Drag target element.
  1217. */
  1218. YAHOO.widget.ColumnDD = function(oDataTable, oColumn, elTh, elTarget) {
  1219. if(oDataTable && oColumn && elTh && elTarget) {
  1220. this.datatable = oDataTable;
  1221. this.table = oDataTable.getTableEl();
  1222. this.column = oColumn;
  1223. this.headCell = elTh;
  1224. this.pointer = elTarget;
  1225. this.newIndex = null;
  1226. this.init(elTh);
  1227. this.initFrame(); // Needed for DDProxy
  1228. this.invalidHandleTypes = {};
  1229. // Set top/bottom padding to account for children of nested columns
  1230. this.setPadding(10, 0, (this.datatable.getTheadEl().offsetHeight + 10) , 0);
  1231. YAHOO.util.Event.on(window, 'resize', function() {
  1232. this.initConstraints();
  1233. }, this, true);
  1234. }
  1235. else {
  1236. YAHOO.log("Column dragdrop could not be created","warn",oDataTable.toString());
  1237. }
  1238. };
  1239. if(YAHOO.util.DDProxy) {
  1240. YAHOO.extend(YAHOO.widget.ColumnDD, YAHOO.util.DDProxy, {
  1241. initConstraints: function() {
  1242. //Get the top, right, bottom and left positions
  1243. var region = YAHOO.util.Dom.getRegion(this.table),
  1244. //Get the element we are working on
  1245. el = this.getEl(),
  1246. //Get the xy position of it
  1247. xy = YAHOO.util.Dom.getXY(el),
  1248. //Get the width and height
  1249. width = parseInt(YAHOO.util.Dom.getStyle(el, 'width'), 10),
  1250. height = parseInt(YAHOO.util.Dom.getStyle(el, 'height'), 10),
  1251. //Set left to x minus left
  1252. left = ((xy[0] - region.left) + 15), //Buffer of 15px
  1253. //Set right to right minus x minus width
  1254. right = ((region.right - xy[0] - width) + 15);
  1255. //Set the constraints based on the above calculations
  1256. this.setXConstraint(left, right);
  1257. this.setYConstraint(10, 10);
  1258. },
  1259. _resizeProxy: function() {
  1260. this.constructor.superclass._resizeProxy.apply(this, arguments);
  1261. var dragEl = this.getDragEl(),
  1262. el = this.getEl();
  1263. YAHOO.util.Dom.setStyle(this.pointer, 'height', (this.table.parentNode.offsetHeight + 10) + 'px');
  1264. YAHOO.util.Dom.setStyle(this.pointer, 'display', 'block');
  1265. var xy = YAHOO.util.Dom.getXY(el);
  1266. YAHOO.util.Dom.setXY(this.pointer, [xy[0], (xy[1] - 5)]);
  1267. YAHOO.util.Dom.setStyle(dragEl, 'height', this.datatable.getContainerEl().offsetHeight + "px");
  1268. YAHOO.util.Dom.setStyle(dragEl, 'width', (parseInt(YAHOO.util.Dom.getStyle(dragEl, 'width'),10) + 4) + 'px');
  1269. YAHOO.util.Dom.setXY(this.dragEl, xy);
  1270. },
  1271. onMouseDown: function() {
  1272. this.initConstraints();
  1273. this.resetConstraints();
  1274. },
  1275. clickValidator: function(e) {
  1276. if(!this.column.hidden) {
  1277. var target = YAHOO.util.Event.getTarget(e);
  1278. return ( this.isValidHandleChild(target) &&
  1279. (this.id == this.handleElId ||
  1280. this.DDM.handleWasClicked(target, this.id)) );
  1281. }
  1282. },
  1283. onDragOver: function(ev, id) {
  1284. // Validate target as a Column
  1285. var target = this.datatable.getColumn(id);
  1286. if(target) {
  1287. // Validate target as a top-level parent
  1288. var targetIndex = target.getTreeIndex();
  1289. while((targetIndex === null) && target.getParent()) {
  1290. target = target.getParent();
  1291. targetIndex = target.getTreeIndex();
  1292. }
  1293. if(targetIndex !== null) {
  1294. // Are we placing to left or right of target?
  1295. var elTarget = target.getThEl();
  1296. var newIndex = targetIndex;
  1297. var mouseX = YAHOO.util.Event.getPageX(ev),
  1298. targetX = YAHOO.util.Dom.getX(elTarget),
  1299. midX = targetX + ((YAHOO.util.Dom.get(elTarget).offsetWidth)/2),
  1300. currentIndex = this.column.getTreeIndex();
  1301. if (mouseX < midX) {
  1302. YAHOO.util.Dom.setX(this.pointer, targetX);
  1303. } else {
  1304. var targetWidth = parseInt(elTarget.offsetWidth, 10);
  1305. YAHOO.util.Dom.setX(this.pointer, (targetX + targetWidth));
  1306. newIndex++;
  1307. }
  1308. if (targetIndex > currentIndex) {
  1309. newIndex--;
  1310. }
  1311. if(newIndex < 0) {
  1312. newIndex = 0;
  1313. }
  1314. else if(newIndex > this.datatable.getColumnSet().tree[0].length) {
  1315. newIndex = this.datatable.getColumnSet().tree[0].length;
  1316. }
  1317. this.newIndex = newIndex;
  1318. }
  1319. }
  1320. },
  1321. onDragDrop: function() {
  1322. this.datatable.reorderColumn(this.column, this.newIndex);
  1323. },
  1324. endDrag: function() {
  1325. this.newIndex = null;
  1326. YAHOO.util.Dom.setStyle(this.pointer, 'display', 'none');
  1327. }
  1328. });
  1329. }
  1330. /****************************************************************************/
  1331. /****************************************************************************/
  1332. /****************************************************************************/
  1333. /**
  1334. * ColumnResizer subclasses DragDrop to support resizeable Columns.
  1335. *
  1336. * @namespace YAHOO.util
  1337. * @class ColumnResizer
  1338. * @extends YAHOO.util.DDProxy
  1339. * @constructor
  1340. * @param oDataTable {YAHOO.widget.DataTable} DataTable instance.
  1341. * @param oColumn {YAHOO.widget.Column} Column instance.
  1342. * @param elTh {HTMLElement} TH element reference.
  1343. * @param sHandleElId {String} DOM ID of the handle element that causes the resize.
  1344. * @param elProxy {HTMLElement} Resizer proxy element.
  1345. */
  1346. YAHOO.util.ColumnResizer = function(oDataTable, oColumn, elTh, sHandleId, elProxy) {
  1347. if(oDataTable && oColumn && elTh && sHandleId) {
  1348. this.datatable = oDataTable;
  1349. this.column = oColumn;
  1350. this.headCell = elTh;
  1351. this.headCellLiner = oColumn.getThLinerEl();
  1352. this.resizerLiner = elTh.firstChild;
  1353. this.init(sHandleId, sHandleId, {dragOnly:true, dragElId: elProxy.id});
  1354. this.initFrame(); // Needed for proxy
  1355. this.resetResizerEl(); // Needed when rowspan > 0
  1356. // Set right padding for bug 1858462
  1357. this.setPadding(0, 1, 0, 0);
  1358. }
  1359. else {
  1360. YAHOO.log("Column resizer could not be created","warn",oDataTable.toString());
  1361. }
  1362. };
  1363. if(YAHOO.util.DD) {
  1364. YAHOO.extend(YAHOO.util.ColumnResizer, YAHOO.util.DDProxy, {
  1365. /////////////////////////////////////////////////////////////////////////////
  1366. //
  1367. // Public methods
  1368. //
  1369. /////////////////////////////////////////////////////////////////////////////
  1370. /**
  1371. * Resets resizer element.
  1372. *
  1373. * @method resetResizerEl
  1374. */
  1375. resetResizerEl : function() {
  1376. var resizerStyle = YAHOO.util.Dom.get(this.handleElId).style;
  1377. resizerStyle.left = "auto";
  1378. resizerStyle.right = 0;
  1379. resizerStyle.top = "auto";
  1380. resizerStyle.bottom = 0;
  1381. resizerStyle.height = this.headCell.offsetHeight+"px";
  1382. },
  1383. /////////////////////////////////////////////////////////////////////////////
  1384. //
  1385. // Public DOM event handlers…