OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 } | 146 } |
147 | 147 |
148 if (Node* firstChild = treeScope.rootNode().firstChild()) | 148 if (Node* firstChild = treeScope.rootNode().firstChild()) |
149 return Position::beforeNode(firstChild); | 149 return Position::beforeNode(firstChild); |
150 | 150 |
151 return Position(); | 151 return Position(); |
152 } | 152 } |
153 | 153 |
154 } // namespace | 154 } // namespace |
155 | 155 |
156 // Updates |selectionInFlatTree| to match with |selection|. | |
157 void SelectionAdjuster::adjustSelectionInFlatTree( | |
158 VisibleSelectionInFlatTree* selectionInFlatTree, | |
159 const VisibleSelection& selection) { | |
160 if (selection.isNone()) { | |
161 *selectionInFlatTree = VisibleSelectionInFlatTree(); | |
162 return; | |
163 } | |
164 | |
165 const PositionInFlatTree& base = toPositionInFlatTree(selection.base()); | |
166 const PositionInFlatTree& extent = toPositionInFlatTree(selection.extent()); | |
167 const PositionInFlatTree& position1 = toPositionInFlatTree(selection.start()); | |
168 const PositionInFlatTree& position2 = toPositionInFlatTree(selection.end()); | |
169 position1.anchorNode()->updateDistribution(); | |
170 position2.anchorNode()->updateDistribution(); | |
171 selectionInFlatTree->m_base = base; | |
172 selectionInFlatTree->m_extent = extent; | |
173 selectionInFlatTree->m_affinity = selection.m_affinity; | |
174 selectionInFlatTree->m_isDirectional = selection.m_isDirectional; | |
175 selectionInFlatTree->m_granularity = selection.m_granularity; | |
176 selectionInFlatTree->m_hasTrailingWhitespace = | |
177 selection.m_hasTrailingWhitespace; | |
178 selectionInFlatTree->m_baseIsFirst = | |
179 base.isNull() || base.compareTo(extent) <= 0; | |
180 if (position1.compareTo(position2) <= 0) { | |
181 selectionInFlatTree->m_start = position1; | |
182 selectionInFlatTree->m_end = position2; | |
183 } else { | |
184 selectionInFlatTree->m_start = position2; | |
185 selectionInFlatTree->m_end = position1; | |
186 } | |
187 selectionInFlatTree->updateSelectionType(); | |
188 } | |
189 | |
190 static bool isCrossingShadowBoundaries( | |
191 const VisibleSelectionInFlatTree& selection) { | |
192 if (!selection.isRange()) | |
193 return false; | |
194 TreeScope& treeScope = selection.base().anchorNode()->treeScope(); | |
195 return selection.extent().anchorNode()->treeScope() != treeScope || | |
196 selection.start().anchorNode()->treeScope() != treeScope || | |
197 selection.end().anchorNode()->treeScope() != treeScope; | |
198 } | |
199 | |
200 // TODO(yosin): We should make |adjustSelectionInDOMTree()| to return | |
201 // |VisibleSelection| once |VisibleSelection| constructor doesn't call | |
202 // |validate()|. | |
203 void SelectionAdjuster::adjustSelectionInDOMTree( | |
204 VisibleSelection* selection, | |
205 const VisibleSelectionInFlatTree& selectionInFlatTree) { | |
206 if (selectionInFlatTree.isNone()) { | |
207 *selection = VisibleSelection(); | |
208 return; | |
209 } | |
210 | |
211 const Position& base = toPositionInDOMTree(selectionInFlatTree.base()); | |
212 const Position& extent = toPositionInDOMTree(selectionInFlatTree.extent()); | |
213 | |
214 if (isCrossingShadowBoundaries(selectionInFlatTree)) { | |
215 DCHECK(base.document()); | |
216 | |
217 // TODO(xiaochengh): The use of updateStyleAndLayoutIgnorePendingStylesheets | |
218 // needs to be audited. See http://crbug.com/590369 for more details. | |
219 // This layout update call cannot be hoisted out of the |if|, otherwise it's | |
220 // going to cause performance regression (http://crbug.com/652301). | |
221 // TODO(yosin): Implement and apply lazy visible selection validation so | |
222 // that we don't need to update layout here. | |
223 base.document()->updateStyleAndLayoutIgnorePendingStylesheets(); | |
224 | |
225 *selection = createVisibleSelection( | |
226 SelectionInDOMTree::Builder().setBaseAndExtent(base, extent).build()); | |
227 return; | |
228 } | |
229 | |
230 const Position& position1 = toPositionInDOMTree(selectionInFlatTree.start()); | |
231 const Position& position2 = toPositionInDOMTree(selectionInFlatTree.end()); | |
232 selection->m_base = base; | |
233 selection->m_extent = extent; | |
234 selection->m_affinity = selectionInFlatTree.m_affinity; | |
235 selection->m_isDirectional = selectionInFlatTree.m_isDirectional; | |
236 selection->m_granularity = selectionInFlatTree.m_granularity; | |
237 selection->m_hasTrailingWhitespace = | |
238 selectionInFlatTree.m_hasTrailingWhitespace; | |
239 selection->m_baseIsFirst = base.isNull() || base.compareTo(extent) <= 0; | |
240 if (position1.compareTo(position2) <= 0) { | |
241 selection->m_start = position1; | |
242 selection->m_end = position2; | |
243 } else { | |
244 selection->m_start = position2; | |
245 selection->m_end = position1; | |
246 } | |
247 selection->updateSelectionType(); | |
248 } | |
249 | |
250 void SelectionAdjuster::adjustSelectionToAvoidCrossingShadowBoundaries( | 156 void SelectionAdjuster::adjustSelectionToAvoidCrossingShadowBoundaries( |
251 VisibleSelection* selection) { | 157 VisibleSelection* selection) { |
252 // Note: |m_selectionType| isn't computed yet. | 158 // Note: |m_selectionType| isn't computed yet. |
253 DCHECK(selection->base().isNotNull()); | 159 DCHECK(selection->base().isNotNull()); |
254 DCHECK(selection->extent().isNotNull()); | 160 DCHECK(selection->extent().isNotNull()); |
255 DCHECK(selection->start().isNotNull()); | 161 DCHECK(selection->start().isNotNull()); |
256 DCHECK(selection->end().isNotNull()); | 162 DCHECK(selection->end().isNotNull()); |
257 | 163 |
258 // TODO(hajimehoshi): Checking treeScope is wrong when a node is | 164 // TODO(hajimehoshi): Checking treeScope is wrong when a node is |
259 // distributed, but we leave it as it is for backward compatibility. | 165 // distributed, but we leave it as it is for backward compatibility. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 return; | 200 return; |
295 } | 201 } |
296 Node* const shadowHost = shadowHostEnd ? shadowHostEnd : shadowHostStart; | 202 Node* const shadowHost = shadowHostEnd ? shadowHostEnd : shadowHostStart; |
297 const PositionInFlatTree& newStart = | 203 const PositionInFlatTree& newStart = |
298 adjustPositionInFlatTreeForStart(selection->start(), shadowHost); | 204 adjustPositionInFlatTreeForStart(selection->start(), shadowHost); |
299 selection->m_extent = newStart; | 205 selection->m_extent = newStart; |
300 selection->m_start = newStart; | 206 selection->m_start = newStart; |
301 } | 207 } |
302 | 208 |
303 } // namespace blink | 209 } // namespace blink |
OLD | NEW |