| 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 |