Chromium Code Reviews| 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 11 matching lines...) Expand all Loading... | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "config.h" | 26 #include "config.h" |
| 27 #include "core/editing/VisibleUnits.h" | 27 #include "core/editing/VisibleUnits.h" |
| 28 | 28 |
| 29 #include "core/HTMLNames.h" | 29 #include "core/HTMLNames.h" |
| 30 #include "core/dom/Document.h" | 30 #include "core/dom/Document.h" |
| 31 #include "core/dom/Element.h" | 31 #include "core/dom/Element.h" |
| 32 #include "core/dom/FirstLetterPseudoElement.h" | |
| 32 #include "core/dom/NodeTraversal.h" | 33 #include "core/dom/NodeTraversal.h" |
| 33 #include "core/dom/Text.h" | 34 #include "core/dom/Text.h" |
| 34 #include "core/editing/EditingUtilities.h" | 35 #include "core/editing/EditingUtilities.h" |
| 35 #include "core/editing/FrameSelection.h" | 36 #include "core/editing/FrameSelection.h" |
| 36 #include "core/editing/Position.h" | 37 #include "core/editing/Position.h" |
| 37 #include "core/editing/PositionIterator.h" | 38 #include "core/editing/PositionIterator.h" |
| 38 #include "core/editing/RenderedPosition.h" | 39 #include "core/editing/RenderedPosition.h" |
| 39 #include "core/editing/TextAffinity.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/frame/LocalFrame.h" | 46 #include "core/frame/LocalFrame.h" |
| 46 #include "core/frame/Settings.h" | 47 #include "core/frame/Settings.h" |
| 47 #include "core/html/HTMLBRElement.h" | 48 #include "core/html/HTMLBRElement.h" |
| 48 #include "core/html/HTMLTextFormControlElement.h" | 49 #include "core/html/HTMLTextFormControlElement.h" |
| 49 #include "core/layout/HitTestRequest.h" | 50 #include "core/layout/HitTestRequest.h" |
| 50 #include "core/layout/HitTestResult.h" | 51 #include "core/layout/HitTestResult.h" |
| 51 #include "core/layout/LayoutBlockFlow.h" | 52 #include "core/layout/LayoutBlockFlow.h" |
| 52 #include "core/layout/LayoutInline.h" | 53 #include "core/layout/LayoutInline.h" |
| 53 #include "core/layout/LayoutObject.h" | 54 #include "core/layout/LayoutObject.h" |
| 55 #include "core/layout/LayoutTextFragment.h" | |
| 54 #include "core/layout/LayoutView.h" | 56 #include "core/layout/LayoutView.h" |
| 55 #include "core/layout/line/InlineIterator.h" | 57 #include "core/layout/line/InlineIterator.h" |
| 56 #include "core/layout/line/InlineTextBox.h" | 58 #include "core/layout/line/InlineTextBox.h" |
| 57 #include "core/paint/PaintLayer.h" | 59 #include "core/paint/PaintLayer.h" |
| 58 #include "platform/Logging.h" | 60 #include "platform/Logging.h" |
| 59 #include "platform/RuntimeEnabledFeatures.h" | 61 #include "platform/RuntimeEnabledFeatures.h" |
| 60 #include "platform/heap/Handle.h" | 62 #include "platform/heap/Handle.h" |
| 61 #include "platform/text/TextBoundaries.h" | 63 #include "platform/text/TextBoundaries.h" |
| 62 | 64 |
| 63 namespace blink { | 65 namespace blink { |
| (...skipping 2078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2142 { | 2144 { |
| 2143 HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | H itTestRequest::Active | HitTestRequest::IgnoreClipping; | 2145 HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | H itTestRequest::Active | HitTestRequest::IgnoreClipping; |
| 2144 HitTestResult result(request, contentsPoint); | 2146 HitTestResult result(request, contentsPoint); |
| 2145 frame->document()->layoutView()->hitTest(result); | 2147 frame->document()->layoutView()->hitTest(result); |
| 2146 | 2148 |
| 2147 if (Node* node = result.innerNode()) | 2149 if (Node* node = result.innerNode()) |
| 2148 return frame->selection().selection().visiblePositionRespectingEditingBo undary(result.localPoint(), node); | 2150 return frame->selection().selection().visiblePositionRespectingEditingBo undary(result.localPoint(), node); |
| 2149 return VisiblePosition(); | 2151 return VisiblePosition(); |
| 2150 } | 2152 } |
| 2151 | 2153 |
| 2154 // TODO(yosin): We should use |associatedLayoutObjetOf()| in "VisibleUnits.cpp" | |
| 2155 // where it takes |LayoutObject| from |Position|. | |
| 2156 static LayoutObject* associatedLayoutObjetOf(const Node& node, int offsetInNode) | |
|
hajimehoshi
2015/10/30 08:36:59
nit: Objet -> Object
yosin_UTC9
2015/11/05 04:22:47
Done.
| |
| 2157 { | |
| 2158 ASSERT(offsetInNode >= 0); | |
| 2159 LayoutObject* layoutObject = node.layoutObject(); | |
| 2160 if (!node.isTextNode() || !layoutObject || !toLayoutText(layoutObject)->isTe xtFragment()) | |
| 2161 return layoutObject; | |
| 2162 LayoutTextFragment* layoutTextFragment = toLayoutTextFragment(layoutObject); | |
| 2163 if (layoutTextFragment->isRemainingTextLayoutObject()) { | |
| 2164 if (static_cast<unsigned>(offsetInNode) >= layoutTextFragment->start()) | |
| 2165 return layoutObject; | |
| 2166 LayoutObject* firstLetterLayoutObject = layoutTextFragment->firstLetterP seudoElement()->layoutObject(); | |
| 2167 if (!firstLetterLayoutObject) | |
| 2168 return nullptr; | |
| 2169 // TODO(yosin): We're not sure when |firstLetterLayoutObject| has | |
| 2170 // multiple child layout object. | |
| 2171 ASSERT(firstLetterLayoutObject->slowFirstChild() == firstLetterLayoutObj ect->slowLastChild()); | |
| 2172 return firstLetterLayoutObject->slowFirstChild(); | |
| 2173 } | |
| 2174 // TODO(yosin): We should rename |LayoutTextFramge::length()| instead of | |
| 2175 // |end()|, once |LayoutTextFramge| has it. See http://crbug.com/545789 | |
| 2176 ASSERT(static_cast<unsigned>(offsetInNode) <= layoutTextFragment->start() + layoutTextFragment->fragmentLength()); | |
| 2177 return layoutTextFragment; | |
| 2178 } | |
| 2179 | |
| 2152 template <typename Strategy> | 2180 template <typename Strategy> |
| 2153 static bool inRenderedText(const PositionTemplate<Strategy>& position) | 2181 static bool inRenderedText(const PositionTemplate<Strategy>& position) |
| 2154 { | 2182 { |
| 2155 Node* const anchorNode = position.anchorNode(); | 2183 Node* const anchorNode = position.anchorNode(); |
| 2156 if (!anchorNode || !anchorNode->isTextNode()) | 2184 if (!anchorNode || !anchorNode->isTextNode()) |
| 2157 return false; | 2185 return false; |
| 2158 | 2186 |
| 2159 LayoutObject* layoutObject = anchorNode->layoutObject(); | 2187 const int offsetInNode = position.computeEditingOffset(); |
| 2188 LayoutObject* layoutObject = associatedLayoutObjetOf(*anchorNode, offsetInNo de); | |
| 2160 if (!layoutObject) | 2189 if (!layoutObject) |
| 2161 return false; | 2190 return false; |
| 2162 | 2191 |
| 2163 const int offsetInNode = position.computeEditingOffset(); | |
| 2164 LayoutText* textLayoutObject = toLayoutText(layoutObject); | 2192 LayoutText* textLayoutObject = toLayoutText(layoutObject); |
| 2193 const int textOffset = offsetInNode - textLayoutObject->textStartOffset(); | |
| 2165 for (InlineTextBox *box = textLayoutObject->firstTextBox(); box; box = box-> nextTextBox()) { | 2194 for (InlineTextBox *box = textLayoutObject->firstTextBox(); box; box = box-> nextTextBox()) { |
| 2166 if (offsetInNode < static_cast<int>(box->start()) && !textLayoutObject-> containsReversedText()) { | 2195 if (textOffset < static_cast<int>(box->start()) && !textLayoutObject->co ntainsReversedText()) { |
| 2167 // The offset we're looking for is before this node | 2196 // The offset we're looking for is before this node |
| 2168 // this means the offset must be in content that is | 2197 // this means the offset must be in content that is |
| 2169 // not laid out. Return false. | 2198 // not laid out. Return false. |
| 2170 return false; | 2199 return false; |
| 2171 } | 2200 } |
| 2172 if (box->containsCaretOffset(offsetInNode)) { | 2201 if (box->containsCaretOffset(textOffset)) { |
| 2173 // Return false for offsets inside composed characters. | 2202 // Return false for offsets inside composed characters. |
| 2174 return offsetInNode == 0 || offsetInNode == textLayoutObject->nextOf fset(textLayoutObject->previousOffset(offsetInNode)); | 2203 return textOffset == 0 || textOffset == textLayoutObject->nextOffset (textLayoutObject->previousOffset(textOffset)); |
| 2175 } | 2204 } |
| 2176 } | 2205 } |
| 2177 | 2206 |
| 2178 return false; | 2207 return false; |
| 2179 } | 2208 } |
| 2180 | 2209 |
| 2181 static Node* nextRenderedEditable(Node* node) | 2210 static Node* nextRenderedEditable(Node* node) |
| 2182 { | 2211 { |
| 2183 for (node = nextAtomicLeafNode(*node); node; node = nextAtomicLeafNode(*node )) { | 2212 for (node = nextAtomicLeafNode(*node); node; node = nextAtomicLeafNode(*node )) { |
| 2184 LayoutObject* layoutObject = node->layoutObject(); | 2213 LayoutObject* layoutObject = node->layoutObject(); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2399 } | 2428 } |
| 2400 lastNode = currentNode; | 2429 lastNode = currentNode; |
| 2401 } | 2430 } |
| 2402 | 2431 |
| 2403 // If we've moved to a position that is visually distinct, return the la st saved position. There | 2432 // If we've moved to a position that is visually distinct, return the la st saved position. There |
| 2404 // is code below that terminates early if we're *about* to move to a vis ually distinct position. | 2433 // is code below that terminates early if we're *about* to move to a vis ually distinct position. |
| 2405 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode ! = boundary) | 2434 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode ! = boundary) |
| 2406 return lastVisible.deprecatedComputePosition(); | 2435 return lastVisible.deprecatedComputePosition(); |
| 2407 | 2436 |
| 2408 // skip position in non-laid out or invisible node | 2437 // skip position in non-laid out or invisible node |
| 2409 LayoutObject* layoutObject = currentNode->layoutObject(); | 2438 LayoutObject* layoutObject = associatedLayoutObjetOf(*currentNode, curre ntPos.offsetInLeafNode()); |
| 2410 if (!layoutObject || layoutObject->style()->visibility() != VISIBLE) | 2439 if (!layoutObject || layoutObject->style()->visibility() != VISIBLE) |
| 2411 continue; | 2440 continue; |
| 2412 | 2441 |
| 2413 if (rule == CanCrossEditingBoundary && boundaryCrossed) { | 2442 if (rule == CanCrossEditingBoundary && boundaryCrossed) { |
| 2414 lastVisible = currentPos; | 2443 lastVisible = currentPos; |
| 2415 break; | 2444 break; |
| 2416 } | 2445 } |
| 2417 | 2446 |
| 2418 // track last visible streamer position | 2447 // track last visible streamer position |
| 2419 if (isStreamer<Strategy>(currentPos)) | 2448 if (isStreamer<Strategy>(currentPos)) |
| 2420 lastVisible = currentPos; | 2449 lastVisible = currentPos; |
| 2421 | 2450 |
| 2422 // Don't move past a position that is visually distinct. We could rely on code above to terminate and | 2451 // Don't move past a position that is visually distinct. We could rely on code above to terminate and |
| 2423 // return lastVisible on the next iteration, but we terminate early to a void doing a nodeIndex() call. | 2452 // return lastVisible on the next iteration, but we terminate early to a void doing a nodeIndex() call. |
| 2424 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentPos.at StartOfNode()) | 2453 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentPos.at StartOfNode()) |
| 2425 return lastVisible.deprecatedComputePosition(); | 2454 return lastVisible.deprecatedComputePosition(); |
| 2426 | 2455 |
| 2427 // Return position after tables and nodes which have content that can be ignored. | 2456 // Return position after tables and nodes which have content that can be ignored. |
| 2428 if (Strategy::editingIgnoresContent(currentNode) || isRenderedHTMLTableE lement(currentNode)) { | 2457 if (Strategy::editingIgnoresContent(currentNode) || isRenderedHTMLTableE lement(currentNode)) { |
| 2429 if (currentPos.atEndOfNode()) | 2458 if (currentPos.atEndOfNode()) |
| 2430 return PositionTemplate<Strategy>::afterNode(currentNode); | 2459 return PositionTemplate<Strategy>::afterNode(currentNode); |
| 2431 continue; | 2460 continue; |
| 2432 } | 2461 } |
| 2433 | 2462 |
| 2434 // return current position if it is in laid out text | 2463 // return current position if it is in laid out text |
| 2435 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox() ) { | 2464 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox() ) { |
| 2465 LayoutText* const textLayoutObject = toLayoutText(layoutObject); | |
| 2466 const unsigned textStartOffset = textLayoutObject->textStartOffset() ; | |
| 2436 if (currentNode != startNode) { | 2467 if (currentNode != startNode) { |
| 2437 // This assertion fires in layout tests in the case-transform.ht ml test because | 2468 // This assertion fires in layout tests in the case-transform.ht ml test because |
| 2438 // of a mix-up between offsets in the text in the DOM tree with text in the | 2469 // of a mix-up between offsets in the text in the DOM tree with text in the |
| 2439 // layout tree which can have a different length due to case tra nsformation. | 2470 // layout tree which can have a different length due to case tra nsformation. |
| 2440 // Until we resolve that, disable this so we can run the layout tests! | 2471 // Until we resolve that, disable this so we can run the layout tests! |
| 2441 // ASSERT(currentOffset >= layoutObject->caretMaxOffset()); | 2472 // ASSERT(currentOffset >= layoutObject->caretMaxOffset()); |
| 2442 return PositionTemplate<Strategy>(currentNode, layoutObject->car etMaxOffset()); | 2473 return PositionTemplate<Strategy>(currentNode, layoutObject->car etMaxOffset() + textStartOffset); |
| 2443 } | 2474 } |
| 2444 | 2475 |
| 2445 unsigned textOffset = currentPos.offsetInLeafNode(); | 2476 // Map offset in DOM node to offset in InlineBox. |
| 2446 LayoutText* textLayoutObject = toLayoutText(layoutObject); | 2477 ASSERT(currentPos.offsetInLeafNode() >= static_cast<int>(textStartOf fset)); |
| 2478 const unsigned textOffset = currentPos.offsetInLeafNode() - textStar tOffset; | |
| 2447 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox(); | 2479 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox(); |
| 2448 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) { | 2480 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) { |
| 2481 if (textOffset == box->start()) { | |
| 2482 if (textLayoutObject->isTextFragment() && toLayoutTextFragme nt(layoutObject)->isRemainingTextLayoutObject()) { | |
| 2483 // |currentPos| is at start of remaining text of | |
| 2484 // |Text| node with :first-letter. | |
| 2485 ASSERT(currentPos.offsetInLeafNode() >= 1); | |
| 2486 LayoutObject* firstLetterLayoutObject = toLayoutTextFrag ment(layoutObject)->firstLetterPseudoElement()->layoutObject(); | |
| 2487 if (firstLetterLayoutObject && firstLetterLayoutObject-> style()->visibility() == VISIBLE) | |
| 2488 return currentPos.computePosition(); | |
| 2489 } | |
| 2490 continue; | |
| 2491 } | |
| 2449 if (textOffset <= box->start() + box->len()) { | 2492 if (textOffset <= box->start() + box->len()) { |
| 2450 if (textOffset > box->start()) | 2493 if (textOffset > box->start()) |
| 2451 return currentPos.computePosition(); | 2494 return currentPos.computePosition(); |
| 2452 continue; | 2495 continue; |
| 2453 } | 2496 } |
| 2454 | 2497 |
| 2455 if (box == lastTextBox || textOffset != box->start() + box->len( ) + 1) | 2498 if (box == lastTextBox || textOffset != box->start() + box->len( ) + 1) |
| 2456 continue; | 2499 continue; |
| 2457 | 2500 |
| 2458 // The text continues on the next line only if the last text box is not on this line and | 2501 // The text continues on the next line only if the last text box is not on this line and |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2536 // Do not move to a visually distinct position. | 2579 // Do not move to a visually distinct position. |
| 2537 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode ! = boundary) | 2580 if (endsOfNodeAreVisuallyDistinctPositions(currentNode) && currentNode ! = boundary) |
| 2538 return lastVisible.deprecatedComputePosition(); | 2581 return lastVisible.deprecatedComputePosition(); |
| 2539 // Do not move past a visually disinct position. | 2582 // Do not move past a visually disinct position. |
| 2540 // Note: The first position after the last in a node whose ends are visu ally distinct | 2583 // Note: The first position after the last in a node whose ends are visu ally distinct |
| 2541 // positions will be [boundary->parentNode(), originalBlock->nodeIndex() + 1]. | 2584 // positions will be [boundary->parentNode(), originalBlock->nodeIndex() + 1]. |
| 2542 if (boundary && Strategy::parent(*boundary) == currentNode) | 2585 if (boundary && Strategy::parent(*boundary) == currentNode) |
| 2543 return lastVisible.deprecatedComputePosition(); | 2586 return lastVisible.deprecatedComputePosition(); |
| 2544 | 2587 |
| 2545 // skip position in non-laid out or invisible node | 2588 // skip position in non-laid out or invisible node |
| 2546 LayoutObject* layoutObject = currentNode->layoutObject(); | 2589 LayoutObject* layoutObject = associatedLayoutObjetOf(*currentNode, curre ntPos.offsetInLeafNode()); |
| 2547 if (!layoutObject || layoutObject->style()->visibility() != VISIBLE) | 2590 if (!layoutObject || layoutObject->style()->visibility() != VISIBLE) |
| 2548 continue; | 2591 continue; |
| 2549 | 2592 |
| 2550 if (rule == CanCrossEditingBoundary && boundaryCrossed) { | 2593 if (rule == CanCrossEditingBoundary && boundaryCrossed) { |
| 2551 lastVisible = currentPos; | 2594 lastVisible = currentPos; |
| 2552 break; | 2595 break; |
| 2553 } | 2596 } |
| 2554 | 2597 |
| 2555 // track last visible streamer position | 2598 // track last visible streamer position |
| 2556 if (isStreamer<Strategy>(currentPos)) | 2599 if (isStreamer<Strategy>(currentPos)) |
| 2557 lastVisible = currentPos; | 2600 lastVisible = currentPos; |
| 2558 | 2601 |
| 2559 // Return position before tables and nodes which have content that can b e ignored. | 2602 // Return position before tables and nodes which have content that can b e ignored. |
| 2560 if (Strategy::editingIgnoresContent(currentNode) || isRenderedHTMLTableE lement(currentNode)) { | 2603 if (Strategy::editingIgnoresContent(currentNode) || isRenderedHTMLTableE lement(currentNode)) { |
| 2561 if (currentPos.offsetInLeafNode() <= layoutObject->caretMinOffset()) | 2604 if (currentPos.offsetInLeafNode() <= layoutObject->caretMinOffset()) |
| 2562 return PositionTemplate<Strategy>::editingPositionOf(currentNode , layoutObject->caretMinOffset()); | 2605 return PositionTemplate<Strategy>::editingPositionOf(currentNode , layoutObject->caretMinOffset()); |
| 2563 continue; | 2606 continue; |
| 2564 } | 2607 } |
| 2565 | 2608 |
| 2566 // return current position if it is in laid out text | 2609 // return current position if it is in laid out text |
| 2567 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox() ) { | 2610 if (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox() ) { |
| 2611 LayoutText* const textLayoutObject = toLayoutText(layoutObject); | |
| 2612 const unsigned textStartOffset = textLayoutObject->textStartOffset() ; | |
| 2568 if (currentNode != startNode) { | 2613 if (currentNode != startNode) { |
| 2569 ASSERT(currentPos.atStartOfNode()); | 2614 ASSERT(currentPos.atStartOfNode()); |
| 2570 return PositionTemplate<Strategy>(currentNode, layoutObject->car etMinOffset()); | 2615 return PositionTemplate<Strategy>(currentNode, layoutObject->car etMinOffset() + textStartOffset); |
| 2571 } | 2616 } |
| 2572 | 2617 |
| 2573 unsigned textOffset = currentPos.offsetInLeafNode(); | 2618 // Map offset in DOM node to offset in InlineBox. |
| 2574 LayoutText* textLayoutObject = toLayoutText(layoutObject); | 2619 ASSERT(currentPos.offsetInLeafNode() >= static_cast<int>(textStartOf fset)); |
| 2620 const unsigned textOffset = currentPos.offsetInLeafNode() - textStar tOffset; | |
| 2575 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox(); | 2621 InlineTextBox* lastTextBox = textLayoutObject->lastTextBox(); |
| 2576 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) { | 2622 for (InlineTextBox* box = textLayoutObject->firstTextBox(); box; box = box->nextTextBox()) { |
| 2577 if (textOffset <= box->end()) { | 2623 if (textOffset <= box->end()) { |
| 2578 if (textOffset >= box->start()) | 2624 if (textOffset >= box->start()) |
| 2579 return currentPos.computePosition(); | 2625 return currentPos.computePosition(); |
| 2580 continue; | 2626 continue; |
| 2581 } | 2627 } |
| 2582 | 2628 |
| 2583 if (box == lastTextBox || textOffset != box->start() + box->len( )) | 2629 if (box == lastTextBox || textOffset != box->start() + box->len( )) |
| 2584 continue; | 2630 continue; |
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3252 { | 3298 { |
| 3253 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); | 3299 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); |
| 3254 } | 3300 } |
| 3255 | 3301 |
| 3256 VisiblePositionInComposedTree previousPositionOf(const VisiblePositionInComposed Tree& visiblePosition, EditingBoundaryCrossingRule rule) | 3302 VisiblePositionInComposedTree previousPositionOf(const VisiblePositionInComposed Tree& visiblePosition, EditingBoundaryCrossingRule rule) |
| 3257 { | 3303 { |
| 3258 return previousPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePos ition, rule); | 3304 return previousPositionOfAlgorithm<EditingInComposedTreeStrategy>(visiblePos ition, rule); |
| 3259 } | 3305 } |
| 3260 | 3306 |
| 3261 } // namespace blink | 3307 } // namespace blink |
| OLD | NEW |