| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |