| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "VisiblePosition.h" | 27 #include "VisiblePosition.h" |
| 28 | 28 |
| 29 #include "Document.h" | 29 #include "Document.h" |
| 30 #include "FloatQuad.h" | 30 #include "FloatQuad.h" |
| 31 #include "HTMLElement.h" | 31 #include "HTMLElement.h" |
| 32 #include "HTMLNames.h" | 32 #include "HTMLNames.h" |
| 33 #include "InlineTextBox.h" | 33 #include "InlineTextBox.h" |
| 34 #include "Logging.h" | 34 #include "Logging.h" |
| 35 #include "Range.h" | 35 #include "Range.h" |
| 36 #include "RootInlineBox.h" |
| 36 #include "Text.h" | 37 #include "Text.h" |
| 37 #include "htmlediting.h" | 38 #include "htmlediting.h" |
| 38 #include "visible_units.h" | 39 #include "visible_units.h" |
| 39 #include <stdio.h> | 40 #include <stdio.h> |
| 40 #include <wtf/text/CString.h> | 41 #include <wtf/text/CString.h> |
| 41 | 42 |
| 42 namespace WebCore { | 43 namespace WebCore { |
| 43 | 44 |
| 44 using namespace HTMLNames; | 45 using namespace HTMLNames; |
| 45 | 46 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 | 128 |
| 128 int caretMinOffset = box->caretMinOffset(); | 129 int caretMinOffset = box->caretMinOffset(); |
| 129 int caretMaxOffset = box->caretMaxOffset(); | 130 int caretMaxOffset = box->caretMaxOffset(); |
| 130 | 131 |
| 131 if (offset > caretMinOffset && offset < caretMaxOffset) | 132 if (offset > caretMinOffset && offset < caretMaxOffset) |
| 132 break; | 133 break; |
| 133 | 134 |
| 134 if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset
> caretMaxOffset) { | 135 if (box->isLeftToRightDirection() ? offset < caretMinOffset : offset
> caretMaxOffset) { |
| 135 // Overshot to the left. | 136 // Overshot to the left. |
| 136 InlineBox* prevBox = box->prevLeafChild(); | 137 InlineBox* prevBox = box->prevLeafChild(); |
| 137 if (!prevBox) | 138 if (!prevBox) { |
| 138 return primaryDirection == LTR ? previousVisuallyDistinctCan
didate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition); | 139 Position positionOnLeft = primaryDirection == LTR ? previous
VisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deep
Position); |
| 140 if (positionOnLeft.isNull()) |
| 141 return Position(); |
| 142 |
| 143 InlineBox* boxOnLeft; |
| 144 int offsetOnLeft; |
| 145 positionOnLeft.getInlineBoxAndOffset(m_affinity, primaryDire
ction, boxOnLeft, offsetOnLeft); |
| 146 if (boxOnLeft && boxOnLeft->root() == box->root()) |
| 147 return Position(); |
| 148 return positionOnLeft; |
| 149 } |
| 139 | 150 |
| 140 // Reposition at the other logical position corresponding to our
edge's visual position and go for another round. | 151 // Reposition at the other logical position corresponding to our
edge's visual position and go for another round. |
| 141 box = prevBox; | 152 box = prevBox; |
| 142 renderer = box->renderer(); | 153 renderer = box->renderer(); |
| 143 offset = prevBox->caretRightmostOffset(); | 154 offset = prevBox->caretRightmostOffset(); |
| 144 continue; | 155 continue; |
| 145 } | 156 } |
| 146 | 157 |
| 147 ASSERT(offset == box->caretLeftmostOffset()); | 158 ASSERT(offset == box->caretLeftmostOffset()); |
| 148 | 159 |
| 149 unsigned char level = box->bidiLevel(); | 160 unsigned char level = box->bidiLevel(); |
| 150 InlineBox* prevBox = box->prevLeafChild(); | 161 InlineBox* prevBox = box->prevLeafChild(); |
| 151 | 162 |
| 152 if (box->direction() == primaryDirection) { | 163 if (box->direction() == primaryDirection) { |
| 153 if (!prevBox || prevBox->bidiLevel() >= level) | 164 if (!prevBox) { |
| 165 InlineBox* logicalStart = 0; |
| 166 if (primaryDirection == LTR ? box->root()->getLogicalStartBo
xWithNode(logicalStart) : box->root()->getLogicalEndBoxWithNode(logicalStart)) { |
| 167 box = logicalStart; |
| 168 renderer = box->renderer(); |
| 169 offset = primaryDirection == LTR ? box->caretMinOffset()
: box->caretMaxOffset(); |
| 170 } |
| 171 break; |
| 172 } |
| 173 if (prevBox->bidiLevel() >= level) |
| 154 break; | 174 break; |
| 155 | 175 |
| 156 level = prevBox->bidiLevel(); | 176 level = prevBox->bidiLevel(); |
| 157 | 177 |
| 158 InlineBox* nextBox = box; | 178 InlineBox* nextBox = box; |
| 159 do { | 179 do { |
| 160 nextBox = nextBox->nextLeafChild(); | 180 nextBox = nextBox->nextLeafChild(); |
| 161 } while (nextBox && nextBox->bidiLevel() > level); | 181 } while (nextBox && nextBox->bidiLevel() > level); |
| 162 | 182 |
| 163 if (nextBox && nextBox->bidiLevel() == level) | 183 if (nextBox && nextBox->bidiLevel() == level) |
| 164 break; | 184 break; |
| 165 | 185 |
| 166 while (InlineBox* prevBox = box->prevLeafChild()) { | 186 box = prevBox; |
| 167 if (prevBox->bidiLevel() < level) | |
| 168 break; | |
| 169 box = prevBox; | |
| 170 } | |
| 171 renderer = box->renderer(); | 187 renderer = box->renderer(); |
| 172 offset = box->caretRightmostOffset(); | 188 offset = box->caretRightmostOffset(); |
| 173 if (box->direction() == primaryDirection) | 189 if (box->direction() == primaryDirection) |
| 174 break; | 190 break; |
| 175 continue; | 191 continue; |
| 176 } | 192 } |
| 177 | 193 |
| 178 if (prevBox) { | 194 if (prevBox) { |
| 179 box = prevBox; | 195 box = prevBox; |
| 180 renderer = box->renderer(); | 196 renderer = box->renderer(); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 | 279 |
| 264 int caretMinOffset = box->caretMinOffset(); | 280 int caretMinOffset = box->caretMinOffset(); |
| 265 int caretMaxOffset = box->caretMaxOffset(); | 281 int caretMaxOffset = box->caretMaxOffset(); |
| 266 | 282 |
| 267 if (offset > caretMinOffset && offset < caretMaxOffset) | 283 if (offset > caretMinOffset && offset < caretMaxOffset) |
| 268 break; | 284 break; |
| 269 | 285 |
| 270 if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset
< caretMinOffset) { | 286 if (box->isLeftToRightDirection() ? offset > caretMaxOffset : offset
< caretMinOffset) { |
| 271 // Overshot to the right. | 287 // Overshot to the right. |
| 272 InlineBox* nextBox = box->nextLeafChild(); | 288 InlineBox* nextBox = box->nextLeafChild(); |
| 273 if (!nextBox) | 289 if (!nextBox) { |
| 274 return primaryDirection == LTR ? nextVisuallyDistinctCandida
te(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition); | 290 Position positionOnRight = primaryDirection == LTR ? nextVis
uallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_dee
pPosition); |
| 291 if (positionOnRight.isNull()) |
| 292 return Position(); |
| 293 |
| 294 InlineBox* boxOnRight; |
| 295 int offsetOnRight; |
| 296 positionOnRight.getInlineBoxAndOffset(m_affinity, primaryDir
ection, boxOnRight, offsetOnRight); |
| 297 if (boxOnRight && boxOnRight->root() == box->root()) |
| 298 return Position(); |
| 299 return positionOnRight; |
| 300 } |
| 275 | 301 |
| 276 // Reposition at the other logical position corresponding to our
edge's visual position and go for another round. | 302 // Reposition at the other logical position corresponding to our
edge's visual position and go for another round. |
| 277 box = nextBox; | 303 box = nextBox; |
| 278 renderer = box->renderer(); | 304 renderer = box->renderer(); |
| 279 offset = nextBox->caretLeftmostOffset(); | 305 offset = nextBox->caretLeftmostOffset(); |
| 280 continue; | 306 continue; |
| 281 } | 307 } |
| 282 | 308 |
| 283 ASSERT(offset == box->caretRightmostOffset()); | 309 ASSERT(offset == box->caretRightmostOffset()); |
| 284 | 310 |
| 285 unsigned char level = box->bidiLevel(); | 311 unsigned char level = box->bidiLevel(); |
| 286 InlineBox* nextBox = box->nextLeafChild(); | 312 InlineBox* nextBox = box->nextLeafChild(); |
| 287 | 313 |
| 288 if (box->direction() == primaryDirection) { | 314 if (box->direction() == primaryDirection) { |
| 289 if (!nextBox || nextBox->bidiLevel() >= level) | 315 if (!nextBox) { |
| 316 InlineBox* logicalEnd = 0; |
| 317 if (primaryDirection == LTR ? box->root()->getLogicalEndBoxW
ithNode(logicalEnd) : box->root()->getLogicalStartBoxWithNode(logicalEnd)) { |
| 318 box = logicalEnd; |
| 319 renderer = box->renderer(); |
| 320 offset = primaryDirection == LTR ? box->caretMaxOffset()
: box->caretMinOffset(); |
| 321 } |
| 322 break; |
| 323 } |
| 324 if (nextBox->bidiLevel() >= level) |
| 290 break; | 325 break; |
| 291 | 326 |
| 292 level = nextBox->bidiLevel(); | 327 level = nextBox->bidiLevel(); |
| 293 | 328 |
| 294 InlineBox* prevBox = box; | 329 InlineBox* prevBox = box; |
| 295 do { | 330 do { |
| 296 prevBox = prevBox->prevLeafChild(); | 331 prevBox = prevBox->prevLeafChild(); |
| 297 } while (prevBox && prevBox->bidiLevel() > level); | 332 } while (prevBox && prevBox->bidiLevel() > level); |
| 298 | 333 |
| 299 if (prevBox && prevBox->bidiLevel() == level) // For example,
abc FED 123 ^ CBA | 334 if (prevBox && prevBox->bidiLevel() == level) // For example,
abc FED 123 ^ CBA |
| 300 break; | 335 break; |
| 301 | 336 |
| 302 // For example, abc 123 ^ CBA | 337 // For example, abc 123 ^ CBA or 123 ^ CBA abc |
| 303 while (InlineBox* nextBox = box->nextLeafChild()) { | 338 box = nextBox; |
| 304 if (nextBox->bidiLevel() < level) | |
| 305 break; | |
| 306 box = nextBox; | |
| 307 } | |
| 308 renderer = box->renderer(); | 339 renderer = box->renderer(); |
| 309 offset = box->caretLeftmostOffset(); | 340 offset = box->caretLeftmostOffset(); |
| 310 if (box->direction() == primaryDirection) | 341 if (box->direction() == primaryDirection) |
| 311 break; | 342 break; |
| 312 continue; | 343 continue; |
| 313 } | 344 } |
| 314 | 345 |
| 315 if (nextBox) { | 346 if (nextBox) { |
| 316 box = nextBox; | 347 box = nextBox; |
| 317 renderer = box->renderer(); | 348 renderer = box->renderer(); |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 if (vpos) | 708 if (vpos) |
| 678 vpos->showTreeForThis(); | 709 vpos->showTreeForThis(); |
| 679 } | 710 } |
| 680 | 711 |
| 681 void showTree(const WebCore::VisiblePosition& vpos) | 712 void showTree(const WebCore::VisiblePosition& vpos) |
| 682 { | 713 { |
| 683 vpos.showTreeForThis(); | 714 vpos.showTreeForThis(); |
| 684 } | 715 } |
| 685 | 716 |
| 686 #endif | 717 #endif |
| OLD | NEW |