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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 return; | 277 return; |
278 m_hasTrailingWhitespace = true; | 278 m_hasTrailingWhitespace = true; |
279 } | 279 } |
280 | 280 |
281 template <typename Strategy> | 281 template <typename Strategy> |
282 void VisibleSelectionTemplate<Strategy>::setBaseAndExtentToDeepEquivalents() | 282 void VisibleSelectionTemplate<Strategy>::setBaseAndExtentToDeepEquivalents() |
283 { | 283 { |
284 // Move the selection to rendered positions, if possible. | 284 // Move the selection to rendered positions, if possible. |
285 bool baseAndExtentEqual = m_base == m_extent; | 285 bool baseAndExtentEqual = m_base == m_extent; |
286 if (m_base.isNotNull()) { | 286 if (m_base.isNotNull()) { |
287 m_base = createVisiblePosition(m_base, m_affinity).deepEquivalent(); | 287 m_base = createVisiblePositionDeprecated(m_base, m_affinity).deepEquival
ent(); |
288 if (baseAndExtentEqual) | 288 if (baseAndExtentEqual) |
289 m_extent = m_base; | 289 m_extent = m_base; |
290 } | 290 } |
291 if (m_extent.isNotNull() && !baseAndExtentEqual) | 291 if (m_extent.isNotNull() && !baseAndExtentEqual) |
292 m_extent = createVisiblePosition(m_extent, m_affinity).deepEquivalent(); | 292 m_extent = createVisiblePositionDeprecated(m_extent, m_affinity).deepEqu
ivalent(); |
293 | 293 |
294 // Make sure we do not have a dangling base or extent. | 294 // Make sure we do not have a dangling base or extent. |
295 if (m_base.isNull() && m_extent.isNull()) { | 295 if (m_base.isNull() && m_extent.isNull()) { |
296 m_baseIsFirst = true; | 296 m_baseIsFirst = true; |
297 } else if (m_base.isNull()) { | 297 } else if (m_base.isNull()) { |
298 m_base = m_extent; | 298 m_base = m_extent; |
299 m_baseIsFirst = true; | 299 m_baseIsFirst = true; |
300 } else if (m_extent.isNull()) { | 300 } else if (m_extent.isNull()) { |
301 m_extent = m_base; | 301 m_extent = m_base; |
302 m_baseIsFirst = true; | 302 m_baseIsFirst = true; |
(...skipping 14 matching lines...) Expand all Loading... |
317 case CharacterGranularity: | 317 case CharacterGranularity: |
318 // Don't do any expansion. | 318 // Don't do any expansion. |
319 break; | 319 break; |
320 case WordGranularity: { | 320 case WordGranularity: { |
321 // General case: Select the word the caret is positioned inside of. | 321 // General case: Select the word the caret is positioned inside of. |
322 // If the caret is on the word boundary, select the word according to |w
ordSide|. | 322 // If the caret is on the word boundary, select the word according to |w
ordSide|. |
323 // Edge case: If the caret is after the last word in a soft-wrapped line
or the last word in | 323 // Edge case: If the caret is after the last word in a soft-wrapped line
or the last word in |
324 // the document, select that last word (LeftWordIfOnBoundary). | 324 // the document, select that last word (LeftWordIfOnBoundary). |
325 // Edge case: If the caret is after the last word in a paragraph, select
from the the end of the | 325 // Edge case: If the caret is after the last word in a paragraph, select
from the the end of the |
326 // last word to the line break (also RightWordIfOnBoundary); | 326 // last word to the line break (also RightWordIfOnBoundary); |
327 const VisiblePositionTemplate<Strategy> visibleStart = createVisiblePosi
tion(m_start, m_affinity); | 327 const VisiblePositionTemplate<Strategy> visibleStart = createVisiblePosi
tionDeprecated(m_start, m_affinity); |
328 EWordSide side = RightWordIfOnBoundary; | 328 EWordSide side = RightWordIfOnBoundary; |
329 if (isEndOfEditableOrNonEditableContent(visibleStart) || (isEndOfLine(vi
sibleStart) && !isStartOfLine(visibleStart) && !isEndOfParagraph(visibleStart))) | 329 if (isEndOfEditableOrNonEditableContent(visibleStart) || (isEndOfLine(vi
sibleStart) && !isStartOfLine(visibleStart) && !isEndOfParagraph(visibleStart))) |
330 side = LeftWordIfOnBoundary; | 330 side = LeftWordIfOnBoundary; |
331 m_start = startOfWord(visibleStart, side).deepEquivalent(); | 331 m_start = startOfWord(visibleStart, side).deepEquivalent(); |
332 break; | 332 break; |
333 } | 333 } |
334 case SentenceGranularity: { | 334 case SentenceGranularity: { |
335 m_start = startOfSentence(createVisiblePosition(m_start, m_affinity)).de
epEquivalent(); | 335 m_start = startOfSentence(createVisiblePositionDeprecated(m_start, m_aff
inity)).deepEquivalent(); |
336 break; | 336 break; |
337 } | 337 } |
338 case LineGranularity: { | 338 case LineGranularity: { |
339 m_start = startOfLine(createVisiblePosition(m_start, m_affinity)).deepEq
uivalent(); | 339 m_start = startOfLine(createVisiblePositionDeprecated(m_start, m_affinit
y)).deepEquivalent(); |
340 break; | 340 break; |
341 } | 341 } |
342 case LineBoundary: | 342 case LineBoundary: |
343 m_start = startOfLine(createVisiblePosition(m_start, m_affinity)).deepEq
uivalent(); | 343 m_start = startOfLine(createVisiblePositionDeprecated(m_start, m_affinit
y)).deepEquivalent(); |
344 break; | 344 break; |
345 case ParagraphGranularity: { | 345 case ParagraphGranularity: { |
346 VisiblePositionTemplate<Strategy> pos = createVisiblePosition(m_start, m
_affinity); | 346 VisiblePositionTemplate<Strategy> pos = createVisiblePositionDeprecated(
m_start, m_affinity); |
347 if (isStartOfLine(pos) && isEndOfEditableOrNonEditableContent(pos)) | 347 if (isStartOfLine(pos) && isEndOfEditableOrNonEditableContent(pos)) |
348 pos = previousPositionOf(pos); | 348 pos = previousPositionOf(pos); |
349 m_start = startOfParagraph(pos).deepEquivalent(); | 349 m_start = startOfParagraph(pos).deepEquivalent(); |
350 break; | 350 break; |
351 } | 351 } |
352 case DocumentBoundary: | 352 case DocumentBoundary: |
353 m_start = startOfDocument(createVisiblePosition(m_start, m_affinity)).de
epEquivalent(); | 353 m_start = startOfDocument(createVisiblePositionDeprecated(m_start, m_aff
inity)).deepEquivalent(); |
354 break; | 354 break; |
355 case ParagraphBoundary: | 355 case ParagraphBoundary: |
356 m_start = startOfParagraph(createVisiblePosition(m_start, m_affinity)).d
eepEquivalent(); | 356 m_start = startOfParagraph(createVisiblePositionDeprecated(m_start, m_af
finity)).deepEquivalent(); |
357 break; | 357 break; |
358 case SentenceBoundary: | 358 case SentenceBoundary: |
359 m_start = startOfSentence(createVisiblePosition(m_start, m_affinity)).de
epEquivalent(); | 359 m_start = startOfSentence(createVisiblePositionDeprecated(m_start, m_aff
inity)).deepEquivalent(); |
360 break; | 360 break; |
361 } | 361 } |
362 | 362 |
363 // Make sure we do not have a Null position. | 363 // Make sure we do not have a Null position. |
364 if (m_start.isNull()) | 364 if (m_start.isNull()) |
365 m_start = m_baseIsFirst ? m_base : m_extent; | 365 m_start = m_baseIsFirst ? m_base : m_extent; |
366 } | 366 } |
367 | 367 |
368 template <typename Strategy> | 368 template <typename Strategy> |
369 void VisibleSelectionTemplate<Strategy>::setEndRespectingGranularity(TextGranula
rity granularity) | 369 void VisibleSelectionTemplate<Strategy>::setEndRespectingGranularity(TextGranula
rity granularity) |
(...skipping 10 matching lines...) Expand all Loading... |
380 case WordGranularity: { | 380 case WordGranularity: { |
381 // General case: Select the word the caret is positioned inside of. | 381 // General case: Select the word the caret is positioned inside of. |
382 // If the caret is on the word boundary, select the word according to | 382 // If the caret is on the word boundary, select the word according to |
383 // |wordSide|. | 383 // |wordSide|. |
384 // Edge case: If the caret is after the last word in a soft-wrapped line | 384 // Edge case: If the caret is after the last word in a soft-wrapped line |
385 // or the last word in the document, select that last word | 385 // or the last word in the document, select that last word |
386 // (|LeftWordIfOnBoundary|). | 386 // (|LeftWordIfOnBoundary|). |
387 // Edge case: If the caret is after the last word in a paragraph, select | 387 // Edge case: If the caret is after the last word in a paragraph, select |
388 // from the the end of the last word to the line break (also | 388 // from the the end of the last word to the line break (also |
389 // |RightWordIfOnBoundary|); | 389 // |RightWordIfOnBoundary|); |
390 const VisiblePositionTemplate<Strategy> originalEnd = createVisiblePosit
ion(m_end, m_affinity); | 390 const VisiblePositionTemplate<Strategy> originalEnd = createVisiblePosit
ionDeprecated(m_end, m_affinity); |
391 EWordSide side = RightWordIfOnBoundary; | 391 EWordSide side = RightWordIfOnBoundary; |
392 if (isEndOfEditableOrNonEditableContent(originalEnd) || (isEndOfLine(ori
ginalEnd) && !isStartOfLine(originalEnd) && !isEndOfParagraph(originalEnd))) | 392 if (isEndOfEditableOrNonEditableContent(originalEnd) || (isEndOfLine(ori
ginalEnd) && !isStartOfLine(originalEnd) && !isEndOfParagraph(originalEnd))) |
393 side = LeftWordIfOnBoundary; | 393 side = LeftWordIfOnBoundary; |
394 | 394 |
395 const VisiblePositionTemplate<Strategy> wordEnd = endOfWord(originalEnd,
side); | 395 const VisiblePositionTemplate<Strategy> wordEnd = endOfWord(originalEnd,
side); |
396 VisiblePositionTemplate<Strategy> end = wordEnd; | 396 VisiblePositionTemplate<Strategy> end = wordEnd; |
397 | 397 |
398 if (isEndOfParagraph(originalEnd) && !isEmptyTableCell(m_start.anchorNod
e())) { | 398 if (isEndOfParagraph(originalEnd) && !isEmptyTableCell(m_start.anchorNod
e())) { |
399 // Select the paragraph break (the space from the end of a paragraph | 399 // Select the paragraph break (the space from the end of a paragraph |
400 // to the start of the next one) to match TextEdit. | 400 // to the start of the next one) to match TextEdit. |
(...skipping 11 matching lines...) Expand all Loading... |
412 | 412 |
413 if (end.isNull()) | 413 if (end.isNull()) |
414 end = wordEnd; | 414 end = wordEnd; |
415 | 415 |
416 } | 416 } |
417 | 417 |
418 m_end = end.deepEquivalent(); | 418 m_end = end.deepEquivalent(); |
419 break; | 419 break; |
420 } | 420 } |
421 case SentenceGranularity: { | 421 case SentenceGranularity: { |
422 m_end = endOfSentence(createVisiblePosition(m_end, m_affinity)).deepEqui
valent(); | 422 m_end = endOfSentence(createVisiblePositionDeprecated(m_end, m_affinity)
).deepEquivalent(); |
423 break; | 423 break; |
424 } | 424 } |
425 case LineGranularity: { | 425 case LineGranularity: { |
426 VisiblePositionTemplate<Strategy> end = endOfLine(createVisiblePosition(
m_end, m_affinity)); | 426 VisiblePositionTemplate<Strategy> end = endOfLine(createVisiblePositionD
eprecated(m_end, m_affinity)); |
427 // If the end of this line is at the end of a paragraph, include the | 427 // If the end of this line is at the end of a paragraph, include the |
428 // space after the end of the line in the selection. | 428 // space after the end of the line in the selection. |
429 if (isEndOfParagraph(end)) { | 429 if (isEndOfParagraph(end)) { |
430 VisiblePositionTemplate<Strategy> next = nextPositionOf(end); | 430 VisiblePositionTemplate<Strategy> next = nextPositionOf(end); |
431 if (next.isNotNull()) | 431 if (next.isNotNull()) |
432 end = next; | 432 end = next; |
433 } | 433 } |
434 m_end = end.deepEquivalent(); | 434 m_end = end.deepEquivalent(); |
435 break; | 435 break; |
436 } | 436 } |
437 case LineBoundary: | 437 case LineBoundary: |
438 m_end = endOfLine(createVisiblePosition(m_end, m_affinity)).deepEquivale
nt(); | 438 m_end = endOfLine(createVisiblePositionDeprecated(m_end, m_affinity)).de
epEquivalent(); |
439 break; | 439 break; |
440 case ParagraphGranularity: { | 440 case ParagraphGranularity: { |
441 const VisiblePositionTemplate<Strategy> visibleParagraphEnd = endOfParag
raph(createVisiblePosition(m_end, m_affinity)); | 441 const VisiblePositionTemplate<Strategy> visibleParagraphEnd = endOfParag
raph(createVisiblePositionDeprecated(m_end, m_affinity)); |
442 | 442 |
443 // Include the "paragraph break" (the space from the end of this | 443 // Include the "paragraph break" (the space from the end of this |
444 // paragraph to the start of the next one) in the selection. | 444 // paragraph to the start of the next one) in the selection. |
445 VisiblePositionTemplate<Strategy> end = nextPositionOf(visibleParagraphE
nd); | 445 VisiblePositionTemplate<Strategy> end = nextPositionOf(visibleParagraphE
nd); |
446 | 446 |
447 if (Element* table = tableElementJustBefore(end)) { | 447 if (Element* table = tableElementJustBefore(end)) { |
448 // The paragraph break after the last paragraph in the last cell of | 448 // The paragraph break after the last paragraph in the last cell of |
449 // a block table ends at the start of the paragraph after the table, | 449 // a block table ends at the start of the paragraph after the table, |
450 // not at the position just after the table. | 450 // not at the position just after the table. |
451 if (isEnclosingBlock(table)) { | 451 if (isEnclosingBlock(table)) { |
452 end = nextPositionOf(end, CannotCrossEditingBoundary); | 452 end = nextPositionOf(end, CannotCrossEditingBoundary); |
453 } else { | 453 } else { |
454 // There is no parargraph break after the last paragraph in the | 454 // There is no parargraph break after the last paragraph in the |
455 // last cell of an inline table. | 455 // last cell of an inline table. |
456 end = visibleParagraphEnd; | 456 end = visibleParagraphEnd; |
457 } | 457 } |
458 } | 458 } |
459 | 459 |
460 if (end.isNull()) | 460 if (end.isNull()) |
461 end = visibleParagraphEnd; | 461 end = visibleParagraphEnd; |
462 | 462 |
463 m_end = end.deepEquivalent(); | 463 m_end = end.deepEquivalent(); |
464 break; | 464 break; |
465 } | 465 } |
466 case DocumentBoundary: | 466 case DocumentBoundary: |
467 m_end = endOfDocument(createVisiblePosition(m_end, m_affinity)).deepEqui
valent(); | 467 m_end = endOfDocument(createVisiblePositionDeprecated(m_end, m_affinity)
).deepEquivalent(); |
468 break; | 468 break; |
469 case ParagraphBoundary: | 469 case ParagraphBoundary: |
470 m_end = endOfParagraph(createVisiblePosition(m_end, m_affinity)).deepEqu
ivalent(); | 470 m_end = endOfParagraph(createVisiblePositionDeprecated(m_end, m_affinity
)).deepEquivalent(); |
471 break; | 471 break; |
472 case SentenceBoundary: | 472 case SentenceBoundary: |
473 m_end = endOfSentence(createVisiblePosition(m_end, m_affinity)).deepEqui
valent(); | 473 m_end = endOfSentence(createVisiblePositionDeprecated(m_end, m_affinity)
).deepEquivalent(); |
474 break; | 474 break; |
475 } | 475 } |
476 | 476 |
477 // Make sure we do not have a Null position. | 477 // Make sure we do not have a Null position. |
478 if (m_end.isNull()) | 478 if (m_end.isNull()) |
479 m_end = m_baseIsFirst ? m_extent : m_base; | 479 m_end = m_baseIsFirst ? m_extent : m_base; |
480 } | 480 } |
481 | 481 |
482 template <typename Strategy> | 482 template <typename Strategy> |
483 void VisibleSelectionTemplate<Strategy>::updateSelectionType() | 483 void VisibleSelectionTemplate<Strategy>::updateSelectionType() |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
645 Element* shadowAncestor = endRoot ? endRoot->ownerShadowHost() : nul
lptr; | 645 Element* shadowAncestor = endRoot ? endRoot->ownerShadowHost() : nul
lptr; |
646 if (p.isNull() && shadowAncestor) | 646 if (p.isNull() && shadowAncestor) |
647 p = PositionTemplate<Strategy>::afterNode(shadowAncestor); | 647 p = PositionTemplate<Strategy>::afterNode(shadowAncestor); |
648 while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerN
ode()) == baseEditableAncestor && !isEditablePosition(p))) { | 648 while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerN
ode()) == baseEditableAncestor && !isEditablePosition(p))) { |
649 Element* root = rootEditableElementOf(p); | 649 Element* root = rootEditableElementOf(p); |
650 shadowAncestor = root ? root->ownerShadowHost() : nullptr; | 650 shadowAncestor = root ? root->ownerShadowHost() : nullptr; |
651 p = isAtomicNode(p.computeContainerNode()) ? PositionTemplate<St
rategy>::inParentBeforeNode(*p.computeContainerNode()) : previousVisuallyDistinc
tCandidate(p); | 651 p = isAtomicNode(p.computeContainerNode()) ? PositionTemplate<St
rategy>::inParentBeforeNode(*p.computeContainerNode()) : previousVisuallyDistinc
tCandidate(p); |
652 if (p.isNull() && shadowAncestor) | 652 if (p.isNull() && shadowAncestor) |
653 p = PositionTemplate<Strategy>::afterNode(shadowAncestor); | 653 p = PositionTemplate<Strategy>::afterNode(shadowAncestor); |
654 } | 654 } |
655 const VisiblePositionTemplate<Strategy> previous = createVisiblePosi
tion(p); | 655 const VisiblePositionTemplate<Strategy> previous = createVisiblePosi
tionDeprecated(p); |
656 | 656 |
657 if (previous.isNull()) { | 657 if (previous.isNull()) { |
658 // The selection crosses an Editing boundary. This is a | 658 // The selection crosses an Editing boundary. This is a |
659 // programmer error in the editing code. Happy debugging! | 659 // programmer error in the editing code. Happy debugging! |
660 NOTREACHED(); | 660 NOTREACHED(); |
661 m_base = PositionTemplate<Strategy>(); | 661 m_base = PositionTemplate<Strategy>(); |
662 m_extent = PositionTemplate<Strategy>(); | 662 m_extent = PositionTemplate<Strategy>(); |
663 validate(); | 663 validate(); |
664 return; | 664 return; |
665 } | 665 } |
666 m_end = previous.deepEquivalent(); | 666 m_end = previous.deepEquivalent(); |
667 } | 667 } |
668 | 668 |
669 // The selection starts in editable content or non-editable content insi
de a different editable ancestor, | 669 // The selection starts in editable content or non-editable content insi
de a different editable ancestor, |
670 // move forward until non-editable content inside the same lowest editab
le ancestor is reached. | 670 // move forward until non-editable content inside the same lowest editab
le ancestor is reached. |
671 Element* startEditableAncestor = lowestEditableAncestor(m_start.computeC
ontainerNode()); | 671 Element* startEditableAncestor = lowestEditableAncestor(m_start.computeC
ontainerNode()); |
672 if (startRoot || startEditableAncestor != baseEditableAncestor) { | 672 if (startRoot || startEditableAncestor != baseEditableAncestor) { |
673 PositionTemplate<Strategy> p = nextVisuallyDistinctCandidate(m_start
); | 673 PositionTemplate<Strategy> p = nextVisuallyDistinctCandidate(m_start
); |
674 Element* shadowAncestor = startRoot ? startRoot->ownerShadowHost() :
nullptr; | 674 Element* shadowAncestor = startRoot ? startRoot->ownerShadowHost() :
nullptr; |
675 if (p.isNull() && shadowAncestor) | 675 if (p.isNull() && shadowAncestor) |
676 p = PositionTemplate<Strategy>::beforeNode(shadowAncestor); | 676 p = PositionTemplate<Strategy>::beforeNode(shadowAncestor); |
677 while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerN
ode()) == baseEditableAncestor && !isEditablePosition(p))) { | 677 while (p.isNotNull() && !(lowestEditableAncestor(p.computeContainerN
ode()) == baseEditableAncestor && !isEditablePosition(p))) { |
678 Element* root = rootEditableElementOf(p); | 678 Element* root = rootEditableElementOf(p); |
679 shadowAncestor = root ? root->ownerShadowHost() : nullptr; | 679 shadowAncestor = root ? root->ownerShadowHost() : nullptr; |
680 p = isAtomicNode(p.computeContainerNode()) ? PositionTemplate<St
rategy>::inParentAfterNode(*p.computeContainerNode()) : nextVisuallyDistinctCand
idate(p); | 680 p = isAtomicNode(p.computeContainerNode()) ? PositionTemplate<St
rategy>::inParentAfterNode(*p.computeContainerNode()) : nextVisuallyDistinctCand
idate(p); |
681 if (p.isNull() && shadowAncestor) | 681 if (p.isNull() && shadowAncestor) |
682 p = PositionTemplate<Strategy>::beforeNode(shadowAncestor); | 682 p = PositionTemplate<Strategy>::beforeNode(shadowAncestor); |
683 } | 683 } |
684 const VisiblePositionTemplate<Strategy> next = createVisiblePosition
(p); | 684 const VisiblePositionTemplate<Strategy> next = createVisiblePosition
Deprecated(p); |
685 | 685 |
686 if (next.isNull()) { | 686 if (next.isNull()) { |
687 // The selection crosses an Editing boundary. This is a | 687 // The selection crosses an Editing boundary. This is a |
688 // programmer error in the editing code. Happy debugging! | 688 // programmer error in the editing code. Happy debugging! |
689 NOTREACHED(); | 689 NOTREACHED(); |
690 m_base = PositionTemplate<Strategy>(); | 690 m_base = PositionTemplate<Strategy>(); |
691 m_extent = PositionTemplate<Strategy>(); | 691 m_extent = PositionTemplate<Strategy>(); |
692 validate(); | 692 validate(); |
693 return; | 693 return; |
694 } | 694 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 { | 842 { |
843 sel.showTreeForThis(); | 843 sel.showTreeForThis(); |
844 } | 844 } |
845 | 845 |
846 void showTree(const blink::VisibleSelectionInFlatTree* sel) | 846 void showTree(const blink::VisibleSelectionInFlatTree* sel) |
847 { | 847 { |
848 if (sel) | 848 if (sel) |
849 sel->showTreeForThis(); | 849 sel->showTreeForThis(); |
850 } | 850 } |
851 #endif | 851 #endif |
OLD | NEW |