Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(453)

Side by Side Diff: third_party/WebKit/Source/core/html/HTMLTextFormControlElement.cpp

Issue 2258033002: Replace ASSERT()s with DCHECK*() in core/html/*.{cpp,h}. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Replace ASSERT()s with DCHECK*() in core/html/*.{cpp,h}. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org) 4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7 * 7 *
8 * This library is free software; you can redistribute it and/or 8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public 9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either 10 * License as published by the Free Software Foundation; either
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 setValue(text, TextFieldEventBehavior::DispatchNoEvent); 239 setValue(text, TextFieldEventBehavior::DispatchNoEvent);
240 240
241 if (selectionMode == "select") { 241 if (selectionMode == "select") {
242 newSelectionStart = start; 242 newSelectionStart = start;
243 newSelectionEnd = start + replacementLength; 243 newSelectionEnd = start + replacementLength;
244 } else if (selectionMode == "start") { 244 } else if (selectionMode == "start") {
245 newSelectionStart = newSelectionEnd = start; 245 newSelectionStart = newSelectionEnd = start;
246 } else if (selectionMode == "end") { 246 } else if (selectionMode == "end") {
247 newSelectionStart = newSelectionEnd = start + replacementLength; 247 newSelectionStart = newSelectionEnd = start + replacementLength;
248 } else { 248 } else {
249 ASSERT(selectionMode == "preserve"); 249 DCHECK_EQ(selectionMode, "preserve");
250 long delta = replacementLength - (end - start); 250 long delta = replacementLength - (end - start);
251 251
252 if (newSelectionStart > end) 252 if (newSelectionStart > end)
253 newSelectionStart += delta; 253 newSelectionStart += delta;
254 else if (newSelectionStart > start) 254 else if (newSelectionStart > start)
255 newSelectionStart = start; 255 newSelectionStart = start;
256 256
257 if (newSelectionEnd > end) 257 if (newSelectionEnd > end)
258 newSelectionEnd += delta; 258 newSelectionEnd += delta;
259 else if (newSelectionEnd > start) 259 else if (newSelectionEnd > start)
(...skipping 12 matching lines...) Expand all
272 direction = SelectionHasBackwardDirection; 272 direction = SelectionHasBackwardDirection;
273 273
274 if (direction == SelectionHasNoDirection && document().frame() && document() .frame()->editor().behavior().shouldConsiderSelectionAsDirectional()) 274 if (direction == SelectionHasNoDirection && document().frame() && document() .frame()->editor().behavior().shouldConsiderSelectionAsDirectional())
275 direction = SelectionHasForwardDirection; 275 direction = SelectionHasForwardDirection;
276 276
277 return setSelectionRange(start, end, direction); 277 return setSelectionRange(start, end, direction);
278 } 278 }
279 279
280 static Position positionForIndex(HTMLElement* innerEditor, int index) 280 static Position positionForIndex(HTMLElement* innerEditor, int index)
281 { 281 {
282 ASSERT(index >= 0); 282 DCHECK_GE(index, 0);
283 if (index == 0) { 283 if (index == 0) {
284 Node* node = NodeTraversal::next(*innerEditor, innerEditor); 284 Node* node = NodeTraversal::next(*innerEditor, innerEditor);
285 if (node && node->isTextNode()) 285 if (node && node->isTextNode())
286 return Position(node, 0); 286 return Position(node, 0);
287 return Position(innerEditor, 0); 287 return Position(innerEditor, 0);
288 } 288 }
289 int remainingCharactersToMoveForward = index; 289 int remainingCharactersToMoveForward = index;
290 Node* lastBrOrText = innerEditor; 290 Node* lastBrOrText = innerEditor;
291 for (Node& node : NodeTraversal::descendantsOf(*innerEditor)) { 291 for (Node& node : NodeTraversal::descendantsOf(*innerEditor)) {
292 ASSERT(remainingCharactersToMoveForward >= 0); 292 DCHECK_GE(remainingCharactersToMoveForward, 0);
293 if (node.hasTagName(brTag)) { 293 if (node.hasTagName(brTag)) {
294 if (remainingCharactersToMoveForward == 0) 294 if (remainingCharactersToMoveForward == 0)
295 return Position::beforeNode(&node); 295 return Position::beforeNode(&node);
296 --remainingCharactersToMoveForward; 296 --remainingCharactersToMoveForward;
297 lastBrOrText = &node; 297 lastBrOrText = &node;
298 continue; 298 continue;
299 } 299 }
300 300
301 if (node.isTextNode()) { 301 if (node.isTextNode()) {
302 Text& text = toText(node); 302 Text& text = toText(node);
303 if (remainingCharactersToMoveForward < static_cast<int>(text.length( ))) 303 if (remainingCharactersToMoveForward < static_cast<int>(text.length( )))
304 return Position(&text, remainingCharactersToMoveForward); 304 return Position(&text, remainingCharactersToMoveForward);
305 remainingCharactersToMoveForward -= text.length(); 305 remainingCharactersToMoveForward -= text.length();
306 lastBrOrText = &node; 306 lastBrOrText = &node;
307 continue; 307 continue;
308 } 308 }
309 309
310 ASSERT_NOT_REACHED(); 310 NOTREACHED();
311 } 311 }
312 return lastPositionInOrAfterNode(lastBrOrText); 312 return lastPositionInOrAfterNode(lastBrOrText);
313 } 313 }
314 314
315 static int indexForPosition(HTMLElement* innerEditor, const Position& passedPosi tion) 315 static int indexForPosition(HTMLElement* innerEditor, const Position& passedPosi tion)
316 { 316 {
317 if (!innerEditor || !innerEditor->contains(passedPosition.anchorNode()) || p assedPosition.isNull()) 317 if (!innerEditor || !innerEditor->contains(passedPosition.anchorNode()) || p assedPosition.isNull())
318 return 0; 318 return 0;
319 319
320 if (Position::beforeNode(innerEditor) == passedPosition) 320 if (Position::beforeNode(innerEditor) == passedPosition)
321 return 0; 321 return 0;
322 322
323 int index = 0; 323 int index = 0;
324 Node* startNode = passedPosition.computeNodeBeforePosition(); 324 Node* startNode = passedPosition.computeNodeBeforePosition();
325 if (!startNode) 325 if (!startNode)
326 startNode = passedPosition.computeContainerNode(); 326 startNode = passedPosition.computeContainerNode();
327 ASSERT(startNode); 327 DCHECK(startNode);
328 ASSERT(innerEditor->contains(startNode)); 328 DCHECK(innerEditor->contains(startNode));
329 329
330 for (Node* node = startNode; node; node = NodeTraversal::previous(*node, inn erEditor)) { 330 for (Node* node = startNode; node; node = NodeTraversal::previous(*node, inn erEditor)) {
331 if (node->isTextNode()) { 331 if (node->isTextNode()) {
332 int length = toText(*node).length(); 332 int length = toText(*node).length();
333 if (node == passedPosition.computeContainerNode()) 333 if (node == passedPosition.computeContainerNode())
334 index += std::min(length, passedPosition.offsetInContainerNode() ); 334 index += std::min(length, passedPosition.offsetInContainerNode() );
335 else 335 else
336 index += length; 336 index += length;
337 } else if (node->hasTagName(brTag)) { 337 } else if (node->hasTagName(brTag)) {
338 ++index; 338 ++index;
339 } 339 }
340 } 340 }
341 341
342 ASSERT(index >= 0); 342 DCHECK_GE(index, 0);
343 return index; 343 return index;
344 } 344 }
345 345
346 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField SelectionDirection direction, NeedToDispatchSelectEvent eventBehaviour, Selectio nOption selectionOption) 346 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField SelectionDirection direction, NeedToDispatchSelectEvent eventBehaviour, Selectio nOption selectionOption)
347 { 347 {
348 if (openShadowRoot() || !isTextFormControl()) 348 if (openShadowRoot() || !isTextFormControl())
349 return; 349 return;
350 const int editorValueLength = static_cast<int>(innerEditorValue().length()); 350 const int editorValueLength = static_cast<int>(innerEditorValue().length());
351 ASSERT(editorValueLength >= 0); 351 DCHECK_GE(editorValueLength, 0);
352 end = std::max(std::min(end, editorValueLength), 0); 352 end = std::max(std::min(end, editorValueLength), 0);
353 start = std::min(std::max(start, 0), end); 353 start = std::min(std::max(start, 0), end);
354 cacheSelection(start, end, direction); 354 cacheSelection(start, end, direction);
355 355
356 if (selectionOption == NotChangeSelection || (selectionOption == ChangeSelec tionIfFocused && document().focusedElement() != this) || !isConnected()) { 356 if (selectionOption == NotChangeSelection || (selectionOption == ChangeSelec tionIfFocused && document().focusedElement() != this) || !isConnected()) {
357 if (eventBehaviour == DispatchSelectEvent) 357 if (eventBehaviour == DispatchSelectEvent)
358 scheduleSelectEvent(); 358 scheduleSelectEvent();
359 return; 359 return;
360 } 360 }
361 361
362 LocalFrame* frame = document().frame(); 362 LocalFrame* frame = document().frame();
363 HTMLElement* innerEditor = innerEditorElement(); 363 HTMLElement* innerEditor = innerEditorElement();
364 if (!frame || !innerEditor) 364 if (!frame || !innerEditor)
365 return; 365 return;
366 366
367 Position startPosition = positionForIndex(innerEditor, start); 367 Position startPosition = positionForIndex(innerEditor, start);
368 Position endPosition = start == end ? startPosition : positionForIndex(inner Editor, end); 368 Position endPosition = start == end ? startPosition : positionForIndex(inner Editor, end);
369 369
370 ASSERT(start == indexForPosition(innerEditor, startPosition)); 370 DCHECK_EQ(start, indexForPosition(innerEditor, startPosition));
371 ASSERT(end == indexForPosition(innerEditor, endPosition)); 371 DCHECK_EQ(end, indexForPosition(innerEditor, endPosition));
372 372
373 #if ENABLE(ASSERT) 373 #if DCHECK_IS_ON()
374 // startPosition and endPosition can be null position for example when 374 // startPosition and endPosition can be null position for example when
375 // "-webkit-user-select: none" style attribute is specified. 375 // "-webkit-user-select: none" style attribute is specified.
376 if (startPosition.isNotNull() && endPosition.isNotNull()) { 376 if (startPosition.isNotNull() && endPosition.isNotNull()) {
377 ASSERT(startPosition.anchorNode()->shadowHost() == this 377 DCHECK_EQ(startPosition.anchorNode()->shadowHost(), this);
378 && endPosition.anchorNode()->shadowHost() == this); 378 DCHECK_EQ(endPosition.anchorNode()->shadowHost(), this);
379 } 379 }
380 #endif // ENABLE(ASSERT) 380 #endif // DCHECK_IS_ON()
381 VisibleSelection newSelection; 381 VisibleSelection newSelection;
382 if (direction == SelectionHasBackwardDirection) 382 if (direction == SelectionHasBackwardDirection)
383 newSelection.setWithoutValidation(endPosition, startPosition); 383 newSelection.setWithoutValidation(endPosition, startPosition);
384 else 384 else
385 newSelection.setWithoutValidation(startPosition, endPosition); 385 newSelection.setWithoutValidation(startPosition, endPosition);
386 newSelection.setIsDirectional(direction != SelectionHasNoDirection); 386 newSelection.setIsDirectional(direction != SelectionHasNoDirection);
387 387
388 frame->selection().setSelection(newSelection, FrameSelection::DoNotAdjustInF latTree | FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | (sele ctionOption == ChangeSelectionAndFocus ? 0 : FrameSelection::DoNotSetFocus)); 388 frame->selection().setSelection(newSelection, FrameSelection::DoNotAdjustInF latTree | FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | (sele ctionOption == ChangeSelectionAndFocus ? 0 : FrameSelection::DoNotSetFocus));
389 if (eventBehaviour == DispatchSelectEvent) 389 if (eventBehaviour == DispatchSelectEvent)
390 scheduleSelectEvent(); 390 scheduleSelectEvent();
(...skipping 10 matching lines...) Expand all
401 CharacterIterator it(start, end); 401 CharacterIterator it(start, end);
402 it.advance(index - 1); 402 it.advance(index - 1);
403 return createVisiblePosition(it.endPosition(), TextAffinity::Upstream); 403 return createVisiblePosition(it.endPosition(), TextAffinity::Upstream);
404 } 404 }
405 405
406 int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& p os) const 406 int HTMLTextFormControlElement::indexForVisiblePosition(const VisiblePosition& p os) const
407 { 407 {
408 Position indexPosition = pos.deepEquivalent().parentAnchoredEquivalent(); 408 Position indexPosition = pos.deepEquivalent().parentAnchoredEquivalent();
409 if (enclosingTextFormControl(indexPosition) != this) 409 if (enclosingTextFormControl(indexPosition) != this)
410 return 0; 410 return 0;
411 ASSERT(indexPosition.document()); 411 DCHECK(indexPosition.document());
412 Range* range = Range::create(*indexPosition.document()); 412 Range* range = Range::create(*indexPosition.document());
413 range->setStart(innerEditorElement(), 0, ASSERT_NO_EXCEPTION); 413 range->setStart(innerEditorElement(), 0, ASSERT_NO_EXCEPTION);
414 range->setEnd(indexPosition.computeContainerNode(), indexPosition.offsetInCo ntainerNode(), ASSERT_NO_EXCEPTION); 414 range->setEnd(indexPosition.computeContainerNode(), indexPosition.offsetInCo ntainerNode(), ASSERT_NO_EXCEPTION);
415 return TextIterator::rangeLength(range->startPosition(), range->endPosition( )); 415 return TextIterator::rangeLength(range->startPosition(), range->endPosition( ));
416 } 416 }
417 417
418 int HTMLTextFormControlElement::selectionStart() const 418 int HTMLTextFormControlElement::selectionStart() const
419 { 419 {
420 if (!isTextFormControl()) 420 if (!isTextFormControl())
421 return 0; 421 return 0;
422 if (document().focusedElement() != this) 422 if (document().focusedElement() != this)
423 return m_cachedSelectionStart; 423 return m_cachedSelectionStart;
424 424
425 return computeSelectionStart(); 425 return computeSelectionStart();
426 } 426 }
427 427
428 int HTMLTextFormControlElement::computeSelectionStart() const 428 int HTMLTextFormControlElement::computeSelectionStart() const
429 { 429 {
430 ASSERT(isTextFormControl()); 430 DCHECK(isTextFormControl());
431 LocalFrame* frame = document().frame(); 431 if (LocalFrame* frame = document().frame())
432 if (!frame) 432 return indexForPosition(innerEditorElement(), frame->selection().start() );
433 return 0; 433 return 0;
434
435 return indexForPosition(innerEditorElement(), frame->selection().start());
436 } 434 }
437 435
438 int HTMLTextFormControlElement::selectionEnd() const 436 int HTMLTextFormControlElement::selectionEnd() const
439 { 437 {
440 if (!isTextFormControl()) 438 if (!isTextFormControl())
441 return 0; 439 return 0;
442 if (document().focusedElement() != this) 440 if (document().focusedElement() != this)
443 return m_cachedSelectionEnd; 441 return m_cachedSelectionEnd;
444 return computeSelectionEnd(); 442 return computeSelectionEnd();
445 } 443 }
446 444
447 int HTMLTextFormControlElement::computeSelectionEnd() const 445 int HTMLTextFormControlElement::computeSelectionEnd() const
448 { 446 {
449 ASSERT(isTextFormControl()); 447 DCHECK(isTextFormControl());
450 LocalFrame* frame = document().frame(); 448 if (LocalFrame* frame = document().frame())
451 if (!frame) 449 return indexForPosition(innerEditorElement(), frame->selection().end());
452 return 0; 450 return 0;
453
454 return indexForPosition(innerEditorElement(), frame->selection().end());
455 } 451 }
456 452
457 static const AtomicString& directionString(TextFieldSelectionDirection direction ) 453 static const AtomicString& directionString(TextFieldSelectionDirection direction )
458 { 454 {
459 DEFINE_STATIC_LOCAL(const AtomicString, none, ("none")); 455 DEFINE_STATIC_LOCAL(const AtomicString, none, ("none"));
460 DEFINE_STATIC_LOCAL(const AtomicString, forward, ("forward")); 456 DEFINE_STATIC_LOCAL(const AtomicString, forward, ("forward"));
461 DEFINE_STATIC_LOCAL(const AtomicString, backward, ("backward")); 457 DEFINE_STATIC_LOCAL(const AtomicString, backward, ("backward"));
462 458
463 switch (direction) { 459 switch (direction) {
464 case SelectionHasNoDirection: 460 case SelectionHasNoDirection:
465 return none; 461 return none;
466 case SelectionHasForwardDirection: 462 case SelectionHasForwardDirection:
467 return forward; 463 return forward;
468 case SelectionHasBackwardDirection: 464 case SelectionHasBackwardDirection:
469 return backward; 465 return backward;
470 } 466 }
471 467
472 ASSERT_NOT_REACHED(); 468 NOTREACHED();
473 return none; 469 return none;
474 } 470 }
475 471
476 const AtomicString& HTMLTextFormControlElement::selectionDirection() const 472 const AtomicString& HTMLTextFormControlElement::selectionDirection() const
477 { 473 {
478 if (!isTextFormControl()) 474 if (!isTextFormControl())
479 return directionString(SelectionHasNoDirection); 475 return directionString(SelectionHasNoDirection);
480 if (document().focusedElement() != this) 476 if (document().focusedElement() != this)
481 return directionString(m_cachedSelectionDirection); 477 return directionString(m_cachedSelectionDirection);
482 478
483 return directionString(computeSelectionDirection()); 479 return directionString(computeSelectionDirection());
484 } 480 }
485 481
486 TextFieldSelectionDirection HTMLTextFormControlElement::computeSelectionDirectio n() const 482 TextFieldSelectionDirection HTMLTextFormControlElement::computeSelectionDirectio n() const
487 { 483 {
488 ASSERT(isTextFormControl()); 484 DCHECK(isTextFormControl());
489 LocalFrame* frame = document().frame(); 485 LocalFrame* frame = document().frame();
490 if (!frame) 486 if (!frame)
491 return SelectionHasNoDirection; 487 return SelectionHasNoDirection;
492 488
493 const VisibleSelection& selection = frame->selection().selection(); 489 const VisibleSelection& selection = frame->selection().selection();
494 return selection.isDirectional() ? (selection.isBaseFirst() ? SelectionHasFo rwardDirection : SelectionHasBackwardDirection) : SelectionHasNoDirection; 490 return selection.isDirectional() ? (selection.isBaseFirst() ? SelectionHasFo rwardDirection : SelectionHasBackwardDirection) : SelectionHasNoDirection;
495 } 491 }
496 492
497 static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*& containerNode, int& offsetInContainer) 493 static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*& containerNode, int& offsetInContainer)
498 { 494 {
499 if (node->isTextNode()) { 495 if (node->isTextNode()) {
500 containerNode = node; 496 containerNode = node;
501 offsetInContainer = offset; 497 offsetInContainer = offset;
502 } else { 498 } else {
503 containerNode = node->parentNode(); 499 containerNode = node->parentNode();
504 offsetInContainer = node->nodeIndex() + offset; 500 offsetInContainer = node->nodeIndex() + offset;
505 } 501 }
506 } 502 }
507 503
508 Range* HTMLTextFormControlElement::selection() const 504 Range* HTMLTextFormControlElement::selection() const
509 { 505 {
510 if (!layoutObject() || !isTextFormControl()) 506 if (!layoutObject() || !isTextFormControl())
511 return nullptr; 507 return nullptr;
512 508
513 int start = m_cachedSelectionStart; 509 int start = m_cachedSelectionStart;
514 int end = m_cachedSelectionEnd; 510 int end = m_cachedSelectionEnd;
515 511
516 ASSERT(start <= end); 512 DCHECK_LE(start, end);
517 HTMLElement* innerText = innerEditorElement(); 513 HTMLElement* innerText = innerEditorElement();
518 if (!innerText) 514 if (!innerText)
519 return nullptr; 515 return nullptr;
520 516
521 if (!innerText->hasChildren()) 517 if (!innerText->hasChildren())
522 return Range::create(document(), innerText, 0, innerText, 0); 518 return Range::create(document(), innerText, 0, innerText, 0);
523 519
524 int offset = 0; 520 int offset = 0;
525 Node* startNode = 0; 521 Node* startNode = 0;
526 Node* endNode = 0; 522 Node* endNode = 0;
527 for (Node& node : NodeTraversal::descendantsOf(*innerText)) { 523 for (Node& node : NodeTraversal::descendantsOf(*innerText)) {
528 ASSERT(!node.hasChildren()); 524 DCHECK(!node.hasChildren());
529 ASSERT(node.isTextNode() || isHTMLBRElement(node)); 525 DCHECK(node.isTextNode() || isHTMLBRElement(node));
530 int length = node.isTextNode() ? Position::lastOffsetInNode(&node) : 1; 526 int length = node.isTextNode() ? Position::lastOffsetInNode(&node) : 1;
531 527
532 if (offset <= start && start <= offset + length) 528 if (offset <= start && start <= offset + length)
533 setContainerAndOffsetForRange(&node, start - offset, startNode, star t); 529 setContainerAndOffsetForRange(&node, start - offset, startNode, star t);
534 530
535 if (offset <= end && end <= offset + length) { 531 if (offset <= end && end <= offset + length) {
536 setContainerAndOffsetForRange(&node, end - offset, endNode, end); 532 setContainerAndOffsetForRange(&node, end - offset, endNode, end);
537 break; 533 break;
538 } 534 }
539 535
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 return; 628 return;
633 Node* lastChild = innerEditor->lastChild(); 629 Node* lastChild = innerEditor->lastChild();
634 if (!lastChild || !lastChild->isTextNode()) 630 if (!lastChild || !lastChild->isTextNode())
635 return; 631 return;
636 if (toText(lastChild)->data().endsWith('\n') || toText(lastChild)->data().en dsWith('\r')) 632 if (toText(lastChild)->data().endsWith('\n') || toText(lastChild)->data().en dsWith('\r'))
637 innerEditor->appendChild(createPlaceholderBreakElement()); 633 innerEditor->appendChild(createPlaceholderBreakElement());
638 } 634 }
639 635
640 void HTMLTextFormControlElement::setInnerEditorValue(const String& value) 636 void HTMLTextFormControlElement::setInnerEditorValue(const String& value)
641 { 637 {
642 ASSERT(!openShadowRoot()); 638 DCHECK(!openShadowRoot());
643 if (!isTextFormControl() || openShadowRoot()) 639 if (!isTextFormControl() || openShadowRoot())
644 return; 640 return;
645 641
646 bool textIsChanged = value != innerEditorValue(); 642 bool textIsChanged = value != innerEditorValue();
647 HTMLElement* innerEditor = innerEditorElement(); 643 HTMLElement* innerEditor = innerEditorElement();
648 if (!textIsChanged && innerEditor->hasChildren()) 644 if (!textIsChanged && innerEditor->hasChildren())
649 return; 645 return;
650 646
651 // If the last child is a trailing <br> that's appended below, remove it 647 // If the last child is a trailing <br> that's appended below, remove it
652 // first so as to enable setInnerText() fast path of updating a text node. 648 // first so as to enable setInnerText() fast path of updating a text node.
(...skipping 11 matching lines...) Expand all
664 addPlaceholderBreakElementIfNecessary(); 660 addPlaceholderBreakElementIfNecessary();
665 661
666 if (textIsChanged && layoutObject()) { 662 if (textIsChanged && layoutObject()) {
667 if (AXObjectCache* cache = document().existingAXObjectCache()) 663 if (AXObjectCache* cache = document().existingAXObjectCache())
668 cache->handleTextFormControlChanged(this); 664 cache->handleTextFormControlChanged(this);
669 } 665 }
670 } 666 }
671 667
672 String HTMLTextFormControlElement::innerEditorValue() const 668 String HTMLTextFormControlElement::innerEditorValue() const
673 { 669 {
674 ASSERT(!openShadowRoot()); 670 DCHECK(!openShadowRoot());
675 HTMLElement* innerEditor = innerEditorElement(); 671 HTMLElement* innerEditor = innerEditorElement();
676 if (!innerEditor || !isTextFormControl()) 672 if (!innerEditor || !isTextFormControl())
677 return emptyString(); 673 return emptyString();
678 674
679 StringBuilder result; 675 StringBuilder result;
680 for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor)) { 676 for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor)) {
681 if (isHTMLBRElement(node)) { 677 if (isHTMLBRElement(node)) {
682 ASSERT(&node == innerEditor->lastChild()); 678 DCHECK_EQ(&node, innerEditor->lastChild());
683 if (&node != innerEditor->lastChild()) 679 if (&node != innerEditor->lastChild())
684 result.append(newlineCharacter); 680 result.append(newlineCharacter);
685 } else if (node.isTextNode()) { 681 } else if (node.isTextNode()) {
686 result.append(toText(node).data()); 682 result.append(toText(node).data());
687 } 683 }
688 } 684 }
689 return result.toString(); 685 return result.toString();
690 } 686 }
691 687
692 static void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& b reakOffset) 688 static void getNextSoftBreak(RootInlineBox*& line, Node*& breakNode, unsigned& b reakOffset)
693 { 689 {
694 RootInlineBox* next; 690 RootInlineBox* next;
695 for (; line; line = next) { 691 for (; line; line = next) {
696 next = line->nextRootBox(); 692 next = line->nextRootBox();
697 if (next && !line->endsWithBreak()) { 693 if (next && !line->endsWithBreak()) {
698 ASSERT(line->lineBreakObj()); 694 DCHECK(line->lineBreakObj());
699 breakNode = line->lineBreakObj().node(); 695 breakNode = line->lineBreakObj().node();
700 breakOffset = line->lineBreakPos(); 696 breakOffset = line->lineBreakPos();
701 line = next; 697 line = next;
702 return; 698 return;
703 } 699 }
704 } 700 }
705 breakNode = 0; 701 breakNode = 0;
706 breakOffset = 0; 702 breakOffset = 0;
707 } 703 }
708 704
(...skipping 13 matching lines...) Expand all
722 unsigned breakOffset; 718 unsigned breakOffset;
723 RootInlineBox* line = layoutObject->firstRootBox(); 719 RootInlineBox* line = layoutObject->firstRootBox();
724 if (!line) 720 if (!line)
725 return value(); 721 return value();
726 722
727 getNextSoftBreak(line, breakNode, breakOffset); 723 getNextSoftBreak(line, breakNode, breakOffset);
728 724
729 StringBuilder result; 725 StringBuilder result;
730 for (Node& node : NodeTraversal::descendantsOf(*innerText)) { 726 for (Node& node : NodeTraversal::descendantsOf(*innerText)) {
731 if (isHTMLBRElement(node)) { 727 if (isHTMLBRElement(node)) {
732 ASSERT(&node == innerText->lastChild()); 728 DCHECK_EQ(&node, innerText->lastChild());
733 if (&node != innerText->lastChild()) 729 if (&node != innerText->lastChild())
734 result.append(newlineCharacter); 730 result.append(newlineCharacter);
735 } else if (node.isTextNode()) { 731 } else if (node.isTextNode()) {
736 String data = toText(node).data(); 732 String data = toText(node).data();
737 unsigned length = data.length(); 733 unsigned length = data.length();
738 unsigned position = 0; 734 unsigned position = 0;
739 while (breakNode == node && breakOffset <= length) { 735 while (breakNode == node && breakOffset <= length) {
740 if (breakOffset > position) { 736 if (breakOffset > position) {
741 result.append(data, position, breakOffset - position); 737 result.append(data, position, breakOffset - position);
742 position = breakOffset; 738 position = breakOffset;
743 result.append(newlineCharacter); 739 result.append(newlineCharacter);
744 } 740 }
745 getNextSoftBreak(line, breakNode, breakOffset); 741 getNextSoftBreak(line, breakNode, breakOffset);
746 } 742 }
747 result.append(data, position, length - position); 743 result.append(data, position, length - position);
748 } 744 }
749 while (breakNode == node) 745 while (breakNode == node)
750 getNextSoftBreak(line, breakNode, breakOffset); 746 getNextSoftBreak(line, breakNode, breakOffset);
751 } 747 }
752 return result.toString(); 748 return result.toString();
753 } 749 }
754 750
755 HTMLTextFormControlElement* enclosingTextFormControl(const Position& position) 751 HTMLTextFormControlElement* enclosingTextFormControl(const Position& position)
756 { 752 {
757 ASSERT(position.isNull() || position.isOffsetInAnchor() 753 DCHECK(position.isNull() || position.isOffsetInAnchor()
758 || position.computeContainerNode() || !position.anchorNode()->shadowHost () 754 || position.computeContainerNode() || !position.anchorNode()->shadowHost ()
759 || (position.anchorNode()->parentNode() && position.anchorNode()->parent Node()->isShadowRoot())); 755 || (position.anchorNode()->parentNode() && position.anchorNode()->parent Node()->isShadowRoot()));
760 return enclosingTextFormControl(position.computeContainerNode()); 756 return enclosingTextFormControl(position.computeContainerNode());
761 } 757 }
762 758
763 HTMLTextFormControlElement* enclosingTextFormControl(Node* container) 759 HTMLTextFormControlElement* enclosingTextFormControl(Node* container)
764 { 760 {
765 if (!container) 761 if (!container)
766 return nullptr; 762 return nullptr;
767 Element* ancestor = container->shadowHost(); 763 Element* ancestor = container->shadowHost();
(...skipping 20 matching lines...) Expand all
788 return "ltr"; 784 return "ltr";
789 } 785 }
790 786
791 HTMLElement* HTMLTextFormControlElement::innerEditorElement() const 787 HTMLElement* HTMLTextFormControlElement::innerEditorElement() const
792 { 788 {
793 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName s::innerEditor())); 789 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName s::innerEditor()));
794 } 790 }
795 791
796 static Position innerNodePosition(const Position& innerPosition) 792 static Position innerNodePosition(const Position& innerPosition)
797 { 793 {
798 ASSERT(!innerPosition.isBeforeAnchor()); 794 DCHECK(!innerPosition.isBeforeAnchor());
799 ASSERT(!innerPosition.isAfterAnchor()); 795 DCHECK(!innerPosition.isAfterAnchor());
800 HTMLElement* element = toHTMLElement(innerPosition.anchorNode()); 796 HTMLElement* element = toHTMLElement(innerPosition.anchorNode());
801 ASSERT(element); 797 DCHECK(element);
802 NodeList* childNodes = element->childNodes(); 798 NodeList* childNodes = element->childNodes();
803 if (!childNodes->length()) 799 if (!childNodes->length())
804 return Position(element, 0); 800 return Position(element, 0);
805 801
806 unsigned offset = 0; 802 unsigned offset = 0;
807 803
808 if (innerPosition.isOffsetInAnchor()) 804 if (innerPosition.isOffsetInAnchor())
809 offset = std::max(0, std::min(innerPosition.offsetInContainerNode(), sta tic_cast<int>(childNodes->length()))); 805 offset = std::max(0, std::min(innerPosition.offsetInContainerNode(), sta tic_cast<int>(childNodes->length())));
810 else if (innerPosition.isAfterChildren()) 806 else if (innerPosition.isAfterChildren())
811 offset = childNodes->length(); 807 offset = childNodes->length();
(...skipping 13 matching lines...) Expand all
825 FindEnd 821 FindEnd
826 }; 822 };
827 823
828 static Position findWordBoundary(const HTMLElement* innerEditor, const Position& startPosition, const Position& endPosition, FindOption findOption) 824 static Position findWordBoundary(const HTMLElement* innerEditor, const Position& startPosition, const Position& endPosition, FindOption findOption)
829 { 825 {
830 StringBuilder concatTexts; 826 StringBuilder concatTexts;
831 Vector<unsigned> lengthList; 827 Vector<unsigned> lengthList;
832 HeapVector<Member<Text>> textList; 828 HeapVector<Member<Text>> textList;
833 829
834 if (startPosition.anchorNode()->isTextNode()) 830 if (startPosition.anchorNode()->isTextNode())
835 ASSERT(startPosition.isOffsetInAnchor()); 831 DCHECK(startPosition.isOffsetInAnchor());
836 if (endPosition.anchorNode()->isTextNode()) 832 if (endPosition.anchorNode()->isTextNode())
837 ASSERT(endPosition.isOffsetInAnchor()); 833 DCHECK(endPosition.isOffsetInAnchor());
838 834
839 // Traverse text nodes. 835 // Traverse text nodes.
840 for (Node* node = startPosition.anchorNode(); node; node = NodeTraversal::ne xt(*node, innerEditor)) { 836 for (Node* node = startPosition.anchorNode(); node; node = NodeTraversal::ne xt(*node, innerEditor)) {
841 bool isStartNode = node == startPosition.anchorNode(); 837 bool isStartNode = node == startPosition.anchorNode();
842 bool isEndNode = node == endPosition.anchorNode(); 838 bool isEndNode = node == endPosition.anchorNode();
843 if (node->isTextNode()) { 839 if (node->isTextNode()) {
844 Text* text = toText(node); 840 Text* text = toText(node);
845 const unsigned start = isStartNode ? startPosition.offsetInContainer Node() : 0; 841 const unsigned start = isStartNode ? startPosition.offsetInContainer Node() : 0;
846 const unsigned end = isEndNode ? endPosition.offsetInContainerNode() : text->data().length(); 842 const unsigned end = isEndNode ? endPosition.offsetInContainerNode() : text->data().length();
847 const unsigned length = end - start; 843 const unsigned length = end - start;
(...skipping 14 matching lines...) Expand all
862 if (findOption == FindEnd && concatTexts[0] == '\n') { 858 if (findOption == FindEnd && concatTexts[0] == '\n') {
863 // findWordBoundary("\ntext", 0, &start, &end) assigns 1 to |end| but 859 // findWordBoundary("\ntext", 0, &start, &end) assigns 1 to |end| but
864 // we expect 0 at the case. 860 // we expect 0 at the case.
865 start = 0; 861 start = 0;
866 end = 0; 862 end = 0;
867 } else { 863 } else {
868 Vector<UChar> characters; 864 Vector<UChar> characters;
869 concatTexts.toString().appendTo(characters); 865 concatTexts.toString().appendTo(characters);
870 findWordBoundary(characters.data(), characters.size(), findOption == Fin dStart ? characters.size() : 0, &start, &end); 866 findWordBoundary(characters.data(), characters.size(), findOption == Fin dStart ? characters.size() : 0, &start, &end);
871 } 867 }
872 ASSERT(start >= 0); 868 DCHECK_GE(start, 0);
873 ASSERT(end >= 0); 869 DCHECK_GE(end, 0);
874 unsigned remainingOffset = findOption == FindStart ? start : end; 870 unsigned remainingOffset = findOption == FindStart ? start : end;
875 // Find position. 871 // Find position.
876 for (unsigned i = 0; i < lengthList.size(); ++i) { 872 for (unsigned i = 0; i < lengthList.size(); ++i) {
877 if (remainingOffset <= lengthList[i]) 873 if (remainingOffset <= lengthList[i])
878 return Position(textList[i], (textList[i] == startPosition.anchorNod e()) ? remainingOffset + startPosition.offsetInContainerNode() : remainingOffset ); 874 return Position(textList[i], (textList[i] == startPosition.anchorNod e()) ? remainingOffset + startPosition.offsetInContainerNode() : remainingOffset );
879 remainingOffset -= lengthList[i]; 875 remainingOffset -= lengthList[i];
880 } 876 }
881 877
882 ASSERT_NOT_REACHED(); 878 NOTREACHED();
883 return Position(); 879 return Position();
884 } 880 }
885 881
886 Position HTMLTextFormControlElement::startOfWord(const Position& position) 882 Position HTMLTextFormControlElement::startOfWord(const Position& position)
887 { 883 {
888 const HTMLTextFormControlElement* textFormControl = enclosingTextFormControl (position); 884 const HTMLTextFormControlElement* textFormControl = enclosingTextFormControl (position);
889 ASSERT(textFormControl); 885 DCHECK(textFormControl);
890 HTMLElement* innerEditor = textFormControl->innerEditorElement(); 886 HTMLElement* innerEditor = textFormControl->innerEditorElement();
891 887
892 const Position startPosition = startOfSentence(position); 888 const Position startPosition = startOfSentence(position);
893 if (startPosition == position) 889 if (startPosition == position)
894 return position; 890 return position;
895 const Position endPosition = (position.anchorNode() == innerEditor) ? innerN odePosition(position) : position; 891 const Position endPosition = (position.anchorNode() == innerEditor) ? innerN odePosition(position) : position;
896 892
897 return findWordBoundary(innerEditor, startPosition, endPosition, FindStart); 893 return findWordBoundary(innerEditor, startPosition, endPosition, FindStart);
898 } 894 }
899 895
900 Position HTMLTextFormControlElement::endOfWord(const Position& position) 896 Position HTMLTextFormControlElement::endOfWord(const Position& position)
901 { 897 {
902 const HTMLTextFormControlElement* textFormControl = enclosingTextFormControl (position); 898 const HTMLTextFormControlElement* textFormControl = enclosingTextFormControl (position);
903 ASSERT(textFormControl); 899 DCHECK(textFormControl);
904 HTMLElement* innerEditor = textFormControl->innerEditorElement(); 900 HTMLElement* innerEditor = textFormControl->innerEditorElement();
905 901
906 const Position endPosition = endOfSentence(position); 902 const Position endPosition = endOfSentence(position);
907 if (endPosition == position) 903 if (endPosition == position)
908 return position; 904 return position;
909 const Position startPosition = (position.anchorNode() == innerEditor) ? inne rNodePosition(position) : position; 905 const Position startPosition = (position.anchorNode() == innerEditor) ? inne rNodePosition(position) : position;
910 906
911 return findWordBoundary(innerEditor, startPosition, endPosition, FindEnd); 907 return findWordBoundary(innerEditor, startPosition, endPosition, FindEnd);
912 } 908 }
913 909
(...skipping 18 matching lines...) Expand all
932 return Position(); 928 return Position();
933 929
934 // Move back if position is just after line break. 930 // Move back if position is just after line break.
935 if (isHTMLBRElement(*position.anchorNode())) { 931 if (isHTMLBRElement(*position.anchorNode())) {
936 if (position.isAfterAnchor()) 932 if (position.isAfterAnchor())
937 return Position(position.anchorNode(), PositionAnchorType::BeforeAnc hor); 933 return Position(position.anchorNode(), PositionAnchorType::BeforeAnc hor);
938 if (position.isBeforeAnchor()) 934 if (position.isBeforeAnchor())
939 return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.an chorNode(), innerEditor), innerEditor); 935 return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.an chorNode(), innerEditor), innerEditor);
940 // We don't place caret into BR element, since well-formed BR element 936 // We don't place caret into BR element, since well-formed BR element
941 // doesn't have child nodes. 937 // doesn't have child nodes.
942 ASSERT_NOT_REACHED(); 938 NOTREACHED();
943 return position; 939 return position;
944 } 940 }
945 941
946 if (!position.anchorNode()->isTextNode()) 942 if (!position.anchorNode()->isTextNode())
947 return position; 943 return position;
948 944
949 Text* textNode = toText(position.anchorNode()); 945 Text* textNode = toText(position.anchorNode());
950 unsigned offset = position.offsetInContainerNode(); 946 unsigned offset = position.offsetInContainerNode();
951 if (textNode->length() == 0 || offset == 0) 947 if (textNode->length() == 0 || offset == 0)
952 return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.anchor Node(), innerEditor), innerEditor); 948 return previousIfPositionIsAfterLineBreak(endOfPrevious(*position.anchor Node(), innerEditor), innerEditor);
953 949
954 if (offset <= textNode->length() && textNode->data()[offset - 1] == '\n') 950 if (offset <= textNode->length() && textNode->data()[offset - 1] == '\n')
955 return Position(textNode, offset - 1); 951 return Position(textNode, offset - 1);
956 952
957 return position; 953 return position;
958 } 954 }
959 955
960 static inline Position startOfInnerText(const HTMLTextFormControlElement* textFo rmControl) 956 static inline Position startOfInnerText(const HTMLTextFormControlElement* textFo rmControl)
961 { 957 {
962 return Position(textFormControl->innerEditorElement(), 0); 958 return Position(textFormControl->innerEditorElement(), 0);
963 } 959 }
964 960
965 Position HTMLTextFormControlElement::startOfSentence(const Position& position) 961 Position HTMLTextFormControlElement::startOfSentence(const Position& position)
966 { 962 {
967 HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(posit ion); 963 HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(posit ion);
968 ASSERT(textFormControl); 964 DCHECK(textFormControl);
969 965
970 HTMLElement* innerEditor = textFormControl->innerEditorElement(); 966 HTMLElement* innerEditor = textFormControl->innerEditorElement();
971 if (!innerEditor->childNodes()->length()) 967 if (!innerEditor->childNodes()->length())
972 return startOfInnerText(textFormControl); 968 return startOfInnerText(textFormControl);
973 969
974 const Position innerPosition = position.anchorNode() == innerEditor ? innerN odePosition(position) : position; 970 const Position innerPosition = position.anchorNode() == innerEditor ? innerN odePosition(position) : position;
975 const Position pivotPosition = previousIfPositionIsAfterLineBreak(innerPosit ion, innerEditor); 971 const Position pivotPosition = previousIfPositionIsAfterLineBreak(innerPosit ion, innerEditor);
976 if (pivotPosition.isNull()) 972 if (pivotPosition.isNull())
977 return startOfInnerText(textFormControl); 973 return startOfInnerText(textFormControl);
978 974
(...skipping 15 matching lines...) Expand all
994 990
995 static Position endOfInnerText(const HTMLTextFormControlElement* textFormControl ) 991 static Position endOfInnerText(const HTMLTextFormControlElement* textFormControl )
996 { 992 {
997 HTMLElement* innerEditor = textFormControl->innerEditorElement(); 993 HTMLElement* innerEditor = textFormControl->innerEditorElement();
998 return Position(innerEditor, innerEditor->childNodes()->length()); 994 return Position(innerEditor, innerEditor->childNodes()->length());
999 } 995 }
1000 996
1001 Position HTMLTextFormControlElement::endOfSentence(const Position& position) 997 Position HTMLTextFormControlElement::endOfSentence(const Position& position)
1002 { 998 {
1003 HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(posit ion); 999 HTMLTextFormControlElement* textFormControl = enclosingTextFormControl(posit ion);
1004 ASSERT(textFormControl); 1000 DCHECK(textFormControl);
1005 1001
1006 HTMLElement* innerEditor = textFormControl->innerEditorElement(); 1002 HTMLElement* innerEditor = textFormControl->innerEditorElement();
1007 if (innerEditor->childNodes()->length() == 0) 1003 if (innerEditor->childNodes()->length() == 0)
1008 return startOfInnerText(textFormControl); 1004 return startOfInnerText(textFormControl);
1009 1005
1010 const Position pivotPosition = position.anchorNode() == innerEditor ? innerN odePosition(position) : position; 1006 const Position pivotPosition = position.anchorNode() == innerEditor ? innerN odePosition(position) : position;
1011 if (pivotPosition.isNull()) 1007 if (pivotPosition.isNull())
1012 return startOfInnerText(textFormControl); 1008 return startOfInnerText(textFormControl);
1013 1009
1014 for (Node* node = pivotPosition.anchorNode(); node; node = NodeTraversal::ne xt(*node, innerEditor)) { 1010 for (Node* node = pivotPosition.anchorNode(); node; node = NodeTraversal::ne xt(*node, innerEditor)) {
(...skipping 13 matching lines...) Expand all
1028 } 1024 }
1029 1025
1030 void HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(const Ele ment& source) 1026 void HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(const Ele ment& source)
1031 { 1027 {
1032 const HTMLTextFormControlElement& sourceElement = static_cast<const HTMLText FormControlElement&>(source); 1028 const HTMLTextFormControlElement& sourceElement = static_cast<const HTMLText FormControlElement&>(source);
1033 m_lastChangeWasUserEdit = sourceElement.m_lastChangeWasUserEdit; 1029 m_lastChangeWasUserEdit = sourceElement.m_lastChangeWasUserEdit;
1034 HTMLFormControlElement::copyNonAttributePropertiesFromElement(source); 1030 HTMLFormControlElement::copyNonAttributePropertiesFromElement(source);
1035 } 1031 }
1036 1032
1037 } // namespace blink 1033 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698