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 19 matching lines...) Expand all Loading... |
30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" | 30 #include "bindings/core/v8/ExceptionStatePlaceholder.h" |
31 #include "core/HTMLNames.h" | 31 #include "core/HTMLNames.h" |
32 #include "core/dom/Document.h" | 32 #include "core/dom/Document.h" |
33 #include "core/dom/Element.h" | 33 #include "core/dom/Element.h" |
34 #include "core/dom/NodeTraversal.h" | 34 #include "core/dom/NodeTraversal.h" |
35 #include "core/dom/Text.h" | 35 #include "core/dom/Text.h" |
36 #include "core/editing/EditingUtilities.h" | 36 #include "core/editing/EditingUtilities.h" |
37 #include "core/editing/FrameSelection.h" | 37 #include "core/editing/FrameSelection.h" |
38 #include "core/editing/Position.h" | 38 #include "core/editing/Position.h" |
39 #include "core/editing/RenderedPosition.h" | 39 #include "core/editing/RenderedPosition.h" |
| 40 #include "core/editing/TextAffinity.h" |
40 #include "core/editing/VisiblePosition.h" | 41 #include "core/editing/VisiblePosition.h" |
41 #include "core/editing/iterators/BackwardsCharacterIterator.h" | 42 #include "core/editing/iterators/BackwardsCharacterIterator.h" |
42 #include "core/editing/iterators/CharacterIterator.h" | 43 #include "core/editing/iterators/CharacterIterator.h" |
43 #include "core/editing/iterators/SimplifiedBackwardsTextIterator.h" | 44 #include "core/editing/iterators/SimplifiedBackwardsTextIterator.h" |
44 #include "core/editing/iterators/TextIterator.h" | 45 #include "core/editing/iterators/TextIterator.h" |
45 #include "core/html/HTMLBRElement.h" | 46 #include "core/html/HTMLBRElement.h" |
46 #include "core/layout/HitTestRequest.h" | 47 #include "core/layout/HitTestRequest.h" |
47 #include "core/layout/HitTestResult.h" | 48 #include "core/layout/HitTestResult.h" |
48 #include "core/layout/LayoutBlockFlow.h" | 49 #include "core/layout/LayoutBlockFlow.h" |
49 #include "core/layout/LayoutObject.h" | 50 #include "core/layout/LayoutObject.h" |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 | 229 |
229 while (1) { | 230 while (1) { |
230 Node* startNode = startBox->layoutObject().nonPseudoNode(); | 231 Node* startNode = startBox->layoutObject().nonPseudoNode(); |
231 if (!startNode) | 232 if (!startNode) |
232 break; | 233 break; |
233 | 234 |
234 Position position = previousRootInlineBoxCandidatePosition(startNode, vi
siblePosition, ContentIsEditable); | 235 Position position = previousRootInlineBoxCandidatePosition(startNode, vi
siblePosition, ContentIsEditable); |
235 if (position.isNull()) | 236 if (position.isNull()) |
236 break; | 237 break; |
237 | 238 |
238 RenderedPosition renderedPosition(position, DOWNSTREAM); | 239 RenderedPosition renderedPosition(position, TextAffinity::Downstream); |
239 RootInlineBox* previousRoot = renderedPosition.rootBox(); | 240 RootInlineBox* previousRoot = renderedPosition.rootBox(); |
240 if (!previousRoot) | 241 if (!previousRoot) |
241 break; | 242 break; |
242 | 243 |
243 previousBox = leafBoxes.previousTextBox(previousRoot, 0); | 244 previousBox = leafBoxes.previousTextBox(previousRoot, 0); |
244 if (previousBox) { | 245 if (previousBox) { |
245 previousBoxInDifferentBlock = true; | 246 previousBoxInDifferentBlock = true; |
246 return previousBox; | 247 return previousBox; |
247 } | 248 } |
248 | 249 |
(...skipping 20 matching lines...) Expand all Loading... |
269 | 270 |
270 while (1) { | 271 while (1) { |
271 Node* startNode =startBox->layoutObject().nonPseudoNode(); | 272 Node* startNode =startBox->layoutObject().nonPseudoNode(); |
272 if (!startNode) | 273 if (!startNode) |
273 break; | 274 break; |
274 | 275 |
275 Position position = nextRootInlineBoxCandidatePosition(startNode, visibl
ePosition, ContentIsEditable); | 276 Position position = nextRootInlineBoxCandidatePosition(startNode, visibl
ePosition, ContentIsEditable); |
276 if (position.isNull()) | 277 if (position.isNull()) |
277 break; | 278 break; |
278 | 279 |
279 RenderedPosition renderedPosition(position, DOWNSTREAM); | 280 RenderedPosition renderedPosition(position, TextAffinity::Downstream); |
280 RootInlineBox* nextRoot = renderedPosition.rootBox(); | 281 RootInlineBox* nextRoot = renderedPosition.rootBox(); |
281 if (!nextRoot) | 282 if (!nextRoot) |
282 break; | 283 break; |
283 | 284 |
284 nextBox = leafBoxes.nextTextBox(nextRoot, 0); | 285 nextBox = leafBoxes.nextTextBox(nextRoot, 0); |
285 if (nextBox) { | 286 if (nextBox) { |
286 nextBoxInDifferentBlock = true; | 287 nextBoxInDifferentBlock = true; |
287 return nextBox; | 288 return nextBox; |
288 } | 289 } |
289 | 290 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 TextBreakIterator* iter = 0; | 367 TextBreakIterator* iter = 0; |
367 | 368 |
368 CachedLogicallyOrderedLeafBoxes leafBoxes; | 369 CachedLogicallyOrderedLeafBoxes leafBoxes; |
369 Vector<UChar, 1024> string; | 370 Vector<UChar, 1024> string; |
370 | 371 |
371 while (1) { | 372 while (1) { |
372 VisiblePosition adjacentCharacterPosition = direction == MoveRight ? cur
rent.right() : current.left(); | 373 VisiblePosition adjacentCharacterPosition = direction == MoveRight ? cur
rent.right() : current.left(); |
373 if (adjacentCharacterPosition.deepEquivalent() == current.deepEquivalent
() || adjacentCharacterPosition.isNull()) | 374 if (adjacentCharacterPosition.deepEquivalent() == current.deepEquivalent
() || adjacentCharacterPosition.isNull()) |
374 return VisiblePosition(); | 375 return VisiblePosition(); |
375 | 376 |
376 InlineBoxPosition boxPosition = adjacentCharacterPosition.deepEquivalent
().computeInlineBoxPosition(UPSTREAM); | 377 InlineBoxPosition boxPosition = adjacentCharacterPosition.deepEquivalent
().computeInlineBoxPosition(TextAffinity::Upstream); |
377 InlineBox* box = boxPosition.inlineBox; | 378 InlineBox* box = boxPosition.inlineBox; |
378 int offsetInBox = boxPosition.offsetInBox; | 379 int offsetInBox = boxPosition.offsetInBox; |
379 | 380 |
380 if (!box) | 381 if (!box) |
381 break; | 382 break; |
382 if (!box->isInlineTextBox()) { | 383 if (!box->isInlineTextBox()) { |
383 current = adjacentCharacterPosition; | 384 current = adjacentCharacterPosition; |
384 continue; | 385 continue; |
385 } | 386 } |
386 | 387 |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 if (charIt.characterAt(0) == '\n') { | 606 if (charIt.characterAt(0) == '\n') { |
606 // FIXME: workaround for collapsed range (where only start position
is correct) emitted for some emitted newlines (see rdar://5192593) | 607 // FIXME: workaround for collapsed range (where only start position
is correct) emitted for some emitted newlines (see rdar://5192593) |
607 VisiblePosition visPos = VisiblePosition(pos); | 608 VisiblePosition visPos = VisiblePosition(pos); |
608 if (visPos.deepEquivalent() == VisiblePosition(charIt.startPosition(
)).deepEquivalent()) { | 609 if (visPos.deepEquivalent() == VisiblePosition(charIt.startPosition(
)).deepEquivalent()) { |
609 charIt.advance(1); | 610 charIt.advance(1); |
610 pos = charIt.startPosition(); | 611 pos = charIt.startPosition(); |
611 } | 612 } |
612 } | 613 } |
613 } | 614 } |
614 | 615 |
615 // generate VisiblePosition, use UPSTREAM affinity if possible | 616 // generate VisiblePosition, use TextAffinity::Upstream affinity if possible |
616 return VisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE); | 617 return VisiblePosition(pos, VP_UPSTREAM_IF_POSSIBLE); |
617 } | 618 } |
618 | 619 |
619 // --------- | 620 // --------- |
620 | 621 |
621 static unsigned startWordBoundary(const UChar* characters, unsigned length, unsi
gned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMor
eContext) | 622 static unsigned startWordBoundary(const UChar* characters, unsigned length, unsi
gned offset, BoundarySearchContextAvailability mayHaveMoreContext, bool& needMor
eContext) |
622 { | 623 { |
623 ASSERT(offset); | 624 ASSERT(offset); |
624 if (mayHaveMoreContext && !startOfLastWordBoundaryContext(characters, offset
)) { | 625 if (mayHaveMoreContext && !startOfLastWordBoundaryContext(characters, offset
)) { |
625 needMoreContext = true; | 626 needMoreContext = true; |
(...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1562 | 1563 |
1563 if (position2.anchorNode()->isTextNode() && !position2.inRenderedText()) | 1564 if (position2.anchorNode()->isTextNode() && !position2.inRenderedText()) |
1564 return false; | 1565 return false; |
1565 | 1566 |
1566 const int renderedOffset1 = renderedOffsetOf(position1); | 1567 const int renderedOffset1 = renderedOffsetOf(position1); |
1567 const int renderedOffset2 = renderedOffsetOf(position2); | 1568 const int renderedOffset2 = renderedOffsetOf(position2); |
1568 | 1569 |
1569 if (layoutObject == posLayoutObject && renderedOffset1 == renderedOffset2) | 1570 if (layoutObject == posLayoutObject && renderedOffset1 == renderedOffset2) |
1570 return false; | 1571 return false; |
1571 | 1572 |
1572 InlineBoxPosition boxPosition1 = position1.computeInlineBoxPosition(DOWNSTRE
AM); | 1573 InlineBoxPosition boxPosition1 = position1.computeInlineBoxPosition(TextAffi
nity::Downstream); |
1573 InlineBoxPosition boxPosition2 = position2.computeInlineBoxPosition(DOWNSTRE
AM); | 1574 InlineBoxPosition boxPosition2 = position2.computeInlineBoxPosition(TextAffi
nity::Downstream); |
1574 | 1575 |
1575 WTF_LOG(Editing, "layoutObject1: %p [%p]\n", layoutObject, boxPosition1.in
lineBox); | 1576 WTF_LOG(Editing, "layoutObject1: %p [%p]\n", layoutObject, boxPosition1.in
lineBox); |
1576 WTF_LOG(Editing, "renderedOffset1: %d\n", renderedOffset1); | 1577 WTF_LOG(Editing, "renderedOffset1: %d\n", renderedOffset1); |
1577 WTF_LOG(Editing, "layoutObject2: %p [%p]\n", posLayoutObject, boxPosition2
.inlineBox); | 1578 WTF_LOG(Editing, "layoutObject2: %p [%p]\n", posLayoutObject, boxPosition2
.inlineBox); |
1578 WTF_LOG(Editing, "renderedOffset2: %d\n", renderedOffset2); | 1579 WTF_LOG(Editing, "renderedOffset2: %d\n", renderedOffset2); |
1579 WTF_LOG(Editing, "node1 min/max: %d:%d\n", caretMinOffset(position1.anchor
Node()), caretMaxOffset(position1.anchorNode())); | 1580 WTF_LOG(Editing, "node1 min/max: %d:%d\n", caretMinOffset(position1.anchor
Node()), caretMaxOffset(position1.anchorNode())); |
1580 WTF_LOG(Editing, "node2 min/max: %d:%d\n", caretMinOffset(position2.anchor
Node()), caretMaxOffset(position2.anchorNode())); | 1581 WTF_LOG(Editing, "node2 min/max: %d:%d\n", caretMinOffset(position2.anchor
Node()), caretMaxOffset(position2.anchorNode())); |
1581 WTF_LOG(Editing, "----------------------------------------------------------
------------\n"); | 1582 WTF_LOG(Editing, "----------------------------------------------------------
------------\n"); |
1582 | 1583 |
1583 if (!boxPosition1.inlineBox || !boxPosition2.inlineBox) { | 1584 if (!boxPosition1.inlineBox || !boxPosition2.inlineBox) { |
(...skipping 11 matching lines...) Expand all Loading... |
1595 | 1596 |
1596 if (previousRenderedEditable(position1.anchorNode()) == position2.anchorNode
() | 1597 if (previousRenderedEditable(position1.anchorNode()) == position2.anchorNode
() |
1597 && !renderedOffset1 && renderedOffset2 == caretMaxOffset(position2.ancho
rNode())) { | 1598 && !renderedOffset1 && renderedOffset2 == caretMaxOffset(position2.ancho
rNode())) { |
1598 return false; | 1599 return false; |
1599 } | 1600 } |
1600 | 1601 |
1601 return true; | 1602 return true; |
1602 } | 1603 } |
1603 | 1604 |
1604 } | 1605 } |
OLD | NEW |