OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright (c) 2014 The Chromium Authors. All rights reserved. | 3 Copyright (c) 2014 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/ui/base/dom_helpers.html"> | 8 <link rel="import" href="/tracing/ui/base/dom_helpers.html"> |
9 <link rel="import" href="/tracing/ui/base/utils.html"> | 9 <link rel="import" href="/tracing/ui/base/utils.html"> |
10 | 10 |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 this.scheduleRebuildBody_(); | 319 this.scheduleRebuildBody_(); |
320 }, | 320 }, |
321 | 321 |
322 get emptyValue() { | 322 get emptyValue() { |
323 return this.emptyValue_; | 323 return this.emptyValue_; |
324 }, | 324 }, |
325 | 325 |
326 set emptyValue(emptyValue) { | 326 set emptyValue(emptyValue) { |
327 var previousEmptyValue = this.emptyValue_; | 327 var previousEmptyValue = this.emptyValue_; |
328 this.emptyValue_ = emptyValue; | 328 this.emptyValue_ = emptyValue; |
329 if (this.tableRows_.length === 0 && emptyValue !== previousEmptyValue) | 329 if (this.tableRows_.length === 0 && emptyValue !== previousEmptyValue) { |
330 this.scheduleRebuildBody_(); | 330 this.scheduleRebuildBody_(); |
| 331 } |
331 }, | 332 }, |
332 | 333 |
333 /** | 334 /** |
334 * Data objects should have the following fields: | 335 * Data objects should have the following fields: |
335 * mandatory: title, value | 336 * mandatory: title, value |
336 * optional: width {string}, cmp {function}, colSpan {number}, | 337 * optional: width {string}, cmp {function}, colSpan {number}, |
337 * showExpandButtons {boolean}, | 338 * showExpandButtons {boolean}, |
338 * align {tr.ui.b.TableFormat.ColumnAlignment} | 339 * align {tr.ui.b.TableFormat.ColumnAlignment} |
339 * | 340 * |
340 * @param {Array} columns An array of data objects. | 341 * @param {Array} columns An array of data objects. |
341 */ | 342 */ |
342 set tableColumns(columns) { | 343 set tableColumns(columns) { |
343 // Figure out the columns with expand buttons... | 344 // Figure out the columns with expand buttons... |
344 var columnsWithExpandButtons = []; | 345 var columnsWithExpandButtons = []; |
345 for (var i = 0; i < columns.length; i++) { | 346 for (var i = 0; i < columns.length; i++) { |
346 if (columns[i].showExpandButtons) | 347 if (columns[i].showExpandButtons) { |
347 columnsWithExpandButtons.push(i); | 348 columnsWithExpandButtons.push(i); |
| 349 } |
348 } | 350 } |
349 if (columnsWithExpandButtons.length === 0) { | 351 if (columnsWithExpandButtons.length === 0) { |
350 // First column if none have specified. | 352 // First column if none have specified. |
351 columnsWithExpandButtons = [0]; | 353 columnsWithExpandButtons = [0]; |
352 } | 354 } |
353 | 355 |
354 // Sanity check columns. | 356 // Sanity check columns. |
355 for (var i = 0; i < columns.length; i++) { | 357 for (var i = 0; i < columns.length; i++) { |
356 var colInfo = columns[i]; | 358 var colInfo = columns[i]; |
357 if (colInfo.width === undefined) | 359 if (colInfo.width === undefined) continue; |
358 continue; | |
359 | 360 |
360 var hasExpandButton = columnsWithExpandButtons.includes(i); | 361 var hasExpandButton = columnsWithExpandButtons.includes(i); |
361 | 362 |
362 var w = colInfo.width; | 363 var w = colInfo.width; |
363 if (w) { | 364 if (w) { |
364 if (/\d+px/.test(w)) { | 365 if (/\d+px/.test(w)) { |
365 continue; | 366 continue; |
366 } else if (/\d+%/.test(w)) { | 367 } else if (/\d+%/.test(w)) { |
367 if (hasExpandButton) { | 368 if (hasExpandButton) { |
368 throw new Error('Columns cannot be %-sized and host ' + | 369 throw new Error('Columns cannot be %-sized and host ' + |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 get footerRows() { | 433 get footerRows() { |
433 return this.tableFooterRows_; | 434 return this.tableFooterRows_; |
434 }, | 435 }, |
435 | 436 |
436 get userCanModifySortOrder() { | 437 get userCanModifySortOrder() { |
437 return this.userCanModifySortOrder_; | 438 return this.userCanModifySortOrder_; |
438 }, | 439 }, |
439 | 440 |
440 set userCanModifySortOrder(userCanModifySortOrder) { | 441 set userCanModifySortOrder(userCanModifySortOrder) { |
441 var newUserCanModifySortOrder = !!userCanModifySortOrder; | 442 var newUserCanModifySortOrder = !!userCanModifySortOrder; |
442 if (newUserCanModifySortOrder === this.userCanModifySortOrder_) | 443 if (newUserCanModifySortOrder === this.userCanModifySortOrder_) { |
443 return; | 444 return; |
| 445 } |
444 | 446 |
445 this.userCanModifySortOrder_ = newUserCanModifySortOrder; | 447 this.userCanModifySortOrder_ = newUserCanModifySortOrder; |
446 this.scheduleRebuildHeaders_(); | 448 this.scheduleRebuildHeaders_(); |
447 }, | 449 }, |
448 | 450 |
449 set sortColumnIndex(number) { | 451 set sortColumnIndex(number) { |
450 if (number === this.sortColumnIndex_) | 452 if (number === this.sortColumnIndex_) return; |
451 return; | |
452 | 453 |
453 if (number !== undefined) { | 454 if (number !== undefined) { |
454 if (this.tableColumns_.length <= number) | 455 if (this.tableColumns_.length <= number) { |
455 throw new Error('Column number ' + number + ' is out of bounds.'); | 456 throw new Error('Column number ' + number + ' is out of bounds.'); |
456 if (!this.tableColumns_[number].cmp) | 457 } |
| 458 if (!this.tableColumns_[number].cmp) { |
457 throw new Error('Column ' + number + ' does not have a comparator.'); | 459 throw new Error('Column ' + number + ' does not have a comparator.'); |
| 460 } |
458 } | 461 } |
459 | 462 |
460 this.sortColumnIndex_ = number; | 463 this.sortColumnIndex_ = number; |
461 this.updateHeaderArrows_(); | 464 this.updateHeaderArrows_(); |
462 this.scheduleRebuildBody_(); | 465 this.scheduleRebuildBody_(); |
463 this.dispatchSortingChangedEvent_(); | 466 this.dispatchSortingChangedEvent_(); |
464 }, | 467 }, |
465 | 468 |
466 get sortColumnIndex() { | 469 get sortColumnIndex() { |
467 return this.sortColumnIndex_; | 470 return this.sortColumnIndex_; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 for (var i = 0; i < this.tableColumns_.length; ++i) { | 511 for (var i = 0; i < this.tableColumns_.length; ++i) { |
509 var colElement = document.createElement('col'); | 512 var colElement = document.createElement('col'); |
510 if (i === selectedTableColumnIndex) { | 513 if (i === selectedTableColumnIndex) { |
511 colElement.setAttribute('selected', true); | 514 colElement.setAttribute('selected', true); |
512 } | 515 } |
513 Polymer.dom(this.$.cols).appendChild(colElement); | 516 Polymer.dom(this.$.cols).appendChild(colElement); |
514 } | 517 } |
515 | 518 |
516 this.headerCells_ = []; | 519 this.headerCells_ = []; |
517 Polymer.dom(this.$.head).textContent = ''; | 520 Polymer.dom(this.$.head).textContent = ''; |
518 if (!this.showHeader_) | 521 if (!this.showHeader_) return; |
519 return; | |
520 | 522 |
521 var tr = this.appendNewElement_(this.$.head, 'tr'); | 523 var tr = this.appendNewElement_(this.$.head, 'tr'); |
522 for (var i = 0; i < this.tableColumns_.length; i++) { | 524 for (var i = 0; i < this.tableColumns_.length; i++) { |
523 var td = this.appendNewElement_(tr, 'td'); | 525 var td = this.appendNewElement_(tr, 'td'); |
524 | 526 |
525 var headerCell = document.createElement('tr-ui-b-table-header-cell'); | 527 var headerCell = document.createElement('tr-ui-b-table-header-cell'); |
526 headerCell.column = this.tableColumns_[i]; | 528 headerCell.column = this.tableColumns_[i]; |
527 | 529 |
528 // If the table can be sorted by this column and the user can modify | 530 // If the table can be sorted by this column and the user can modify |
529 // the sort order, attach a tap callback to the column. | 531 // the sort order, attach a tap callback to the column. |
530 if (this.tableColumns_[i].cmp) { | 532 if (this.tableColumns_[i].cmp) { |
531 var isColumnCurrentlySorted = i === this.sortColumnIndex_; | 533 var isColumnCurrentlySorted = i === this.sortColumnIndex_; |
532 if (isColumnCurrentlySorted) { | 534 if (isColumnCurrentlySorted) { |
533 headerCell.sideContent = this.sortDescending_ ? | 535 headerCell.sideContent = this.sortDescending_ ? |
534 DESCENDING_ARROW : ASCENDING_ARROW; | 536 DESCENDING_ARROW : ASCENDING_ARROW; |
535 if (!this.userCanModifySortOrder_) | 537 if (!this.userCanModifySortOrder_) { |
536 headerCell.sideContentDisabled = true; | 538 headerCell.sideContentDisabled = true; |
| 539 } |
537 } | 540 } |
538 if (this.userCanModifySortOrder_) { | 541 if (this.userCanModifySortOrder_) { |
539 Polymer.dom(td).classList.add('sensitive'); | 542 Polymer.dom(td).classList.add('sensitive'); |
540 if (!isColumnCurrentlySorted) | 543 if (!isColumnCurrentlySorted) { |
541 headerCell.sideContent = UNSORTED_ARROW; | 544 headerCell.sideContent = UNSORTED_ARROW; |
| 545 } |
542 headerCell.tapCallback = this.createSortCallback_(i); | 546 headerCell.tapCallback = this.createSortCallback_(i); |
543 } | 547 } |
544 } | 548 } |
545 | 549 |
546 Polymer.dom(td).appendChild(headerCell); | 550 Polymer.dom(td).appendChild(headerCell); |
547 this.headerCells_.push(headerCell); | 551 this.headerCells_.push(headerCell); |
548 } | 552 } |
549 }, | 553 }, |
550 | 554 |
551 applySizes_: function() { | 555 applySizes_: function() { |
552 if (this.tableRows_.length === 0 && !this.showHeader) | 556 if (this.tableRows_.length === 0 && !this.showHeader) return; |
553 return; | 557 |
554 var rowToRemoveSizing; | 558 var rowToRemoveSizing; |
555 var rowToSize; | 559 var rowToSize; |
556 if (this.showHeader) { | 560 if (this.showHeader) { |
557 rowToSize = Polymer.dom(this.$.head).children[0]; | 561 rowToSize = Polymer.dom(this.$.head).children[0]; |
558 rowToRemoveSizing = Polymer.dom(this.$.body).children[0]; | 562 rowToRemoveSizing = Polymer.dom(this.$.body).children[0]; |
559 } else { | 563 } else { |
560 rowToSize = Polymer.dom(this.$.body).children[0]; | 564 rowToSize = Polymer.dom(this.$.body).children[0]; |
561 rowToRemoveSizing = Polymer.dom(this.$.head).children[0]; | 565 rowToRemoveSizing = Polymer.dom(this.$.head).children[0]; |
562 } | 566 } |
563 for (var i = 0; i < this.tableColumns_.length; i++) { | 567 for (var i = 0; i < this.tableColumns_.length; i++) { |
564 if (rowToRemoveSizing && Polymer.dom(rowToRemoveSizing).children[i]) { | 568 if (rowToRemoveSizing && Polymer.dom(rowToRemoveSizing).children[i]) { |
565 var tdToRemoveSizing = Polymer.dom(rowToRemoveSizing).children[i]; | 569 var tdToRemoveSizing = Polymer.dom(rowToRemoveSizing).children[i]; |
566 tdToRemoveSizing.style.minWidth = ''; | 570 tdToRemoveSizing.style.minWidth = ''; |
567 tdToRemoveSizing.style.width = ''; | 571 tdToRemoveSizing.style.width = ''; |
568 } | 572 } |
569 | 573 |
570 // Apply sizing. | 574 // Apply sizing. |
571 var td = Polymer.dom(rowToSize).children[i]; | 575 var td = Polymer.dom(rowToSize).children[i]; |
572 | 576 |
573 var delta; | 577 var delta; |
574 if (this.columnsWithExpandButtons_.includes(i)) { | 578 if (this.columnsWithExpandButtons_.includes(i)) { |
575 td.style.paddingLeft = this.basicIndentation_ + 'px'; | 579 td.style.paddingLeft = this.basicIndentation_ + 'px'; |
576 delta = this.basicIndentation_ + 'px'; | 580 delta = this.basicIndentation_ + 'px'; |
577 } else { | 581 } else { |
578 delta = undefined; | 582 delta = undefined; |
579 } | 583 } |
580 | 584 |
581 function calc(base, delta) { | 585 function calc(base, delta) { |
582 if (delta) | 586 if (delta) { |
583 return 'calc(' + base + ' - ' + delta + ')'; | 587 return 'calc(' + base + ' - ' + delta + ')'; |
| 588 } |
584 return base; | 589 return base; |
585 } | 590 } |
586 | 591 |
587 var w = this.tableColumns_[i].width; | 592 var w = this.tableColumns_[i].width; |
588 if (w) { | 593 if (w) { |
589 if (/\d+px/.test(w)) { | 594 if (/\d+px/.test(w)) { |
590 td.style.minWidth = calc(w, delta); | 595 td.style.minWidth = calc(w, delta); |
591 } else if (/\d+%/.test(w)) { | 596 } else if (/\d+%/.test(w)) { |
592 td.style.width = w; | 597 td.style.width = w; |
593 } else { | 598 } else { |
594 throw new Error('Unrecognized width string: ' + w); | 599 throw new Error('Unrecognized width string: ' + w); |
595 } | 600 } |
596 } | 601 } |
597 } | 602 } |
598 }, | 603 }, |
599 | 604 |
600 createSortCallback_: function(columnNumber) { | 605 createSortCallback_: function(columnNumber) { |
601 return function() { | 606 return function() { |
602 if (!this.userCanModifySortOrder_) | 607 if (!this.userCanModifySortOrder_) return; |
603 return; | 608 |
604 var previousIndex = this.sortColumnIndex; | 609 var previousIndex = this.sortColumnIndex; |
605 this.sortColumnIndex = columnNumber; | 610 this.sortColumnIndex = columnNumber; |
606 if (previousIndex !== columnNumber) | 611 if (previousIndex !== columnNumber) { |
607 this.sortDescending = false; | 612 this.sortDescending = false; |
608 else | 613 } else { |
609 this.sortDescending = !this.sortDescending; | 614 this.sortDescending = !this.sortDescending; |
| 615 } |
610 }.bind(this); | 616 }.bind(this); |
611 }, | 617 }, |
612 | 618 |
613 generateTableRowNodes_: function(tableSection, userRows, rowInfoMap, | 619 generateTableRowNodes_: function(tableSection, userRows, rowInfoMap, |
614 indentation, lastAddedRow, | 620 indentation, lastAddedRow, |
615 parentRowInfo) { | 621 parentRowInfo) { |
616 if (this.sortColumnIndex_ !== undefined && | 622 if (this.sortColumnIndex_ !== undefined && |
617 tableSection === this.$.body) { | 623 tableSection === this.$.body) { |
618 userRows = userRows.slice(); // Don't mess with the input data. | 624 userRows = userRows.slice(); // Don't mess with the input data. |
619 userRows.sort(function(rowA, rowB) { | 625 userRows.sort(function(rowA, rowB) { |
620 var c = this.tableColumns_[this.sortColumnIndex_].cmp( | 626 var c = this.tableColumns_[this.sortColumnIndex_].cmp( |
621 rowA, rowB); | 627 rowA, rowB); |
622 if (this.sortDescending_) | 628 if (this.sortDescending_) { |
623 c = -c; | 629 c = -c; |
| 630 } |
624 return c; | 631 return c; |
625 }.bind(this)); | 632 }.bind(this)); |
626 } | 633 } |
627 | 634 |
628 for (var i = 0; i < userRows.length; i++) { | 635 for (var i = 0; i < userRows.length; i++) { |
629 var userRow = userRows[i]; | 636 var userRow = userRows[i]; |
630 var rowInfo = this.getOrCreateRowInfoFor_(rowInfoMap, userRow, | 637 var rowInfo = this.getOrCreateRowInfoFor_(rowInfoMap, userRow, |
631 parentRowInfo); | 638 parentRowInfo); |
632 var htmlNode = this.getHTMLNodeForRowInfo_( | 639 var htmlNode = this.getHTMLNodeForRowInfo_( |
633 tableSection, rowInfo, rowInfoMap, indentation); | 640 tableSection, rowInfo, rowInfoMap, indentation); |
634 | 641 |
635 if (lastAddedRow === undefined) { | 642 if (lastAddedRow === undefined) { |
636 // Put first into the table. | 643 // Put first into the table. |
637 Polymer.dom(tableSection).insertBefore( | 644 Polymer.dom(tableSection).insertBefore( |
638 htmlNode, Polymer.dom(tableSection).firstChild); | 645 htmlNode, Polymer.dom(tableSection).firstChild); |
639 } else { | 646 } else { |
640 // This is shorthand for insertAfter(htmlNode, lastAdded). | 647 // This is shorthand for insertAfter(htmlNode, lastAdded). |
641 var nextSiblingOfLastAdded = Polymer.dom(lastAddedRow).nextSibling; | 648 var nextSiblingOfLastAdded = Polymer.dom(lastAddedRow).nextSibling; |
642 Polymer.dom(tableSection).insertBefore( | 649 Polymer.dom(tableSection).insertBefore( |
643 htmlNode, nextSiblingOfLastAdded); | 650 htmlNode, nextSiblingOfLastAdded); |
644 } | 651 } |
645 | 652 |
646 lastAddedRow = htmlNode; | 653 lastAddedRow = htmlNode; |
647 if (!rowInfo.isExpanded) | 654 if (!rowInfo.isExpanded) continue; |
648 continue; | |
649 | 655 |
650 // Append subrows now. | 656 // Append subrows now. |
651 lastAddedRow = this.generateTableRowNodes_( | 657 lastAddedRow = this.generateTableRowNodes_( |
652 tableSection, userRow[this.subRowsPropertyName_], rowInfoMap, | 658 tableSection, userRow[this.subRowsPropertyName_], rowInfoMap, |
653 indentation + 1, lastAddedRow, rowInfo); | 659 indentation + 1, lastAddedRow, rowInfo); |
654 } | 660 } |
655 return lastAddedRow; | 661 return lastAddedRow; |
656 }, | 662 }, |
657 | 663 |
658 getOrCreateRowInfoFor_: function(rowInfoMap, userRow, parentRowInfo) { | 664 getOrCreateRowInfoFor_: function(rowInfoMap, userRow, parentRowInfo) { |
(...skipping 11 matching lines...) Expand all Loading... |
670 } | 676 } |
671 | 677 |
672 // Recompute isExpanded in case defaultExpansionStateCallback_ has | 678 // Recompute isExpanded in case defaultExpansionStateCallback_ has |
673 // changed. | 679 // changed. |
674 rowInfo.isExpanded = this.getExpandedForUserRow_(userRow); | 680 rowInfo.isExpanded = this.getExpandedForUserRow_(userRow); |
675 | 681 |
676 return rowInfo; | 682 return rowInfo; |
677 }, | 683 }, |
678 | 684 |
679 customizeTableRow_: function(userRow, trElement) { | 685 customizeTableRow_: function(userRow, trElement) { |
680 if (!this.customizeTableRowCallback_) | 686 if (!this.customizeTableRowCallback_) return; |
681 return; | |
682 this.customizeTableRowCallback_(userRow, trElement); | 687 this.customizeTableRowCallback_(userRow, trElement); |
683 }, | 688 }, |
684 | 689 |
685 get basicIndentation_() { | 690 get basicIndentation_() { |
686 if (this.computedFontSizePx_ === undefined) { | 691 if (this.computedFontSizePx_ === undefined) { |
687 this.computedFontSizePx_ = parseInt( | 692 this.computedFontSizePx_ = parseInt( |
688 getComputedStyle(this).fontSize) || 16; | 693 getComputedStyle(this).fontSize) || 16; |
689 } | 694 } |
690 return this.computedFontSizePx_ - 2; | 695 return this.computedFontSizePx_ - 2; |
691 }, | 696 }, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 | 730 |
726 case ColumnAlignment.RIGHT: | 731 case ColumnAlignment.RIGHT: |
727 td.style.textAlign = 'right'; | 732 td.style.textAlign = 'right'; |
728 break; | 733 break; |
729 | 734 |
730 default: | 735 default: |
731 throw new Error('Invalid alignment of column at index=' + i + | 736 throw new Error('Invalid alignment of column at index=' + i + |
732 ': ' + column.align); | 737 ': ' + column.align); |
733 } | 738 } |
734 | 739 |
735 if (this.doesColumnIndexSupportSelection(i)) | 740 if (this.doesColumnIndexSupportSelection(i)) { |
736 Polymer.dom(td).classList.add('supports-selection'); | 741 Polymer.dom(td).classList.add('supports-selection'); |
| 742 } |
737 | 743 |
738 if (this.columnsWithExpandButtons_.includes(i)) { | 744 if (this.columnsWithExpandButtons_.includes(i)) { |
739 if (rowInfo.userRow[this.subRowsPropertyName_] && | 745 if (rowInfo.userRow[this.subRowsPropertyName_] && |
740 rowInfo.userRow[this.subRowsPropertyName_].length > 0) { | 746 rowInfo.userRow[this.subRowsPropertyName_].length > 0) { |
741 td.style.paddingLeft = INDENT_SPACE + 'px'; | 747 td.style.paddingLeft = INDENT_SPACE + 'px'; |
742 td.style.display = 'flex'; | 748 td.style.display = 'flex'; |
743 var expandButton = this.appendNewElement_(td, 'expand-button'); | 749 var expandButton = this.appendNewElement_(td, 'expand-button'); |
744 Polymer.dom(expandButton).textContent = RIGHT_ARROW; | 750 Polymer.dom(expandButton).textContent = RIGHT_ARROW; |
745 if (rowInfo.isExpanded) | 751 if (rowInfo.isExpanded) { |
746 Polymer.dom(expandButton).classList.add('button-expanded'); | 752 Polymer.dom(expandButton).classList.add('button-expanded'); |
| 753 } |
747 } else { | 754 } else { |
748 td.style.paddingLeft = INDENT_SPACE_NO_BUTTON + 'px'; | 755 td.style.paddingLeft = INDENT_SPACE_NO_BUTTON + 'px'; |
749 } | 756 } |
750 } | 757 } |
751 | 758 |
752 if (value !== undefined) { | 759 if (value !== undefined) { |
753 Polymer.dom(td).appendChild( | 760 Polymer.dom(td).appendChild( |
754 tr.ui.b.asHTMLOrTextNode(value, this.ownerDocument)); | 761 tr.ui.b.asHTMLOrTextNode(value, this.ownerDocument)); |
755 } | 762 } |
756 | 763 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 }.bind(this, i)); | 824 }.bind(this, i)); |
818 } | 825 } |
819 | 826 |
820 i += colSpan; | 827 i += colSpan; |
821 } | 828 } |
822 | 829 |
823 return rowInfo.htmlNode; | 830 return rowInfo.htmlNode; |
824 }, | 831 }, |
825 | 832 |
826 removeSubNodes_: function(tableSection, rowInfo, rowInfoMap) { | 833 removeSubNodes_: function(tableSection, rowInfo, rowInfoMap) { |
827 if (rowInfo.userRow[this.subRowsPropertyName_] === undefined) | 834 if (rowInfo.userRow[this.subRowsPropertyName_] === undefined) return; |
828 return; | 835 |
829 for (var i = 0; | 836 for (var i = 0; |
830 i < rowInfo.userRow[this.subRowsPropertyName_].length; i++) { | 837 i < rowInfo.userRow[this.subRowsPropertyName_].length; i++) { |
831 var subRow = rowInfo.userRow[this.subRowsPropertyName_][i]; | 838 var subRow = rowInfo.userRow[this.subRowsPropertyName_][i]; |
832 var subRowInfo = rowInfoMap.get(subRow); | 839 var subRowInfo = rowInfoMap.get(subRow); |
833 if (!subRowInfo) | 840 if (!subRowInfo) continue; |
834 continue; | |
835 | 841 |
836 var subNode = subRowInfo.htmlNode; | 842 var subNode = subRowInfo.htmlNode; |
837 if (subNode && Polymer.dom(subNode).parentNode === tableSection) { | 843 if (subNode && Polymer.dom(subNode).parentNode === tableSection) { |
838 Polymer.dom(tableSection).removeChild(subNode); | 844 Polymer.dom(tableSection).removeChild(subNode); |
839 this.removeSubNodes_(tableSection, subRowInfo, rowInfoMap); | 845 this.removeSubNodes_(tableSection, subRowInfo, rowInfoMap); |
840 } | 846 } |
841 } | 847 } |
842 }, | 848 }, |
843 | 849 |
844 scheduleRebuildHeaders_: function() { | 850 scheduleRebuildHeaders_: function() { |
845 this.headerDirty_ = true; | 851 this.headerDirty_ = true; |
846 this.scheduleRebuild_(); | 852 this.scheduleRebuild_(); |
847 }, | 853 }, |
848 | 854 |
849 scheduleRebuildBody_: function() { | 855 scheduleRebuildBody_: function() { |
850 this.bodyDirty_ = true; | 856 this.bodyDirty_ = true; |
851 this.scheduleRebuild_(); | 857 this.scheduleRebuild_(); |
852 }, | 858 }, |
853 | 859 |
854 scheduleRebuildFooter_: function() { | 860 scheduleRebuildFooter_: function() { |
855 this.footerDirty_ = true; | 861 this.footerDirty_ = true; |
856 this.scheduleRebuild_(); | 862 this.scheduleRebuild_(); |
857 }, | 863 }, |
858 | 864 |
859 scheduleRebuild_: function() { | 865 scheduleRebuild_: function() { |
860 if (this.rebuildPending_) | 866 if (this.rebuildPending_) return; |
861 return; | 867 |
862 this.rebuildPending_ = true; | 868 this.rebuildPending_ = true; |
863 setTimeout(function() { | 869 setTimeout(function() { |
864 this.rebuildPending_ = false; | 870 this.rebuildPending_ = false; |
865 this.rebuild(); | 871 this.rebuild(); |
866 }.bind(this), 0); | 872 }.bind(this), 0); |
867 }, | 873 }, |
868 | 874 |
869 rebuildIfNeeded_: function() { | 875 rebuildIfNeeded_: function() { |
870 this.rebuild(); | 876 this.rebuild(); |
871 }, | 877 }, |
(...skipping 18 matching lines...) Expand all Loading... |
890 var td = this.ownerDocument.createElement('td'); | 896 var td = this.ownerDocument.createElement('td'); |
891 Polymer.dom(trElement).appendChild(td); | 897 Polymer.dom(trElement).appendChild(td); |
892 td.colSpan = this.tableColumns_.length; | 898 td.colSpan = this.tableColumns_.length; |
893 var emptyValue = this.emptyValue_; | 899 var emptyValue = this.emptyValue_; |
894 Polymer.dom(td).appendChild( | 900 Polymer.dom(td).appendChild( |
895 tr.ui.b.asHTMLOrTextNode(emptyValue, this.ownerDocument)); | 901 tr.ui.b.asHTMLOrTextNode(emptyValue, this.ownerDocument)); |
896 } | 902 } |
897 this.bodyDirty_ = false; | 903 this.bodyDirty_ = false; |
898 } | 904 } |
899 | 905 |
900 if (wasBodyOrHeaderDirty) | 906 if (wasBodyOrHeaderDirty) this.applySizes_(); |
901 this.applySizes_(); | |
902 | 907 |
903 if (this.footerDirty_) { | 908 if (this.footerDirty_) { |
904 Polymer.dom(this.$.foot).textContent = ''; | 909 Polymer.dom(this.$.foot).textContent = ''; |
905 this.generateTableRowNodes_( | 910 this.generateTableRowNodes_( |
906 this.$.foot, | 911 this.$.foot, |
907 this.tableFooterRows_, this.tableFooterRowsInfo_, 0, | 912 this.tableFooterRows_, this.tableFooterRowsInfo_, 0, |
908 undefined, undefined); | 913 undefined, undefined); |
909 if (this.tableFooterRowsInfo_.length) { | 914 if (this.tableFooterRowsInfo_.length) { |
910 Polymer.dom(this.$.body).classList.add('has-footer'); | 915 Polymer.dom(this.$.body).classList.add('has-footer'); |
911 } else { | 916 } else { |
912 Polymer.dom(this.$.body).classList.remove('has-footer'); | 917 Polymer.dom(this.$.body).classList.remove('has-footer'); |
913 } | 918 } |
914 this.footerDirty_ = false; | 919 this.footerDirty_ = false; |
915 } | 920 } |
916 }, | 921 }, |
917 | 922 |
918 appendNewElement_: function(parent, tagName) { | 923 appendNewElement_: function(parent, tagName) { |
919 var element = parent.ownerDocument.createElement(tagName); | 924 var element = parent.ownerDocument.createElement(tagName); |
920 Polymer.dom(parent).appendChild(element); | 925 Polymer.dom(parent).appendChild(element); |
921 return element; | 926 return element; |
922 }, | 927 }, |
923 | 928 |
924 getExpandedForTableRow: function(userRow) { | 929 getExpandedForTableRow: function(userRow) { |
925 this.rebuildIfNeeded_(); | 930 this.rebuildIfNeeded_(); |
926 var rowInfo = this.tableRowsInfo_.get(userRow); | 931 var rowInfo = this.tableRowsInfo_.get(userRow); |
927 if (rowInfo === undefined) | 932 if (rowInfo === undefined) { |
928 throw new Error('Row has not been seen, must expand its parents'); | 933 throw new Error('Row has not been seen, must expand its parents'); |
| 934 } |
929 return rowInfo.isExpanded; | 935 return rowInfo.isExpanded; |
930 }, | 936 }, |
931 | 937 |
932 getExpandedForUserRow_: function(userRow) { | 938 getExpandedForUserRow_: function(userRow) { |
933 if (userRow[this.subRowsPropertyName_] === undefined) | 939 if (userRow[this.subRowsPropertyName_] === undefined) { |
934 return false; | 940 return false; |
935 if (userRow[this.subRowsPropertyName_].length === 0) | 941 } |
| 942 if (userRow[this.subRowsPropertyName_].length === 0) { |
936 return false; | 943 return false; |
937 if (userRow.isExpanded) | 944 } |
| 945 if (userRow.isExpanded) { |
938 return true; | 946 return true; |
| 947 } |
939 if ((userRow.isExpanded !== undefined) && | 948 if ((userRow.isExpanded !== undefined) && |
940 (userRow.isExpanded === false)) | 949 (userRow.isExpanded === false)) { |
941 return false; | 950 return false; |
| 951 } |
942 | 952 |
943 var rowInfo = this.tableRowsInfo_.get(userRow); | 953 var rowInfo = this.tableRowsInfo_.get(userRow); |
944 if (rowInfo && rowInfo.isExpanded) | 954 if (rowInfo && rowInfo.isExpanded) { |
945 return true; | 955 return true; |
| 956 } |
946 | 957 |
947 if (this.defaultExpansionStateCallback_ === undefined) | 958 if (this.defaultExpansionStateCallback_ === undefined) { |
948 return false; | 959 return false; |
| 960 } |
949 | 961 |
950 var parentUserRow = undefined; | 962 var parentUserRow = undefined; |
951 if (rowInfo && rowInfo.parentRowInfo) | 963 if (rowInfo && rowInfo.parentRowInfo) { |
952 parentUserRow = rowInfo.parentRowInfo.userRow; | 964 parentUserRow = rowInfo.parentRowInfo.userRow; |
| 965 } |
953 | 966 |
954 return this.defaultExpansionStateCallback_( | 967 return this.defaultExpansionStateCallback_( |
955 userRow, parentUserRow); | 968 userRow, parentUserRow); |
956 }, | 969 }, |
957 | 970 |
958 setExpandedForTableRow: function(userRow, expanded) { | 971 setExpandedForTableRow: function(userRow, expanded) { |
959 this.rebuildIfNeeded_(); | 972 this.rebuildIfNeeded_(); |
960 var rowInfo = this.tableRowsInfo_.get(userRow); | 973 var rowInfo = this.tableRowsInfo_.get(userRow); |
961 if (rowInfo === undefined) | 974 if (rowInfo === undefined) { |
962 throw new Error('Row has not been seen, must expand its parents'); | 975 throw new Error('Row has not been seen, must expand its parents'); |
| 976 } |
963 return this.setExpandedForUserRow_(this.$.body, this.tableRowsInfo_, | 977 return this.setExpandedForUserRow_(this.$.body, this.tableRowsInfo_, |
964 userRow, expanded); | 978 userRow, expanded); |
965 }, | 979 }, |
966 | 980 |
967 setExpandedForUserRow_: function(tableSection, rowInfoMap, | 981 setExpandedForUserRow_: function(tableSection, rowInfoMap, |
968 userRow, expanded) { | 982 userRow, expanded) { |
969 this.rebuildIfNeeded_(); | 983 this.rebuildIfNeeded_(); |
970 | 984 |
971 var rowInfo = rowInfoMap.get(userRow); | 985 var rowInfo = rowInfoMap.get(userRow); |
972 if (rowInfo === undefined) | 986 if (rowInfo === undefined) { |
973 throw new Error('Row has not been seen, must expand its parents'); | 987 throw new Error('Row has not been seen, must expand its parents'); |
| 988 } |
974 | 989 |
975 rowInfo.isExpanded = !!expanded; | 990 rowInfo.isExpanded = !!expanded; |
976 // If no node, then nothing further needs doing. | 991 // If no node, then nothing further needs doing. |
977 if (rowInfo.htmlNode === undefined) | 992 if (rowInfo.htmlNode === undefined) return; |
978 return; | |
979 | 993 |
980 // If its detached, then nothing needs doing. | 994 // If its detached, then nothing needs doing. |
981 if (rowInfo.htmlNode.parentElement !== tableSection) | 995 if (rowInfo.htmlNode.parentElement !== tableSection) { |
982 return; | 996 return; |
| 997 } |
983 | 998 |
984 // Otherwise, rebuild. | 999 // Otherwise, rebuild. |
985 var expandButton = | 1000 var expandButton = |
986 Polymer.dom(rowInfo.htmlNode).querySelector('expand-button'); | 1001 Polymer.dom(rowInfo.htmlNode).querySelector('expand-button'); |
987 if (rowInfo.isExpanded) { | 1002 if (rowInfo.isExpanded) { |
988 Polymer.dom(expandButton).classList.add('button-expanded'); | 1003 Polymer.dom(expandButton).classList.add('button-expanded'); |
989 var lastAddedRow = rowInfo.htmlNode; | 1004 var lastAddedRow = rowInfo.htmlNode; |
990 if (rowInfo.userRow[this.subRowsPropertyName_]) { | 1005 if (rowInfo.userRow[this.subRowsPropertyName_]) { |
991 this.generateTableRowNodes_( | 1006 this.generateTableRowNodes_( |
992 tableSection, | 1007 tableSection, |
993 rowInfo.userRow[this.subRowsPropertyName_], rowInfoMap, | 1008 rowInfo.userRow[this.subRowsPropertyName_], rowInfoMap, |
994 rowInfo.indentation + 1, | 1009 rowInfo.indentation + 1, |
995 lastAddedRow, rowInfo); | 1010 lastAddedRow, rowInfo); |
996 } | 1011 } |
997 } else { | 1012 } else { |
998 Polymer.dom(expandButton).classList.remove('button-expanded'); | 1013 Polymer.dom(expandButton).classList.remove('button-expanded'); |
999 this.removeSubNodes_(tableSection, rowInfo, rowInfoMap); | 1014 this.removeSubNodes_(tableSection, rowInfo, rowInfoMap); |
1000 } | 1015 } |
1001 | 1016 |
1002 this.maybeUpdateSelectedRow_(); | 1017 this.maybeUpdateSelectedRow_(); |
1003 }, | 1018 }, |
1004 | 1019 |
1005 get selectionMode() { | 1020 get selectionMode() { |
1006 return this.selectionMode_; | 1021 return this.selectionMode_; |
1007 }, | 1022 }, |
1008 | 1023 |
1009 set selectionMode(selectionMode) { | 1024 set selectionMode(selectionMode) { |
1010 if (!tr.b.dictionaryContainsValue(SelectionMode, selectionMode)) | 1025 if (!tr.b.dictionaryContainsValue(SelectionMode, selectionMode)) { |
1011 throw new Error('Invalid selection mode ' + selectionMode); | 1026 throw new Error('Invalid selection mode ' + selectionMode); |
| 1027 } |
1012 this.rebuildIfNeeded_(); | 1028 this.rebuildIfNeeded_(); |
1013 this.selectionMode_ = selectionMode; | 1029 this.selectionMode_ = selectionMode; |
1014 this.didSelectionStateChange_(); | 1030 this.didSelectionStateChange_(); |
1015 }, | 1031 }, |
1016 | 1032 |
1017 get rowHighlightStyle() { | 1033 get rowHighlightStyle() { |
1018 return this.rowHighlightStyle_; | 1034 return this.rowHighlightStyle_; |
1019 }, | 1035 }, |
1020 | 1036 |
1021 set rowHighlightStyle(rowHighlightStyle) { | 1037 set rowHighlightStyle(rowHighlightStyle) { |
1022 if (!tr.b.dictionaryContainsValue(HighlightStyle, rowHighlightStyle)) | 1038 if (!tr.b.dictionaryContainsValue(HighlightStyle, rowHighlightStyle)) { |
1023 throw new Error('Invalid row highlight style ' + rowHighlightStyle); | 1039 throw new Error('Invalid row highlight style ' + rowHighlightStyle); |
| 1040 } |
1024 this.rebuildIfNeeded_(); | 1041 this.rebuildIfNeeded_(); |
1025 this.rowHighlightStyle_ = rowHighlightStyle; | 1042 this.rowHighlightStyle_ = rowHighlightStyle; |
1026 this.didSelectionStateChange_(); | 1043 this.didSelectionStateChange_(); |
1027 }, | 1044 }, |
1028 | 1045 |
1029 get resolvedRowHighlightStyle() { | 1046 get resolvedRowHighlightStyle() { |
1030 if (this.rowHighlightStyle_ !== HighlightStyle.DEFAULT) | 1047 if (this.rowHighlightStyle_ !== HighlightStyle.DEFAULT) { |
1031 return this.rowHighlightStyle_; | 1048 return this.rowHighlightStyle_; |
| 1049 } |
1032 switch (this.selectionMode_) { | 1050 switch (this.selectionMode_) { |
1033 case SelectionMode.NONE: | 1051 case SelectionMode.NONE: |
1034 return HighlightStyle.NONE; | 1052 return HighlightStyle.NONE; |
1035 case SelectionMode.ROW: | 1053 case SelectionMode.ROW: |
1036 return HighlightStyle.DARK; | 1054 return HighlightStyle.DARK; |
1037 case SelectionMode.CELL: | 1055 case SelectionMode.CELL: |
1038 return HighlightStyle.LIGHT; | 1056 return HighlightStyle.LIGHT; |
1039 default: | 1057 default: |
1040 throw new Error('Invalid selection mode ' + selectionMode); | 1058 throw new Error('Invalid selection mode ' + selectionMode); |
1041 } | 1059 } |
1042 }, | 1060 }, |
1043 | 1061 |
1044 get cellHighlightStyle() { | 1062 get cellHighlightStyle() { |
1045 return this.cellHighlightStyle_; | 1063 return this.cellHighlightStyle_; |
1046 }, | 1064 }, |
1047 | 1065 |
1048 set cellHighlightStyle(cellHighlightStyle) { | 1066 set cellHighlightStyle(cellHighlightStyle) { |
1049 if (!tr.b.dictionaryContainsValue(HighlightStyle, cellHighlightStyle)) | 1067 if (!tr.b.dictionaryContainsValue(HighlightStyle, cellHighlightStyle)) { |
1050 throw new Error('Invalid cell highlight style ' + cellHighlightStyle); | 1068 throw new Error('Invalid cell highlight style ' + cellHighlightStyle); |
| 1069 } |
1051 this.rebuildIfNeeded_(); | 1070 this.rebuildIfNeeded_(); |
1052 this.cellHighlightStyle_ = cellHighlightStyle; | 1071 this.cellHighlightStyle_ = cellHighlightStyle; |
1053 this.didSelectionStateChange_(); | 1072 this.didSelectionStateChange_(); |
1054 }, | 1073 }, |
1055 | 1074 |
1056 get resolvedCellHighlightStyle() { | 1075 get resolvedCellHighlightStyle() { |
1057 if (this.cellHighlightStyle_ !== HighlightStyle.DEFAULT) | 1076 if (this.cellHighlightStyle_ !== HighlightStyle.DEFAULT) { |
1058 return this.cellHighlightStyle_; | 1077 return this.cellHighlightStyle_; |
| 1078 } |
1059 switch (this.selectionMode_) { | 1079 switch (this.selectionMode_) { |
1060 case SelectionMode.NONE: | 1080 case SelectionMode.NONE: |
1061 case SelectionMode.ROW: | 1081 case SelectionMode.ROW: |
1062 return HighlightStyle.NONE; | 1082 return HighlightStyle.NONE; |
1063 case SelectionMode.CELL: | 1083 case SelectionMode.CELL: |
1064 return HighlightStyle.DARK; | 1084 return HighlightStyle.DARK; |
1065 default: | 1085 default: |
1066 throw new Error('Invalid selection mode ' + selectionMode); | 1086 throw new Error('Invalid selection mode ' + selectionMode); |
1067 } | 1087 } |
1068 }, | 1088 }, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1121 this.selectedColumnIndex_ = undefined; | 1141 this.selectedColumnIndex_ = undefined; |
1122 break; | 1142 break; |
1123 default: | 1143 default: |
1124 throw new Error('Invalid selection mode ' + this.selectionMode_); | 1144 throw new Error('Invalid selection mode ' + this.selectionMode_); |
1125 } | 1145 } |
1126 | 1146 |
1127 this.maybeUpdateSelectedRow_(); | 1147 this.maybeUpdateSelectedRow_(); |
1128 }, | 1148 }, |
1129 | 1149 |
1130 maybeUpdateSelectedRow_: function() { | 1150 maybeUpdateSelectedRow_: function() { |
1131 if (this.selectedTableRowInfo_ === undefined) | 1151 if (this.selectedTableRowInfo_ === undefined) return; |
1132 return; | |
1133 | 1152 |
1134 // selectedUserRow may not be visible | 1153 // selectedUserRow may not be visible |
1135 function isVisible(rowInfo) { | 1154 function isVisible(rowInfo) { |
1136 if (!rowInfo.htmlNode) | 1155 if (!rowInfo.htmlNode) return false; |
1137 return false; | |
1138 return !!rowInfo.htmlNode.parentElement; | 1156 return !!rowInfo.htmlNode.parentElement; |
1139 } | 1157 } |
1140 if (isVisible(this.selectedTableRowInfo_)) { | 1158 if (isVisible(this.selectedTableRowInfo_)) { |
1141 this.updateSelectedState_(); | 1159 this.updateSelectedState_(); |
1142 return; | 1160 return; |
1143 } | 1161 } |
1144 | 1162 |
1145 this.removeSelectedState_(); | 1163 this.removeSelectedState_(); |
1146 var curRowInfo = this.selectedTableRowInfo_; | 1164 var curRowInfo = this.selectedTableRowInfo_; |
1147 while (curRowInfo && !isVisible(curRowInfo)) | 1165 while (curRowInfo && !isVisible(curRowInfo)) { |
1148 curRowInfo = curRowInfo.parentRowInfo; | 1166 curRowInfo = curRowInfo.parentRowInfo; |
| 1167 } |
1149 | 1168 |
1150 this.selectedTableRowInfo_ = curRowInfo; | 1169 this.selectedTableRowInfo_ = curRowInfo; |
1151 if (this.selectedTableRowInfo_) | 1170 if (this.selectedTableRowInfo_) { |
1152 this.updateSelectedState_(); | 1171 this.updateSelectedState_(); |
1153 else | 1172 } else { |
1154 this.selectedColumnIndex_ = undefined; | 1173 this.selectedColumnIndex_ = undefined; |
| 1174 } |
1155 }, | 1175 }, |
1156 | 1176 |
1157 didTableRowInfoGetClicked_: function(rowInfo, columnIndex) { | 1177 didTableRowInfoGetClicked_: function(rowInfo, columnIndex) { |
1158 switch (this.selectionMode_) { | 1178 switch (this.selectionMode_) { |
1159 case SelectionMode.NONE: | 1179 case SelectionMode.NONE: |
1160 return; | 1180 return; |
1161 | 1181 |
1162 case SelectionMode.CELL: | 1182 case SelectionMode.CELL: |
1163 if (!this.doesColumnIndexSupportSelection(columnIndex)) | 1183 if (!this.doesColumnIndexSupportSelection(columnIndex)) { |
1164 return; | 1184 return; |
1165 if (this.selectedColumnIndex !== columnIndex) | 1185 } |
| 1186 if (this.selectedColumnIndex !== columnIndex) { |
1166 this.selectedColumnIndex = columnIndex; | 1187 this.selectedColumnIndex = columnIndex; |
| 1188 } |
1167 // Fall through. | 1189 // Fall through. |
1168 | 1190 |
1169 case SelectionMode.ROW: | 1191 case SelectionMode.ROW: |
1170 if (this.selectedTableRowInfo_ !== rowInfo) | 1192 if (this.selectedTableRowInfo_ !== rowInfo) { |
1171 this.selectedTableRow = rowInfo.userRow; | 1193 this.selectedTableRow = rowInfo.userRow; |
| 1194 } |
1172 } | 1195 } |
1173 }, | 1196 }, |
1174 | 1197 |
1175 dispatchStepIntoEvent_: function(rowInfo, columnIndex) { | 1198 dispatchStepIntoEvent_: function(rowInfo, columnIndex) { |
1176 var e = new tr.b.Event('step-into'); | 1199 var e = new tr.b.Event('step-into'); |
1177 e.tableRow = rowInfo.userRow; | 1200 e.tableRow = rowInfo.userRow; |
1178 e.tableColumn = this.tableColumns_[columnIndex]; | 1201 e.tableColumn = this.tableColumns_[columnIndex]; |
1179 e.columnIndex = columnIndex; | 1202 e.columnIndex = columnIndex; |
1180 this.dispatchEvent(e); | 1203 this.dispatchEvent(e); |
1181 }, | 1204 }, |
1182 | 1205 |
1183 /** | 1206 /** |
1184 * If the selectionMode is CELL and a cell is selected, | 1207 * If the selectionMode is CELL and a cell is selected, |
1185 * return an object containing the row, column, and value of the selected | 1208 * return an object containing the row, column, and value of the selected |
1186 * cell. | 1209 * cell. |
1187 * | 1210 * |
1188 * @return {undefined|!Object} | 1211 * @return {undefined|!Object} |
1189 */ | 1212 */ |
1190 get selectedCell() { | 1213 get selectedCell() { |
1191 var row = this.selectedTableRow; | 1214 var row = this.selectedTableRow; |
1192 var columnIndex = this.selectedColumnIndex; | 1215 var columnIndex = this.selectedColumnIndex; |
1193 if (row === undefined || columnIndex === undefined || | 1216 if (row === undefined || columnIndex === undefined || |
1194 this.tableColumns_.length <= columnIndex) | 1217 this.tableColumns_.length <= columnIndex) { |
1195 return undefined; | 1218 return undefined; |
| 1219 } |
1196 var column = this.tableColumns_[columnIndex]; | 1220 var column = this.tableColumns_[columnIndex]; |
1197 return { | 1221 return { |
1198 row: row, | 1222 row: row, |
1199 column: column, | 1223 column: column, |
1200 value: column.value(row) | 1224 value: column.value(row) |
1201 }; | 1225 }; |
1202 }, | 1226 }, |
1203 | 1227 |
1204 /** | 1228 /** |
1205 * If a column is selected, return the object describing the selected | 1229 * If a column is selected, return the object describing the selected |
(...skipping 23 matching lines...) Expand all Loading... |
1229 } | 1253 } |
1230 return undefined; | 1254 return undefined; |
1231 }, | 1255 }, |
1232 | 1256 |
1233 /** | 1257 /** |
1234 * @param {number|undefined} index | 1258 * @param {number|undefined} index |
1235 */ | 1259 */ |
1236 set selectedTableColumnIndex(selectedIndex) { | 1260 set selectedTableColumnIndex(selectedIndex) { |
1237 var cols = Polymer.dom(this.$.cols).children; | 1261 var cols = Polymer.dom(this.$.cols).children; |
1238 for (var i = 0; i < cols.length; ++i) { | 1262 for (var i = 0; i < cols.length; ++i) { |
1239 if (i === selectedIndex) | 1263 if (i === selectedIndex) { |
1240 cols[i].setAttribute('selected', true); | 1264 cols[i].setAttribute('selected', true); |
1241 else | 1265 } else { |
1242 cols[i].removeAttribute('selected'); | 1266 cols[i].removeAttribute('selected'); |
| 1267 } |
1243 } | 1268 } |
1244 }, | 1269 }, |
1245 | 1270 |
1246 get selectedTableRow() { | 1271 get selectedTableRow() { |
1247 if (!this.selectedTableRowInfo_) | 1272 if (!this.selectedTableRowInfo_) return undefined; |
1248 return undefined; | |
1249 return this.selectedTableRowInfo_.userRow; | 1273 return this.selectedTableRowInfo_.userRow; |
1250 }, | 1274 }, |
1251 | 1275 |
1252 set selectedTableRow(userRow) { | 1276 set selectedTableRow(userRow) { |
1253 this.rebuildIfNeeded_(); | 1277 this.rebuildIfNeeded_(); |
1254 if (this.selectionMode_ === SelectionMode.NONE) | 1278 if (this.selectionMode_ === SelectionMode.NONE) { |
1255 throw new Error('Selection is off.'); | 1279 throw new Error('Selection is off.'); |
| 1280 } |
1256 | 1281 |
1257 var rowInfo; | 1282 var rowInfo; |
1258 if (userRow === undefined) { | 1283 if (userRow === undefined) { |
1259 rowInfo = undefined; | 1284 rowInfo = undefined; |
1260 } else { | 1285 } else { |
1261 rowInfo = this.tableRowsInfo_.get(userRow); | 1286 rowInfo = this.tableRowsInfo_.get(userRow); |
1262 if (!rowInfo) | 1287 if (!rowInfo) { |
1263 throw new Error('Row has not been seen, must expand its parents.'); | 1288 throw new Error('Row has not been seen, must expand its parents.'); |
| 1289 } |
1264 } | 1290 } |
1265 | 1291 |
1266 var e = this.prepareToChangeSelection_(); | 1292 var e = this.prepareToChangeSelection_(); |
1267 | 1293 |
1268 if (!rowInfo) { | 1294 if (!rowInfo) { |
1269 this.selectedColumnIndex_ = undefined; | 1295 this.selectedColumnIndex_ = undefined; |
1270 } else { | 1296 } else { |
1271 switch (this.selectionMode_) { | 1297 switch (this.selectionMode_) { |
1272 case SelectionMode.ROW: | 1298 case SelectionMode.ROW: |
1273 this.selectedColumnIndex_ = undefined; | 1299 this.selectedColumnIndex_ = undefined; |
1274 break; | 1300 break; |
1275 | 1301 |
1276 case SelectionMode.CELL: | 1302 case SelectionMode.CELL: |
1277 if (this.selectedColumnIndex_ === undefined) { | 1303 if (this.selectedColumnIndex_ === undefined) { |
1278 var i = this.getFirstSelectableColumnIndex_(); | 1304 var i = this.getFirstSelectableColumnIndex_(); |
1279 if (i === -1) | 1305 if (i === -1) { |
1280 throw new Error('Cannot find a selectable column.'); | 1306 throw new Error('Cannot find a selectable column.'); |
| 1307 } |
1281 this.selectedColumnIndex_ = i; | 1308 this.selectedColumnIndex_ = i; |
1282 } | 1309 } |
1283 break; | 1310 break; |
1284 | 1311 |
1285 default: | 1312 default: |
1286 throw new Error('Invalid selection mode ' + this.selectionMode_); | 1313 throw new Error('Invalid selection mode ' + this.selectionMode_); |
1287 } | 1314 } |
1288 } | 1315 } |
1289 | 1316 |
1290 this.selectedTableRowInfo_ = rowInfo; | 1317 this.selectedTableRowInfo_ = rowInfo; |
1291 this.updateSelectedState_(); | 1318 this.updateSelectedState_(); |
1292 this.dispatchEvent(e); | 1319 this.dispatchEvent(e); |
1293 }, | 1320 }, |
1294 | 1321 |
1295 prepareToChangeSelection_: function() { | 1322 prepareToChangeSelection_: function() { |
1296 var e = new tr.b.Event('selection-changed'); | 1323 var e = new tr.b.Event('selection-changed'); |
1297 var previousSelectedRowInfo = this.selectedTableRowInfo_; | 1324 var previousSelectedRowInfo = this.selectedTableRowInfo_; |
1298 if (previousSelectedRowInfo) | 1325 if (previousSelectedRowInfo) { |
1299 e.previousSelectedTableRow = previousSelectedRowInfo.userRow; | 1326 e.previousSelectedTableRow = previousSelectedRowInfo.userRow; |
1300 else | 1327 } else { |
1301 e.previousSelectedTableRow = undefined; | 1328 e.previousSelectedTableRow = undefined; |
| 1329 } |
1302 | 1330 |
1303 this.removeSelectedState_(); | 1331 this.removeSelectedState_(); |
1304 | 1332 |
1305 return e; | 1333 return e; |
1306 }, | 1334 }, |
1307 | 1335 |
1308 removeSelectedState_: function() { | 1336 removeSelectedState_: function() { |
1309 this.setSelectedState_(false); | 1337 this.setSelectedState_(false); |
1310 }, | 1338 }, |
1311 | 1339 |
1312 updateSelectedState_: function() { | 1340 updateSelectedState_: function() { |
1313 this.setSelectedState_(true); | 1341 this.setSelectedState_(true); |
1314 }, | 1342 }, |
1315 | 1343 |
1316 setSelectedState_: function(select) { | 1344 setSelectedState_: function(select) { |
1317 if (this.selectedTableRowInfo_ === undefined) | 1345 if (this.selectedTableRowInfo_ === undefined) return; |
1318 return; | |
1319 | 1346 |
1320 // Row selection. | 1347 // Row selection. |
1321 var rowNode = this.selectedTableRowInfo_.htmlNode; | 1348 var rowNode = this.selectedTableRowInfo_.htmlNode; |
1322 if (select) | 1349 if (select) { |
1323 Polymer.dom(rowNode).setAttribute('selected', true); | 1350 Polymer.dom(rowNode).setAttribute('selected', true); |
1324 else | 1351 } else { |
1325 Polymer.dom(rowNode).removeAttribute('selected'); | 1352 Polymer.dom(rowNode).removeAttribute('selected'); |
| 1353 } |
1326 | 1354 |
1327 // Cell selection (if applicable). | 1355 // Cell selection (if applicable). |
1328 var cellNode = Polymer.dom(rowNode).children[this.selectedColumnIndex_]; | 1356 var cellNode = Polymer.dom(rowNode).children[this.selectedColumnIndex_]; |
1329 if (!cellNode) | 1357 if (!cellNode) return; |
1330 return; | 1358 if (select) { |
1331 if (select) | |
1332 Polymer.dom(cellNode).setAttribute('selected', true); | 1359 Polymer.dom(cellNode).setAttribute('selected', true); |
1333 else | 1360 } else { |
1334 Polymer.dom(cellNode).removeAttribute('selected'); | 1361 Polymer.dom(cellNode).removeAttribute('selected'); |
| 1362 } |
1335 }, | 1363 }, |
1336 | 1364 |
1337 doesColumnIndexSupportSelection: function(columnIndex) { | 1365 doesColumnIndexSupportSelection: function(columnIndex) { |
1338 var columnInfo = this.tableColumns_[columnIndex]; | 1366 var columnInfo = this.tableColumns_[columnIndex]; |
1339 var scs = columnInfo.supportsCellSelection; | 1367 var scs = columnInfo.supportsCellSelection; |
1340 if (scs === false) | 1368 if (scs === false) return false; |
1341 return false; | |
1342 return true; | 1369 return true; |
1343 }, | 1370 }, |
1344 | 1371 |
1345 getFirstSelectableColumnIndex_: function() { | 1372 getFirstSelectableColumnIndex_: function() { |
1346 for (var i = 0; i < this.tableColumns_.length; i++) { | 1373 for (var i = 0; i < this.tableColumns_.length; i++) { |
1347 if (this.doesColumnIndexSupportSelection(i)) | 1374 if (this.doesColumnIndexSupportSelection(i)) { |
1348 return i; | 1375 return i; |
| 1376 } |
1349 } | 1377 } |
1350 return -1; | 1378 return -1; |
1351 }, | 1379 }, |
1352 | 1380 |
1353 getSelectableNodeGivenTableRowNode_: function(htmlNode) { | 1381 getSelectableNodeGivenTableRowNode_: function(htmlNode) { |
1354 switch (this.selectionMode_) { | 1382 switch (this.selectionMode_) { |
1355 case SelectionMode.ROW: | 1383 case SelectionMode.ROW: |
1356 return htmlNode; | 1384 return htmlNode; |
1357 | 1385 |
1358 case SelectionMode.CELL: | 1386 case SelectionMode.CELL: |
1359 return Polymer.dom(htmlNode).children[this.selectedColumnIndex_]; | 1387 return Polymer.dom(htmlNode).children[this.selectedColumnIndex_]; |
1360 | 1388 |
1361 default: | 1389 default: |
1362 throw new Error('Invalid selection mode ' + this.selectionMode_); | 1390 throw new Error('Invalid selection mode ' + this.selectionMode_); |
1363 } | 1391 } |
1364 }, | 1392 }, |
1365 | 1393 |
1366 get selectedColumnIndex() { | 1394 get selectedColumnIndex() { |
1367 if (this.selectionMode_ !== SelectionMode.CELL) | 1395 if (this.selectionMode_ !== SelectionMode.CELL) { |
1368 return undefined; | 1396 return undefined; |
| 1397 } |
1369 return this.selectedColumnIndex_; | 1398 return this.selectedColumnIndex_; |
1370 }, | 1399 }, |
1371 | 1400 |
1372 set selectedColumnIndex(selectedColumnIndex) { | 1401 set selectedColumnIndex(selectedColumnIndex) { |
1373 this.rebuildIfNeeded_(); | 1402 this.rebuildIfNeeded_(); |
1374 if (this.selectionMode_ === SelectionMode.NONE) | 1403 if (this.selectionMode_ === SelectionMode.NONE) { |
1375 throw new Error('Selection is off.'); | 1404 throw new Error('Selection is off.'); |
| 1405 } |
1376 if (selectedColumnIndex < 0 || | 1406 if (selectedColumnIndex < 0 || |
1377 selectedColumnIndex >= this.tableColumns_.length) | 1407 selectedColumnIndex >= this.tableColumns_.length) { |
1378 throw new Error('Invalid index'); | 1408 throw new Error('Invalid index'); |
1379 if (!this.doesColumnIndexSupportSelection(selectedColumnIndex)) | 1409 } |
| 1410 if (!this.doesColumnIndexSupportSelection(selectedColumnIndex)) { |
1380 throw new Error('Selection is not supported on this column'); | 1411 throw new Error('Selection is not supported on this column'); |
| 1412 } |
1381 | 1413 |
1382 var e = this.prepareToChangeSelection_(); | 1414 var e = this.prepareToChangeSelection_(); |
1383 if (this.selectedColumnIndex_ === undefined) { | 1415 if (this.selectedColumnIndex_ === undefined) { |
1384 this.selectedTableRowInfo_ = undefined; | 1416 this.selectedTableRowInfo_ = undefined; |
1385 } else if (!this.selectedTableRowInfo_) { | 1417 } else if (!this.selectedTableRowInfo_) { |
1386 if (this.tableRows_.length === 0) | 1418 if (this.tableRows_.length === 0) { |
1387 throw new Error('No available row to be selected'); | 1419 throw new Error('No available row to be selected'); |
| 1420 } |
1388 this.selectedTableRowInfo_ = | 1421 this.selectedTableRowInfo_ = |
1389 this.tableRowsInfo_.get(this.tableRows_[0]); | 1422 this.tableRowsInfo_.get(this.tableRows_[0]); |
1390 } | 1423 } |
1391 this.selectedColumnIndex_ = selectedColumnIndex; | 1424 this.selectedColumnIndex_ = selectedColumnIndex; |
1392 this.updateSelectedState_(); | 1425 this.updateSelectedState_(); |
1393 this.dispatchEvent(e); | 1426 this.dispatchEvent(e); |
1394 }, | 1427 }, |
1395 | 1428 |
1396 onKeyDown_: function(e) { | 1429 onKeyDown_: function(e) { |
1397 if (this.selectionMode_ === SelectionMode.NONE) | 1430 if (this.selectionMode_ === SelectionMode.NONE) return; |
1398 return; | |
1399 | 1431 |
1400 var CODE_TO_COMMAND_NAMES = { | 1432 var CODE_TO_COMMAND_NAMES = { |
1401 13: 'ENTER', | 1433 13: 'ENTER', |
1402 32: 'SPACE', | 1434 32: 'SPACE', |
1403 37: 'ARROW_LEFT', | 1435 37: 'ARROW_LEFT', |
1404 38: 'ARROW_UP', | 1436 38: 'ARROW_UP', |
1405 39: 'ARROW_RIGHT', | 1437 39: 'ARROW_RIGHT', |
1406 40: 'ARROW_DOWN' | 1438 40: 'ARROW_DOWN' |
1407 }; | 1439 }; |
1408 var cmdName = CODE_TO_COMMAND_NAMES[e.keyCode]; | 1440 var cmdName = CODE_TO_COMMAND_NAMES[e.keyCode]; |
1409 if (cmdName === undefined) | 1441 if (cmdName === undefined) return; |
1410 return; | |
1411 | 1442 |
1412 e.stopPropagation(); | 1443 e.stopPropagation(); |
1413 e.preventDefault(); | 1444 e.preventDefault(); |
1414 this.performKeyCommand_(cmdName); | 1445 this.performKeyCommand_(cmdName); |
1415 }, | 1446 }, |
1416 | 1447 |
1417 onFocus_: function(e) { | 1448 onFocus_: function(e) { |
1418 // This method should be idempotent. If it can't be, then focus() must be | 1449 // This method should be idempotent. If it can't be, then focus() must be |
1419 // updated. | 1450 // updated. |
1420 if (this.selectionMode_ === SelectionMode.NONE || | 1451 if (this.selectionMode_ === SelectionMode.NONE || |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 | 1534 |
1504 default: | 1535 default: |
1505 throw new Error('Unrecognized command ' + cmdName); | 1536 throw new Error('Unrecognized command ' + cmdName); |
1506 } | 1537 } |
1507 }, | 1538 }, |
1508 | 1539 |
1509 selectPreviousOrFirstRowIfPossible_: function() { | 1540 selectPreviousOrFirstRowIfPossible_: function() { |
1510 var prev = this.selectedTableRowInfo_ ? | 1541 var prev = this.selectedTableRowInfo_ ? |
1511 this.selectedTableRowInfo_.htmlNode.previousElementSibling : | 1542 this.selectedTableRowInfo_.htmlNode.previousElementSibling : |
1512 this.$.body.firstChild; | 1543 this.$.body.firstChild; |
1513 if (!prev) | 1544 if (!prev) return; |
1514 return; | 1545 |
1515 if (this.selectionMode_ === SelectionMode.CELL && | 1546 if (this.selectionMode_ === SelectionMode.CELL && |
1516 this.getFirstSelectableColumnIndex_() === -1) { | 1547 this.getFirstSelectableColumnIndex_() === -1) { |
1517 // If there are no selectable columns in cell selection mode, don't do | 1548 // If there are no selectable columns in cell selection mode, don't do |
1518 // anything. | 1549 // anything. |
1519 return; | 1550 return; |
1520 } | 1551 } |
1521 tr.ui.b.scrollIntoViewIfNeeded(prev); | 1552 tr.ui.b.scrollIntoViewIfNeeded(prev); |
1522 this.selectedTableRow = prev.rowInfo.userRow; | 1553 this.selectedTableRow = prev.rowInfo.userRow; |
1523 }, | 1554 }, |
1524 | 1555 |
1525 selectNextOrFirstRowIfPossible_: function() { | 1556 selectNextOrFirstRowIfPossible_: function() { |
1526 this.getFirstSelectableColumnIndex_; | 1557 this.getFirstSelectableColumnIndex_; |
1527 var next = this.selectedTableRowInfo_ ? | 1558 var next = this.selectedTableRowInfo_ ? |
1528 this.selectedTableRowInfo_.htmlNode.nextElementSibling : | 1559 this.selectedTableRowInfo_.htmlNode.nextElementSibling : |
1529 this.$.body.firstChild; | 1560 this.$.body.firstChild; |
1530 if (!next) | 1561 if (!next) return; |
1531 return; | 1562 |
1532 if (this.selectionMode_ === SelectionMode.CELL && | 1563 if (this.selectionMode_ === SelectionMode.CELL && |
1533 this.getFirstSelectableColumnIndex_() === -1) { | 1564 this.getFirstSelectableColumnIndex_() === -1) { |
1534 // If there are no selectable columns in cell selection mode, don't do | 1565 // If there are no selectable columns in cell selection mode, don't do |
1535 // anything. | 1566 // anything. |
1536 return; | 1567 return; |
1537 } | 1568 } |
1538 tr.ui.b.scrollIntoViewIfNeeded(next); | 1569 tr.ui.b.scrollIntoViewIfNeeded(next); |
1539 this.selectedTableRow = next.rowInfo.userRow; | 1570 this.selectedTableRow = next.rowInfo.userRow; |
1540 }, | 1571 }, |
1541 | 1572 |
1542 expandRowAndSelectChildRowIfPossible_: function() { | 1573 expandRowAndSelectChildRowIfPossible_: function() { |
1543 var selectedRowInfo = this.selectedTableRowInfo_; | 1574 var selectedRowInfo = this.selectedTableRowInfo_; |
1544 if (!selectedRowInfo || | 1575 if (!selectedRowInfo || |
1545 selectedRowInfo.userRow[this.subRowsPropertyName_] === undefined || | 1576 selectedRowInfo.userRow[this.subRowsPropertyName_] === undefined || |
1546 selectedRowInfo.userRow[this.subRowsPropertyName_].length === 0) { | 1577 selectedRowInfo.userRow[this.subRowsPropertyName_].length === 0) { |
1547 return; | 1578 return; |
1548 } | 1579 } |
1549 if (!selectedRowInfo.isExpanded) | 1580 if (!selectedRowInfo.isExpanded) { |
1550 this.setExpandedForTableRow(selectedRowInfo.userRow, true); | 1581 this.setExpandedForTableRow(selectedRowInfo.userRow, true); |
| 1582 } |
1551 this.selectedTableRow = | 1583 this.selectedTableRow = |
1552 selectedRowInfo.htmlNode.nextElementSibling.rowInfo.userRow; | 1584 selectedRowInfo.htmlNode.nextElementSibling.rowInfo.userRow; |
1553 }, | 1585 }, |
1554 | 1586 |
1555 collapseRowOrSelectParentRowIfPossible_: function() { | 1587 collapseRowOrSelectParentRowIfPossible_: function() { |
1556 var selectedRowInfo = this.selectedTableRowInfo_; | 1588 var selectedRowInfo = this.selectedTableRowInfo_; |
1557 if (!selectedRowInfo) | 1589 if (!selectedRowInfo) return; |
1558 return; | 1590 |
1559 if (selectedRowInfo.isExpanded) { | 1591 if (selectedRowInfo.isExpanded) { |
1560 // If the node is expanded, collapse it. | 1592 // If the node is expanded, collapse it. |
1561 this.setExpandedForTableRow(selectedRowInfo.userRow, false); | 1593 this.setExpandedForTableRow(selectedRowInfo.userRow, false); |
1562 } else { | 1594 } else { |
1563 // If the node is not expanded, select its parent. | 1595 // If the node is not expanded, select its parent. |
1564 var parentRowInfo = selectedRowInfo.parentRowInfo; | 1596 var parentRowInfo = selectedRowInfo.parentRowInfo; |
1565 if (parentRowInfo) | 1597 if (parentRowInfo) { |
1566 this.selectedTableRow = parentRowInfo.userRow; | 1598 this.selectedTableRow = parentRowInfo.userRow; |
| 1599 } |
1567 } | 1600 } |
1568 }, | 1601 }, |
1569 | 1602 |
1570 selectNextSelectableCellToTheRightIfPossible_: function() { | 1603 selectNextSelectableCellToTheRightIfPossible_: function() { |
1571 if (!this.selectedTableRowInfo_ || | 1604 if (!this.selectedTableRowInfo_ || |
1572 this.selectedColumnIndex_ === undefined) { | 1605 this.selectedColumnIndex_ === undefined) { |
1573 return; | 1606 return; |
1574 } | 1607 } |
1575 for (var i = this.selectedColumnIndex_ + 1; i < this.tableColumns_.length; | 1608 for (var i = this.selectedColumnIndex_ + 1; i < this.tableColumns_.length; |
1576 i++) { | 1609 i++) { |
(...skipping 22 matching lines...) Expand all Loading... |
1599 if (!selectedRowInfo || | 1632 if (!selectedRowInfo || |
1600 selectedRowInfo.userRow[this.subRowsPropertyName_] === undefined || | 1633 selectedRowInfo.userRow[this.subRowsPropertyName_] === undefined || |
1601 selectedRowInfo.userRow[this.subRowsPropertyName_].length === 0) { | 1634 selectedRowInfo.userRow[this.subRowsPropertyName_].length === 0) { |
1602 return; | 1635 return; |
1603 } | 1636 } |
1604 this.setExpandedForTableRow(selectedRowInfo.userRow, | 1637 this.setExpandedForTableRow(selectedRowInfo.userRow, |
1605 !selectedRowInfo.isExpanded); | 1638 !selectedRowInfo.isExpanded); |
1606 }, | 1639 }, |
1607 | 1640 |
1608 stepIntoSelectionIfPossible_: function() { | 1641 stepIntoSelectionIfPossible_: function() { |
1609 if (!this.selectedTableRowInfo_) | 1642 if (!this.selectedTableRowInfo_) return; |
1610 return; | |
1611 this.dispatchStepIntoEvent_(this.selectedTableRowInfo_, | 1643 this.dispatchStepIntoEvent_(this.selectedTableRowInfo_, |
1612 this.selectedColumnIndex_); | 1644 this.selectedColumnIndex_); |
1613 }, | 1645 }, |
1614 | 1646 |
1615 dispatchSortingChangedEvent_: function() { | 1647 dispatchSortingChangedEvent_: function() { |
1616 var e = new tr.b.Event('sort-column-changed'); | 1648 var e = new tr.b.Event('sort-column-changed'); |
1617 e.sortColumnIndex = this.sortColumnIndex_; | 1649 e.sortColumnIndex = this.sortColumnIndex_; |
1618 e.sortDescending = this.sortDescending_; | 1650 e.sortDescending = this.sortDescending_; |
1619 this.dispatchEvent(e); | 1651 this.dispatchEvent(e); |
1620 } | 1652 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1750 set tapCallback(callback) { | 1782 set tapCallback(callback) { |
1751 this.style.cursor = 'pointer'; | 1783 this.style.cursor = 'pointer'; |
1752 this.tapCallback_ = callback; | 1784 this.tapCallback_ = callback; |
1753 }, | 1785 }, |
1754 | 1786 |
1755 get tapCallback() { | 1787 get tapCallback() { |
1756 return this.tapCallback_; | 1788 return this.tapCallback_; |
1757 }, | 1789 }, |
1758 | 1790 |
1759 onTap_: function() { | 1791 onTap_: function() { |
1760 if (this.tapCallback_) | 1792 if (this.tapCallback_) { |
1761 this.tapCallback_(); | 1793 this.tapCallback_(); |
| 1794 } |
1762 } | 1795 } |
1763 }); | 1796 }); |
1764 </script> | 1797 </script> |
OLD | NEW |