| 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 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 updatePlaceholderText(); | 164 updatePlaceholderText(); |
| 165 HTMLElement* placeholder = placeholderElement(); | 165 HTMLElement* placeholder = placeholderElement(); |
| 166 if (!placeholder) | 166 if (!placeholder) |
| 167 return; | 167 return; |
| 168 | 168 |
| 169 placeholder->setInlineStyleProperty(CSSPropertyDisplay, placeholderShouldBeV
isible() ? CSSValueBlock : CSSValueNone); | 169 placeholder->setInlineStyleProperty(CSSPropertyDisplay, placeholderShouldBeV
isible() ? CSSValueBlock : CSSValueNone); |
| 170 } | 170 } |
| 171 | 171 |
| 172 void HTMLTextFormControlElement::setSelectionStart(int start) | 172 void HTMLTextFormControlElement::setSelectionStart(int start) |
| 173 { | 173 { |
| 174 setSelectionRange(start, std::max(start, selectionEnd()), selectionDirection
()); | 174 setSelectionRange(start, std::max<unsigned>(start, selectionEnd()), selectio
nDirection()); |
| 175 } | 175 } |
| 176 | 176 |
| 177 void HTMLTextFormControlElement::setSelectionEnd(int end) | 177 void HTMLTextFormControlElement::setSelectionEnd(int end) |
| 178 { | 178 { |
| 179 setSelectionRange(std::min(end, selectionStart()), end, selectionDirection()
); | 179 setSelectionRange(std::min<unsigned>(end, selectionStart()), end, selectionD
irection()); |
| 180 } | 180 } |
| 181 | 181 |
| 182 void HTMLTextFormControlElement::setSelectionDirection(const String& direction) | 182 void HTMLTextFormControlElement::setSelectionDirection(const String& direction) |
| 183 { | 183 { |
| 184 setSelectionRange(selectionStart(), selectionEnd(), direction); | 184 setSelectionRange(selectionStart(), selectionEnd(), direction); |
| 185 } | 185 } |
| 186 | 186 |
| 187 void HTMLTextFormControlElement::select(NeedToDispatchSelectEvent eventBehaviour
) | 187 void HTMLTextFormControlElement::select(NeedToDispatchSelectEvent eventBehaviour
) |
| 188 { | 188 { |
| 189 document().updateLayoutIgnorePendingStylesheets(); | 189 document().updateLayoutIgnorePendingStylesheets(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 | 259 |
| 260 if (newSelectionEnd > end) | 260 if (newSelectionEnd > end) |
| 261 newSelectionEnd += delta; | 261 newSelectionEnd += delta; |
| 262 else if (newSelectionEnd > start) | 262 else if (newSelectionEnd > start) |
| 263 newSelectionEnd = start + replacementLength; | 263 newSelectionEnd = start + replacementLength; |
| 264 } | 264 } |
| 265 | 265 |
| 266 setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirectio
n); | 266 setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirectio
n); |
| 267 } | 267 } |
| 268 | 268 |
| 269 void HTMLTextFormControlElement::setSelectionRange(int start, int end, const Str
ing& directionString) | 269 void HTMLTextFormControlElement::setSelectionRange(unsigned start, unsigned end,
const String& directionString) |
| 270 { | 270 { |
| 271 TextFieldSelectionDirection direction = SelectionHasNoDirection; | 271 TextFieldSelectionDirection direction = SelectionHasNoDirection; |
| 272 if (directionString == "forward") | 272 if (directionString == "forward") |
| 273 direction = SelectionHasForwardDirection; | 273 direction = SelectionHasForwardDirection; |
| 274 else if (directionString == "backward") | 274 else if (directionString == "backward") |
| 275 direction = SelectionHasBackwardDirection; | 275 direction = SelectionHasBackwardDirection; |
| 276 | 276 |
| 277 if (direction == SelectionHasNoDirection && document().frame() && document()
.frame()->editor().behavior().shouldConsiderSelectionAsDirectional()) | 277 if (direction == SelectionHasNoDirection && document().frame() && document()
.frame()->editor().behavior().shouldConsiderSelectionAsDirectional()) |
| 278 direction = SelectionHasForwardDirection; | 278 direction = SelectionHasForwardDirection; |
| 279 | 279 |
| 280 return setSelectionRange(start, end, direction); | 280 return setSelectionRange(start, end, direction); |
| 281 } | 281 } |
| 282 | 282 |
| 283 static Position positionForIndex(HTMLElement* innerEditor, int index) | 283 static Position positionForIndex(HTMLElement* innerEditor, unsigned index) |
| 284 { | 284 { |
| 285 ASSERT(index >= 0); | |
| 286 if (index == 0) { | 285 if (index == 0) { |
| 287 Node* node = NodeTraversal::next(*innerEditor, innerEditor); | 286 Node* node = NodeTraversal::next(*innerEditor, innerEditor); |
| 288 if (node && node->isTextNode()) | 287 if (node && node->isTextNode()) |
| 289 return Position(node, 0); | 288 return Position(node, 0); |
| 290 return Position(innerEditor, 0); | 289 return Position(innerEditor, 0); |
| 291 } | 290 } |
| 292 int remainingCharactersToMoveForward = index; | 291 unsigned remainingCharactersToMoveForward = index; |
| 293 Node* lastBrOrText = innerEditor; | 292 Node* lastBrOrText = innerEditor; |
| 294 for (Node& node : NodeTraversal::descendantsOf(*innerEditor)) { | 293 for (Node& node : NodeTraversal::descendantsOf(*innerEditor)) { |
| 295 ASSERT(remainingCharactersToMoveForward >= 0); | 294 ASSERT(remainingCharactersToMoveForward >= 0); |
| 296 if (node.hasTagName(brTag)) { | 295 if (node.hasTagName(brTag)) { |
| 297 if (remainingCharactersToMoveForward == 0) | 296 if (remainingCharactersToMoveForward == 0) |
| 298 return positionBeforeNode(&node); | 297 return positionBeforeNode(&node); |
| 299 --remainingCharactersToMoveForward; | 298 --remainingCharactersToMoveForward; |
| 300 lastBrOrText = &node; | 299 lastBrOrText = &node; |
| 301 continue; | 300 continue; |
| 302 } | 301 } |
| 303 | 302 |
| 304 if (node.isTextNode()) { | 303 if (node.isTextNode()) { |
| 305 Text& text = toText(node); | 304 Text& text = toText(node); |
| 306 if (remainingCharactersToMoveForward < static_cast<int>(text.length(
))) | 305 if (remainingCharactersToMoveForward < text.length()) |
| 307 return Position(&text, remainingCharactersToMoveForward); | 306 return Position(&text, remainingCharactersToMoveForward); |
| 308 remainingCharactersToMoveForward -= text.length(); | 307 remainingCharactersToMoveForward -= text.length(); |
| 309 lastBrOrText = &node; | 308 lastBrOrText = &node; |
| 310 continue; | 309 continue; |
| 311 } | 310 } |
| 312 | 311 |
| 313 ASSERT_NOT_REACHED(); | 312 ASSERT_NOT_REACHED(); |
| 314 } | 313 } |
| 315 return lastPositionInOrAfterNode(lastBrOrText); | 314 return lastPositionInOrAfterNode(lastBrOrText); |
| 316 } | 315 } |
| 317 | 316 |
| 318 static int indexForPosition(HTMLElement* innerEditor, const Position& passedPosi
tion) | 317 static unsigned indexForPosition(HTMLElement* innerEditor, const Position& passe
dPosition) |
| 319 { | 318 { |
| 320 if (!innerEditor || !innerEditor->contains(passedPosition.anchorNode()) || p
assedPosition.isNull()) | 319 if (!innerEditor || !innerEditor->contains(passedPosition.anchorNode()) || p
assedPosition.isNull()) |
| 321 return 0; | 320 return 0; |
| 322 | 321 |
| 323 if (positionBeforeNode(innerEditor) == passedPosition) | 322 if (positionBeforeNode(innerEditor) == passedPosition) |
| 324 return 0; | 323 return 0; |
| 325 | 324 |
| 326 int index = 0; | 325 unsigned index = 0; |
| 326 int offset = passedPosition.offsetInContainerNode(); |
| 327 ASSERT(offset >= 0); |
| 327 Node* startNode = passedPosition.computeNodeBeforePosition(); | 328 Node* startNode = passedPosition.computeNodeBeforePosition(); |
| 328 if (!startNode) | 329 if (!startNode) |
| 329 startNode = passedPosition.computeContainerNode(); | 330 startNode = passedPosition.computeContainerNode(); |
| 330 ASSERT(startNode); | 331 ASSERT(startNode); |
| 331 ASSERT(innerEditor->contains(startNode)); | 332 ASSERT(innerEditor->contains(startNode)); |
| 332 | 333 |
| 333 for (Node* node = startNode; node; node = NodeTraversal::previous(*node, inn
erEditor)) { | 334 for (Node* node = startNode; node; node = NodeTraversal::previous(*node, inn
erEditor)) { |
| 334 if (node->isTextNode()) { | 335 if (node->isTextNode()) { |
| 335 int length = toText(*node).length(); | 336 unsigned length = toText(*node).length(); |
| 336 if (node == passedPosition.computeContainerNode()) | 337 if (node == passedPosition.computeContainerNode()) |
| 337 index += std::min(length, passedPosition.offsetInContainerNode()
); | 338 index += std::min<unsigned>(length, offset); |
| 338 else | 339 else |
| 339 index += length; | 340 index += length; |
| 340 } else if (node->hasTagName(brTag)) { | 341 } else if (node->hasTagName(brTag)) { |
| 341 ++index; | 342 ++index; |
| 342 } | 343 } |
| 343 } | 344 } |
| 344 | 345 |
| 345 ASSERT(index >= 0); | |
| 346 return index; | 346 return index; |
| 347 } | 347 } |
| 348 | 348 |
| 349 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction, NeedToDispatchSelectEvent eventBehaviour, Selectio
nOption selectionOption) | 349 void HTMLTextFormControlElement::setSelectionRange(unsigned start, unsigned end,
TextFieldSelectionDirection direction, NeedToDispatchSelectEvent eventBehaviour
, SelectionOption selectionOption) |
| 350 { | 350 { |
| 351 if (openShadowRoot() || !isTextFormControl() || !inDocument()) | 351 if (openShadowRoot() || !isTextFormControl() || !inDocument()) |
| 352 return; | 352 return; |
| 353 | 353 |
| 354 const int editorValueLength = static_cast<int>(innerEditorValue().length()); | 354 const unsigned editorValueLength = innerEditorValue().length(); |
| 355 ASSERT(editorValueLength >= 0); | 355 end = std::min<unsigned>(end, editorValueLength); |
| 356 end = std::max(std::min(end, editorValueLength), 0); | 356 start = std::min<unsigned>(start, end); |
| 357 start = std::min(std::max(start, 0), end); | |
| 358 cacheSelection(start, end, direction); | 357 cacheSelection(start, end, direction); |
| 359 | 358 |
| 360 if (selectionOption == NotChangeSelection || (selectionOption == ChangeSelec
tionIfFocused && document().focusedElement() != this)) { | 359 if (selectionOption == NotChangeSelection || (selectionOption == ChangeSelec
tionIfFocused && document().focusedElement() != this)) { |
| 361 if (eventBehaviour == DispatchSelectEvent) | 360 if (eventBehaviour == DispatchSelectEvent) |
| 362 scheduleSelectEvent(); | 361 scheduleSelectEvent(); |
| 363 return; | 362 return; |
| 364 } | 363 } |
| 365 | 364 |
| 366 LocalFrame* frame = document().frame(); | 365 LocalFrame* frame = document().frame(); |
| 367 HTMLElement* innerEditor = innerEditorElement(); | 366 HTMLElement* innerEditor = innerEditorElement(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 Position indexPosition = pos.deepEquivalent().parentAnchoredEquivalent(); | 409 Position indexPosition = pos.deepEquivalent().parentAnchoredEquivalent(); |
| 411 if (enclosingTextFormControl(indexPosition) != this) | 410 if (enclosingTextFormControl(indexPosition) != this) |
| 412 return 0; | 411 return 0; |
| 413 ASSERT(indexPosition.document()); | 412 ASSERT(indexPosition.document()); |
| 414 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document()); | 413 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document()); |
| 415 range->setStart(innerEditorElement(), 0, ASSERT_NO_EXCEPTION); | 414 range->setStart(innerEditorElement(), 0, ASSERT_NO_EXCEPTION); |
| 416 range->setEnd(indexPosition.computeContainerNode(), indexPosition.offsetInCo
ntainerNode(), ASSERT_NO_EXCEPTION); | 415 range->setEnd(indexPosition.computeContainerNode(), indexPosition.offsetInCo
ntainerNode(), ASSERT_NO_EXCEPTION); |
| 417 return TextIterator::rangeLength(range->startPosition(), range->endPosition(
)); | 416 return TextIterator::rangeLength(range->startPosition(), range->endPosition(
)); |
| 418 } | 417 } |
| 419 | 418 |
| 420 int HTMLTextFormControlElement::selectionStart() const | 419 unsigned HTMLTextFormControlElement::selectionStart() const |
| 421 { | 420 { |
| 422 if (!isTextFormControl()) | 421 if (!isTextFormControl()) |
| 423 return 0; | 422 return 0; |
| 424 if (document().focusedElement() != this) | 423 if (document().focusedElement() != this) |
| 425 return m_cachedSelectionStart; | 424 return m_cachedSelectionStart; |
| 426 | 425 |
| 427 return computeSelectionStart(); | 426 return computeSelectionStart(); |
| 428 } | 427 } |
| 429 | 428 |
| 430 int HTMLTextFormControlElement::computeSelectionStart() const | 429 unsigned HTMLTextFormControlElement::computeSelectionStart() const |
| 431 { | 430 { |
| 432 ASSERT(isTextFormControl()); | 431 ASSERT(isTextFormControl()); |
| 433 LocalFrame* frame = document().frame(); | 432 LocalFrame* frame = document().frame(); |
| 434 if (!frame) | 433 if (!frame) |
| 435 return 0; | 434 return 0; |
| 436 | 435 |
| 437 return indexForPosition(innerEditorElement(), frame->selection().start()); | 436 return indexForPosition(innerEditorElement(), frame->selection().start()); |
| 438 } | 437 } |
| 439 | 438 |
| 440 int HTMLTextFormControlElement::selectionEnd() const | 439 unsigned HTMLTextFormControlElement::selectionEnd() const |
| 441 { | 440 { |
| 442 if (!isTextFormControl()) | 441 if (!isTextFormControl()) |
| 443 return 0; | 442 return 0; |
| 444 if (document().focusedElement() != this) | 443 if (document().focusedElement() != this) |
| 445 return m_cachedSelectionEnd; | 444 return m_cachedSelectionEnd; |
| 446 return computeSelectionEnd(); | 445 return computeSelectionEnd(); |
| 447 } | 446 } |
| 448 | 447 |
| 449 int HTMLTextFormControlElement::computeSelectionEnd() const | 448 unsigned HTMLTextFormControlElement::computeSelectionEnd() const |
| 450 { | 449 { |
| 451 ASSERT(isTextFormControl()); | 450 ASSERT(isTextFormControl()); |
| 452 LocalFrame* frame = document().frame(); | 451 LocalFrame* frame = document().frame(); |
| 453 if (!frame) | 452 if (!frame) |
| 454 return 0; | 453 return 0; |
| 455 | 454 |
| 456 return indexForPosition(innerEditorElement(), frame->selection().end()); | 455 return indexForPosition(innerEditorElement(), frame->selection().end()); |
| 457 } | 456 } |
| 458 | 457 |
| 459 static const AtomicString& directionString(TextFieldSelectionDirection direction
) | 458 static const AtomicString& directionString(TextFieldSelectionDirection direction
) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 489 { | 488 { |
| 490 ASSERT(isTextFormControl()); | 489 ASSERT(isTextFormControl()); |
| 491 LocalFrame* frame = document().frame(); | 490 LocalFrame* frame = document().frame(); |
| 492 if (!frame) | 491 if (!frame) |
| 493 return SelectionHasNoDirection; | 492 return SelectionHasNoDirection; |
| 494 | 493 |
| 495 const VisibleSelection& selection = frame->selection().selection(); | 494 const VisibleSelection& selection = frame->selection().selection(); |
| 496 return selection.isDirectional() ? (selection.isBaseFirst() ? SelectionHasFo
rwardDirection : SelectionHasBackwardDirection) : SelectionHasNoDirection; | 495 return selection.isDirectional() ? (selection.isBaseFirst() ? SelectionHasFo
rwardDirection : SelectionHasBackwardDirection) : SelectionHasNoDirection; |
| 497 } | 496 } |
| 498 | 497 |
| 499 static inline void setContainerAndOffsetForRange(Node* node, int offset, Node*&
containerNode, int& offsetInContainer) | 498 static inline void setContainerAndOffsetForRange(Node* node, unsigned offset, No
de*& containerNode, unsigned& offsetInContainer) |
| 500 { | 499 { |
| 501 if (node->isTextNode()) { | 500 if (node->isTextNode()) { |
| 502 containerNode = node; | 501 containerNode = node; |
| 503 offsetInContainer = offset; | 502 offsetInContainer = offset; |
| 504 } else { | 503 } else { |
| 505 containerNode = node->parentNode(); | 504 containerNode = node->parentNode(); |
| 506 offsetInContainer = node->nodeIndex() + offset; | 505 offsetInContainer = node->nodeIndex() + offset; |
| 507 } | 506 } |
| 508 } | 507 } |
| 509 | 508 |
| 510 PassRefPtrWillBeRawPtr<Range> HTMLTextFormControlElement::selection() const | 509 PassRefPtrWillBeRawPtr<Range> HTMLTextFormControlElement::selection() const |
| 511 { | 510 { |
| 512 if (!layoutObject() || !isTextFormControl()) | 511 if (!layoutObject() || !isTextFormControl()) |
| 513 return nullptr; | 512 return nullptr; |
| 514 | 513 |
| 515 int start = m_cachedSelectionStart; | 514 unsigned start = m_cachedSelectionStart; |
| 516 int end = m_cachedSelectionEnd; | 515 unsigned end = m_cachedSelectionEnd; |
| 517 | 516 |
| 518 ASSERT(start <= end); | 517 ASSERT(start <= end); |
| 519 HTMLElement* innerText = innerEditorElement(); | 518 HTMLElement* innerText = innerEditorElement(); |
| 520 if (!innerText) | 519 if (!innerText) |
| 521 return nullptr; | 520 return nullptr; |
| 522 | 521 |
| 523 if (!innerText->hasChildren()) | 522 if (!innerText->hasChildren()) |
| 524 return Range::create(document(), innerText, 0, innerText, 0); | 523 return Range::create(document(), innerText, 0, innerText, 0); |
| 525 | 524 |
| 526 int offset = 0; | 525 unsigned offset = 0; |
| 527 Node* startNode = 0; | 526 Node* startNode = 0; |
| 528 Node* endNode = 0; | 527 Node* endNode = 0; |
| 529 for (Node& node : NodeTraversal::descendantsOf(*innerText)) { | 528 for (Node& node : NodeTraversal::descendantsOf(*innerText)) { |
| 530 ASSERT(!node.hasChildren()); | 529 ASSERT(!node.hasChildren()); |
| 531 ASSERT(node.isTextNode() || isHTMLBRElement(node)); | 530 ASSERT(node.isTextNode() || isHTMLBRElement(node)); |
| 532 int length = node.isTextNode() ? lastOffsetInNode(&node) : 1; | 531 int length = node.isTextNode() ? lastOffsetInNode(&node) : 1; |
| 533 | 532 |
| 534 if (offset <= start && start <= offset + length) | 533 if (offset <= start && start <= offset + length) |
| 535 setContainerAndOffsetForRange(&node, start - offset, startNode, star
t); | 534 setContainerAndOffsetForRange(&node, start - offset, startNode, star
t); |
| 536 | 535 |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 } | 1002 } |
| 1004 | 1003 |
| 1005 void HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(const Ele
ment& source) | 1004 void HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(const Ele
ment& source) |
| 1006 { | 1005 { |
| 1007 const HTMLTextFormControlElement& sourceElement = static_cast<const HTMLText
FormControlElement&>(source); | 1006 const HTMLTextFormControlElement& sourceElement = static_cast<const HTMLText
FormControlElement&>(source); |
| 1008 m_lastChangeWasUserEdit = sourceElement.m_lastChangeWasUserEdit; | 1007 m_lastChangeWasUserEdit = sourceElement.m_lastChangeWasUserEdit; |
| 1009 HTMLFormControlElement::copyNonAttributePropertiesFromElement(source); | 1008 HTMLFormControlElement::copyNonAttributePropertiesFromElement(source); |
| 1010 } | 1009 } |
| 1011 | 1010 |
| 1012 } // namespace blink | 1011 } // namespace blink |
| OLD | NEW |