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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 // (upstream/downstream won't leave blocks or enter new ones), we search | 118 // (upstream/downstream won't leave blocks or enter new ones), we search |
119 // forward and backward until we find one. | 119 // forward and backward until we find one. |
120 PositionType next = canonicalizeCandidate(nextCandidate(position)); | 120 PositionType next = canonicalizeCandidate(nextCandidate(position)); |
121 PositionType prev = canonicalizeCandidate(previousCandidate(position)); | 121 PositionType prev = canonicalizeCandidate(previousCandidate(position)); |
122 Node* nextNode = next.anchorNode(); | 122 Node* nextNode = next.anchorNode(); |
123 Node* prevNode = prev.anchorNode(); | 123 Node* prevNode = prev.anchorNode(); |
124 | 124 |
125 // The new position must be in the same editable element. Enforce that | 125 // The new position must be in the same editable element. Enforce that |
126 // first. Unless the descent is from a non-editable html element to an | 126 // first. Unless the descent is from a non-editable html element to an |
127 // editable body. | 127 // editable body. |
128 if (node && node->document().documentElement() == node && !node->hasEditable
Style() && node->document().body() && node->document().body()->hasEditableStyle(
)) | 128 if (node && node->document().documentElement() == node && !hasEditableStyle(
*node) && node->document().body() && hasEditableStyle(*node->document().body())) |
129 return next.isNotNull() ? next : prev; | 129 return next.isNotNull() ? next : prev; |
130 | 130 |
131 Element* editingRoot = rootEditableElementOf(position); | 131 Element* editingRoot = rootEditableElementOf(position); |
132 | 132 |
133 // If the html element is editable, descending into its body will look like | 133 // If the html element is editable, descending into its body will look like |
134 // a descent from non-editable to editable content since | 134 // a descent from non-editable to editable content since |
135 // |rootEditableElementOf()| always stops at the body. | 135 // |rootEditableElementOf()| always stops at the body. |
136 if ((editingRoot && editingRoot->document().documentElement() == editingRoot
) || position.anchorNode()->isDocumentNode()) | 136 if ((editingRoot && editingRoot->document().documentElement() == editingRoot
) || position.anchorNode()->isDocumentNode()) |
137 return next.isNotNull() ? next : prev; | 137 return next.isNotNull() ? next : prev; |
138 | 138 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 if (!highestRoot) | 232 if (!highestRoot) |
233 return VisiblePositionTemplate<Strategy>(); | 233 return VisiblePositionTemplate<Strategy>(); |
234 | 234 |
235 // Return the next position after |pos| that is in the same editable region | 235 // Return the next position after |pos| that is in the same editable region |
236 // as this position | 236 // as this position |
237 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(),
*highestRoot); | 237 return firstEditableVisiblePositionAfterPositionInRoot(pos.deepEquivalent(),
*highestRoot); |
238 } | 238 } |
239 | 239 |
240 static Node* previousLeafWithSameEditability(Node* node, EditableType editableTy
pe) | 240 static Node* previousLeafWithSameEditability(Node* node, EditableType editableTy
pe) |
241 { | 241 { |
242 bool editable = node->hasEditableStyle(editableType); | 242 bool editable = hasEditableStyle(*node, editableType); |
243 node = previousAtomicLeafNode(*node); | 243 node = previousAtomicLeafNode(*node); |
244 while (node) { | 244 while (node) { |
245 if (editable == node->hasEditableStyle(editableType)) | 245 if (editable == hasEditableStyle(*node, editableType)) |
246 return node; | 246 return node; |
247 node = previousAtomicLeafNode(*node); | 247 node = previousAtomicLeafNode(*node); |
248 } | 248 } |
249 return 0; | 249 return 0; |
250 } | 250 } |
251 | 251 |
252 static Node* nextLeafWithSameEditability(Node* node, EditableType editableType =
ContentIsEditable) | 252 static Node* nextLeafWithSameEditability(Node* node, EditableType editableType =
ContentIsEditable) |
253 { | 253 { |
254 if (!node) | 254 if (!node) |
255 return 0; | 255 return 0; |
256 | 256 |
257 bool editable = node->hasEditableStyle(editableType); | 257 bool editable = hasEditableStyle(*node, editableType); |
258 node = nextAtomicLeafNode(*node); | 258 node = nextAtomicLeafNode(*node); |
259 while (node) { | 259 while (node) { |
260 if (editable == node->hasEditableStyle(editableType)) | 260 if (editable == hasEditableStyle(*node, editableType)) |
261 return node; | 261 return node; |
262 node = nextAtomicLeafNode(*node); | 262 node = nextAtomicLeafNode(*node); |
263 } | 263 } |
264 return 0; | 264 return 0; |
265 } | 265 } |
266 | 266 |
267 // FIXME: consolidate with code in previousLinePosition. | 267 // FIXME: consolidate with code in previousLinePosition. |
268 static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible
Position& visiblePosition, EditableType editableType) | 268 static Position previousRootInlineBoxCandidatePosition(Node* node, const Visible
Position& visiblePosition, EditableType editableType) |
269 { | 269 { |
270 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival
ent(), editableType); | 270 ContainerNode* highestRoot = highestEditableRoot(visiblePosition.deepEquival
ent(), editableType); |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 { | 640 { |
641 Node* const anchorNode = position.anchorNode(); | 641 Node* const anchorNode = position.anchorNode(); |
642 if (!anchorNode) | 642 if (!anchorNode) |
643 return nullptr; | 643 return nullptr; |
644 | 644 |
645 Node* documentElement = anchorNode->document().documentElement(); | 645 Node* documentElement = anchorNode->document().documentElement(); |
646 if (!documentElement) | 646 if (!documentElement) |
647 return nullptr; | 647 return nullptr; |
648 | 648 |
649 Node* boundary = position.computeContainerNode(); | 649 Node* boundary = position.computeContainerNode(); |
650 while (boundary != documentElement && nonShadowBoundaryParentNode<Strategy>(
boundary) && anchorNode->hasEditableStyle() == Strategy::parent(*boundary)->hasE
ditableStyle()) | 650 while (boundary != documentElement && nonShadowBoundaryParentNode<Strategy>(
boundary) && hasEditableStyle(*anchorNode) == hasEditableStyle(*Strategy::parent
(*boundary))) |
651 boundary = nonShadowBoundaryParentNode<Strategy>(boundary); | 651 boundary = nonShadowBoundaryParentNode<Strategy>(boundary); |
652 | 652 |
653 return boundary; | 653 return boundary; |
654 } | 654 } |
655 | 655 |
656 enum BoundarySearchContextAvailability { DontHaveMoreContext, MayHaveMoreContext
}; | 656 enum BoundarySearchContextAvailability { DontHaveMoreContext, MayHaveMoreContext
}; |
657 | 657 |
658 typedef unsigned (*BoundarySearchFunction)(const UChar*, unsigned length, unsign
ed offset, BoundarySearchContextAvailability, bool& needMoreContext); | 658 typedef unsigned (*BoundarySearchFunction)(const UChar*, unsigned length, unsign
ed offset, BoundarySearchContextAvailability, bool& needMoreContext); |
659 | 659 |
660 template <typename Strategy> | 660 template <typename Strategy> |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1329 LineLayoutItem lineLayoutItem = root->closestLeafChildForPoint(pointInLi
ne, isEditablePosition(p, ContentIsEditable))->getLineLayoutItem(); | 1329 LineLayoutItem lineLayoutItem = root->closestLeafChildForPoint(pointInLi
ne, isEditablePosition(p, ContentIsEditable))->getLineLayoutItem(); |
1330 Node* node = lineLayoutItem.node(); | 1330 Node* node = lineLayoutItem.node(); |
1331 if (node && editingIgnoresContent(node)) | 1331 if (node && editingIgnoresContent(node)) |
1332 return VisiblePosition::inParentBeforeNode(*node); | 1332 return VisiblePosition::inParentBeforeNode(*node); |
1333 return createVisiblePosition(lineLayoutItem.positionForPoint(pointInLine
)); | 1333 return createVisiblePosition(lineLayoutItem.positionForPoint(pointInLine
)); |
1334 } | 1334 } |
1335 | 1335 |
1336 // Could not find a previous line. This means we must already be on the firs
t line. | 1336 // Could not find a previous line. This means we must already be on the firs
t line. |
1337 // Move to the start of the content in this block, which effectively moves u
s | 1337 // Move to the start of the content in this block, which effectively moves u
s |
1338 // to the start of the line we're on. | 1338 // to the start of the line we're on. |
1339 Element* rootElement = node->hasEditableStyle(editableType) ? rootEditableEl
ement(*node, editableType) : node->document().documentElement(); | 1339 Element* rootElement = hasEditableStyle(*node, editableType) ? rootEditableE
lement(*node, editableType) : node->document().documentElement(); |
1340 if (!rootElement) | 1340 if (!rootElement) |
1341 return VisiblePosition(); | 1341 return VisiblePosition(); |
1342 return VisiblePosition::firstPositionInNode(rootElement); | 1342 return VisiblePosition::firstPositionInNode(rootElement); |
1343 } | 1343 } |
1344 | 1344 |
1345 VisiblePosition nextLinePosition(const VisiblePosition& visiblePosition, LayoutU
nit lineDirectionPoint, EditableType editableType) | 1345 VisiblePosition nextLinePosition(const VisiblePosition& visiblePosition, LayoutU
nit lineDirectionPoint, EditableType editableType) |
1346 { | 1346 { |
1347 Position p = visiblePosition.deepEquivalent(); | 1347 Position p = visiblePosition.deepEquivalent(); |
1348 Node* node = p.anchorNode(); | 1348 Node* node = p.anchorNode(); |
1349 | 1349 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 LineLayoutItem lineLayoutItem = root->closestLeafChildForPoint(pointInLi
ne, isEditablePosition(p))->getLineLayoutItem(); | 1385 LineLayoutItem lineLayoutItem = root->closestLeafChildForPoint(pointInLi
ne, isEditablePosition(p))->getLineLayoutItem(); |
1386 Node* node = lineLayoutItem.node(); | 1386 Node* node = lineLayoutItem.node(); |
1387 if (node && editingIgnoresContent(node)) | 1387 if (node && editingIgnoresContent(node)) |
1388 return VisiblePosition::inParentBeforeNode(*node); | 1388 return VisiblePosition::inParentBeforeNode(*node); |
1389 return createVisiblePosition(lineLayoutItem.positionForPoint(pointInLine
)); | 1389 return createVisiblePosition(lineLayoutItem.positionForPoint(pointInLine
)); |
1390 } | 1390 } |
1391 | 1391 |
1392 // Could not find a next line. This means we must already be on the last lin
e. | 1392 // Could not find a next line. This means we must already be on the last lin
e. |
1393 // Move to the end of the content in this block, which effectively moves us | 1393 // Move to the end of the content in this block, which effectively moves us |
1394 // to the end of the line we're on. | 1394 // to the end of the line we're on. |
1395 Element* rootElement = node->hasEditableStyle(editableType) ? rootEditableEl
ement(*node, editableType) : node->document().documentElement(); | 1395 Element* rootElement = hasEditableStyle(*node, editableType) ? rootEditableE
lement(*node, editableType) : node->document().documentElement(); |
1396 if (!rootElement) | 1396 if (!rootElement) |
1397 return VisiblePosition(); | 1397 return VisiblePosition(); |
1398 return VisiblePosition::lastPositionInNode(rootElement); | 1398 return VisiblePosition::lastPositionInNode(rootElement); |
1399 } | 1399 } |
1400 | 1400 |
1401 // --------- | 1401 // --------- |
1402 | 1402 |
1403 static unsigned startSentenceBoundary(const UChar* characters, unsigned length,
unsigned, BoundarySearchContextAvailability, bool&) | 1403 static unsigned startSentenceBoundary(const UChar* characters, unsigned length,
unsigned, BoundarySearchContextAvailability, bool&) |
1404 { | 1404 { |
1405 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); | 1405 TextBreakIterator* iterator = sentenceBreakIterator(characters, length); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1488 return createVisiblePosition(PositionTemplate<Strategy>::beforeNode(star
tNode)); | 1488 return createVisiblePosition(PositionTemplate<Strategy>::beforeNode(star
tNode)); |
1489 | 1489 |
1490 Element* startBlock = enclosingBlock(PositionTemplate<Strategy>::firstPositi
onInOrBeforeNode(startNode), CannotCrossEditingBoundary); | 1490 Element* startBlock = enclosingBlock(PositionTemplate<Strategy>::firstPositi
onInOrBeforeNode(startNode), CannotCrossEditingBoundary); |
1491 | 1491 |
1492 Node* node = startNode; | 1492 Node* node = startNode; |
1493 ContainerNode* highestRoot = highestEditableRoot(p); | 1493 ContainerNode* highestRoot = highestEditableRoot(p); |
1494 int offset = p.computeEditingOffset(); | 1494 int offset = p.computeEditingOffset(); |
1495 PositionAnchorType type = p.anchorType(); | 1495 PositionAnchorType type = p.anchorType(); |
1496 | 1496 |
1497 Node* n = startNode; | 1497 Node* n = startNode; |
1498 bool startNodeIsEditable = startNode->hasEditableStyle(); | 1498 bool startNodeIsEditable = hasEditableStyle(*startNode); |
1499 while (n) { | 1499 while (n) { |
1500 if (boundaryCrossingRule == CannotCrossEditingBoundary && !nodeIsUserSel
ectAll(n) && n->hasEditableStyle() != startNodeIsEditable) | 1500 if (boundaryCrossingRule == CannotCrossEditingBoundary && !nodeIsUserSel
ectAll(n) && hasEditableStyle(*n) != startNodeIsEditable) |
1501 break; | 1501 break; |
1502 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { | 1502 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { |
1503 while (n && n->hasEditableStyle() != startNodeIsEditable) | 1503 while (n && hasEditableStyle(*n) != startNodeIsEditable) |
1504 n = Strategy::previousPostOrder(*n, startBlock); | 1504 n = Strategy::previousPostOrder(*n, startBlock); |
1505 if (!n || !n->isDescendantOf(highestRoot)) | 1505 if (!n || !n->isDescendantOf(highestRoot)) |
1506 break; | 1506 break; |
1507 } | 1507 } |
1508 LayoutObject* r = n->layoutObject(); | 1508 LayoutObject* r = n->layoutObject(); |
1509 LayoutItem ri = LayoutItem(r); | 1509 LayoutItem ri = LayoutItem(r); |
1510 if (ri.isNull()) { | 1510 if (ri.isNull()) { |
1511 n = Strategy::previousPostOrder(*n, startBlock); | 1511 n = Strategy::previousPostOrder(*n, startBlock); |
1512 continue; | 1512 continue; |
1513 } | 1513 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1576 | 1576 |
1577 Element* startBlock = enclosingBlock(PositionTemplate<Strategy>::firstPositi
onInOrBeforeNode(startNode), CannotCrossEditingBoundary); | 1577 Element* startBlock = enclosingBlock(PositionTemplate<Strategy>::firstPositi
onInOrBeforeNode(startNode), CannotCrossEditingBoundary); |
1578 Element* stayInsideBlock = startBlock; | 1578 Element* stayInsideBlock = startBlock; |
1579 | 1579 |
1580 Node* node = startNode; | 1580 Node* node = startNode; |
1581 ContainerNode* highestRoot = highestEditableRoot(p); | 1581 ContainerNode* highestRoot = highestEditableRoot(p); |
1582 int offset = p.computeEditingOffset(); | 1582 int offset = p.computeEditingOffset(); |
1583 PositionAnchorType type = p.anchorType(); | 1583 PositionAnchorType type = p.anchorType(); |
1584 | 1584 |
1585 Node* n = startNode; | 1585 Node* n = startNode; |
1586 bool startNodeIsEditable = startNode->hasEditableStyle(); | 1586 bool startNodeIsEditable = hasEditableStyle(*startNode); |
1587 while (n) { | 1587 while (n) { |
1588 if (boundaryCrossingRule == CannotCrossEditingBoundary && !nodeIsUserSel
ectAll(n) && n->hasEditableStyle() != startNodeIsEditable) | 1588 if (boundaryCrossingRule == CannotCrossEditingBoundary && !nodeIsUserSel
ectAll(n) && hasEditableStyle(*n) != startNodeIsEditable) |
1589 break; | 1589 break; |
1590 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { | 1590 if (boundaryCrossingRule == CanSkipOverEditingBoundary) { |
1591 while (n && n->hasEditableStyle() != startNodeIsEditable) | 1591 while (n && hasEditableStyle(*n) != startNodeIsEditable) |
1592 n = Strategy::next(*n, stayInsideBlock); | 1592 n = Strategy::next(*n, stayInsideBlock); |
1593 if (!n || !n->isDescendantOf(highestRoot)) | 1593 if (!n || !n->isDescendantOf(highestRoot)) |
1594 break; | 1594 break; |
1595 } | 1595 } |
1596 | 1596 |
1597 LayoutObject* r = n->layoutObject(); | 1597 LayoutObject* r = n->layoutObject(); |
1598 if (!r) { | 1598 if (!r) { |
1599 n = Strategy::next(*n, stayInsideBlock); | 1599 n = Strategy::next(*n, stayInsideBlock); |
1600 continue; | 1600 continue; |
1601 } | 1601 } |
(...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2357 | 2357 |
2358 Node* startNode = position.anchorNode(); | 2358 Node* startNode = position.anchorNode(); |
2359 if (!startNode) | 2359 if (!startNode) |
2360 return PositionTemplate<Strategy>(); | 2360 return PositionTemplate<Strategy>(); |
2361 | 2361 |
2362 // iterate backward from there, looking for a qualified position | 2362 // iterate backward from there, looking for a qualified position |
2363 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); | 2363 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); |
2364 // FIXME: PositionIterator should respect Before and After positions. | 2364 // FIXME: PositionIterator should respect Before and After positions. |
2365 PositionIteratorAlgorithm<Strategy> lastVisible(position.isAfterAnchor() ? P
ositionTemplate<Strategy>::editingPositionOf(position.anchorNode(), Strategy::ca
retMaxOffset(*position.anchorNode())) : position); | 2365 PositionIteratorAlgorithm<Strategy> lastVisible(position.isAfterAnchor() ? P
ositionTemplate<Strategy>::editingPositionOf(position.anchorNode(), Strategy::ca
retMaxOffset(*position.anchorNode())) : position); |
2366 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; | 2366 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; |
2367 bool startEditable = startNode->hasEditableStyle(); | 2367 bool startEditable = hasEditableStyle(*startNode); |
2368 Node* lastNode = startNode; | 2368 Node* lastNode = startNode; |
2369 bool boundaryCrossed = false; | 2369 bool boundaryCrossed = false; |
2370 for (; !currentPos.atStart(); currentPos.decrement()) { | 2370 for (; !currentPos.atStart(); currentPos.decrement()) { |
2371 Node* currentNode = currentPos.node(); | 2371 Node* currentNode = currentPos.node(); |
2372 // Don't check for an editability change if we haven't moved to a differ
ent node, | 2372 // Don't check for an editability change if we haven't moved to a differ
ent node, |
2373 // to avoid the expense of computing hasEditableStyle(). | 2373 // to avoid the expense of computing hasEditableStyle(). |
2374 if (currentNode != lastNode) { | 2374 if (currentNode != lastNode) { |
2375 // Don't change editability. | 2375 // Don't change editability. |
2376 bool currentEditable = currentNode->hasEditableStyle(); | 2376 bool currentEditable = hasEditableStyle(*currentNode); |
2377 if (startEditable != currentEditable) { | 2377 if (startEditable != currentEditable) { |
2378 if (rule == CannotCrossEditingBoundary) | 2378 if (rule == CannotCrossEditingBoundary) |
2379 break; | 2379 break; |
2380 boundaryCrossed = true; | 2380 boundaryCrossed = true; |
2381 } | 2381 } |
2382 lastNode = currentNode; | 2382 lastNode = currentNode; |
2383 } | 2383 } |
2384 | 2384 |
2385 // If we've moved to a position that is visually distinct, return the la
st saved position. There | 2385 // If we've moved to a position that is visually distinct, return the la
st saved position. There |
2386 // is code below that terminates early if we're *about* to move to a vis
ually distinct position. | 2386 // is code below that terminates early if we're *about* to move to a vis
ually distinct position. |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2498 | 2498 |
2499 Node* startNode = position.anchorNode(); | 2499 Node* startNode = position.anchorNode(); |
2500 if (!startNode) | 2500 if (!startNode) |
2501 return PositionTemplate<Strategy>(); | 2501 return PositionTemplate<Strategy>(); |
2502 | 2502 |
2503 // iterate forward from there, looking for a qualified position | 2503 // iterate forward from there, looking for a qualified position |
2504 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); | 2504 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); |
2505 // FIXME: PositionIterator should respect Before and After positions. | 2505 // FIXME: PositionIterator should respect Before and After positions. |
2506 PositionIteratorAlgorithm<Strategy> lastVisible(position.isAfterAnchor() ? P
ositionTemplate<Strategy>::editingPositionOf(position.anchorNode(), Strategy::ca
retMaxOffset(*position.anchorNode())) : position); | 2506 PositionIteratorAlgorithm<Strategy> lastVisible(position.isAfterAnchor() ? P
ositionTemplate<Strategy>::editingPositionOf(position.anchorNode(), Strategy::ca
retMaxOffset(*position.anchorNode())) : position); |
2507 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; | 2507 PositionIteratorAlgorithm<Strategy> currentPos = lastVisible; |
2508 bool startEditable = startNode->hasEditableStyle(); | 2508 bool startEditable = hasEditableStyle(*startNode); |
2509 Node* lastNode = startNode; | 2509 Node* lastNode = startNode; |
2510 bool boundaryCrossed = false; | 2510 bool boundaryCrossed = false; |
2511 for (; !currentPos.atEnd(); currentPos.increment()) { | 2511 for (; !currentPos.atEnd(); currentPos.increment()) { |
2512 Node* currentNode = currentPos.node(); | 2512 Node* currentNode = currentPos.node(); |
2513 // Don't check for an editability change if we haven't moved to a differ
ent node, | 2513 // Don't check for an editability change if we haven't moved to a differ
ent node, |
2514 // to avoid the expense of computing hasEditableStyle(). | 2514 // to avoid the expense of computing hasEditableStyle(). |
2515 if (currentNode != lastNode) { | 2515 if (currentNode != lastNode) { |
2516 // Don't change editability. | 2516 // Don't change editability. |
2517 bool currentEditable = currentNode->hasEditableStyle(); | 2517 bool currentEditable = hasEditableStyle(*currentNode); |
2518 if (startEditable != currentEditable) { | 2518 if (startEditable != currentEditable) { |
2519 if (rule == CannotCrossEditingBoundary) | 2519 if (rule == CannotCrossEditingBoundary) |
2520 break; | 2520 break; |
2521 boundaryCrossed = true; | 2521 boundaryCrossed = true; |
2522 } | 2522 } |
2523 | 2523 |
2524 lastNode = currentNode; | 2524 lastNode = currentNode; |
2525 } | 2525 } |
2526 | 2526 |
2527 // stop before going above the body, up into the head | 2527 // stop before going above the body, up into the head |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2629 // 1. It is the first position in the node and the next visually equivalent | 2629 // 1. It is the first position in the node and the next visually equivalent |
2630 // position is non editable. | 2630 // position is non editable. |
2631 // 2. It is the last position in the node and the previous visually equivalent | 2631 // 2. It is the last position in the node and the previous visually equivalent |
2632 // position is non editable. | 2632 // position is non editable. |
2633 // 3. It is an editable position and both the next and previous visually | 2633 // 3. It is an editable position and both the next and previous visually |
2634 // equivalent positions are both non editable. | 2634 // equivalent positions are both non editable. |
2635 template <typename Strategy> | 2635 template <typename Strategy> |
2636 static bool atEditingBoundary(const PositionTemplate<Strategy> positions) | 2636 static bool atEditingBoundary(const PositionTemplate<Strategy> positions) |
2637 { | 2637 { |
2638 PositionTemplate<Strategy> nextPosition = mostForwardCaretPosition(positions
, CanCrossEditingBoundary); | 2638 PositionTemplate<Strategy> nextPosition = mostForwardCaretPosition(positions
, CanCrossEditingBoundary); |
2639 if (positions.atFirstEditingPositionForNode() && nextPosition.isNotNull() &&
!nextPosition.anchorNode()->hasEditableStyle()) | 2639 if (positions.atFirstEditingPositionForNode() && nextPosition.isNotNull() &&
!hasEditableStyle(*nextPosition.anchorNode())) |
2640 return true; | 2640 return true; |
2641 | 2641 |
2642 PositionTemplate<Strategy> prevPosition = mostBackwardCaretPosition(position
s, CanCrossEditingBoundary); | 2642 PositionTemplate<Strategy> prevPosition = mostBackwardCaretPosition(position
s, CanCrossEditingBoundary); |
2643 if (positions.atLastEditingPositionForNode() && prevPosition.isNotNull() &&
!prevPosition.anchorNode()->hasEditableStyle()) | 2643 if (positions.atLastEditingPositionForNode() && prevPosition.isNotNull() &&
!hasEditableStyle(*prevPosition.anchorNode())) |
2644 return true; | 2644 return true; |
2645 | 2645 |
2646 return nextPosition.isNotNull() && !nextPosition.anchorNode()->hasEditableSt
yle() | 2646 return nextPosition.isNotNull() && !hasEditableStyle(*nextPosition.anchorNod
e()) |
2647 && prevPosition.isNotNull() && !prevPosition.anchorNode()->hasEditableSt
yle(); | 2647 && prevPosition.isNotNull() && !hasEditableStyle(*prevPosition.anchorNod
e()); |
2648 } | 2648 } |
2649 | 2649 |
2650 template <typename Strategy> | 2650 template <typename Strategy> |
2651 static bool isVisuallyEquivalentCandidateAlgorithm(const PositionTemplate<Strate
gy>& position) | 2651 static bool isVisuallyEquivalentCandidateAlgorithm(const PositionTemplate<Strate
gy>& position) |
2652 { | 2652 { |
2653 Node* const anchorNode = position.anchorNode(); | 2653 Node* const anchorNode = position.anchorNode(); |
2654 if (!anchorNode) | 2654 if (!anchorNode) |
2655 return false; | 2655 return false; |
2656 | 2656 |
2657 LayoutObject* layoutObject = anchorNode->layoutObject(); | 2657 LayoutObject* layoutObject = anchorNode->layoutObject(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2693 if (anchorNode->document().documentElement() == anchorNode || anchorNode->is
DocumentNode()) | 2693 if (anchorNode->document().documentElement() == anchorNode || anchorNode->is
DocumentNode()) |
2694 return false; | 2694 return false; |
2695 | 2695 |
2696 if (!layoutObject->isSelectable()) | 2696 if (!layoutObject->isSelectable()) |
2697 return false; | 2697 return false; |
2698 | 2698 |
2699 if (layoutObject->isLayoutBlockFlow() || layoutObject->isFlexibleBox() || la
youtObject->isLayoutGrid()) { | 2699 if (layoutObject->isLayoutBlockFlow() || layoutObject->isFlexibleBox() || la
youtObject->isLayoutGrid()) { |
2700 if (toLayoutBlock(layoutObject)->logicalHeight() || isHTMLBodyElement(*a
nchorNode)) { | 2700 if (toLayoutBlock(layoutObject)->logicalHeight() || isHTMLBodyElement(*a
nchorNode)) { |
2701 if (!hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) | 2701 if (!hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) |
2702 return position.atFirstEditingPositionForNode(); | 2702 return position.atFirstEditingPositionForNode(); |
2703 return anchorNode->hasEditableStyle() && atEditingBoundary(position)
; | 2703 return hasEditableStyle(*anchorNode) && atEditingBoundary(position); |
2704 } | 2704 } |
2705 } else { | 2705 } else { |
2706 LocalFrame* frame = anchorNode->document().frame(); | 2706 LocalFrame* frame = anchorNode->document().frame(); |
2707 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsi
ngEnabled(); | 2707 bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsi
ngEnabled(); |
2708 return (caretBrowsing || anchorNode->hasEditableStyle()) && atEditingBou
ndary(position); | 2708 return (caretBrowsing || hasEditableStyle(*anchorNode)) && atEditingBoun
dary(position); |
2709 } | 2709 } |
2710 | 2710 |
2711 return false; | 2711 return false; |
2712 } | 2712 } |
2713 | 2713 |
2714 bool isVisuallyEquivalentCandidate(const Position& position) | 2714 bool isVisuallyEquivalentCandidate(const Position& position) |
2715 { | 2715 { |
2716 return isVisuallyEquivalentCandidateAlgorithm<EditingStrategy>(position); | 2716 return isVisuallyEquivalentCandidateAlgorithm<EditingStrategy>(position); |
2717 } | 2717 } |
2718 | 2718 |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3252 { | 3252 { |
3253 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); | 3253 return previousPositionOfAlgorithm<EditingStrategy>(visiblePosition, rule); |
3254 } | 3254 } |
3255 | 3255 |
3256 VisiblePositionInFlatTree previousPositionOf(const VisiblePositionInFlatTree& vi
siblePosition, EditingBoundaryCrossingRule rule) | 3256 VisiblePositionInFlatTree previousPositionOf(const VisiblePositionInFlatTree& vi
siblePosition, EditingBoundaryCrossingRule rule) |
3257 { | 3257 { |
3258 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>(visiblePositio
n, rule); | 3258 return previousPositionOfAlgorithm<EditingInFlatTreeStrategy>(visiblePositio
n, rule); |
3259 } | 3259 } |
3260 | 3260 |
3261 } // namespace blink | 3261 } // namespace blink |
OLD | NEW |