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 |