OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 } | 335 } |
336 if (changed) | 336 if (changed) |
337 didChange(); | 337 didChange(); |
338 } | 338 } |
339 | 339 |
340 void VisibleSelection::setBaseAndExtentToDeepEquivalents() | 340 void VisibleSelection::setBaseAndExtentToDeepEquivalents() |
341 { | 341 { |
342 // Move the selection to rendered positions, if possible. | 342 // Move the selection to rendered positions, if possible. |
343 bool baseAndExtentEqual = m_base == m_extent; | 343 bool baseAndExtentEqual = m_base == m_extent; |
344 if (m_base.isNotNull()) { | 344 if (m_base.isNotNull()) { |
345 m_base = VisiblePosition(m_base, m_affinity).deepEquivalent(); | 345 m_base = createVisiblePosition(m_base, m_affinity).deepEquivalent(); |
346 if (baseAndExtentEqual) | 346 if (baseAndExtentEqual) |
347 m_extent = m_base; | 347 m_extent = m_base; |
348 } | 348 } |
349 if (m_extent.isNotNull() && !baseAndExtentEqual) | 349 if (m_extent.isNotNull() && !baseAndExtentEqual) |
350 m_extent = VisiblePosition(m_extent, m_affinity).deepEquivalent(); | 350 m_extent = createVisiblePosition(m_extent, m_affinity).deepEquivalent(); |
351 | 351 |
352 // Make sure we do not have a dangling base or extent. | 352 // Make sure we do not have a dangling base or extent. |
353 if (m_base.isNull() && m_extent.isNull()) { | 353 if (m_base.isNull() && m_extent.isNull()) { |
354 m_baseIsFirst = true; | 354 m_baseIsFirst = true; |
355 } else if (m_base.isNull()) { | 355 } else if (m_base.isNull()) { |
356 m_base = m_extent; | 356 m_base = m_extent; |
357 m_baseIsFirst = true; | 357 m_baseIsFirst = true; |
358 } else if (m_extent.isNull()) { | 358 } else if (m_extent.isNull()) { |
359 m_extent = m_base; | 359 m_extent = m_base; |
360 m_baseIsFirst = true; | 360 m_baseIsFirst = true; |
(...skipping 13 matching lines...) Expand all Loading... |
374 case CharacterGranularity: | 374 case CharacterGranularity: |
375 // Don't do any expansion. | 375 // Don't do any expansion. |
376 break; | 376 break; |
377 case WordGranularity: { | 377 case WordGranularity: { |
378 // General case: Select the word the caret is positioned inside of. | 378 // General case: Select the word the caret is positioned inside of. |
379 // If the caret is on the word boundary, select the word according to |w
ordSide|. | 379 // If the caret is on the word boundary, select the word according to |w
ordSide|. |
380 // Edge case: If the caret is after the last word in a soft-wrapped line
or the last word in | 380 // Edge case: If the caret is after the last word in a soft-wrapped line
or the last word in |
381 // the document, select that last word (LeftWordIfOnBoundary). | 381 // the document, select that last word (LeftWordIfOnBoundary). |
382 // Edge case: If the caret is after the last word in a paragraph, select
from the the end of the | 382 // Edge case: If the caret is after the last word in a paragraph, select
from the the end of the |
383 // last word to the line break (also RightWordIfOnBoundary); | 383 // last word to the line break (also RightWordIfOnBoundary); |
384 VisiblePosition visibleStart = VisiblePosition(m_start, m_affinity); | 384 VisiblePosition visibleStart = createVisiblePosition(m_start, m_affinity
); |
385 EWordSide side = wordSide; | 385 EWordSide side = wordSide; |
386 if (isEndOfEditableOrNonEditableContent(visibleStart) || (isEndOfLine(vi
sibleStart) && !isStartOfLine(visibleStart) && !isEndOfParagraph(visibleStart))) | 386 if (isEndOfEditableOrNonEditableContent(visibleStart) || (isEndOfLine(vi
sibleStart) && !isStartOfLine(visibleStart) && !isEndOfParagraph(visibleStart))) |
387 side = LeftWordIfOnBoundary; | 387 side = LeftWordIfOnBoundary; |
388 m_start = startOfWord(visibleStart, side).deepEquivalent(); | 388 m_start = startOfWord(visibleStart, side).deepEquivalent(); |
389 break; | 389 break; |
390 } | 390 } |
391 case SentenceGranularity: { | 391 case SentenceGranularity: { |
392 m_start = startOfSentence(VisiblePosition(m_start, m_affinity)).deepEqui
valent(); | 392 m_start = startOfSentence(createVisiblePosition(m_start, m_affinity)).de
epEquivalent(); |
393 break; | 393 break; |
394 } | 394 } |
395 case LineGranularity: { | 395 case LineGranularity: { |
396 m_start = startOfLine(VisiblePosition(m_start, m_affinity)).deepEquivale
nt(); | 396 m_start = startOfLine(createVisiblePosition(m_start, m_affinity)).deepEq
uivalent(); |
397 break; | 397 break; |
398 } | 398 } |
399 case LineBoundary: | 399 case LineBoundary: |
400 m_start = startOfLine(VisiblePosition(m_start, m_affinity)).deepEquivale
nt(); | 400 m_start = startOfLine(createVisiblePosition(m_start, m_affinity)).deepEq
uivalent(); |
401 break; | 401 break; |
402 case ParagraphGranularity: { | 402 case ParagraphGranularity: { |
403 VisiblePosition pos(m_start, m_affinity); | 403 VisiblePosition pos = createVisiblePosition(m_start, m_affinity); |
404 if (isStartOfLine(pos) && isEndOfEditableOrNonEditableContent(pos)) | 404 if (isStartOfLine(pos) && isEndOfEditableOrNonEditableContent(pos)) |
405 pos = previousPositionOf(pos); | 405 pos = previousPositionOf(pos); |
406 m_start = startOfParagraph(pos).deepEquivalent(); | 406 m_start = startOfParagraph(pos).deepEquivalent(); |
407 break; | 407 break; |
408 } | 408 } |
409 case DocumentBoundary: | 409 case DocumentBoundary: |
410 m_start = startOfDocument(VisiblePosition(m_start, m_affinity)).deepEqui
valent(); | 410 m_start = startOfDocument(createVisiblePosition(m_start, m_affinity)).de
epEquivalent(); |
411 break; | 411 break; |
412 case ParagraphBoundary: | 412 case ParagraphBoundary: |
413 m_start = startOfParagraph(VisiblePosition(m_start, m_affinity)).deepEqu
ivalent(); | 413 m_start = startOfParagraph(createVisiblePosition(m_start, m_affinity)).d
eepEquivalent(); |
414 break; | 414 break; |
415 case SentenceBoundary: | 415 case SentenceBoundary: |
416 m_start = startOfSentence(VisiblePosition(m_start, m_affinity)).deepEqui
valent(); | 416 m_start = startOfSentence(createVisiblePosition(m_start, m_affinity)).de
epEquivalent(); |
417 break; | 417 break; |
418 } | 418 } |
419 | 419 |
420 // Make sure we do not have a Null position. | 420 // Make sure we do not have a Null position. |
421 if (m_start.isNull()) | 421 if (m_start.isNull()) |
422 m_start = m_baseIsFirst ? m_base : m_extent; | 422 m_start = m_baseIsFirst ? m_base : m_extent; |
423 resetPositionsInComposedTree(); | 423 resetPositionsInComposedTree(); |
424 } | 424 } |
425 | 425 |
426 void VisibleSelection::setEndRespectingGranularity(TextGranularity granularity,
EWordSide wordSide) | 426 void VisibleSelection::setEndRespectingGranularity(TextGranularity granularity,
EWordSide wordSide) |
427 { | 427 { |
428 ASSERT(m_base.isNotNull()); | 428 ASSERT(m_base.isNotNull()); |
429 ASSERT(m_extent.isNotNull()); | 429 ASSERT(m_extent.isNotNull()); |
430 | 430 |
431 m_end = m_baseIsFirst ? m_extent : m_base; | 431 m_end = m_baseIsFirst ? m_extent : m_base; |
432 | 432 |
433 switch (granularity) { | 433 switch (granularity) { |
434 case CharacterGranularity: | 434 case CharacterGranularity: |
435 // Don't do any expansion. | 435 // Don't do any expansion. |
436 break; | 436 break; |
437 case WordGranularity: { | 437 case WordGranularity: { |
438 // General case: Select the word the caret is positioned inside of. | 438 // General case: Select the word the caret is positioned inside of. |
439 // If the caret is on the word boundary, select the word according to |w
ordSide|. | 439 // If the caret is on the word boundary, select the word according to |w
ordSide|. |
440 // Edge case: If the caret is after the last word in a soft-wrapped line
or the last word in | 440 // Edge case: If the caret is after the last word in a soft-wrapped line
or the last word in |
441 // the document, select that last word (LeftWordIfOnBoundary). | 441 // the document, select that last word (LeftWordIfOnBoundary). |
442 // Edge case: If the caret is after the last word in a paragraph, select
from the the end of the | 442 // Edge case: If the caret is after the last word in a paragraph, select
from the the end of the |
443 // last word to the line break (also RightWordIfOnBoundary); | 443 // last word to the line break (also RightWordIfOnBoundary); |
444 VisiblePosition originalEnd(m_end, m_affinity); | 444 VisiblePosition originalEnd = createVisiblePosition(m_end, m_affinity); |
445 EWordSide side = wordSide; | 445 EWordSide side = wordSide; |
446 if (isEndOfEditableOrNonEditableContent(originalEnd) || (isEndOfLine(ori
ginalEnd) && !isStartOfLine(originalEnd) && !isEndOfParagraph(originalEnd))) | 446 if (isEndOfEditableOrNonEditableContent(originalEnd) || (isEndOfLine(ori
ginalEnd) && !isStartOfLine(originalEnd) && !isEndOfParagraph(originalEnd))) |
447 side = LeftWordIfOnBoundary; | 447 side = LeftWordIfOnBoundary; |
448 | 448 |
449 VisiblePosition wordEnd(endOfWord(originalEnd, side)); | 449 VisiblePosition wordEnd = endOfWord(originalEnd, side); |
450 VisiblePosition end(wordEnd); | 450 VisiblePosition end = wordEnd; |
451 | 451 |
452 if (isEndOfParagraph(originalEnd) && !isEmptyTableCell(m_start.anchorNod
e())) { | 452 if (isEndOfParagraph(originalEnd) && !isEmptyTableCell(m_start.anchorNod
e())) { |
453 // Select the paragraph break (the space from the end of a paragraph
to the start of | 453 // Select the paragraph break (the space from the end of a paragraph
to the start of |
454 // the next one) to match TextEdit. | 454 // the next one) to match TextEdit. |
455 end = nextPositionOf(wordEnd); | 455 end = nextPositionOf(wordEnd); |
456 | 456 |
457 if (Element* table = isFirstPositionAfterTable(end)) { | 457 if (Element* table = isFirstPositionAfterTable(end)) { |
458 // The paragraph break after the last paragraph in the last cell
of a block table ends | 458 // The paragraph break after the last paragraph in the last cell
of a block table ends |
459 // at the start of the paragraph after the table. | 459 // at the start of the paragraph after the table. |
460 if (isEnclosingBlock(table)) | 460 if (isEnclosingBlock(table)) |
461 end = nextPositionOf(end, CannotCrossEditingBoundary); | 461 end = nextPositionOf(end, CannotCrossEditingBoundary); |
462 else | 462 else |
463 end = wordEnd; | 463 end = wordEnd; |
464 } | 464 } |
465 | 465 |
466 if (end.isNull()) | 466 if (end.isNull()) |
467 end = wordEnd; | 467 end = wordEnd; |
468 | 468 |
469 } | 469 } |
470 | 470 |
471 m_end = end.deepEquivalent(); | 471 m_end = end.deepEquivalent(); |
472 break; | 472 break; |
473 } | 473 } |
474 case SentenceGranularity: { | 474 case SentenceGranularity: { |
475 m_end = endOfSentence(VisiblePosition(m_end, m_affinity)).deepEquivalent
(); | 475 m_end = endOfSentence(createVisiblePosition(m_end, m_affinity)).deepEqui
valent(); |
476 break; | 476 break; |
477 } | 477 } |
478 case LineGranularity: { | 478 case LineGranularity: { |
479 VisiblePosition end = endOfLine(VisiblePosition(m_end, m_affinity)); | 479 VisiblePosition end = endOfLine(createVisiblePosition(m_end, m_affinity)
); |
480 // If the end of this line is at the end of a paragraph, include the spa
ce | 480 // If the end of this line is at the end of a paragraph, include the spa
ce |
481 // after the end of the line in the selection. | 481 // after the end of the line in the selection. |
482 if (isEndOfParagraph(end)) { | 482 if (isEndOfParagraph(end)) { |
483 VisiblePosition next = nextPositionOf(end); | 483 VisiblePosition next = nextPositionOf(end); |
484 if (next.isNotNull()) | 484 if (next.isNotNull()) |
485 end = next; | 485 end = next; |
486 } | 486 } |
487 m_end = end.deepEquivalent(); | 487 m_end = end.deepEquivalent(); |
488 break; | 488 break; |
489 } | 489 } |
490 case LineBoundary: | 490 case LineBoundary: |
491 m_end = endOfLine(VisiblePosition(m_end, m_affinity)).deepEquivalent(); | 491 m_end = endOfLine(createVisiblePosition(m_end, m_affinity)).deepEquivale
nt(); |
492 break; | 492 break; |
493 case ParagraphGranularity: { | 493 case ParagraphGranularity: { |
494 VisiblePosition visibleParagraphEnd = endOfParagraph(VisiblePosition(m_e
nd, m_affinity)); | 494 VisiblePosition visibleParagraphEnd = endOfParagraph(createVisiblePositi
on(m_end, m_affinity)); |
495 | 495 |
496 // Include the "paragraph break" (the space from the end of this paragra
ph to the start | 496 // Include the "paragraph break" (the space from the end of this paragra
ph to the start |
497 // of the next one) in the selection. | 497 // of the next one) in the selection. |
498 VisiblePosition end(nextPositionOf(visibleParagraphEnd)); | 498 VisiblePosition end = nextPositionOf(visibleParagraphEnd); |
499 | 499 |
500 if (Element* table = isFirstPositionAfterTable(end)) { | 500 if (Element* table = isFirstPositionAfterTable(end)) { |
501 // The paragraph break after the last paragraph in the last cell of
a block table ends | 501 // The paragraph break after the last paragraph in the last cell of
a block table ends |
502 // at the start of the paragraph after the table, not at the positio
n just after the table. | 502 // at the start of the paragraph after the table, not at the positio
n just after the table. |
503 if (isEnclosingBlock(table)) | 503 if (isEnclosingBlock(table)) |
504 end = nextPositionOf(end, CannotCrossEditingBoundary); | 504 end = nextPositionOf(end, CannotCrossEditingBoundary); |
505 // There is no parargraph break after the last paragraph in the last
cell of an inline table. | 505 // There is no parargraph break after the last paragraph in the last
cell of an inline table. |
506 else | 506 else |
507 end = visibleParagraphEnd; | 507 end = visibleParagraphEnd; |
508 } | 508 } |
509 | 509 |
510 if (end.isNull()) | 510 if (end.isNull()) |
511 end = visibleParagraphEnd; | 511 end = visibleParagraphEnd; |
512 | 512 |
513 m_end = end.deepEquivalent(); | 513 m_end = end.deepEquivalent(); |
514 break; | 514 break; |
515 } | 515 } |
516 case DocumentBoundary: | 516 case DocumentBoundary: |
517 m_end = endOfDocument(VisiblePosition(m_end, m_affinity)).deepEquivalent
(); | 517 m_end = endOfDocument(createVisiblePosition(m_end, m_affinity)).deepEqui
valent(); |
518 break; | 518 break; |
519 case ParagraphBoundary: | 519 case ParagraphBoundary: |
520 m_end = endOfParagraph(VisiblePosition(m_end, m_affinity)).deepEquivalen
t(); | 520 m_end = endOfParagraph(createVisiblePosition(m_end, m_affinity)).deepEqu
ivalent(); |
521 break; | 521 break; |
522 case SentenceBoundary: | 522 case SentenceBoundary: |
523 m_end = endOfSentence(VisiblePosition(m_end, m_affinity)).deepEquivalent
(); | 523 m_end = endOfSentence(createVisiblePosition(m_end, m_affinity)).deepEqui
valent(); |
524 break; | 524 break; |
525 } | 525 } |
526 | 526 |
527 // Make sure we do not have a Null position. | 527 // Make sure we do not have a Null position. |
528 if (m_end.isNull()) | 528 if (m_end.isNull()) |
529 m_end = m_baseIsFirst ? m_extent : m_base; | 529 m_end = m_baseIsFirst ? m_extent : m_base; |
530 resetPositionsInComposedTree(); | 530 resetPositionsInComposedTree(); |
531 } | 531 } |
532 | 532 |
533 SelectionType VisibleSelection::selectionType(const Position& start, const Posit
ion& end) | 533 SelectionType VisibleSelection::selectionType(const Position& start, const Posit
ion& end) |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 updateSelectionType(); | 646 updateSelectionType(); |
647 | 647 |
648 if (selectionType() == RangeSelection) { | 648 if (selectionType() == RangeSelection) { |
649 // "Constrain" the selection to be the smallest equivalent range of node
s. | 649 // "Constrain" the selection to be the smallest equivalent range of node
s. |
650 // This is a somewhat arbitrary choice, but experience shows that it is | 650 // This is a somewhat arbitrary choice, but experience shows that it is |
651 // useful to make to make the selection "canonical" (if only for | 651 // useful to make to make the selection "canonical" (if only for |
652 // purposes of comparing selections). This is an ideal point of the code | 652 // purposes of comparing selections). This is an ideal point of the code |
653 // to do this operation, since all selection changes that result in a RA
NGE | 653 // to do this operation, since all selection changes that result in a RA
NGE |
654 // come through here before anyone uses it. | 654 // come through here before anyone uses it. |
655 // FIXME: Canonicalizing is good, but haven't we already done it (when w
e | 655 // FIXME: Canonicalizing is good, but haven't we already done it (when w
e |
656 // set these two positions to VisiblePosition deepEquivalent()s above)? | 656 // set these two positions to VisiblePosition deepEquivalent = createVis
iblePosition()s above)? |
657 m_start = mostForwardCaretPosition(m_start); | 657 m_start = mostForwardCaretPosition(m_start); |
658 m_end = mostBackwardCaretPosition(m_end); | 658 m_end = mostBackwardCaretPosition(m_end); |
659 | 659 |
660 // Even by downstreaming, |m_start| can be moved to the upper place from | 660 // Even by downstreaming, |m_start| can be moved to the upper place from |
661 // the original position, same as |m_end|. | 661 // the original position, same as |m_end|. |
662 // e.g.) editing/shadow/select-contenteditable-shadowhost.html | 662 // e.g.) editing/shadow/select-contenteditable-shadowhost.html |
663 m_startInComposedTree = mostForwardCaretPosition(m_startInComposedTree); | 663 m_startInComposedTree = mostForwardCaretPosition(m_startInComposedTree); |
664 m_endInComposedTree = mostBackwardCaretPosition(m_endInComposedTree); | 664 m_endInComposedTree = mostBackwardCaretPosition(m_endInComposedTree); |
665 adjustStartAndEndInComposedTree(); | 665 adjustStartAndEndInComposedTree(); |
666 | 666 |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
932 Element* shadowAncestor = endRoot ? endRoot->shadowHost() : 0; | 932 Element* shadowAncestor = endRoot ? endRoot->shadowHost() : 0; |
933 if (p.isNull() && shadowAncestor) | 933 if (p.isNull() && shadowAncestor) |
934 p = positionAfterNode(shadowAncestor); | 934 p = positionAfterNode(shadowAncestor); |
935 while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerN
ode()) == baseEditableAncestor && !isEditablePosition(p))) { | 935 while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerN
ode()) == baseEditableAncestor && !isEditablePosition(p))) { |
936 Element* root = editableRootForPosition(p); | 936 Element* root = editableRootForPosition(p); |
937 shadowAncestor = root ? root->shadowHost() : 0; | 937 shadowAncestor = root ? root->shadowHost() : 0; |
938 p = isAtomicNode(p.computeContainerNode()) ? positionInParentBef
oreNode(*p.computeContainerNode()) : previousVisuallyDistinctCandidate(p); | 938 p = isAtomicNode(p.computeContainerNode()) ? positionInParentBef
oreNode(*p.computeContainerNode()) : previousVisuallyDistinctCandidate(p); |
939 if (p.isNull() && shadowAncestor) | 939 if (p.isNull() && shadowAncestor) |
940 p = positionAfterNode(shadowAncestor); | 940 p = positionAfterNode(shadowAncestor); |
941 } | 941 } |
942 VisiblePosition previous(p); | 942 VisiblePosition previous = createVisiblePosition(p); |
943 | 943 |
944 if (previous.isNull()) { | 944 if (previous.isNull()) { |
945 // The selection crosses an Editing boundary. This is a | 945 // The selection crosses an Editing boundary. This is a |
946 // programmer error in the editing code. Happy debugging! | 946 // programmer error in the editing code. Happy debugging! |
947 ASSERT_NOT_REACHED(); | 947 ASSERT_NOT_REACHED(); |
948 m_base = Position(); | 948 m_base = Position(); |
949 m_extent = Position(); | 949 m_extent = Position(); |
950 validate(); | 950 validate(); |
951 return; | 951 return; |
952 } | 952 } |
953 m_end = previous.deepEquivalent(); | 953 m_end = previous.deepEquivalent(); |
954 } | 954 } |
955 | 955 |
956 // The selection starts in editable content or non-editable content insi
de a different editable ancestor, | 956 // The selection starts in editable content or non-editable content insi
de a different editable ancestor, |
957 // move forward until non-editable content inside the same lowest editab
le ancestor is reached. | 957 // move forward until non-editable content inside the same lowest editab
le ancestor is reached. |
958 Element* startEditableAncestor = lowestEditableAncestor(m_start.computeC
ontainerNode()); | 958 Element* startEditableAncestor = lowestEditableAncestor(m_start.computeC
ontainerNode()); |
959 if (startRoot || startEditableAncestor != baseEditableAncestor) { | 959 if (startRoot || startEditableAncestor != baseEditableAncestor) { |
960 Position p = nextVisuallyDistinctCandidate(m_start); | 960 Position p = nextVisuallyDistinctCandidate(m_start); |
961 Element* shadowAncestor = startRoot ? startRoot->shadowHost() : 0; | 961 Element* shadowAncestor = startRoot ? startRoot->shadowHost() : 0; |
962 if (p.isNull() && shadowAncestor) | 962 if (p.isNull() && shadowAncestor) |
963 p = positionBeforeNode(shadowAncestor); | 963 p = positionBeforeNode(shadowAncestor); |
964 while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerN
ode()) == baseEditableAncestor && !isEditablePosition(p))) { | 964 while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerN
ode()) == baseEditableAncestor && !isEditablePosition(p))) { |
965 Element* root = editableRootForPosition(p); | 965 Element* root = editableRootForPosition(p); |
966 shadowAncestor = root ? root->shadowHost() : 0; | 966 shadowAncestor = root ? root->shadowHost() : 0; |
967 p = isAtomicNode(p.computeContainerNode()) ? positionInParentAft
erNode(*p.computeContainerNode()) : nextVisuallyDistinctCandidate(p); | 967 p = isAtomicNode(p.computeContainerNode()) ? positionInParentAft
erNode(*p.computeContainerNode()) : nextVisuallyDistinctCandidate(p); |
968 if (p.isNull() && shadowAncestor) | 968 if (p.isNull() && shadowAncestor) |
969 p = positionBeforeNode(shadowAncestor); | 969 p = positionBeforeNode(shadowAncestor); |
970 } | 970 } |
971 VisiblePosition next(p); | 971 VisiblePosition next = createVisiblePosition(p); |
972 | 972 |
973 if (next.isNull()) { | 973 if (next.isNull()) { |
974 // The selection crosses an Editing boundary. This is a | 974 // The selection crosses an Editing boundary. This is a |
975 // programmer error in the editing code. Happy debugging! | 975 // programmer error in the editing code. Happy debugging! |
976 ASSERT_NOT_REACHED(); | 976 ASSERT_NOT_REACHED(); |
977 m_base = Position(); | 977 m_base = Position(); |
978 m_extent = Position(); | 978 m_extent = Position(); |
979 validate(); | 979 validate(); |
980 return; | 980 return; |
981 } | 981 } |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1220 sel.showTreeForThis(); | 1220 sel.showTreeForThis(); |
1221 } | 1221 } |
1222 | 1222 |
1223 void showTree(const blink::VisibleSelection* sel) | 1223 void showTree(const blink::VisibleSelection* sel) |
1224 { | 1224 { |
1225 if (sel) | 1225 if (sel) |
1226 sel->showTreeForThis(); | 1226 sel->showTreeForThis(); |
1227 } | 1227 } |
1228 | 1228 |
1229 #endif | 1229 #endif |
OLD | NEW |