| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights | 2 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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 2223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2234 } | 2234 } |
| 2235 | 2235 |
| 2236 static bool isNonTextLeafChild(LayoutObject* object) { | 2236 static bool isNonTextLeafChild(LayoutObject* object) { |
| 2237 if (object->slowFirstChild()) | 2237 if (object->slowFirstChild()) |
| 2238 return false; | 2238 return false; |
| 2239 if (object->isText()) | 2239 if (object->isText()) |
| 2240 return false; | 2240 return false; |
| 2241 return true; | 2241 return true; |
| 2242 } | 2242 } |
| 2243 | 2243 |
| 2244 static InlineTextBox* searchAheadForBetterMatch(LayoutObject* layoutObject) { | 2244 static InlineTextBox* searchAheadForBetterMatch( |
| 2245 LayoutObject* layoutObject, |
| 2246 EditingBoundaryCrossingRule rule) { |
| 2245 LayoutBlock* container = layoutObject->containingBlock(); | 2247 LayoutBlock* container = layoutObject->containingBlock(); |
| 2246 for (LayoutObject* next = layoutObject->nextInPreOrder(container); next; | 2248 for (LayoutObject* next = layoutObject->nextInPreOrder(container); next; |
| 2247 next = next->nextInPreOrder(container)) { | 2249 next = next->nextInPreOrder(container)) { |
| 2248 if (next->isLayoutBlock()) | 2250 if (next->isLayoutBlock()) |
| 2249 return 0; | 2251 return 0; |
| 2250 if (next->isBR()) | 2252 if (next->isBR()) |
| 2251 return 0; | 2253 return 0; |
| 2252 if (isNonTextLeafChild(next)) | 2254 if (isNonTextLeafChild(next)) |
| 2253 return 0; | 2255 return 0; |
| 2254 if (next->isText()) { | 2256 if (next->isText()) { |
| 2257 if (rule == CannotCrossEditingBoundary && |
| 2258 next->style()->userModify() == READ_ONLY) |
| 2259 return 0; |
| 2255 InlineTextBox* match = 0; | 2260 InlineTextBox* match = 0; |
| 2256 int minOffset = INT_MAX; | 2261 int minOffset = INT_MAX; |
| 2257 for (InlineTextBox* box = toLayoutText(next)->firstTextBox(); box; | 2262 for (InlineTextBox* box = toLayoutText(next)->firstTextBox(); box; |
| 2258 box = box->nextTextBox()) { | 2263 box = box->nextTextBox()) { |
| 2259 int caretMinOffset = box->caretMinOffset(); | 2264 int caretMinOffset = box->caretMinOffset(); |
| 2260 if (caretMinOffset < minOffset) { | 2265 if (caretMinOffset < minOffset) { |
| 2261 match = box; | 2266 match = box; |
| 2262 minOffset = caretMinOffset; | 2267 minOffset = caretMinOffset; |
| 2263 } | 2268 } |
| 2264 } | 2269 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2317 ? toShadowRoot(anchorNode)->host().layoutObject() | 2322 ? toShadowRoot(anchorNode)->host().layoutObject() |
| 2318 : anchorNode->layoutObject(); | 2323 : anchorNode->layoutObject(); |
| 2319 | 2324 |
| 2320 DCHECK(layoutObject) << position; | 2325 DCHECK(layoutObject) << position; |
| 2321 | 2326 |
| 2322 if (!layoutObject->isText()) { | 2327 if (!layoutObject->isText()) { |
| 2323 inlineBox = 0; | 2328 inlineBox = 0; |
| 2324 if (canHaveChildrenForEditing(anchorNode) && | 2329 if (canHaveChildrenForEditing(anchorNode) && |
| 2325 layoutObject->isLayoutBlockFlow() && | 2330 layoutObject->isLayoutBlockFlow() && |
| 2326 hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { | 2331 hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { |
| 2332 if (layoutObject->isLayoutBlock() && |
| 2333 toLayoutBlock(layoutObject)->childrenInline()) { |
| 2334 return InlineBoxPosition(inlineBox, caretOffset); |
| 2335 } |
| 2327 // Try a visually equivalent position with possibly opposite | 2336 // Try a visually equivalent position with possibly opposite |
| 2328 // editability. This helps in case |this| is in an editable block | 2337 // editability. This helps in case |this| is in an editable block |
| 2329 // but surrounded by non-editable positions. It acts to negate the | 2338 // but surrounded by non-editable positions. It acts to negate the |
| 2330 // logic at the beginning of | 2339 // logic at the beginning of |
| 2331 // |LayoutObject::createPositionWithAffinity()|. | 2340 // |LayoutObject::createPositionWithAffinity()|. |
| 2332 PositionTemplate<Strategy> equivalent = | 2341 PositionTemplate<Strategy> equivalent = |
| 2333 downstreamIgnoringEditingBoundaries(position); | 2342 downstreamIgnoringEditingBoundaries(position); |
| 2334 if (equivalent == position) { | 2343 if (equivalent == position) { |
| 2335 equivalent = upstreamIgnoringEditingBoundaries(position); | 2344 equivalent = upstreamIgnoringEditingBoundaries(position); |
| 2336 if (equivalent == position || | 2345 if (equivalent == position || |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 ((caretOffset == caretMinOffset) ^ | 2379 ((caretOffset == caretMinOffset) ^ |
| 2371 (affinity == TextAffinity::Upstream)) || | 2380 (affinity == TextAffinity::Upstream)) || |
| 2372 (caretOffset == caretMaxOffset && box->nextLeafChild() && | 2381 (caretOffset == caretMaxOffset && box->nextLeafChild() && |
| 2373 box->nextLeafChild()->isLineBreak())) | 2382 box->nextLeafChild()->isLineBreak())) |
| 2374 break; | 2383 break; |
| 2375 | 2384 |
| 2376 candidate = box; | 2385 candidate = box; |
| 2377 } | 2386 } |
| 2378 if (candidate && candidate == textLayoutObject->lastTextBox() && | 2387 if (candidate && candidate == textLayoutObject->lastTextBox() && |
| 2379 affinity == TextAffinity::Downstream) { | 2388 affinity == TextAffinity::Downstream) { |
| 2380 box = searchAheadForBetterMatch(textLayoutObject); | 2389 box = searchAheadForBetterMatch(textLayoutObject, |
| 2390 hasEditableStyle(*anchorNode) |
| 2391 ? CannotCrossEditingBoundary |
| 2392 : CanCrossEditingBoundary); |
| 2381 if (box) | 2393 if (box) |
| 2382 caretOffset = box->caretMinOffset(); | 2394 caretOffset = box->caretMinOffset(); |
| 2383 } | 2395 } |
| 2384 inlineBox = box ? box : candidate; | 2396 inlineBox = box ? box : candidate; |
| 2385 } | 2397 } |
| 2386 | 2398 |
| 2387 if (!inlineBox) | 2399 if (!inlineBox) |
| 2388 return InlineBoxPosition(inlineBox, caretOffset); | 2400 return InlineBoxPosition(inlineBox, caretOffset); |
| 2389 | 2401 |
| 2390 unsigned char level = inlineBox->bidiLevel(); | 2402 unsigned char level = inlineBox->bidiLevel(); |
| (...skipping 1537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3928 | 3940 |
| 3929 VisiblePositionInFlatTree previousPositionOf( | 3941 VisiblePositionInFlatTree previousPositionOf( |
| 3930 const VisiblePositionInFlatTree& visiblePosition, | 3942 const VisiblePositionInFlatTree& visiblePosition, |
| 3931 EditingBoundaryCrossingRule rule) { | 3943 EditingBoundaryCrossingRule rule) { |
| 3932 DCHECK(visiblePosition.isValid()) << visiblePosition; | 3944 DCHECK(visiblePosition.isValid()) << visiblePosition; |
| 3933 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>( | 3945 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>( |
| 3934 visiblePosition.deepEquivalent(), rule); | 3946 visiblePosition.deepEquivalent(), rule); |
| 3935 } | 3947 } |
| 3936 | 3948 |
| 3937 } // namespace blink | 3949 } // namespace blink |
| OLD | NEW |