| 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 |