OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006, 2009 Apple Inc. All rights reserved. |
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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 continue; | 74 continue; |
75 if (!node->hasEditableStyle()) | 75 if (!node->hasEditableStyle()) |
76 continue; | 76 continue; |
77 if ((layoutObject->isBox() && toLayoutBox(layoutObject)->inlineBoxWrappe r()) || (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox())) | 77 if ((layoutObject->isBox() && toLayoutBox(layoutObject)->inlineBoxWrappe r()) || (layoutObject->isText() && toLayoutText(layoutObject)->firstTextBox())) |
78 return node; | 78 return node; |
79 } | 79 } |
80 return 0; | 80 return 0; |
81 } | 81 } |
82 | 82 |
83 template <typename Strategy> | 83 template <typename Strategy> |
84 const TreeScope* PositionAlgorithm<Strategy>::commonAncestorTreeScope(const Posi tionType& a, const PositionType& b) | 84 const TreeScope* PositionAlgorithm<Strategy>::commonAncestorTreeScope(const Posi tionAlgorithm<Strategy>& a, const PositionAlgorithm<Strategy>& b) |
85 { | 85 { |
86 if (!a.containerNode() || !b.containerNode()) | 86 if (!a.containerNode() || !b.containerNode()) |
87 return nullptr; | 87 return nullptr; |
88 return a.containerNode()->treeScope().commonAncestorTreeScope(b.containerNod e()->treeScope()); | 88 return a.containerNode()->treeScope().commonAncestorTreeScope(b.containerNod e()->treeScope()); |
89 } | 89 } |
90 | 90 |
91 template <typename Strategy> | 91 template <typename Strategy> |
92 PositionAlgorithm<Strategy>::PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anch orNode, LegacyEditingOffset offset) | 92 PositionAlgorithm<Strategy>::PositionAlgorithm(PassRefPtrWillBeRawPtr<Node> anch orNode, LegacyEditingOffset offset) |
93 : m_anchorNode(anchorNode) | 93 : m_anchorNode(anchorNode) |
94 , m_offset(offset.value()) | 94 , m_offset(offset.value()) |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
223 int PositionAlgorithm<Strategy>::offsetForPositionAfterAnchor() const | 223 int PositionAlgorithm<Strategy>::offsetForPositionAfterAnchor() const |
224 { | 224 { |
225 ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAf terChildren); | 225 ASSERT(m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAf terChildren); |
226 ASSERT(!m_isLegacyEditingPosition); | 226 ASSERT(!m_isLegacyEditingPosition); |
227 return Strategy::lastOffsetForEditing(m_anchorNode.get()); | 227 return Strategy::lastOffsetForEditing(m_anchorNode.get()); |
228 } | 228 } |
229 | 229 |
230 // Neighbor-anchored positions are invalid DOM positions, so they need to be | 230 // Neighbor-anchored positions are invalid DOM positions, so they need to be |
231 // fixed up before handing them off to the Range object. | 231 // fixed up before handing them off to the Range object. |
232 template <typename Strategy> | 232 template <typename Strategy> |
233 typename Strategy::PositionType PositionAlgorithm<Strategy>::parentAnchoredEquiv alent() const | 233 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::parentAnchored Equivalent() const |
yosin_UTC9
2015/06/26 08:39:24
We don't need to have |typename|.
Apply this comme
yoichio
2015/06/29 06:00:33
Done.
| |
234 { | 234 { |
235 if (!m_anchorNode) | 235 if (!m_anchorNode) |
236 return PositionType(); | 236 return PositionAlgorithm<Strategy>(); |
237 | 237 |
238 // FIXME: This should only be necessary for legacy positions, but is also ne eded for positions before and after Tables | 238 // FIXME: This should only be necessary for legacy positions, but is also ne eded for positions before and after Tables |
239 if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) { | 239 if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) { |
240 if (Strategy::parent(*m_anchorNode) && (Strategy::editingIgnoresContent( m_anchorNode.get()) || isRenderedHTMLTableElement(m_anchorNode.get()))) | 240 if (Strategy::parent(*m_anchorNode) && (Strategy::editingIgnoresContent( m_anchorNode.get()) || isRenderedHTMLTableElement(m_anchorNode.get()))) |
241 return inParentBeforeNode(*m_anchorNode); | 241 return inParentBeforeNode(*m_anchorNode); |
242 return PositionType(m_anchorNode.get(), 0, PositionIsOffsetInAnchor); | 242 return PositionAlgorithm<Strategy>(m_anchorNode.get(), 0, PositionIsOffs etInAnchor); |
243 } | 243 } |
244 if (!m_anchorNode->offsetInCharacters() | 244 if (!m_anchorNode->offsetInCharacters() |
245 && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsA fterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildren() ) | 245 && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsA fterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildren() ) |
246 && (Strategy::editingIgnoresContent(m_anchorNode.get()) || isRenderedHTM LTableElement(m_anchorNode.get())) | 246 && (Strategy::editingIgnoresContent(m_anchorNode.get()) || isRenderedHTM LTableElement(m_anchorNode.get())) |
247 && containerNode()) { | 247 && containerNode()) { |
248 return inParentAfterNode(*m_anchorNode); | 248 return inParentAfterNode(*m_anchorNode); |
249 } | 249 } |
250 | 250 |
251 return PositionType(containerNode(), computeOffsetInContainerNode(), Positio nIsOffsetInAnchor); | 251 return PositionAlgorithm<Strategy>(containerNode(), computeOffsetInContainer Node(), PositionIsOffsetInAnchor); |
252 } | 252 } |
253 | 253 |
254 template <typename Strategy> | 254 template <typename Strategy> |
255 typename Strategy::PositionType PositionAlgorithm<Strategy>::toOffsetInAnchor() const | 255 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::toOffsetInAnch or() const |
256 { | 256 { |
257 if (isNull()) | 257 if (isNull()) |
258 return PositionType(); | 258 return PositionAlgorithm<Strategy>(); |
259 | 259 |
260 return PositionType(containerNode(), computeOffsetInContainerNode(), Positio nIsOffsetInAnchor); | 260 return PositionAlgorithm<Strategy>(containerNode(), computeOffsetInContainer Node(), PositionIsOffsetInAnchor); |
261 } | 261 } |
262 | 262 |
263 template <typename Strategy> | 263 template <typename Strategy> |
264 Node* PositionAlgorithm<Strategy>::computeNodeBeforePosition() const | 264 Node* PositionAlgorithm<Strategy>::computeNodeBeforePosition() const |
265 { | 265 { |
266 if (!m_anchorNode) | 266 if (!m_anchorNode) |
267 return 0; | 267 return 0; |
268 switch (anchorType()) { | 268 switch (anchorType()) { |
269 case PositionIsBeforeChildren: | 269 case PositionIsBeforeChildren: |
270 return 0; | 270 return 0; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
339 if (m_anchorType != PositionIsOffsetInAnchor) | 339 if (m_anchorType != PositionIsOffsetInAnchor) |
340 return toOffsetInAnchor().nodeAsRangePastLastNode(); | 340 return toOffsetInAnchor().nodeAsRangePastLastNode(); |
341 if (m_anchorNode->offsetInCharacters()) | 341 if (m_anchorNode->offsetInCharacters()) |
342 return Strategy::nextSkippingChildren(*m_anchorNode); | 342 return Strategy::nextSkippingChildren(*m_anchorNode); |
343 if (Node* child = Strategy::childAt(*m_anchorNode, m_offset)) | 343 if (Node* child = Strategy::childAt(*m_anchorNode, m_offset)) |
344 return child; | 344 return child; |
345 return Strategy::nextSkippingChildren(*m_anchorNode); | 345 return Strategy::nextSkippingChildren(*m_anchorNode); |
346 } | 346 } |
347 | 347 |
348 template <typename Strategy> | 348 template <typename Strategy> |
349 Node* PositionAlgorithm<Strategy>::commonAncestorContainer(const PositionType& o ther) const | 349 Node* PositionAlgorithm<Strategy>::commonAncestorContainer(const PositionAlgorit hm<Strategy>& other) const |
350 { | 350 { |
351 return Strategy::commonAncestor(*containerNode(), *other.containerNode()); | 351 return Strategy::commonAncestor(*containerNode(), *other.containerNode()); |
352 } | 352 } |
353 | 353 |
354 template <typename Strategy> | 354 template <typename Strategy> |
355 typename PositionAlgorithm<Strategy>::AnchorType PositionAlgorithm<Strategy>::an chorTypeForLegacyEditingPosition(Node* anchorNode, int offset) | 355 typename PositionAlgorithm<Strategy>::AnchorType PositionAlgorithm<Strategy>::an chorTypeForLegacyEditingPosition(Node* anchorNode, int offset) |
356 { | 356 { |
357 if (anchorNode && Strategy::editingIgnoresContent(anchorNode)) { | 357 if (anchorNode && Strategy::editingIgnoresContent(anchorNode)) { |
358 if (offset == 0) | 358 if (offset == 0) |
359 return PositionIsBeforeAnchor; | 359 return PositionIsBeforeAnchor; |
(...skipping 28 matching lines...) Expand all Loading... | |
388 ASSERT(positionB.isNotNull()); | 388 ASSERT(positionB.isNotNull()); |
389 | 389 |
390 Node* containerA = positionA.containerNode(); | 390 Node* containerA = positionA.containerNode(); |
391 Node* containerB = positionB.containerNode(); | 391 Node* containerB = positionB.containerNode(); |
392 int offsetA = positionA.computeOffsetInContainerNode(); | 392 int offsetA = positionA.computeOffsetInContainerNode(); |
393 int offsetB = positionB.computeOffsetInContainerNode(); | 393 int offsetB = positionB.computeOffsetInContainerNode(); |
394 return EditingInComposedTreeStrategy::comparePositions(containerA, offsetA, containerB, offsetB); | 394 return EditingInComposedTreeStrategy::comparePositions(containerA, offsetA, containerB, offsetB); |
395 } | 395 } |
396 | 396 |
397 template <typename Strategy> | 397 template <typename Strategy> |
398 int PositionAlgorithm<Strategy>::compareTo(const PositionType& other) const | 398 int PositionAlgorithm<Strategy>::compareTo(const PositionAlgorithm<Strategy>& ot her) const |
399 { | 399 { |
400 return comparePositions(*this, other); | 400 return comparePositions(*this, other); |
401 } | 401 } |
402 | 402 |
403 template <typename Strategy> | 403 template <typename Strategy> |
404 typename Strategy::PositionType PositionAlgorithm<Strategy>::previous(PositionMo veType moveType) const | 404 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::previous(Posit ionMoveType moveType) const |
405 { | 405 { |
406 Node* node = deprecatedNode(); | 406 Node* node = deprecatedNode(); |
407 if (!node) | 407 if (!node) |
408 return PositionType(*this); | 408 return PositionAlgorithm<Strategy>(*this); |
409 | 409 |
410 int offset = deprecatedEditingOffset(); | 410 int offset = deprecatedEditingOffset(); |
411 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r. | 411 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r. |
412 ASSERT(offset >= 0); | 412 ASSERT(offset >= 0); |
413 | 413 |
414 if (offset > 0) { | 414 if (offset > 0) { |
415 if (Node* child = Strategy::childAt(*node, offset - 1)) | 415 if (Node* child = Strategy::childAt(*node, offset - 1)) |
416 return lastPositionInOrAfterNode(child); | 416 return lastPositionInOrAfterNode(child); |
417 | 417 |
418 // There are two reasons child might be 0: | 418 // There are two reasons child might be 0: |
419 // 1) The node is node like a text node that is not an element, and th erefore has no children. | 419 // 1) The node is node like a text node that is not an element, and th erefore has no children. |
420 // Going backward one character at a time is correct. | 420 // Going backward one character at a time is correct. |
421 // 2) The old offset was a bogus offset like (<br>, 1), and there is n o child. | 421 // 2) The old offset was a bogus offset like (<br>, 1), and there is n o child. |
422 // Going from 1 to 0 is correct. | 422 // Going from 1 to 0 is correct. |
423 switch (moveType) { | 423 switch (moveType) { |
424 case CodePoint: | 424 case CodePoint: |
425 return createLegacyEditingPosition(node, offset - 1); | 425 return createLegacyEditingPosition(node, offset - 1); |
426 case Character: | 426 case Character: |
427 return createLegacyEditingPosition(node, uncheckedPreviousOffset(nod e, offset)); | 427 return createLegacyEditingPosition(node, uncheckedPreviousOffset(nod e, offset)); |
428 case BackwardDeletion: | 428 case BackwardDeletion: |
429 return createLegacyEditingPosition(node, uncheckedPreviousOffsetForB ackwardDeletion(node, offset)); | 429 return createLegacyEditingPosition(node, uncheckedPreviousOffsetForB ackwardDeletion(node, offset)); |
430 } | 430 } |
431 } | 431 } |
432 | 432 |
433 if (ContainerNode* parent = Strategy::parent(*node)) | 433 if (ContainerNode* parent = Strategy::parent(*node)) |
434 return createLegacyEditingPosition(parent, node->nodeIndex()); | 434 return createLegacyEditingPosition(parent, node->nodeIndex()); |
435 return PositionType(*this); | 435 return PositionAlgorithm<Strategy>(*this); |
436 } | 436 } |
437 | 437 |
438 template <typename Strategy> | 438 template <typename Strategy> |
439 typename Strategy::PositionType PositionAlgorithm<Strategy>::next(PositionMoveTy pe moveType) const | 439 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::next(PositionM oveType moveType) const |
440 { | 440 { |
441 ASSERT(moveType != BackwardDeletion); | 441 ASSERT(moveType != BackwardDeletion); |
442 | 442 |
443 Node* node = deprecatedNode(); | 443 Node* node = deprecatedNode(); |
444 if (!node) | 444 if (!node) |
445 return PositionType(*this); | 445 return PositionAlgorithm<Strategy>(*this); |
446 | 446 |
447 int offset = deprecatedEditingOffset(); | 447 int offset = deprecatedEditingOffset(); |
448 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r. | 448 // FIXME: Negative offsets shouldn't be allowed. We should catch this earlie r. |
449 ASSERT(offset >= 0); | 449 ASSERT(offset >= 0); |
450 | 450 |
451 if (Node* child = Strategy::childAt(*node, offset)) | 451 if (Node* child = Strategy::childAt(*node, offset)) |
452 return firstPositionInOrBeforeNode(child); | 452 return firstPositionInOrBeforeNode(child); |
453 | 453 |
454 if (!Strategy::hasChildren(*node) && offset < lastOffsetForEditing(node)) { | 454 if (!Strategy::hasChildren(*node) && offset < lastOffsetForEditing(node)) { |
455 // There are two reasons child might be 0: | 455 // There are two reasons child might be 0: |
456 // 1) The node is node like a text node that is not an element, and th erefore has no children. | 456 // 1) The node is node like a text node that is not an element, and th erefore has no children. |
457 // Going forward one character at a time is correct. | 457 // Going forward one character at a time is correct. |
458 // 2) The new offset is a bogus offset like (<br>, 1), and there is no child. | 458 // 2) The new offset is a bogus offset like (<br>, 1), and there is no child. |
459 // Going from 0 to 1 is correct. | 459 // Going from 0 to 1 is correct. |
460 return createLegacyEditingPosition(node, (moveType == Character) ? unche ckedNextOffset(node, offset) : offset + 1); | 460 return createLegacyEditingPosition(node, (moveType == Character) ? unche ckedNextOffset(node, offset) : offset + 1); |
461 } | 461 } |
462 | 462 |
463 if (ContainerNode* parent = Strategy::parent(*node)) | 463 if (ContainerNode* parent = Strategy::parent(*node)) |
464 return createLegacyEditingPosition(parent, node->nodeIndex() + 1); | 464 return createLegacyEditingPosition(parent, node->nodeIndex() + 1); |
465 return PositionType(*this); | 465 return PositionAlgorithm<Strategy>(*this); |
466 } | 466 } |
467 | 467 |
468 template <typename Strategy> | 468 template <typename Strategy> |
469 int PositionAlgorithm<Strategy>::uncheckedPreviousOffset(const Node* n, int curr ent) | 469 int PositionAlgorithm<Strategy>::uncheckedPreviousOffset(const Node* n, int curr ent) |
470 { | 470 { |
471 return n->layoutObject() ? n->layoutObject()->previousOffset(current) : curr ent - 1; | 471 return n->layoutObject() ? n->layoutObject()->previousOffset(current) : curr ent - 1; |
472 } | 472 } |
473 | 473 |
474 template <typename Strategy> | 474 template <typename Strategy> |
475 int PositionAlgorithm<Strategy>::uncheckedPreviousOffsetForBackwardDeletion(cons t Node* n, int current) | 475 int PositionAlgorithm<Strategy>::uncheckedPreviousOffsetForBackwardDeletion(cons t Node* n, int current) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 // A position is considered at editing boundary if one of the following is true: | 517 // A position is considered at editing boundary if one of the following is true: |
518 // 1. It is the first position in the node and the next visually equivalent posi tion | 518 // 1. It is the first position in the node and the next visually equivalent posi tion |
519 // is non editable. | 519 // is non editable. |
520 // 2. It is the last position in the node and the previous visually equivalent p osition | 520 // 2. It is the last position in the node and the previous visually equivalent p osition |
521 // is non editable. | 521 // is non editable. |
522 // 3. It is an editable position and both the next and previous visually equival ent | 522 // 3. It is an editable position and both the next and previous visually equival ent |
523 // positions are both non editable. | 523 // positions are both non editable. |
524 template <typename Strategy> | 524 template <typename Strategy> |
525 bool PositionAlgorithm<Strategy>::atEditingBoundary() const | 525 bool PositionAlgorithm<Strategy>::atEditingBoundary() const |
526 { | 526 { |
527 PositionType nextPosition = downstream(CanCrossEditingBoundary); | 527 PositionAlgorithm<Strategy> nextPosition = downstream(CanCrossEditingBoundar y); |
528 if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosi tion.deprecatedNode()->hasEditableStyle()) | 528 if (atFirstEditingPositionForNode() && nextPosition.isNotNull() && !nextPosi tion.deprecatedNode()->hasEditableStyle()) |
529 return true; | 529 return true; |
530 | 530 |
531 PositionType prevPosition = upstream(CanCrossEditingBoundary); | 531 PositionAlgorithm<Strategy> prevPosition = upstream(CanCrossEditingBoundary) ; |
532 if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosit ion.deprecatedNode()->hasEditableStyle()) | 532 if (atLastEditingPositionForNode() && prevPosition.isNotNull() && !prevPosit ion.deprecatedNode()->hasEditableStyle()) |
533 return true; | 533 return true; |
534 | 534 |
535 return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->hasEditab leStyle() | 535 return nextPosition.isNotNull() && !nextPosition.deprecatedNode()->hasEditab leStyle() |
536 && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->hasEditab leStyle(); | 536 && prevPosition.isNotNull() && !prevPosition.deprecatedNode()->hasEditab leStyle(); |
537 } | 537 } |
538 | 538 |
539 template <typename Strategy> | 539 template <typename Strategy> |
540 static ContainerNode* nonShadowBoundaryParentNode(Node* node) | 540 static ContainerNode* nonShadowBoundaryParentNode(Node* node) |
541 { | 541 { |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
650 return pos.atStartOfNode(); | 650 return pos.atStartOfNode(); |
651 } | 651 } |
652 | 652 |
653 // This function and downstream() are used for moving back and forth between vis ually equivalent candidates. | 653 // This function and downstream() are used for moving back and forth between vis ually equivalent candidates. |
654 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates | 654 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates |
655 // that map to the VisiblePosition between 'b' and the space. This function wil l return the left candidate | 655 // that map to the VisiblePosition between 'b' and the space. This function wil l return the left candidate |
656 // and downstream() will return the right one. | 656 // and downstream() will return the right one. |
657 // Also, upstream() will return [boundary, 0] for any of the positions from [bou ndary, 0] to the first candidate | 657 // Also, upstream() will return [boundary, 0] for any of the positions from [bou ndary, 0] to the first candidate |
658 // in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true. | 658 // in boundary, where endsOfNodeAreVisuallyDistinctPositions(boundary) is true. |
659 template <typename Strategy> | 659 template <typename Strategy> |
660 typename Strategy::PositionType PositionAlgorithm<Strategy>::upstream(EditingBou ndaryCrossingRule rule) const | 660 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::upstream(Editi ngBoundaryCrossingRule rule) const |
661 { | 661 { |
662 Node* startNode = deprecatedNode(); | 662 Node* startNode = deprecatedNode(); |
663 if (!startNode) | 663 if (!startNode) |
664 return PositionType(); | 664 return PositionAlgorithm<Strategy>(); |
665 | 665 |
666 // iterate backward from there, looking for a qualified position | 666 // iterate backward from there, looking for a qualified position |
667 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); | 667 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); |
668 // FIXME: PositionIterator should respect Before and After positions. | 668 // FIXME: PositionIterator should respect Before and After positions. |
669 typename Strategy::PositionIteratorType lastVisible(m_anchorType == Position IsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m _anchorNode.get())) : PositionType(*this)); | 669 typename Strategy::PositionIteratorType lastVisible(m_anchorType == Position IsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m _anchorNode.get())) : PositionAlgorithm<Strategy>(*this)); |
670 typename Strategy::PositionIteratorType currentPos = lastVisible; | 670 typename Strategy::PositionIteratorType currentPos = lastVisible; |
671 bool startEditable = startNode->hasEditableStyle(); | 671 bool startEditable = startNode->hasEditableStyle(); |
672 Node* lastNode = startNode; | 672 Node* lastNode = startNode; |
673 bool boundaryCrossed = false; | 673 bool boundaryCrossed = false; |
674 for (; !currentPos.atStart(); currentPos.decrement()) { | 674 for (; !currentPos.atStart(); currentPos.decrement()) { |
675 Node* currentNode = currentPos.node(); | 675 Node* currentNode = currentPos.node(); |
676 // Don't check for an editability change if we haven't moved to a differ ent node, | 676 // Don't check for an editability change if we haven't moved to a differ ent node, |
677 // to avoid the expense of computing hasEditableStyle(). | 677 // to avoid the expense of computing hasEditableStyle(). |
678 if (currentNode != lastNode) { | 678 if (currentNode != lastNode) { |
679 // Don't change editability. | 679 // Don't change editability. |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
772 } | 772 } |
773 | 773 |
774 // This function and upstream() are used for moving back and forth between visua lly equivalent candidates. | 774 // This function and upstream() are used for moving back and forth between visua lly equivalent candidates. |
775 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates | 775 // For example, for the text node "foo bar" where whitespace is collapsible, there are two candidates |
776 // that map to the VisiblePosition between 'b' and the space. This function wil l return the right candidate | 776 // that map to the VisiblePosition between 'b' and the space. This function wil l return the right candidate |
777 // and upstream() will return the left one. | 777 // and upstream() will return the left one. |
778 // Also, downstream() will return the last position in the last atomic node in b oundary for all of the positions | 778 // Also, downstream() will return the last position in the last atomic node in b oundary for all of the positions |
779 // in boundary after the last candidate, where endsOfNodeAreVisuallyDistinctPosi tions(boundary). | 779 // in boundary after the last candidate, where endsOfNodeAreVisuallyDistinctPosi tions(boundary). |
780 // FIXME: This function should never be called when the line box tree is dirty. See https://bugs.webkit.org/show_bug.cgi?id=97264 | 780 // FIXME: This function should never be called when the line box tree is dirty. See https://bugs.webkit.org/show_bug.cgi?id=97264 |
781 template <typename Strategy> | 781 template <typename Strategy> |
782 typename Strategy::PositionType PositionAlgorithm<Strategy>::downstream(EditingB oundaryCrossingRule rule) const | 782 typename PositionAlgorithm<Strategy> PositionAlgorithm<Strategy>::downstream(Edi tingBoundaryCrossingRule rule) const |
783 { | 783 { |
784 Node* startNode = deprecatedNode(); | 784 Node* startNode = deprecatedNode(); |
785 if (!startNode) | 785 if (!startNode) |
786 return PositionType(); | 786 return PositionAlgorithm<Strategy>(); |
787 | 787 |
788 // iterate forward from there, looking for a qualified position | 788 // iterate forward from there, looking for a qualified position |
789 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); | 789 Node* boundary = enclosingVisualBoundary<Strategy>(startNode); |
790 // FIXME: PositionIterator should respect Before and After positions. | 790 // FIXME: PositionIterator should respect Before and After positions. |
791 typename Strategy::PositionIteratorType lastVisible(m_anchorType == Position IsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m _anchorNode.get())) : PositionType(*this)); | 791 typename Strategy::PositionIteratorType lastVisible(m_anchorType == Position IsAfterAnchor ? createLegacyEditingPosition(m_anchorNode.get(), caretMaxOffset(m _anchorNode.get())) : PositionAlgorithm<Strategy>(*this)); |
792 typename Strategy::PositionIteratorType currentPos = lastVisible; | 792 typename Strategy::PositionIteratorType currentPos = lastVisible; |
793 bool startEditable = startNode->hasEditableStyle(); | 793 bool startEditable = startNode->hasEditableStyle(); |
794 Node* lastNode = startNode; | 794 Node* lastNode = startNode; |
795 bool boundaryCrossed = false; | 795 bool boundaryCrossed = false; |
796 for (; !currentPos.atEnd(); currentPos.increment()) { | 796 for (; !currentPos.atEnd(); currentPos.increment()) { |
797 Node* currentNode = currentPos.node(); | 797 Node* currentNode = currentPos.node(); |
798 // Don't check for an editability change if we haven't moved to a differ ent node, | 798 // Don't check for an editability change if we haven't moved to a differ ent node, |
799 // to avoid the expense of computing hasEditableStyle(). | 799 // to avoid the expense of computing hasEditableStyle(). |
800 if (currentNode != lastNode) { | 800 if (currentNode != lastNode) { |
801 // Don't change editability. | 801 // Don't change editability. |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1043 return false; | 1043 return false; |
1044 } | 1044 } |
1045 if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast <int>(box->start() + box->len())) | 1045 if (m_offset >= static_cast<int>(box->start()) && m_offset < static_cast <int>(box->start() + box->len())) |
1046 return true; | 1046 return true; |
1047 } | 1047 } |
1048 | 1048 |
1049 return false; | 1049 return false; |
1050 } | 1050 } |
1051 | 1051 |
1052 template <typename Strategy> | 1052 template <typename Strategy> |
1053 bool PositionAlgorithm<Strategy>::rendersInDifferentPosition(const PositionType &pos) const | 1053 bool PositionAlgorithm<Strategy>::rendersInDifferentPosition(const PositionAlgor ithm<Strategy> &pos) const |
1054 { | 1054 { |
1055 if (isNull() || pos.isNull()) | 1055 if (isNull() || pos.isNull()) |
1056 return false; | 1056 return false; |
1057 | 1057 |
1058 LayoutObject* layoutObject = deprecatedNode()->layoutObject(); | 1058 LayoutObject* layoutObject = deprecatedNode()->layoutObject(); |
1059 if (!layoutObject) | 1059 if (!layoutObject) |
1060 return false; | 1060 return false; |
1061 | 1061 |
1062 LayoutObject* posLayoutObject = pos.deprecatedNode()->layoutObject(); | 1062 LayoutObject* posLayoutObject = pos.deprecatedNode()->layoutObject(); |
1063 if (!posLayoutObject) | 1063 if (!posLayoutObject) |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1171 minOffset = caretMinOffset; | 1171 minOffset = caretMinOffset; |
1172 } | 1172 } |
1173 } | 1173 } |
1174 if (match) | 1174 if (match) |
1175 return match; | 1175 return match; |
1176 } | 1176 } |
1177 } | 1177 } |
1178 return 0; | 1178 return 0; |
1179 } | 1179 } |
1180 | 1180 |
1181 template <typename PositionType> | 1181 template <typename Strategy> |
1182 PositionType downstreamIgnoringEditingBoundaries(PositionType position) | 1182 PositionAlgorithm<Strategy> downstreamIgnoringEditingBoundaries(PositionAlgorith m<Strategy> position) |
1183 { | 1183 { |
1184 PositionType lastPosition; | 1184 PositionAlgorithm<Strategy> lastPosition; |
1185 while (position != lastPosition) { | 1185 while (position != lastPosition) { |
1186 lastPosition = position; | 1186 lastPosition = position; |
1187 position = position.downstream(CanCrossEditingBoundary); | 1187 position = position.downstream(CanCrossEditingBoundary); |
1188 } | 1188 } |
1189 return position; | 1189 return position; |
1190 } | 1190 } |
1191 | 1191 |
1192 template <typename PositionType> | 1192 template <typename Strategy> |
1193 PositionType upstreamIgnoringEditingBoundaries(PositionType position) | 1193 PositionAlgorithm<Strategy> upstreamIgnoringEditingBoundaries(PositionAlgorithm< Strategy> position) |
1194 { | 1194 { |
1195 PositionType lastPosition; | 1195 PositionAlgorithm<Strategy> lastPosition; |
1196 while (position != lastPosition) { | 1196 while (position != lastPosition) { |
1197 lastPosition = position; | 1197 lastPosition = position; |
1198 position = position.upstream(CanCrossEditingBoundary); | 1198 position = position.upstream(CanCrossEditingBoundary); |
1199 } | 1199 } |
1200 return position; | 1200 return position; |
1201 } | 1201 } |
1202 | 1202 |
1203 template <typename Strategy> | 1203 template <typename Strategy> |
1204 void PositionAlgorithm<Strategy>::getInlineBoxAndOffset(EAffinity affinity, Text Direction primaryDirection, InlineBox*& inlineBox, int& caretOffset) const | 1204 void PositionAlgorithm<Strategy>::getInlineBoxAndOffset(EAffinity affinity, Text Direction primaryDirection, InlineBox*& inlineBox, int& caretOffset) const |
1205 { | 1205 { |
1206 caretOffset = deprecatedEditingOffset(); | 1206 caretOffset = deprecatedEditingOffset(); |
1207 LayoutObject* layoutObject = deprecatedNode()->layoutObject(); | 1207 LayoutObject* layoutObject = deprecatedNode()->layoutObject(); |
1208 | 1208 |
1209 if (!layoutObject->isText()) { | 1209 if (!layoutObject->isText()) { |
1210 inlineBox = 0; | 1210 inlineBox = 0; |
1211 if (canHaveChildrenForEditing(deprecatedNode()) && layoutObject->isLayou tBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { | 1211 if (canHaveChildrenForEditing(deprecatedNode()) && layoutObject->isLayou tBlockFlow() && hasRenderedNonAnonymousDescendantsWithHeight(layoutObject)) { |
1212 // Try a visually equivalent position with possibly opposite editabi lity. This helps in case |this| is in | 1212 // Try a visually equivalent position with possibly opposite editabi lity. This helps in case |this| is in |
1213 // an editable block but surrounded by non-editable positions. It ac ts to negate the logic at the beginning | 1213 // an editable block but surrounded by non-editable positions. It ac ts to negate the logic at the beginning |
1214 // of LayoutObject::createVisiblePosition(). | 1214 // of LayoutObject::createVisiblePosition(). |
1215 PositionType thisPosition = PositionType(*this); | 1215 PositionAlgorithm<Strategy> thisPosition = PositionAlgorithm<Strateg y>(*this); |
1216 PositionType equivalent = downstreamIgnoringEditingBoundaries<typena me Strategy::PositionType>(thisPosition); | 1216 PositionAlgorithm<Strategy> equivalent = downstreamIgnoringEditingBo undaries(thisPosition); |
1217 if (equivalent == thisPosition) { | 1217 if (equivalent == thisPosition) { |
1218 equivalent = upstreamIgnoringEditingBoundaries(thisPosition); | 1218 equivalent = upstreamIgnoringEditingBoundaries(thisPosition); |
1219 if (equivalent == thisPosition || downstreamIgnoringEditingBound aries<typename Strategy::PositionType>(equivalent) == thisPosition) | 1219 if (equivalent == thisPosition || downstreamIgnoringEditingBound aries(equivalent) == thisPosition) |
1220 return; | 1220 return; |
1221 } | 1221 } |
1222 | 1222 |
1223 equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineB ox, caretOffset); | 1223 equivalent.getInlineBoxAndOffset(UPSTREAM, primaryDirection, inlineB ox, caretOffset); |
1224 return; | 1224 return; |
1225 } | 1225 } |
1226 if (layoutObject->isBox()) { | 1226 if (layoutObject->isBox()) { |
1227 inlineBox = toLayoutBox(layoutObject)->inlineBoxWrapper(); | 1227 inlineBox = toLayoutBox(layoutObject)->inlineBoxWrapper(); |
1228 if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && care tOffset < inlineBox->caretMaxOffset())) | 1228 if (!inlineBox || (caretOffset > inlineBox->caretMinOffset() && care tOffset < inlineBox->caretMaxOffset())) |
1229 return; | 1229 return; |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1545 | 1545 |
1546 void showTree(const blink::Position* pos) | 1546 void showTree(const blink::Position* pos) |
1547 { | 1547 { |
1548 if (pos) | 1548 if (pos) |
1549 pos->showTreeForThis(); | 1549 pos->showTreeForThis(); |
1550 else | 1550 else |
1551 fprintf(stderr, "Cannot showTree for (nil)\n"); | 1551 fprintf(stderr, "Cannot showTree for (nil)\n"); |
1552 } | 1552 } |
1553 | 1553 |
1554 #endif | 1554 #endif |
OLD | NEW |