| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights |
| 3 * reserved. | 3 * reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2020 // This assertion fires in layout tests in the case-transform.html test | 2020 // This assertion fires in layout tests in the case-transform.html test |
| 2021 // because of a mix-up between offsets in the text in the DOM tree with | 2021 // because of a mix-up between offsets in the text in the DOM tree with |
| 2022 // text in the layout tree which can have a different length due to case | 2022 // text in the layout tree which can have a different length due to case |
| 2023 // transformation. | 2023 // transformation. |
| 2024 // Until we resolve that, disable this so we can run the layout tests! | 2024 // Until we resolve that, disable this so we can run the layout tests! |
| 2025 // DCHECK_GE(currentOffset, layoutObject->caretMaxOffset()); | 2025 // DCHECK_GE(currentOffset, layoutObject->caretMaxOffset()); |
| 2026 return PositionTemplate<Strategy>( | 2026 return PositionTemplate<Strategy>( |
| 2027 current_node, layout_object->CaretMaxOffset() + text_start_offset); | 2027 current_node, layout_object->CaretMaxOffset() + text_start_offset); |
| 2028 } | 2028 } |
| 2029 | 2029 |
| 2030 // Map offset in DOM node to offset in InlineBox. | 2030 if (CanBeBackwardCaretPosition(text_layout_object, |
| 2031 DCHECK_GE(current_pos.OffsetInLeafNode(), | 2031 current_pos.OffsetInLeafNode())) { |
| 2032 static_cast<int>(text_start_offset)); | 2032 return current_pos.ComputePosition(); |
| 2033 const unsigned text_offset = | |
| 2034 current_pos.OffsetInLeafNode() - text_start_offset; | |
| 2035 InlineTextBox* last_text_box = text_layout_object->LastTextBox(); | |
| 2036 for (InlineTextBox* box = text_layout_object->FirstTextBox(); box; | |
| 2037 box = box->NextTextBox()) { | |
| 2038 if (text_offset == box->Start()) { | |
| 2039 if (text_layout_object->IsTextFragment() && | |
| 2040 ToLayoutTextFragment(layout_object) | |
| 2041 ->IsRemainingTextLayoutObject()) { | |
| 2042 // |currentPos| is at start of remaining text of | |
| 2043 // |Text| node with :first-letter. | |
| 2044 DCHECK_GE(current_pos.OffsetInLeafNode(), 1); | |
| 2045 LayoutObject* first_letter_layout_object = | |
| 2046 ToLayoutTextFragment(layout_object) | |
| 2047 ->GetFirstLetterPseudoElement() | |
| 2048 ->GetLayoutObject(); | |
| 2049 if (first_letter_layout_object && | |
| 2050 first_letter_layout_object->Style()->Visibility() == | |
| 2051 EVisibility::kVisible) | |
| 2052 return current_pos.ComputePosition(); | |
| 2053 } | |
| 2054 continue; | |
| 2055 } | |
| 2056 if (text_offset <= box->Start() + box->Len()) { | |
| 2057 if (text_offset > box->Start()) | |
| 2058 return current_pos.ComputePosition(); | |
| 2059 continue; | |
| 2060 } | |
| 2061 | |
| 2062 if (box == last_text_box || | |
| 2063 text_offset != box->Start() + box->Len() + 1) | |
| 2064 continue; | |
| 2065 | |
| 2066 // The text continues on the next line only if the last text box is not | |
| 2067 // on this line and none of the boxes on this line have a larger start | |
| 2068 // offset. | |
| 2069 | |
| 2070 bool continues_on_next_line = true; | |
| 2071 InlineBox* other_box = box; | |
| 2072 while (continues_on_next_line) { | |
| 2073 other_box = other_box->NextLeafChild(); | |
| 2074 if (!other_box) | |
| 2075 break; | |
| 2076 if (other_box == last_text_box || | |
| 2077 (LineLayoutAPIShim::LayoutObjectFrom( | |
| 2078 other_box->GetLineLayoutItem()) == text_layout_object && | |
| 2079 ToInlineTextBox(other_box)->Start() > text_offset)) | |
| 2080 continues_on_next_line = false; | |
| 2081 } | |
| 2082 | |
| 2083 other_box = box; | |
| 2084 while (continues_on_next_line) { | |
| 2085 other_box = other_box->PrevLeafChild(); | |
| 2086 if (!other_box) | |
| 2087 break; | |
| 2088 if (other_box == last_text_box || | |
| 2089 (LineLayoutAPIShim::LayoutObjectFrom( | |
| 2090 other_box->GetLineLayoutItem()) == text_layout_object && | |
| 2091 ToInlineTextBox(other_box)->Start() > text_offset)) | |
| 2092 continues_on_next_line = false; | |
| 2093 } | |
| 2094 | |
| 2095 if (continues_on_next_line) | |
| 2096 return current_pos.ComputePosition(); | |
| 2097 } | 2033 } |
| 2098 } | 2034 } |
| 2099 } | 2035 } |
| 2100 return last_visible.DeprecatedComputePosition(); | 2036 return last_visible.DeprecatedComputePosition(); |
| 2101 } | 2037 } |
| 2102 | 2038 |
| 2039 // TODO(editing-dev): This function is just moved out from |
| 2040 // |MostBackwardCaretPosition()|. We should study this function more and |
| 2041 // name it appropriately. See https://trac.webkit.org/changeset/32438/ |
| 2042 // which introduce this. |
| 2043 static bool CanBeBackwardCaretPosition(const LayoutText* text_layout_object, |
| 2044 int offset_in_node) { |
| 2045 const unsigned text_start_offset = text_layout_object->TextStartOffset(); |
| 2046 DCHECK_GE(offset_in_node, static_cast<int>(text_start_offset)); |
| 2047 const unsigned text_offset = offset_in_node - text_start_offset; |
| 2048 InlineTextBox* const last_text_box = text_layout_object->LastTextBox(); |
| 2049 for (InlineTextBox* box = text_layout_object->FirstTextBox(); box; |
| 2050 box = box->NextTextBox()) { |
| 2051 if (text_offset == box->Start()) { |
| 2052 if (text_layout_object->IsTextFragment() && |
| 2053 ToLayoutTextFragment(text_layout_object) |
| 2054 ->IsRemainingTextLayoutObject()) { |
| 2055 // |offset_in_node| is at start of remaining text of |
| 2056 // |Text| node with :first-letter. |
| 2057 DCHECK_GE(offset_in_node, 1); |
| 2058 LayoutObject* first_letter_layout_object = |
| 2059 ToLayoutTextFragment(text_layout_object) |
| 2060 ->GetFirstLetterPseudoElement() |
| 2061 ->GetLayoutObject(); |
| 2062 if (first_letter_layout_object && |
| 2063 first_letter_layout_object->Style()->Visibility() == |
| 2064 EVisibility::kVisible) |
| 2065 return true; |
| 2066 } |
| 2067 continue; |
| 2068 } |
| 2069 if (text_offset <= box->Start() + box->Len()) { |
| 2070 if (text_offset > box->Start()) |
| 2071 return true; |
| 2072 continue; |
| 2073 } |
| 2074 |
| 2075 if (box == last_text_box || text_offset != box->Start() + box->Len() + 1) |
| 2076 continue; |
| 2077 |
| 2078 // TODO(yosin): We should move below code fragment into |
| 2079 // |DoesContinueOnNextLine()|. Note: |MostForwardCaretPosition()| has |
| 2080 // same code fragment except for comparison on |text_offset|. |
| 2081 // Backward: other_box->Start() > text_offset |
| 2082 // Forward: other_box->Start() >= text_offset |
| 2083 // The text continues on the next line only if the last text box is not |
| 2084 // on this line and none of the boxes on this line have a larger start |
| 2085 // offset. |
| 2086 bool continues_on_next_line = true; |
| 2087 InlineBox* other_box = box; |
| 2088 while (continues_on_next_line) { |
| 2089 other_box = other_box->NextLeafChild(); |
| 2090 if (!other_box) |
| 2091 break; |
| 2092 if (other_box == last_text_box || |
| 2093 (LineLayoutAPIShim::LayoutObjectFrom( |
| 2094 other_box->GetLineLayoutItem()) == text_layout_object && |
| 2095 ToInlineTextBox(other_box)->Start() > text_offset)) |
| 2096 continues_on_next_line = false; |
| 2097 } |
| 2098 |
| 2099 other_box = box; |
| 2100 while (continues_on_next_line) { |
| 2101 other_box = other_box->PrevLeafChild(); |
| 2102 if (!other_box) |
| 2103 break; |
| 2104 if (other_box == last_text_box || |
| 2105 (LineLayoutAPIShim::LayoutObjectFrom( |
| 2106 other_box->GetLineLayoutItem()) == text_layout_object && |
| 2107 ToInlineTextBox(other_box)->Start() > text_offset)) |
| 2108 continues_on_next_line = false; |
| 2109 } |
| 2110 |
| 2111 if (continues_on_next_line) |
| 2112 return true; |
| 2113 } |
| 2114 return false; |
| 2115 } |
| 2116 |
| 2103 Position MostBackwardCaretPosition(const Position& position, | 2117 Position MostBackwardCaretPosition(const Position& position, |
| 2104 EditingBoundaryCrossingRule rule) { | 2118 EditingBoundaryCrossingRule rule) { |
| 2105 return MostBackwardCaretPosition<EditingStrategy>(position, rule); | 2119 return MostBackwardCaretPosition<EditingStrategy>(position, rule); |
| 2106 } | 2120 } |
| 2107 | 2121 |
| 2108 PositionInFlatTree MostBackwardCaretPosition(const PositionInFlatTree& position, | 2122 PositionInFlatTree MostBackwardCaretPosition(const PositionInFlatTree& position, |
| 2109 EditingBoundaryCrossingRule rule) { | 2123 EditingBoundaryCrossingRule rule) { |
| 2110 return MostBackwardCaretPosition<EditingInFlatTreeStrategy>(position, rule); | 2124 return MostBackwardCaretPosition<EditingInFlatTreeStrategy>(position, rule); |
| 2111 } | 2125 } |
| 2112 | 2126 |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3137 | 3151 |
| 3138 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) { | 3152 IntRect ComputeTextRect(const EphemeralRangeInFlatTree& range) { |
| 3139 return EnclosingIntRect(ComputeTextRectTemplate(range)); | 3153 return EnclosingIntRect(ComputeTextRectTemplate(range)); |
| 3140 } | 3154 } |
| 3141 | 3155 |
| 3142 FloatRect ComputeTextFloatRect(const EphemeralRange& range) { | 3156 FloatRect ComputeTextFloatRect(const EphemeralRange& range) { |
| 3143 return ComputeTextRectTemplate(range); | 3157 return ComputeTextRectTemplate(range); |
| 3144 } | 3158 } |
| 3145 | 3159 |
| 3146 } // namespace blink | 3160 } // namespace blink |
| OLD | NEW |