Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) | 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) |
| 3 * (C) 1997 Torben Weis (weis@kde.org) | 3 * (C) 1997 Torben Weis (weis@kde.org) |
| 4 * (C) 1998 Waldo Bastian (bastian@kde.org) | 4 * (C) 1998 Waldo Bastian (bastian@kde.org) |
| 5 * (C) 1999 Lars Knoll (knoll@kde.org) | 5 * (C) 1999 Lars Knoll (knoll@kde.org) |
| 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. |
| 8 * All rights reserved. | 8 * All rights reserved. |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 | 52 |
| 53 static_assert(sizeof(LayoutTableCell) == sizeof(SameSizeAsLayoutTableCell), | 53 static_assert(sizeof(LayoutTableCell) == sizeof(SameSizeAsLayoutTableCell), |
| 54 "LayoutTableCell should stay small"); | 54 "LayoutTableCell should stay small"); |
| 55 static_assert(sizeof(CollapsedBorderValue) == 8, | 55 static_assert(sizeof(CollapsedBorderValue) == 8, |
| 56 "CollapsedBorderValue should stay small"); | 56 "CollapsedBorderValue should stay small"); |
| 57 | 57 |
| 58 LayoutTableCell::LayoutTableCell(Element* element) | 58 LayoutTableCell::LayoutTableCell(Element* element) |
| 59 : LayoutBlockFlow(element), | 59 : LayoutBlockFlow(element), |
| 60 absolute_column_index_(kUnsetColumnIndex), | 60 absolute_column_index_(kUnsetColumnIndex), |
| 61 cell_width_changed_(false), | 61 cell_width_changed_(false), |
| 62 collapsed_border_values_valid_(false), | |
| 63 collapsed_borders_visually_changed_(false), | |
| 62 intrinsic_padding_before_(0), | 64 intrinsic_padding_before_(0), |
| 63 intrinsic_padding_after_(0) { | 65 intrinsic_padding_after_(0) { |
| 64 // We only update the flags when notified of DOM changes in | 66 // We only update the flags when notified of DOM changes in |
| 65 // colSpanOrRowSpanChanged() so we need to set their initial values here in | 67 // colSpanOrRowSpanChanged() so we need to set their initial values here in |
| 66 // case something asks for colSpan()/rowSpan() before then. | 68 // case something asks for colSpan()/rowSpan() before then. |
| 67 UpdateColAndRowSpanFlags(); | 69 UpdateColAndRowSpanFlags(); |
| 68 } | 70 } |
| 69 | 71 |
| 70 LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues( | 72 LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues( |
| 71 const LayoutTableCell& layout_table_cell, | 73 const LayoutTableCell& layout_table_cell, |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 589 return HasSameDirectionAs(Table()) ? IsInStartColumn() : IsInEndColumn(); | 591 return HasSameDirectionAs(Table()) ? IsInStartColumn() : IsInEndColumn(); |
| 590 } | 592 } |
| 591 | 593 |
| 592 bool LayoutTableCell::HasEndBorderAdjoiningTable() const { | 594 bool LayoutTableCell::HasEndBorderAdjoiningTable() const { |
| 593 // The table direction determines the row direction. In mixed directionality, | 595 // The table direction determines the row direction. In mixed directionality, |
| 594 // we cannot guarantee that we have a common border with the table (think a | 596 // we cannot guarantee that we have a common border with the table (think a |
| 595 // ltr table with ltr end cell). | 597 // ltr table with ltr end cell). |
| 596 return HasSameDirectionAs(Table()) ? IsInEndColumn() : IsInStartColumn(); | 598 return HasSameDirectionAs(Table()) ? IsInEndColumn() : IsInStartColumn(); |
| 597 } | 599 } |
| 598 | 600 |
| 599 CollapsedBorderValue LayoutTableCell::ComputeCollapsedStartBorder( | 601 CollapsedBorderValue LayoutTableCell::ComputeCollapsedStartBorder() const { |
| 600 IncludeBorderColorOrNot include_color) const { | |
| 601 LayoutTable* table = this->Table(); | 602 LayoutTable* table = this->Table(); |
| 603 LayoutTableCell* cell_before = table->CellBefore(this); | |
| 604 // We can use the border shared with cellBefore if it is valid. | |
|
wkorman
2017/04/27 20:11:15
cellBefore -> |cell_before|
Xianzhu
2017/04/28 20:31:44
Done.
| |
| 605 if (cell_before && cell_before->collapsed_border_values_valid_ && | |
| 606 cell_before->RowIndex() == RowIndex()) { | |
| 607 return cell_before->GetCollapsedBorderValues() | |
| 608 ? cell_before->GetCollapsedBorderValues()->EndBorder() | |
| 609 : CollapsedBorderValue(); | |
| 610 } | |
| 602 | 611 |
| 603 // For the start border, we need to check, in order of precedence: | 612 // For the start border, we need to check, in order of precedence: |
| 604 // (1) Our start border. | 613 // (1) Our start border. |
| 605 int start_color_property = include_color | 614 int start_color_property = CSSProperty::ResolveDirectionAwareProperty( |
| 606 ? CSSProperty::ResolveDirectionAwareProperty( | 615 CSSPropertyWebkitBorderStartColor, StyleForCellFlow().Direction(), |
| 607 CSSPropertyWebkitBorderStartColor, | 616 StyleForCellFlow().GetWritingMode()); |
| 608 StyleForCellFlow().Direction(), | 617 int end_color_property = CSSProperty::ResolveDirectionAwareProperty( |
| 609 StyleForCellFlow().GetWritingMode()) | 618 CSSPropertyWebkitBorderEndColor, StyleForCellFlow().Direction(), |
| 610 : 0; | 619 StyleForCellFlow().GetWritingMode()); |
| 611 int end_color_property = | 620 CollapsedBorderValue result(Style()->BorderStart(), |
| 612 include_color | 621 ResolveColor(start_color_property), |
| 613 ? CSSProperty::ResolveDirectionAwareProperty( | 622 kBorderPrecedenceCell); |
| 614 CSSPropertyWebkitBorderEndColor, StyleForCellFlow().Direction(), | |
| 615 StyleForCellFlow().GetWritingMode()) | |
| 616 : 0; | |
| 617 CollapsedBorderValue result( | |
| 618 Style()->BorderStart(), | |
| 619 include_color ? ResolveColor(start_color_property) : Color(), | |
| 620 kBorderPrecedenceCell); | |
| 621 | 623 |
| 622 // (2) The end border of the preceding cell. | 624 // (2) The end border of the preceding cell. |
| 623 LayoutTableCell* cell_before = table->CellBefore(this); | |
| 624 if (cell_before) { | 625 if (cell_before) { |
| 625 CollapsedBorderValue cell_before_adjoining_border = CollapsedBorderValue( | 626 CollapsedBorderValue cell_before_adjoining_border = CollapsedBorderValue( |
| 626 cell_before->BorderAdjoiningCellAfter(this), | 627 cell_before->BorderAdjoiningCellAfter(this), |
| 627 include_color ? cell_before->ResolveColor(end_color_property) : Color(), | 628 cell_before->ResolveColor(end_color_property), kBorderPrecedenceCell); |
| 628 kBorderPrecedenceCell); | |
| 629 // |result| should be the 2nd argument as |cellBefore| should win in case of | 629 // |result| should be the 2nd argument as |cellBefore| should win in case of |
| 630 // equality per CSS 2.1 (Border conflict resolution, point 4). | 630 // equality per CSS 2.1 (Border conflict resolution, point 4). |
| 631 result = ChooseBorder(cell_before_adjoining_border, result); | 631 result = ChooseBorder(cell_before_adjoining_border, result); |
| 632 if (!result.Exists()) | 632 if (!result.Exists()) |
| 633 return result; | 633 return result; |
| 634 } | 634 } |
| 635 | 635 |
| 636 bool start_border_adjoins_table = HasStartBorderAdjoiningTable(); | 636 bool start_border_adjoins_table = HasStartBorderAdjoiningTable(); |
| 637 if (start_border_adjoins_table) { | 637 if (start_border_adjoins_table) { |
| 638 // (3) Our row's start border. | 638 // (3) Our row's start border. |
| 639 result = ChooseBorder( | 639 result = ChooseBorder( |
| 640 result, CollapsedBorderValue( | 640 result, |
| 641 Row()->BorderAdjoiningStartCell(this), | 641 CollapsedBorderValue(Row()->BorderAdjoiningStartCell(this), |
| 642 include_color ? Parent()->ResolveColor(start_color_property) | 642 Parent()->ResolveColor(start_color_property), |
| 643 : Color(), | 643 kBorderPrecedenceRow)); |
| 644 kBorderPrecedenceRow)); | |
| 645 if (!result.Exists()) | 644 if (!result.Exists()) |
| 646 return result; | 645 return result; |
| 647 | 646 |
| 648 // (4) Our row group's start border. | 647 // (4) Our row group's start border. |
| 649 result = ChooseBorder( | 648 result = ChooseBorder( |
| 650 result, CollapsedBorderValue(Section()->BorderAdjoiningStartCell(this), | 649 result, |
| 651 include_color ? Section()->ResolveColor( | 650 CollapsedBorderValue(Section()->BorderAdjoiningStartCell(this), |
| 652 start_color_property) | 651 Section()->ResolveColor(start_color_property), |
| 653 : Color(), | 652 kBorderPrecedenceRowGroup)); |
| 654 kBorderPrecedenceRowGroup)); | |
| 655 if (!result.Exists()) | 653 if (!result.Exists()) |
| 656 return result; | 654 return result; |
| 657 } | 655 } |
| 658 | 656 |
| 659 // (5) Our column and column group's start borders. | 657 // (5) Our column and column group's start borders. |
| 660 LayoutTable::ColAndColGroup col_and_col_group = | 658 LayoutTable::ColAndColGroup col_and_col_group = |
| 661 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()); | 659 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()); |
| 662 if (col_and_col_group.colgroup && | 660 if (col_and_col_group.colgroup && |
| 663 col_and_col_group.adjoins_start_border_of_col_group) { | 661 col_and_col_group.adjoins_start_border_of_col_group) { |
| 664 // Only apply the colgroup's border if this cell touches the colgroup edge. | 662 // Only apply the colgroup's border if this cell touches the colgroup edge. |
| 665 result = ChooseBorder( | 663 result = ChooseBorder( |
| 666 result, | 664 result, |
| 667 CollapsedBorderValue( | 665 CollapsedBorderValue( |
| 668 col_and_col_group.colgroup->BorderAdjoiningCellStartBorder(this), | 666 col_and_col_group.colgroup->BorderAdjoiningCellStartBorder(this), |
| 669 include_color | 667 col_and_col_group.colgroup->ResolveColor(start_color_property), |
| 670 ? col_and_col_group.colgroup->ResolveColor(start_color_property) | |
| 671 : Color(), | |
| 672 kBorderPrecedenceColumnGroup)); | 668 kBorderPrecedenceColumnGroup)); |
| 673 if (!result.Exists()) | 669 if (!result.Exists()) |
| 674 return result; | 670 return result; |
| 675 } | 671 } |
| 676 if (col_and_col_group.col) { | 672 if (col_and_col_group.col) { |
| 677 // Always apply the col's border irrespective of whether this cell touches | 673 // Always apply the col's border irrespective of whether this cell touches |
| 678 // it. This is per HTML5: "For the purposes of the CSS table model, the col | 674 // it. This is per HTML5: "For the purposes of the CSS table model, the col |
| 679 // element is expected to be treated as if it "was present as many times as | 675 // element is expected to be treated as if it "was present as many times as |
| 680 // its span attribute specifies". | 676 // its span attribute specifies". |
| 681 result = ChooseBorder( | 677 result = ChooseBorder( |
| 682 result, CollapsedBorderValue( | 678 result, CollapsedBorderValue( |
| 683 col_and_col_group.col->BorderAdjoiningCellStartBorder(this), | 679 col_and_col_group.col->BorderAdjoiningCellStartBorder(this), |
| 684 include_color ? col_and_col_group.col->ResolveColor( | 680 col_and_col_group.col->ResolveColor(start_color_property), |
| 685 start_color_property) | |
| 686 : Color(), | |
| 687 kBorderPrecedenceColumn)); | 681 kBorderPrecedenceColumn)); |
| 688 if (!result.Exists()) | 682 if (!result.Exists()) |
| 689 return result; | 683 return result; |
| 690 } | 684 } |
| 691 | 685 |
| 692 // (6) The end border of the preceding column. | 686 // (6) The end border of the preceding column. |
| 693 if (cell_before) { | 687 if (cell_before) { |
| 694 LayoutTable::ColAndColGroup col_and_col_group = | 688 LayoutTable::ColAndColGroup col_and_col_group = |
| 695 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() - 1); | 689 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() - 1); |
| 696 // Only apply the colgroup's border if this cell touches the colgroup edge. | 690 // Only apply the colgroup's border if this cell touches the colgroup edge. |
| 697 if (col_and_col_group.colgroup && | 691 if (col_and_col_group.colgroup && |
| 698 col_and_col_group.adjoins_end_border_of_col_group) { | 692 col_and_col_group.adjoins_end_border_of_col_group) { |
| 699 result = ChooseBorder( | 693 result = ChooseBorder( |
| 700 CollapsedBorderValue( | 694 CollapsedBorderValue( |
| 701 col_and_col_group.colgroup->BorderAdjoiningCellEndBorder(this), | 695 col_and_col_group.colgroup->BorderAdjoiningCellEndBorder(this), |
| 702 include_color | 696 col_and_col_group.colgroup->ResolveColor(end_color_property), |
| 703 ? col_and_col_group.colgroup->ResolveColor(end_color_property) | |
| 704 : Color(), | |
| 705 kBorderPrecedenceColumnGroup), | 697 kBorderPrecedenceColumnGroup), |
| 706 result); | 698 result); |
| 707 if (!result.Exists()) | 699 if (!result.Exists()) |
| 708 return result; | 700 return result; |
| 709 } | 701 } |
| 710 // Always apply the col's border irrespective of whether this cell touches | 702 // Always apply the col's border irrespective of whether this cell touches |
| 711 // it. This is per HTML5: "For the purposes of the CSS table model, the col | 703 // it. This is per HTML5: "For the purposes of the CSS table model, the col |
| 712 // element is expected to be treated as if it "was present as many times as | 704 // element is expected to be treated as if it "was present as many times as |
| 713 // its span attribute specifies". | 705 // its span attribute specifies". |
| 714 if (col_and_col_group.col) { | 706 if (col_and_col_group.col) { |
| 715 result = ChooseBorder( | 707 result = ChooseBorder( |
| 716 CollapsedBorderValue( | 708 CollapsedBorderValue( |
| 717 col_and_col_group.col->BorderAdjoiningCellAfter(this), | 709 col_and_col_group.col->BorderAdjoiningCellAfter(this), |
| 718 include_color | 710 col_and_col_group.col->ResolveColor(end_color_property), |
| 719 ? col_and_col_group.col->ResolveColor(end_color_property) | |
| 720 : Color(), | |
| 721 kBorderPrecedenceColumn), | 711 kBorderPrecedenceColumn), |
| 722 result); | 712 result); |
| 723 if (!result.Exists()) | 713 if (!result.Exists()) |
| 724 return result; | 714 return result; |
| 725 } | 715 } |
| 726 } | 716 } |
| 727 | 717 |
| 728 if (start_border_adjoins_table) { | 718 if (start_border_adjoins_table) { |
| 729 // (7) The table's start border. | 719 // (7) The table's start border. |
| 730 result = ChooseBorder( | 720 result = ChooseBorder( |
| 731 result, | 721 result, CollapsedBorderValue(table->TableStartBorderAdjoiningCell(this), |
| 732 CollapsedBorderValue( | 722 table->ResolveColor(start_color_property), |
| 733 table->TableStartBorderAdjoiningCell(this), | 723 kBorderPrecedenceTable)); |
| 734 include_color ? table->ResolveColor(start_color_property) : Color(), | |
| 735 kBorderPrecedenceTable)); | |
| 736 if (!result.Exists()) | 724 if (!result.Exists()) |
| 737 return result; | 725 return result; |
| 738 } | 726 } |
| 739 | 727 |
| 740 return result; | 728 return result; |
| 741 } | 729 } |
| 742 | 730 |
| 743 CollapsedBorderValue LayoutTableCell::ComputeCollapsedEndBorder( | 731 CollapsedBorderValue LayoutTableCell::ComputeCollapsedEndBorder() const { |
| 744 IncludeBorderColorOrNot include_color) const { | |
| 745 LayoutTable* table = this->Table(); | 732 LayoutTable* table = this->Table(); |
| 746 // Note: We have to use the effective column information instead of whether we | 733 // Note: We have to use the effective column information instead of whether we |
| 747 // have a cell after as a table doesn't have to be regular (any row can have | 734 // have a cell after as a table doesn't have to be regular (any row can have |
| 748 // less cells than the total cell count). | 735 // less cells than the total cell count). |
| 749 bool is_end_column = table->AbsoluteColumnToEffectiveColumn( | 736 bool is_end_column = IsInEndColumn(); |
| 750 AbsoluteColumnIndex() + ColSpan() - 1) == | 737 LayoutTableCell* cell_after = |
| 751 table->NumEffectiveColumns() - 1; | 738 is_end_column ? nullptr : table->CellAfter(this); |
| 739 // We can use the border shared with cellAfter if it is valid. | |
| 740 if (cell_after && cell_after->collapsed_border_values_valid_ && | |
| 741 cell_after->RowIndex() == RowIndex()) { | |
| 742 return cell_after->GetCollapsedBorderValues() | |
| 743 ? cell_after->GetCollapsedBorderValues()->StartBorder() | |
| 744 : CollapsedBorderValue(); | |
| 745 } | |
| 752 | 746 |
| 753 // For end border, we need to check, in order of precedence: | 747 // For end border, we need to check, in order of precedence: |
| 754 // (1) Our end border. | 748 // (1) Our end border. |
| 755 int start_color_property = include_color | 749 int start_color_property = CSSProperty::ResolveDirectionAwareProperty( |
|
wkorman
2017/04/27 20:11:15
We do similar to these 3 lines about 8 times in th
Xianzhu
2017/04/28 20:31:44
Done.
| |
| 756 ? CSSProperty::ResolveDirectionAwareProperty( | 750 CSSPropertyWebkitBorderStartColor, StyleForCellFlow().Direction(), |
| 757 CSSPropertyWebkitBorderStartColor, | 751 StyleForCellFlow().GetWritingMode()); |
| 758 StyleForCellFlow().Direction(), | 752 int end_color_property = CSSProperty::ResolveDirectionAwareProperty( |
| 759 StyleForCellFlow().GetWritingMode()) | 753 CSSPropertyWebkitBorderEndColor, StyleForCellFlow().Direction(), |
| 760 : 0; | 754 StyleForCellFlow().GetWritingMode()); |
| 761 int end_color_property = | |
| 762 include_color | |
| 763 ? CSSProperty::ResolveDirectionAwareProperty( | |
| 764 CSSPropertyWebkitBorderEndColor, StyleForCellFlow().Direction(), | |
| 765 StyleForCellFlow().GetWritingMode()) | |
| 766 : 0; | |
| 767 CollapsedBorderValue result = CollapsedBorderValue( | 755 CollapsedBorderValue result = CollapsedBorderValue( |
| 768 Style()->BorderEnd(), | 756 Style()->BorderEnd(), ResolveColor(end_color_property), |
| 769 include_color ? ResolveColor(end_color_property) : Color(), | |
| 770 kBorderPrecedenceCell); | 757 kBorderPrecedenceCell); |
| 771 | 758 |
| 772 // (2) The start border of the following cell. | 759 // (2) The start border of the following cell. |
| 773 if (!is_end_column) { | 760 if (cell_after) { |
| 774 if (LayoutTableCell* cell_after = table->CellAfter(this)) { | 761 CollapsedBorderValue cell_after_adjoining_border = CollapsedBorderValue( |
| 775 CollapsedBorderValue cell_after_adjoining_border = CollapsedBorderValue( | 762 cell_after->BorderAdjoiningCellBefore(this), |
| 776 cell_after->BorderAdjoiningCellBefore(this), | 763 cell_after->ResolveColor(start_color_property), kBorderPrecedenceCell); |
| 777 include_color ? cell_after->ResolveColor(start_color_property) | 764 result = ChooseBorder(result, cell_after_adjoining_border); |
| 778 : Color(), | 765 if (!result.Exists()) |
| 779 kBorderPrecedenceCell); | 766 return result; |
| 780 result = ChooseBorder(result, cell_after_adjoining_border); | |
| 781 if (!result.Exists()) | |
| 782 return result; | |
| 783 } | |
| 784 } | 767 } |
| 785 | 768 |
| 786 bool end_border_adjoins_table = HasEndBorderAdjoiningTable(); | 769 bool end_border_adjoins_table = HasEndBorderAdjoiningTable(); |
| 787 if (end_border_adjoins_table) { | 770 if (end_border_adjoins_table) { |
| 788 // (3) Our row's end border. | 771 // (3) Our row's end border. |
| 789 result = ChooseBorder( | 772 result = ChooseBorder( |
| 790 result, CollapsedBorderValue( | 773 result, CollapsedBorderValue(Row()->BorderAdjoiningEndCell(this), |
| 791 Row()->BorderAdjoiningEndCell(this), | 774 Parent()->ResolveColor(end_color_property), |
| 792 include_color ? Parent()->ResolveColor(end_color_property) | 775 kBorderPrecedenceRow)); |
| 793 : Color(), | |
| 794 kBorderPrecedenceRow)); | |
| 795 if (!result.Exists()) | 776 if (!result.Exists()) |
| 796 return result; | 777 return result; |
| 797 | 778 |
| 798 // (4) Our row group's end border. | 779 // (4) Our row group's end border. |
| 799 result = ChooseBorder( | 780 result = ChooseBorder( |
| 800 result, CollapsedBorderValue( | 781 result, |
| 801 Section()->BorderAdjoiningEndCell(this), | 782 CollapsedBorderValue(Section()->BorderAdjoiningEndCell(this), |
| 802 include_color ? Section()->ResolveColor(end_color_property) | 783 Section()->ResolveColor(end_color_property), |
| 803 : Color(), | 784 kBorderPrecedenceRowGroup)); |
| 804 kBorderPrecedenceRowGroup)); | |
| 805 if (!result.Exists()) | 785 if (!result.Exists()) |
| 806 return result; | 786 return result; |
| 807 } | 787 } |
| 808 | 788 |
| 809 // (5) Our column and column group's end borders. | 789 // (5) Our column and column group's end borders. |
| 810 LayoutTable::ColAndColGroup col_and_col_group = | 790 LayoutTable::ColAndColGroup col_and_col_group = |
| 811 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() + ColSpan() - 1); | 791 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() + ColSpan() - 1); |
| 812 if (col_and_col_group.colgroup && | 792 if (col_and_col_group.colgroup && |
| 813 col_and_col_group.adjoins_end_border_of_col_group) { | 793 col_and_col_group.adjoins_end_border_of_col_group) { |
| 814 // Only apply the colgroup's border if this cell touches the colgroup edge. | 794 // Only apply the colgroup's border if this cell touches the colgroup edge. |
| 815 result = ChooseBorder( | 795 result = ChooseBorder( |
| 816 result, | 796 result, |
| 817 CollapsedBorderValue( | 797 CollapsedBorderValue( |
| 818 col_and_col_group.colgroup->BorderAdjoiningCellEndBorder(this), | 798 col_and_col_group.colgroup->BorderAdjoiningCellEndBorder(this), |
| 819 include_color | 799 col_and_col_group.colgroup->ResolveColor(end_color_property), |
| 820 ? col_and_col_group.colgroup->ResolveColor(end_color_property) | |
| 821 : Color(), | |
| 822 kBorderPrecedenceColumnGroup)); | 800 kBorderPrecedenceColumnGroup)); |
| 823 if (!result.Exists()) | 801 if (!result.Exists()) |
| 824 return result; | 802 return result; |
| 825 } | 803 } |
| 826 if (col_and_col_group.col) { | 804 if (col_and_col_group.col) { |
| 827 // Always apply the col's border irrespective of whether this cell touches | 805 // Always apply the col's border irrespective of whether this cell touches |
| 828 // it. This is per HTML5: "For the purposes of the CSS table model, the col | 806 // it. This is per HTML5: "For the purposes of the CSS table model, the col |
| 829 // element is expected to be treated as if it "was present as many times as | 807 // element is expected to be treated as if it "was present as many times as |
| 830 // its span attribute specifies". | 808 // its span attribute specifies". |
| 831 result = ChooseBorder( | 809 result = ChooseBorder( |
| 832 result, CollapsedBorderValue( | 810 result, CollapsedBorderValue( |
| 833 col_and_col_group.col->BorderAdjoiningCellEndBorder(this), | 811 col_and_col_group.col->BorderAdjoiningCellEndBorder(this), |
| 834 include_color ? col_and_col_group.col->ResolveColor( | 812 col_and_col_group.col->ResolveColor(end_color_property), |
| 835 end_color_property) | |
| 836 : Color(), | |
| 837 kBorderPrecedenceColumn)); | 813 kBorderPrecedenceColumn)); |
| 838 if (!result.Exists()) | 814 if (!result.Exists()) |
| 839 return result; | 815 return result; |
| 840 } | 816 } |
| 841 | 817 |
| 842 // (6) The start border of the next column. | 818 // (6) The start border of the next column. |
| 843 if (!is_end_column) { | 819 if (!is_end_column) { |
| 844 LayoutTable::ColAndColGroup col_and_col_group = | 820 LayoutTable::ColAndColGroup col_and_col_group = |
| 845 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() + ColSpan()); | 821 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() + ColSpan()); |
| 846 if (col_and_col_group.colgroup && | 822 if (col_and_col_group.colgroup && |
| 847 col_and_col_group.adjoins_start_border_of_col_group) { | 823 col_and_col_group.adjoins_start_border_of_col_group) { |
| 848 // Only apply the colgroup's border if this cell touches the colgroup | 824 // Only apply the colgroup's border if this cell touches the colgroup |
| 849 // edge. | 825 // edge. |
| 850 result = ChooseBorder( | 826 result = ChooseBorder( |
| 851 result, | 827 result, |
| 852 CollapsedBorderValue( | 828 CollapsedBorderValue( |
| 853 col_and_col_group.colgroup->BorderAdjoiningCellStartBorder(this), | 829 col_and_col_group.colgroup->BorderAdjoiningCellStartBorder(this), |
| 854 include_color ? col_and_col_group.colgroup->ResolveColor( | 830 col_and_col_group.colgroup->ResolveColor(start_color_property), |
| 855 start_color_property) | |
| 856 : Color(), | |
| 857 kBorderPrecedenceColumnGroup)); | 831 kBorderPrecedenceColumnGroup)); |
| 858 if (!result.Exists()) | 832 if (!result.Exists()) |
| 859 return result; | 833 return result; |
| 860 } | 834 } |
| 861 if (col_and_col_group.col) { | 835 if (col_and_col_group.col) { |
| 862 // Always apply the col's border irrespective of whether this cell touches | 836 // Always apply the col's border irrespective of whether this cell touches |
| 863 // it. This is per HTML5: "For the purposes of the CSS table model, the | 837 // it. This is per HTML5: "For the purposes of the CSS table model, the |
| 864 // col element is expected to be treated as if it "was present as many | 838 // col element is expected to be treated as if it "was present as many |
| 865 // times as its span attribute specifies". | 839 // times as its span attribute specifies". |
| 866 result = ChooseBorder( | 840 result = ChooseBorder( |
| 867 result, CollapsedBorderValue( | 841 result, CollapsedBorderValue( |
| 868 col_and_col_group.col->BorderAdjoiningCellBefore(this), | 842 col_and_col_group.col->BorderAdjoiningCellBefore(this), |
| 869 include_color ? col_and_col_group.col->ResolveColor( | 843 col_and_col_group.col->ResolveColor(start_color_property), |
| 870 start_color_property) | |
| 871 : Color(), | |
| 872 kBorderPrecedenceColumn)); | 844 kBorderPrecedenceColumn)); |
| 873 if (!result.Exists()) | 845 if (!result.Exists()) |
| 874 return result; | 846 return result; |
| 875 } | 847 } |
| 876 } | 848 } |
| 877 | 849 |
| 878 if (end_border_adjoins_table) { | 850 if (end_border_adjoins_table) { |
| 879 // (7) The table's end border. | 851 // (7) The table's end border. |
| 880 result = ChooseBorder( | 852 result = ChooseBorder( |
| 881 result, | 853 result, CollapsedBorderValue(table->TableEndBorderAdjoiningCell(this), |
| 882 CollapsedBorderValue( | 854 table->ResolveColor(end_color_property), |
| 883 table->TableEndBorderAdjoiningCell(this), | 855 kBorderPrecedenceTable)); |
| 884 include_color ? table->ResolveColor(end_color_property) : Color(), | |
| 885 kBorderPrecedenceTable)); | |
| 886 if (!result.Exists()) | 856 if (!result.Exists()) |
| 887 return result; | 857 return result; |
| 888 } | 858 } |
| 889 | 859 |
| 890 return result; | 860 return result; |
| 891 } | 861 } |
| 892 | 862 |
| 893 CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder( | 863 CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const { |
| 894 IncludeBorderColorOrNot include_color) const { | |
| 895 LayoutTable* table = this->Table(); | 864 LayoutTable* table = this->Table(); |
| 865 LayoutTableCell* prev_cell = table->CellAbove(this); | |
| 866 // We can use the border shared with prevCell if it is valid. | |
|
wkorman
2017/04/27 20:11:15
prevCell -> |prev_cell|
Xianzhu
2017/04/28 20:31:44
Done.
| |
| 867 if (prev_cell && prev_cell->collapsed_border_values_valid_ && | |
| 868 prev_cell->AbsoluteColumnIndex() == AbsoluteColumnIndex()) { | |
| 869 return prev_cell->GetCollapsedBorderValues() | |
| 870 ? prev_cell->GetCollapsedBorderValues()->AfterBorder() | |
| 871 : CollapsedBorderValue(); | |
| 872 } | |
| 896 | 873 |
| 897 // For before border, we need to check, in order of precedence: | 874 // For before border, we need to check, in order of precedence: |
| 898 // (1) Our before border. | 875 // (1) Our before border. |
| 899 int before_color_property = include_color | 876 int before_color_property = CSSProperty::ResolveDirectionAwareProperty( |
| 900 ? CSSProperty::ResolveDirectionAwareProperty( | 877 CSSPropertyWebkitBorderBeforeColor, StyleForCellFlow().Direction(), |
| 901 CSSPropertyWebkitBorderBeforeColor, | 878 StyleForCellFlow().GetWritingMode()); |
| 902 StyleForCellFlow().Direction(), | 879 int after_color_property = CSSProperty::ResolveDirectionAwareProperty( |
| 903 StyleForCellFlow().GetWritingMode()) | 880 CSSPropertyWebkitBorderAfterColor, StyleForCellFlow().Direction(), |
| 904 : 0; | 881 StyleForCellFlow().GetWritingMode()); |
| 905 int after_color_property = include_color | |
| 906 ? CSSProperty::ResolveDirectionAwareProperty( | |
| 907 CSSPropertyWebkitBorderAfterColor, | |
| 908 StyleForCellFlow().Direction(), | |
| 909 StyleForCellFlow().GetWritingMode()) | |
| 910 : 0; | |
| 911 CollapsedBorderValue result = CollapsedBorderValue( | 882 CollapsedBorderValue result = CollapsedBorderValue( |
| 912 Style()->BorderBefore(), | 883 Style()->BorderBefore(), ResolveColor(before_color_property), |
| 913 include_color ? ResolveColor(before_color_property) : Color(), | |
| 914 kBorderPrecedenceCell); | 884 kBorderPrecedenceCell); |
| 915 | 885 |
| 916 LayoutTableCell* prev_cell = table->CellAbove(this); | |
| 917 if (prev_cell) { | 886 if (prev_cell) { |
| 918 // (2) A before cell's after border. | 887 // (2) A before cell's after border. |
| 919 result = ChooseBorder( | 888 result = ChooseBorder( |
| 920 CollapsedBorderValue(prev_cell->Style()->BorderAfter(), | 889 CollapsedBorderValue(prev_cell->Style()->BorderAfter(), |
| 921 include_color | 890 prev_cell->ResolveColor(after_color_property), |
| 922 ? prev_cell->ResolveColor(after_color_property) | |
| 923 : Color(), | |
| 924 kBorderPrecedenceCell), | 891 kBorderPrecedenceCell), |
| 925 result); | 892 result); |
| 926 if (!result.Exists()) | 893 if (!result.Exists()) |
| 927 return result; | 894 return result; |
| 928 } | 895 } |
| 929 | 896 |
| 930 // (3) Our row's before border. | 897 // (3) Our row's before border. |
| 931 result = ChooseBorder( | 898 result = ChooseBorder( |
| 932 result, CollapsedBorderValue( | 899 result, |
| 933 Parent()->Style()->BorderBefore(), | 900 CollapsedBorderValue(Parent()->Style()->BorderBefore(), |
| 934 include_color ? Parent()->ResolveColor(before_color_property) | 901 Parent()->ResolveColor(before_color_property), |
| 935 : Color(), | 902 kBorderPrecedenceRow)); |
| 936 kBorderPrecedenceRow)); | |
| 937 if (!result.Exists()) | 903 if (!result.Exists()) |
| 938 return result; | 904 return result; |
| 939 | 905 |
| 940 // (4) The previous row's after border. | 906 // (4) The previous row's after border. |
| 941 if (prev_cell) { | 907 if (prev_cell) { |
| 942 LayoutObject* prev_row = nullptr; | 908 LayoutObject* prev_row = nullptr; |
| 943 if (prev_cell->Section() == Section()) | 909 if (prev_cell->Section() == Section()) |
| 944 prev_row = Parent()->PreviousSibling(); | 910 prev_row = Parent()->PreviousSibling(); |
| 945 else | 911 else |
| 946 prev_row = prev_cell->Section()->LastRow(); | 912 prev_row = prev_cell->Section()->LastRow(); |
| 947 | 913 |
| 948 if (prev_row) { | 914 if (prev_row) { |
| 949 result = ChooseBorder( | 915 result = ChooseBorder( |
| 950 CollapsedBorderValue( | 916 CollapsedBorderValue(prev_row->Style()->BorderAfter(), |
| 951 prev_row->Style()->BorderAfter(), | 917 prev_row->ResolveColor(after_color_property), |
| 952 include_color ? prev_row->ResolveColor(after_color_property) | 918 kBorderPrecedenceRow), |
| 953 : Color(), | |
| 954 kBorderPrecedenceRow), | |
| 955 result); | 919 result); |
| 956 if (!result.Exists()) | 920 if (!result.Exists()) |
| 957 return result; | 921 return result; |
| 958 } | 922 } |
| 959 } | 923 } |
| 960 | 924 |
| 961 // Now check row groups. | 925 // Now check row groups. |
| 962 LayoutTableSection* curr_section = Section(); | 926 LayoutTableSection* curr_section = Section(); |
| 963 if (!RowIndex()) { | 927 if (!RowIndex()) { |
| 964 // (5) Our row group's before border. | 928 // (5) Our row group's before border. |
| 965 result = ChooseBorder( | 929 result = ChooseBorder( |
| 966 result, CollapsedBorderValue(curr_section->Style()->BorderBefore(), | 930 result, |
| 967 include_color ? curr_section->ResolveColor( | 931 CollapsedBorderValue(curr_section->Style()->BorderBefore(), |
| 968 before_color_property) | 932 curr_section->ResolveColor(before_color_property), |
| 969 : Color(), | 933 kBorderPrecedenceRowGroup)); |
| 970 kBorderPrecedenceRowGroup)); | |
| 971 if (!result.Exists()) | 934 if (!result.Exists()) |
| 972 return result; | 935 return result; |
| 973 | 936 |
| 974 // (6) Previous row group's after border. | 937 // (6) Previous row group's after border. |
| 975 curr_section = table->SectionAbove(curr_section, kSkipEmptySections); | 938 curr_section = table->SectionAbove(curr_section, kSkipEmptySections); |
| 976 if (curr_section) { | 939 if (curr_section) { |
| 977 result = ChooseBorder( | 940 result = ChooseBorder( |
| 978 CollapsedBorderValue( | 941 CollapsedBorderValue(curr_section->Style()->BorderAfter(), |
| 979 curr_section->Style()->BorderAfter(), | 942 curr_section->ResolveColor(after_color_property), |
| 980 include_color ? curr_section->ResolveColor(after_color_property) | 943 kBorderPrecedenceRowGroup), |
| 981 : Color(), | |
| 982 kBorderPrecedenceRowGroup), | |
| 983 result); | 944 result); |
| 984 if (!result.Exists()) | 945 if (!result.Exists()) |
| 985 return result; | 946 return result; |
| 986 } | 947 } |
| 987 } | 948 } |
| 988 | 949 |
| 989 if (!curr_section) { | 950 if (!curr_section) { |
| 990 // (8) Our column and column group's before borders. | 951 // (8) Our column and column group's before borders. |
| 991 LayoutTableCol* col_elt = | 952 LayoutTableCol* col_elt = |
| 992 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()) | 953 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()) |
| 993 .InnermostColOrColGroup(); | 954 .InnermostColOrColGroup(); |
| 994 if (col_elt) { | 955 if (col_elt) { |
| 995 result = ChooseBorder( | 956 result = ChooseBorder( |
| 996 result, | 957 result, |
| 997 CollapsedBorderValue( | 958 CollapsedBorderValue(col_elt->Style()->BorderBefore(), |
| 998 col_elt->Style()->BorderBefore(), | 959 col_elt->ResolveColor(before_color_property), |
| 999 include_color ? col_elt->ResolveColor(before_color_property) | 960 kBorderPrecedenceColumn)); |
| 1000 : Color(), | |
| 1001 kBorderPrecedenceColumn)); | |
| 1002 if (!result.Exists()) | 961 if (!result.Exists()) |
| 1003 return result; | 962 return result; |
| 1004 if (LayoutTableCol* enclosing_column_group = | 963 if (LayoutTableCol* enclosing_column_group = |
| 1005 col_elt->EnclosingColumnGroup()) { | 964 col_elt->EnclosingColumnGroup()) { |
| 1006 result = ChooseBorder( | 965 result = ChooseBorder( |
| 1007 result, CollapsedBorderValue( | 966 result, |
| 1008 enclosing_column_group->Style()->BorderBefore(), | 967 CollapsedBorderValue( |
| 1009 include_color ? enclosing_column_group->ResolveColor( | 968 enclosing_column_group->Style()->BorderBefore(), |
| 1010 before_color_property) | 969 enclosing_column_group->ResolveColor(before_color_property), |
| 1011 : Color(), | 970 kBorderPrecedenceColumnGroup)); |
| 1012 kBorderPrecedenceColumnGroup)); | |
| 1013 if (!result.Exists()) | 971 if (!result.Exists()) |
| 1014 return result; | 972 return result; |
| 1015 } | 973 } |
| 1016 } | 974 } |
| 1017 | 975 |
| 1018 // (9) The table's before border. | 976 // (9) The table's before border. |
| 1019 result = ChooseBorder( | 977 result = ChooseBorder( |
| 1020 result, CollapsedBorderValue( | 978 result, CollapsedBorderValue(table->Style()->BorderBefore(), |
| 1021 table->Style()->BorderBefore(), | 979 table->ResolveColor(before_color_property), |
| 1022 include_color ? table->ResolveColor(before_color_property) | 980 kBorderPrecedenceTable)); |
| 1023 : Color(), | |
| 1024 kBorderPrecedenceTable)); | |
| 1025 if (!result.Exists()) | 981 if (!result.Exists()) |
| 1026 return result; | 982 return result; |
| 1027 } | 983 } |
| 1028 | 984 |
| 1029 return result; | 985 return result; |
| 1030 } | 986 } |
| 1031 | 987 |
| 1032 CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder( | 988 CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const { |
| 1033 IncludeBorderColorOrNot include_color) const { | |
| 1034 LayoutTable* table = this->Table(); | 989 LayoutTable* table = this->Table(); |
| 990 LayoutTableCell* next_cell = table->CellBelow(this); | |
| 991 // We can use the border shared with nextCell if it is valid. | |
| 992 if (next_cell && next_cell->collapsed_border_values_valid_ && | |
| 993 next_cell->AbsoluteColumnIndex() == AbsoluteColumnIndex()) { | |
| 994 return next_cell->GetCollapsedBorderValues() | |
| 995 ? next_cell->GetCollapsedBorderValues()->BeforeBorder() | |
| 996 : CollapsedBorderValue(); | |
| 997 } | |
| 1035 | 998 |
| 1036 // For after border, we need to check, in order of precedence: | 999 // For after border, we need to check, in order of precedence: |
| 1037 // (1) Our after border. | 1000 // (1) Our after border. |
| 1038 int before_color_property = include_color | 1001 int before_color_property = CSSProperty::ResolveDirectionAwareProperty( |
| 1039 ? CSSProperty::ResolveDirectionAwareProperty( | 1002 CSSPropertyWebkitBorderBeforeColor, StyleForCellFlow().Direction(), |
| 1040 CSSPropertyWebkitBorderBeforeColor, | 1003 StyleForCellFlow().GetWritingMode()); |
| 1041 StyleForCellFlow().Direction(), | 1004 int after_color_property = CSSProperty::ResolveDirectionAwareProperty( |
| 1042 StyleForCellFlow().GetWritingMode()) | 1005 CSSPropertyWebkitBorderAfterColor, StyleForCellFlow().Direction(), |
| 1043 : 0; | 1006 StyleForCellFlow().GetWritingMode()); |
| 1044 int after_color_property = include_color | |
| 1045 ? CSSProperty::ResolveDirectionAwareProperty( | |
| 1046 CSSPropertyWebkitBorderAfterColor, | |
| 1047 StyleForCellFlow().Direction(), | |
| 1048 StyleForCellFlow().GetWritingMode()) | |
| 1049 : 0; | |
| 1050 CollapsedBorderValue result = CollapsedBorderValue( | 1007 CollapsedBorderValue result = CollapsedBorderValue( |
| 1051 Style()->BorderAfter(), | 1008 Style()->BorderAfter(), ResolveColor(after_color_property), |
| 1052 include_color ? ResolveColor(after_color_property) : Color(), | |
| 1053 kBorderPrecedenceCell); | 1009 kBorderPrecedenceCell); |
| 1054 | 1010 |
| 1055 LayoutTableCell* next_cell = table->CellBelow(this); | |
| 1056 if (next_cell) { | 1011 if (next_cell) { |
| 1057 // (2) An after cell's before border. | 1012 // (2) An after cell's before border. |
| 1058 result = ChooseBorder( | 1013 result = ChooseBorder( |
| 1059 result, CollapsedBorderValue(next_cell->Style()->BorderBefore(), | 1014 result, |
| 1060 include_color ? next_cell->ResolveColor( | 1015 CollapsedBorderValue(next_cell->Style()->BorderBefore(), |
| 1061 before_color_property) | 1016 next_cell->ResolveColor(before_color_property), |
| 1062 : Color(), | 1017 kBorderPrecedenceCell)); |
| 1063 kBorderPrecedenceCell)); | |
| 1064 if (!result.Exists()) | 1018 if (!result.Exists()) |
| 1065 return result; | 1019 return result; |
| 1066 } | 1020 } |
| 1067 | 1021 |
| 1068 // (3) Our row's after border. (FIXME: Deal with rowspan!) | 1022 // (3) Our row's after border. (FIXME: Deal with rowspan!) |
| 1069 result = ChooseBorder( | 1023 result = ChooseBorder( |
| 1070 result, CollapsedBorderValue( | 1024 result, CollapsedBorderValue(Parent()->Style()->BorderAfter(), |
| 1071 Parent()->Style()->BorderAfter(), | 1025 Parent()->ResolveColor(after_color_property), |
| 1072 include_color ? Parent()->ResolveColor(after_color_property) | 1026 kBorderPrecedenceRow)); |
| 1073 : Color(), | |
| 1074 kBorderPrecedenceRow)); | |
| 1075 if (!result.Exists()) | 1027 if (!result.Exists()) |
| 1076 return result; | 1028 return result; |
| 1077 | 1029 |
| 1078 // (4) The next row's before border. | 1030 // (4) The next row's before border. |
| 1079 if (next_cell) { | 1031 if (next_cell) { |
| 1080 result = ChooseBorder( | 1032 result = ChooseBorder( |
| 1081 result, | 1033 result, CollapsedBorderValue( |
| 1082 CollapsedBorderValue(next_cell->Parent()->Style()->BorderBefore(), | 1034 next_cell->Parent()->Style()->BorderBefore(), |
| 1083 include_color ? next_cell->Parent()->ResolveColor( | 1035 next_cell->Parent()->ResolveColor(before_color_property), |
| 1084 before_color_property) | 1036 kBorderPrecedenceRow)); |
| 1085 : Color(), | |
| 1086 kBorderPrecedenceRow)); | |
| 1087 if (!result.Exists()) | 1037 if (!result.Exists()) |
| 1088 return result; | 1038 return result; |
| 1089 } | 1039 } |
| 1090 | 1040 |
| 1091 // Now check row groups. | 1041 // Now check row groups. |
| 1092 LayoutTableSection* curr_section = Section(); | 1042 LayoutTableSection* curr_section = Section(); |
| 1093 if (RowIndex() + RowSpan() >= curr_section->NumRows()) { | 1043 if (RowIndex() + RowSpan() >= curr_section->NumRows()) { |
| 1094 // (5) Our row group's after border. | 1044 // (5) Our row group's after border. |
| 1095 result = ChooseBorder( | 1045 result = ChooseBorder( |
| 1096 result, CollapsedBorderValue(curr_section->Style()->BorderAfter(), | 1046 result, |
| 1097 include_color ? curr_section->ResolveColor( | 1047 CollapsedBorderValue(curr_section->Style()->BorderAfter(), |
| 1098 after_color_property) | 1048 curr_section->ResolveColor(after_color_property), |
| 1099 : Color(), | 1049 kBorderPrecedenceRowGroup)); |
| 1100 kBorderPrecedenceRowGroup)); | |
| 1101 if (!result.Exists()) | 1050 if (!result.Exists()) |
| 1102 return result; | 1051 return result; |
| 1103 | 1052 |
| 1104 // (6) Following row group's before border. | 1053 // (6) Following row group's before border. |
| 1105 curr_section = table->SectionBelow(curr_section, kSkipEmptySections); | 1054 curr_section = table->SectionBelow(curr_section, kSkipEmptySections); |
| 1106 if (curr_section) { | 1055 if (curr_section) { |
| 1107 result = ChooseBorder( | 1056 result = ChooseBorder( |
| 1108 result, | 1057 result, CollapsedBorderValue( |
| 1109 CollapsedBorderValue( | 1058 curr_section->Style()->BorderBefore(), |
| 1110 curr_section->Style()->BorderBefore(), | 1059 curr_section->ResolveColor(before_color_property), |
| 1111 include_color ? curr_section->ResolveColor(before_color_property) | 1060 kBorderPrecedenceRowGroup)); |
| 1112 : Color(), | |
| 1113 kBorderPrecedenceRowGroup)); | |
| 1114 if (!result.Exists()) | 1061 if (!result.Exists()) |
| 1115 return result; | 1062 return result; |
| 1116 } | 1063 } |
| 1117 } | 1064 } |
| 1118 | 1065 |
| 1119 if (!curr_section) { | 1066 if (!curr_section) { |
| 1120 // (8) Our column and column group's after borders. | 1067 // (8) Our column and column group's after borders. |
| 1121 LayoutTableCol* col_elt = | 1068 LayoutTableCol* col_elt = |
| 1122 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()) | 1069 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()) |
| 1123 .InnermostColOrColGroup(); | 1070 .InnermostColOrColGroup(); |
| 1124 if (col_elt) { | 1071 if (col_elt) { |
| 1125 result = ChooseBorder( | 1072 result = ChooseBorder( |
| 1126 result, CollapsedBorderValue(col_elt->Style()->BorderAfter(), | 1073 result, |
| 1127 include_color ? col_elt->ResolveColor( | 1074 CollapsedBorderValue(col_elt->Style()->BorderAfter(), |
| 1128 after_color_property) | 1075 col_elt->ResolveColor(after_color_property), |
| 1129 : Color(), | 1076 kBorderPrecedenceColumn)); |
| 1130 kBorderPrecedenceColumn)); | |
| 1131 if (!result.Exists()) | 1077 if (!result.Exists()) |
| 1132 return result; | 1078 return result; |
| 1133 if (LayoutTableCol* enclosing_column_group = | 1079 if (LayoutTableCol* enclosing_column_group = |
| 1134 col_elt->EnclosingColumnGroup()) { | 1080 col_elt->EnclosingColumnGroup()) { |
| 1135 result = ChooseBorder( | 1081 result = ChooseBorder( |
| 1136 result, CollapsedBorderValue( | 1082 result, |
| 1137 enclosing_column_group->Style()->BorderAfter(), | 1083 CollapsedBorderValue( |
| 1138 include_color ? enclosing_column_group->ResolveColor( | 1084 enclosing_column_group->Style()->BorderAfter(), |
|
wkorman
2017/04/27 20:11:15
Perhaps worth mentioning this color change in CL d
Xianzhu
2017/04/28 20:31:45
Done.
| |
| 1139 after_color_property) | 1085 enclosing_column_group->ResolveColor(after_color_property), |
| 1140 : Color(), | 1086 kBorderPrecedenceColumnGroup)); |
| 1141 kBorderPrecedenceColumnGroup)); | |
| 1142 if (!result.Exists()) | 1087 if (!result.Exists()) |
| 1143 return result; | 1088 return result; |
| 1144 } | 1089 } |
| 1145 } | 1090 } |
| 1146 | 1091 |
| 1147 // (9) The table's after border. | 1092 // (9) The table's after border. |
| 1148 result = ChooseBorder( | 1093 result = ChooseBorder( |
| 1149 result, | 1094 result, CollapsedBorderValue(table->Style()->BorderAfter(), |
| 1150 CollapsedBorderValue( | 1095 table->ResolveColor(after_color_property), |
| 1151 table->Style()->BorderAfter(), | 1096 kBorderPrecedenceTable)); |
| 1152 include_color ? table->ResolveColor(after_color_property) : Color(), | |
| 1153 kBorderPrecedenceTable)); | |
| 1154 if (!result.Exists()) | 1097 if (!result.Exists()) |
| 1155 return result; | 1098 return result; |
| 1156 } | 1099 } |
| 1157 | 1100 |
| 1158 return result; | 1101 return result; |
| 1159 } | 1102 } |
| 1160 | 1103 |
| 1161 LayoutUnit LayoutTableCell::BorderLeft() const { | 1104 LayoutUnit LayoutTableCell::BorderLeft() const { |
| 1162 return Table()->CollapseBorders() ? CollapsedBorderHalfLeft(false) | 1105 return Table()->CollapseBorders() ? CollapsedBorderHalfLeft(false) |
| 1163 : LayoutBlockFlow::BorderLeft(); | 1106 : LayoutBlockFlow::BorderLeft(); |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1243 return style_for_cell_flow.IsFlippedBlocksWritingMode() | 1186 return style_for_cell_flow.IsFlippedBlocksWritingMode() |
| 1244 ? CollapsedBorderHalfBefore(outer) | 1187 ? CollapsedBorderHalfBefore(outer) |
| 1245 : CollapsedBorderHalfAfter(outer); | 1188 : CollapsedBorderHalfAfter(outer); |
| 1246 } | 1189 } |
| 1247 return style_for_cell_flow.IsLeftToRightDirection() | 1190 return style_for_cell_flow.IsLeftToRightDirection() |
| 1248 ? CollapsedBorderHalfEnd(outer) | 1191 ? CollapsedBorderHalfEnd(outer) |
| 1249 : CollapsedBorderHalfStart(outer); | 1192 : CollapsedBorderHalfStart(outer); |
| 1250 } | 1193 } |
| 1251 | 1194 |
| 1252 LayoutUnit LayoutTableCell::CollapsedBorderHalfStart(bool outer) const { | 1195 LayoutUnit LayoutTableCell::CollapsedBorderHalfStart(bool outer) const { |
| 1253 CollapsedBorderValue border = | 1196 RecalcCollapsedBorderValuesIfNeeded(); |
| 1254 ComputeCollapsedStartBorder(kDoNotIncludeBorderColor); | 1197 const auto* collapsed_border_values = this->GetCollapsedBorderValues(); |
| 1198 if (!collapsed_border_values) | |
| 1199 return LayoutUnit(); | |
| 1200 | |
| 1201 const auto& border = collapsed_border_values->StartBorder(); | |
| 1255 if (border.Exists()) { | 1202 if (border.Exists()) { |
| 1256 return LayoutUnit( | 1203 return LayoutUnit( |
| 1257 (border.Width() + | 1204 (border.Width() + |
| 1258 ((StyleForCellFlow().IsLeftToRightDirection() ^ outer) ? 1 : 0)) / | 1205 ((StyleForCellFlow().IsLeftToRightDirection() ^ outer) ? 1 : 0)) / |
| 1259 2); // Give the extra pixel to top and left. | 1206 2); // Give the extra pixel to top and left. |
| 1260 } | 1207 } |
| 1261 return LayoutUnit(); | 1208 return LayoutUnit(); |
| 1262 } | 1209 } |
| 1263 | 1210 |
| 1264 LayoutUnit LayoutTableCell::CollapsedBorderHalfEnd(bool outer) const { | 1211 LayoutUnit LayoutTableCell::CollapsedBorderHalfEnd(bool outer) const { |
| 1265 CollapsedBorderValue border = | 1212 RecalcCollapsedBorderValuesIfNeeded(); |
| 1266 ComputeCollapsedEndBorder(kDoNotIncludeBorderColor); | 1213 const auto* collapsed_border_values = this->GetCollapsedBorderValues(); |
| 1214 if (!collapsed_border_values) | |
| 1215 return LayoutUnit(); | |
| 1216 | |
| 1217 const auto& border = collapsed_border_values->EndBorder(); | |
| 1267 if (border.Exists()) { | 1218 if (border.Exists()) { |
| 1268 return LayoutUnit( | 1219 return LayoutUnit( |
| 1269 (border.Width() + | 1220 (border.Width() + |
| 1270 ((StyleForCellFlow().IsLeftToRightDirection() ^ outer) ? 0 : 1)) / | 1221 ((StyleForCellFlow().IsLeftToRightDirection() ^ outer) ? 0 : 1)) / |
| 1271 2); | 1222 2); |
| 1272 } | 1223 } |
| 1273 return LayoutUnit(); | 1224 return LayoutUnit(); |
| 1274 } | 1225 } |
| 1275 | 1226 |
| 1276 LayoutUnit LayoutTableCell::CollapsedBorderHalfBefore(bool outer) const { | 1227 LayoutUnit LayoutTableCell::CollapsedBorderHalfBefore(bool outer) const { |
| 1277 CollapsedBorderValue border = | 1228 RecalcCollapsedBorderValuesIfNeeded(); |
| 1278 ComputeCollapsedBeforeBorder(kDoNotIncludeBorderColor); | 1229 const auto* collapsed_border_values = this->GetCollapsedBorderValues(); |
| 1230 if (!collapsed_border_values) | |
| 1231 return LayoutUnit(); | |
| 1232 | |
| 1233 const auto& border = collapsed_border_values->BeforeBorder(); | |
| 1279 if (border.Exists()) { | 1234 if (border.Exists()) { |
| 1280 return LayoutUnit( | 1235 return LayoutUnit( |
| 1281 (border.Width() + | 1236 (border.Width() + |
| 1282 ((StyleForCellFlow().IsFlippedBlocksWritingMode() ^ outer) ? 0 : 1)) / | 1237 ((StyleForCellFlow().IsFlippedBlocksWritingMode() ^ outer) ? 0 : 1)) / |
| 1283 2); // Give the extra pixel to top and left. | 1238 2); // Give the extra pixel to top and left. |
| 1284 } | 1239 } |
| 1285 return LayoutUnit(); | 1240 return LayoutUnit(); |
| 1286 } | 1241 } |
| 1287 | 1242 |
| 1288 LayoutUnit LayoutTableCell::CollapsedBorderHalfAfter(bool outer) const { | 1243 LayoutUnit LayoutTableCell::CollapsedBorderHalfAfter(bool outer) const { |
| 1289 CollapsedBorderValue border = | 1244 RecalcCollapsedBorderValuesIfNeeded(); |
| 1290 ComputeCollapsedAfterBorder(kDoNotIncludeBorderColor); | 1245 const auto* collapsed_border_values = this->GetCollapsedBorderValues(); |
| 1246 if (!collapsed_border_values) | |
| 1247 return LayoutUnit(); | |
| 1248 | |
| 1249 const auto& border = collapsed_border_values->AfterBorder(); | |
| 1291 if (border.Exists()) { | 1250 if (border.Exists()) { |
| 1292 return LayoutUnit( | 1251 return LayoutUnit( |
| 1293 (border.Width() + | 1252 (border.Width() + |
| 1294 ((StyleForCellFlow().IsFlippedBlocksWritingMode() ^ outer) ? 1 : 0)) / | 1253 ((StyleForCellFlow().IsFlippedBlocksWritingMode() ^ outer) ? 1 : 0)) / |
| 1295 2); | 1254 2); |
| 1296 } | 1255 } |
| 1297 return LayoutUnit(); | 1256 return LayoutUnit(); |
| 1298 } | 1257 } |
| 1299 | 1258 |
| 1300 void LayoutTableCell::Paint(const PaintInfo& paint_info, | 1259 void LayoutTableCell::Paint(const PaintInfo& paint_info, |
| 1301 const LayoutPoint& paint_offset) const { | 1260 const LayoutPoint& paint_offset) const { |
| 1302 TableCellPainter(*this).Paint(paint_info, paint_offset); | 1261 TableCellPainter(*this).Paint(paint_info, paint_offset); |
| 1303 } | 1262 } |
| 1304 | 1263 |
| 1264 void LayoutTableCell::RecalcCollapsedBorderValuesIfNeeded() const { | |
|
wkorman
2017/04/27 20:11:15
Same as previous -- believe prefer without ...IfNe
Xianzhu
2017/04/28 20:31:44
Renamed to UpdateCollapsedBorderValues(). Simply r
| |
| 1265 Table()->InvalidateCollapsedBordersForAllCellsIfNeeded(); | |
| 1266 if (collapsed_border_values_valid_) | |
| 1267 return; | |
| 1268 | |
| 1269 collapsed_border_values_valid_ = true; | |
| 1270 | |
| 1271 if (!Table()->CollapseBorders()) { | |
| 1272 if (collapsed_border_values_) { | |
| 1273 collapsed_borders_visually_changed_ = true; | |
| 1274 collapsed_border_values_ = nullptr; | |
| 1275 } | |
| 1276 return; | |
| 1277 } | |
| 1278 | |
| 1279 CollapsedBorderValues new_values( | |
| 1280 *this, ComputeCollapsedStartBorder(), ComputeCollapsedEndBorder(), | |
| 1281 ComputeCollapsedBeforeBorder(), ComputeCollapsedAfterBorder()); | |
| 1282 | |
| 1283 // We need to save collapsed border if has a non-zero width even if it's | |
| 1284 // invisible because the width affects table layout. | |
| 1285 if (!new_values.StartBorder().Width() && !new_values.EndBorder().Width() && | |
| 1286 !new_values.BeforeBorder().Width() && !new_values.AfterBorder().Width()) { | |
| 1287 if (collapsed_border_values_) { | |
| 1288 collapsed_borders_visually_changed_ = true; | |
| 1289 collapsed_border_values_ = nullptr; | |
| 1290 } | |
| 1291 return; | |
| 1292 } | |
| 1293 | |
| 1294 if (!collapsed_border_values_) { | |
| 1295 collapsed_borders_visually_changed_ = true; | |
| 1296 collapsed_border_values_ = WTF::WrapUnique(new CollapsedBorderValues( | |
| 1297 *this, new_values.StartBorder(), new_values.EndBorder(), | |
| 1298 new_values.BeforeBorder(), new_values.AfterBorder())); | |
| 1299 return; | |
| 1300 } | |
| 1301 | |
| 1302 // We check VisuallyEquals so that the table cell is invalidated only if a | |
| 1303 // changed collapsed border is visible in the first place. | |
| 1304 if (!collapsed_border_values_->StartBorder().VisuallyEquals( | |
| 1305 new_values.StartBorder()) || | |
| 1306 !collapsed_border_values_->EndBorder().VisuallyEquals( | |
| 1307 new_values.EndBorder()) || | |
| 1308 !collapsed_border_values_->BeforeBorder().VisuallyEquals( | |
| 1309 new_values.BeforeBorder()) || | |
| 1310 !collapsed_border_values_->AfterBorder().VisuallyEquals( | |
| 1311 new_values.AfterBorder())) { | |
| 1312 collapsed_border_values_->SetCollapsedBorderValues(new_values); | |
| 1313 collapsed_borders_visually_changed_ = true; | |
| 1314 } | |
| 1315 } | |
| 1316 | |
| 1305 static void AddBorderStyle(LayoutTable::CollapsedBorderValues& border_values, | 1317 static void AddBorderStyle(LayoutTable::CollapsedBorderValues& border_values, |
| 1306 CollapsedBorderValue border_value) { | 1318 CollapsedBorderValue border_value) { |
| 1307 if (!border_value.IsVisible()) | 1319 if (!border_value.IsVisible()) |
| 1308 return; | 1320 return; |
| 1309 size_t count = border_values.size(); | 1321 size_t count = border_values.size(); |
| 1310 for (size_t i = 0; i < count; ++i) { | 1322 for (size_t i = 0; i < count; ++i) { |
| 1311 if (border_values[i].IsSameIgnoringColor(border_value)) | 1323 if (border_values[i].IsSameIgnoringColor(border_value)) |
| 1312 return; | 1324 return; |
| 1313 } | 1325 } |
| 1314 border_values.push_back(border_value); | 1326 border_values.push_back(border_value); |
| 1315 } | 1327 } |
| 1316 | 1328 |
| 1317 void LayoutTableCell::CollectCollapsedBorderValues( | 1329 void LayoutTableCell::CollectCollapsedBorderValues( |
| 1318 LayoutTable::CollapsedBorderValues& border_values) { | 1330 LayoutTable::CollapsedBorderValues& border_values) { |
| 1319 CollapsedBorderValues new_values( | 1331 RecalcCollapsedBorderValuesIfNeeded(); |
| 1320 *this, ComputeCollapsedStartBorder(), ComputeCollapsedEndBorder(), | |
| 1321 ComputeCollapsedBeforeBorder(), ComputeCollapsedAfterBorder()); | |
| 1322 | |
| 1323 bool changed = false; | |
| 1324 if (!new_values.StartBorder().IsVisible() && | |
| 1325 !new_values.EndBorder().IsVisible() && | |
| 1326 !new_values.BeforeBorder().IsVisible() && | |
| 1327 !new_values.AfterBorder().IsVisible()) { | |
| 1328 changed = !!collapsed_border_values_; | |
| 1329 collapsed_border_values_ = nullptr; | |
| 1330 } else if (!collapsed_border_values_) { | |
| 1331 changed = true; | |
| 1332 collapsed_border_values_ = WTF::WrapUnique(new CollapsedBorderValues( | |
| 1333 *this, new_values.StartBorder(), new_values.EndBorder(), | |
| 1334 new_values.BeforeBorder(), new_values.AfterBorder())); | |
| 1335 } else { | |
| 1336 // We check visuallyEquals so that the table cell is invalidated only if a | |
| 1337 // changed collapsed border is visible in the first place. | |
| 1338 changed = !collapsed_border_values_->StartBorder().VisuallyEquals( | |
| 1339 new_values.StartBorder()) || | |
| 1340 !collapsed_border_values_->EndBorder().VisuallyEquals( | |
| 1341 new_values.EndBorder()) || | |
| 1342 !collapsed_border_values_->BeforeBorder().VisuallyEquals( | |
| 1343 new_values.BeforeBorder()) || | |
| 1344 !collapsed_border_values_->AfterBorder().VisuallyEquals( | |
| 1345 new_values.AfterBorder()); | |
| 1346 if (changed) | |
| 1347 collapsed_border_values_->SetCollapsedBorderValues(new_values); | |
| 1348 } | |
| 1349 | 1332 |
| 1350 // If collapsed borders changed, invalidate the cell's display item client on | 1333 // If collapsed borders changed, invalidate the cell's display item client on |
| 1351 // the table's backing. | 1334 // the table's backing. |
| 1352 // TODO(crbug.com/451090#c5): Need a way to invalidate/repaint the borders | 1335 // TODO(crbug.com/451090#c5): Need a way to invalidate/repaint the borders |
| 1353 // only. | 1336 // only. |
| 1354 if (changed) { | 1337 if (collapsed_borders_visually_changed_) { |
| 1355 ObjectPaintInvalidator(*Table()) | 1338 ObjectPaintInvalidator(*Table()) |
| 1356 .SlowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient( | 1339 .SlowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient( |
| 1357 *this, kPaintInvalidationStyleChange); | 1340 *this, kPaintInvalidationStyleChange); |
| 1341 collapsed_borders_visually_changed_ = false; | |
| 1358 } | 1342 } |
| 1359 | 1343 |
| 1360 AddBorderStyle(border_values, new_values.StartBorder()); | 1344 if (!collapsed_border_values_) |
| 1361 AddBorderStyle(border_values, new_values.EndBorder()); | 1345 return; |
| 1362 AddBorderStyle(border_values, new_values.BeforeBorder()); | 1346 |
| 1363 AddBorderStyle(border_values, new_values.AfterBorder()); | 1347 AddBorderStyle(border_values, collapsed_border_values_->StartBorder()); |
| 1348 AddBorderStyle(border_values, collapsed_border_values_->EndBorder()); | |
| 1349 AddBorderStyle(border_values, collapsed_border_values_->BeforeBorder()); | |
| 1350 AddBorderStyle(border_values, collapsed_border_values_->AfterBorder()); | |
| 1364 } | 1351 } |
| 1365 | 1352 |
| 1366 void LayoutTableCell::SortCollapsedBorderValues( | 1353 void LayoutTableCell::SortCollapsedBorderValues( |
| 1367 LayoutTable::CollapsedBorderValues& border_values) { | 1354 LayoutTable::CollapsedBorderValues& border_values) { |
| 1368 std::sort(border_values.begin(), border_values.end(), CompareBorders); | 1355 std::sort(border_values.begin(), border_values.end(), CompareBorders); |
| 1369 } | 1356 } |
| 1370 | 1357 |
| 1371 void LayoutTableCell::PaintBoxDecorationBackground( | 1358 void LayoutTableCell::PaintBoxDecorationBackground( |
| 1372 const PaintInfo& paint_info, | 1359 const PaintInfo& paint_info, |
| 1373 const LayoutPoint& paint_offset) const { | 1360 const LayoutPoint& paint_offset) const { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1485 } | 1472 } |
| 1486 | 1473 |
| 1487 bool LayoutTableCell::HasLineIfEmpty() const { | 1474 bool LayoutTableCell::HasLineIfEmpty() const { |
| 1488 if (GetNode() && HasEditableStyle(*GetNode())) | 1475 if (GetNode() && HasEditableStyle(*GetNode())) |
| 1489 return true; | 1476 return true; |
| 1490 | 1477 |
| 1491 return LayoutBlock::HasLineIfEmpty(); | 1478 return LayoutBlock::HasLineIfEmpty(); |
| 1492 } | 1479 } |
| 1493 | 1480 |
| 1494 } // namespace blink | 1481 } // namespace blink |
| OLD | NEW |