| 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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 setSelectionRangeForBinding(std::min(end, selectionStart()), end, selectionD
irection()); | 182 setSelectionRangeForBinding(std::min(end, selectionStart()), end, selectionD
irection()); |
| 183 } | 183 } |
| 184 | 184 |
| 185 void HTMLTextFormControlElement::setSelectionDirection(const String& direction) | 185 void HTMLTextFormControlElement::setSelectionDirection(const String& direction) |
| 186 { | 186 { |
| 187 setSelectionRangeForBinding(selectionStart(), selectionEnd(), direction); | 187 setSelectionRangeForBinding(selectionStart(), selectionEnd(), direction); |
| 188 } | 188 } |
| 189 | 189 |
| 190 void HTMLTextFormControlElement::select() | 190 void HTMLTextFormControlElement::select() |
| 191 { | 191 { |
| 192 setSelectionRange(0, std::numeric_limits<int>::max(), SelectionHasNoDirectio
n, DispatchSelectEvent); | 192 setSelectionRangeForBinding(0, std::numeric_limits<int>::max()); |
| 193 focus(); | 193 focus(); |
| 194 } | 194 } |
| 195 | 195 |
| 196 bool HTMLTextFormControlElement::shouldDispatchFormControlChangeEvent(String& ol
dValue, String& newValue) | 196 bool HTMLTextFormControlElement::shouldDispatchFormControlChangeEvent(String& ol
dValue, String& newValue) |
| 197 { | 197 { |
| 198 return !equalIgnoringNullity(oldValue, newValue); | 198 return !equalIgnoringNullity(oldValue, newValue); |
| 199 } | 199 } |
| 200 | 200 |
| 201 void HTMLTextFormControlElement::dispatchFormControlChangeEvent() | 201 void HTMLTextFormControlElement::dispatchFormControlChangeEvent() |
| 202 { | 202 { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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) |
| 260 newSelectionEnd = start + replacementLength; | 260 newSelectionEnd = start + replacementLength; |
| 261 } | 261 } |
| 262 | 262 |
| 263 setSelectionRange(newSelectionStart, newSelectionEnd, SelectionHasNoDirectio
n); | 263 setSelectionRangeForBinding(newSelectionStart, newSelectionEnd); |
| 264 } | 264 } |
| 265 | 265 |
| 266 void HTMLTextFormControlElement::setSelectionRangeForBinding(int start, int end,
const String& directionString) | 266 void HTMLTextFormControlElement::setSelectionRangeForBinding(int start, int end,
const String& directionString) |
| 267 { | 267 { |
| 268 TextFieldSelectionDirection direction = SelectionHasNoDirection; | 268 TextFieldSelectionDirection direction = SelectionHasNoDirection; |
| 269 if (directionString == "forward") | 269 if (directionString == "forward") |
| 270 direction = SelectionHasForwardDirection; | 270 direction = SelectionHasForwardDirection; |
| 271 else if (directionString == "backward") | 271 else if (directionString == "backward") |
| 272 direction = SelectionHasBackwardDirection; | 272 direction = SelectionHasBackwardDirection; |
| 273 setSelectionRange(start, end, direction); | 273 if (setSelectionRange(start, end, direction)) |
| 274 scheduleSelectEvent(); |
| 274 } | 275 } |
| 275 | 276 |
| 276 static Position positionForIndex(HTMLElement* innerEditor, int index) | 277 static Position positionForIndex(HTMLElement* innerEditor, int index) |
| 277 { | 278 { |
| 278 DCHECK_GE(index, 0); | 279 DCHECK_GE(index, 0); |
| 279 if (index == 0) { | 280 if (index == 0) { |
| 280 Node* node = NodeTraversal::next(*innerEditor, innerEditor); | 281 Node* node = NodeTraversal::next(*innerEditor, innerEditor); |
| 281 if (node && node->isTextNode()) | 282 if (node && node->isTextNode()) |
| 282 return Position(node, 0); | 283 return Position(node, 0); |
| 283 return Position(innerEditor, 0); | 284 return Position(innerEditor, 0); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 index += length; | 333 index += length; |
| 333 } else if (node->hasTagName(brTag)) { | 334 } else if (node->hasTagName(brTag)) { |
| 334 ++index; | 335 ++index; |
| 335 } | 336 } |
| 336 } | 337 } |
| 337 | 338 |
| 338 DCHECK_GE(index, 0); | 339 DCHECK_GE(index, 0); |
| 339 return index; | 340 return index; |
| 340 } | 341 } |
| 341 | 342 |
| 342 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction, NeedToDispatchSelectEvent eventBehaviour) | 343 bool HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) |
| 343 { | 344 { |
| 344 if (openShadowRoot() || !isTextFormControl()) | 345 if (openShadowRoot() || !isTextFormControl()) |
| 345 return; | 346 return false; |
| 346 const int editorValueLength = static_cast<int>(innerEditorValue().length()); | 347 const int editorValueLength = static_cast<int>(innerEditorValue().length()); |
| 347 DCHECK_GE(editorValueLength, 0); | 348 DCHECK_GE(editorValueLength, 0); |
| 348 end = std::max(std::min(end, editorValueLength), 0); | 349 end = std::max(std::min(end, editorValueLength), 0); |
| 349 start = std::min(std::max(start, 0), end); | 350 start = std::min(std::max(start, 0), end); |
| 350 LocalFrame* frame = document().frame(); | 351 LocalFrame* frame = document().frame(); |
| 351 if (direction == SelectionHasNoDirection && frame && frame->editor().behavio
r().shouldConsiderSelectionAsDirectional()) | 352 if (direction == SelectionHasNoDirection && frame && frame->editor().behavio
r().shouldConsiderSelectionAsDirectional()) |
| 352 direction = SelectionHasForwardDirection; | 353 direction = SelectionHasForwardDirection; |
| 353 cacheSelection(start, end, direction); | 354 cacheSelection(start, end, direction); |
| 354 | 355 |
| 355 if (document().focusedElement() != this) { | 356 if (document().focusedElement() != this) |
| 356 if (eventBehaviour == DispatchSelectEvent) | 357 return true; |
| 357 scheduleSelectEvent(); | |
| 358 return; | |
| 359 } | |
| 360 | 358 |
| 361 HTMLElement* innerEditor = innerEditorElement(); | 359 HTMLElement* innerEditor = innerEditorElement(); |
| 362 if (!frame || !innerEditor) | 360 if (!frame || !innerEditor) |
| 363 return; | 361 return true; |
| 364 | 362 |
| 365 Position startPosition = positionForIndex(innerEditor, start); | 363 Position startPosition = positionForIndex(innerEditor, start); |
| 366 Position endPosition = start == end ? startPosition : positionForIndex(inner
Editor, end); | 364 Position endPosition = start == end ? startPosition : positionForIndex(inner
Editor, end); |
| 367 | 365 |
| 368 DCHECK_EQ(start, indexForPosition(innerEditor, startPosition)); | 366 DCHECK_EQ(start, indexForPosition(innerEditor, startPosition)); |
| 369 DCHECK_EQ(end, indexForPosition(innerEditor, endPosition)); | 367 DCHECK_EQ(end, indexForPosition(innerEditor, endPosition)); |
| 370 | 368 |
| 371 #if DCHECK_IS_ON() | 369 #if DCHECK_IS_ON() |
| 372 // startPosition and endPosition can be null position for example when | 370 // startPosition and endPosition can be null position for example when |
| 373 // "-webkit-user-select: none" style attribute is specified. | 371 // "-webkit-user-select: none" style attribute is specified. |
| 374 if (startPosition.isNotNull() && endPosition.isNotNull()) { | 372 if (startPosition.isNotNull() && endPosition.isNotNull()) { |
| 375 DCHECK_EQ(startPosition.anchorNode()->shadowHost(), this); | 373 DCHECK_EQ(startPosition.anchorNode()->shadowHost(), this); |
| 376 DCHECK_EQ(endPosition.anchorNode()->shadowHost(), this); | 374 DCHECK_EQ(endPosition.anchorNode()->shadowHost(), this); |
| 377 } | 375 } |
| 378 #endif // DCHECK_IS_ON() | 376 #endif // DCHECK_IS_ON() |
| 379 VisibleSelection newSelection; | 377 VisibleSelection newSelection; |
| 380 if (direction == SelectionHasBackwardDirection) | 378 if (direction == SelectionHasBackwardDirection) |
| 381 newSelection.setWithoutValidation(endPosition, startPosition); | 379 newSelection.setWithoutValidation(endPosition, startPosition); |
| 382 else | 380 else |
| 383 newSelection.setWithoutValidation(startPosition, endPosition); | 381 newSelection.setWithoutValidation(startPosition, endPosition); |
| 384 newSelection.setIsDirectional(direction != SelectionHasNoDirection); | 382 newSelection.setIsDirectional(direction != SelectionHasNoDirection); |
| 385 | 383 |
| 386 frame->selection().setSelection(newSelection, FrameSelection::DoNotAdjustInF
latTree | FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | Frame
Selection::DoNotSetFocus); | 384 frame->selection().setSelection(newSelection, FrameSelection::DoNotAdjustInF
latTree | FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle | Frame
Selection::DoNotSetFocus); |
| 387 if (eventBehaviour == DispatchSelectEvent) | 385 return true; |
| 388 scheduleSelectEvent(); | |
| 389 } | 386 } |
| 390 | 387 |
| 391 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c
onst | 388 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c
onst |
| 392 { | 389 { |
| 393 if (index <= 0) | 390 if (index <= 0) |
| 394 return VisiblePosition::firstPositionInNode(innerEditorElement()); | 391 return VisiblePosition::firstPositionInNode(innerEditorElement()); |
| 395 Position start, end; | 392 Position start, end; |
| 396 bool selected = Range::selectNodeContents(innerEditorElement(), start, end); | 393 bool selected = Range::selectNodeContents(innerEditorElement(), start, end); |
| 397 if (!selected) | 394 if (!selected) |
| 398 return VisiblePosition(); | 395 return VisiblePosition(); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 return defaultAutocapitalize(); | 558 return defaultAutocapitalize(); |
| 562 } | 559 } |
| 563 | 560 |
| 564 void HTMLTextFormControlElement::setAutocapitalize(const AtomicString& autocapit
alize) | 561 void HTMLTextFormControlElement::setAutocapitalize(const AtomicString& autocapit
alize) |
| 565 { | 562 { |
| 566 setAttribute(autocapitalizeAttr, autocapitalize); | 563 setAttribute(autocapitalizeAttr, autocapitalize); |
| 567 } | 564 } |
| 568 | 565 |
| 569 void HTMLTextFormControlElement::restoreCachedSelection() | 566 void HTMLTextFormControlElement::restoreCachedSelection() |
| 570 { | 567 { |
| 571 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele
ctionDirection, DispatchSelectEvent); | 568 if (setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cached
SelectionDirection)) |
| 569 scheduleSelectEvent(); |
| 572 } | 570 } |
| 573 | 571 |
| 574 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) | 572 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) |
| 575 { | 573 { |
| 576 if (!layoutObject() || !isTextFormControl()) | 574 if (!layoutObject() || !isTextFormControl()) |
| 577 return; | 575 return; |
| 578 | 576 |
| 579 // selectionStart() or selectionEnd() will return cached selection when this
node doesn't have focus | 577 // selectionStart() or selectionEnd() will return cached selection when this
node doesn't have focus |
| 580 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelect
ionDirection()); | 578 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelect
ionDirection()); |
| 581 | 579 |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 } | 1019 } |
| 1022 | 1020 |
| 1023 void HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(const Ele
ment& source) | 1021 void HTMLTextFormControlElement::copyNonAttributePropertiesFromElement(const Ele
ment& source) |
| 1024 { | 1022 { |
| 1025 const HTMLTextFormControlElement& sourceElement = static_cast<const HTMLText
FormControlElement&>(source); | 1023 const HTMLTextFormControlElement& sourceElement = static_cast<const HTMLText
FormControlElement&>(source); |
| 1026 m_lastChangeWasUserEdit = sourceElement.m_lastChangeWasUserEdit; | 1024 m_lastChangeWasUserEdit = sourceElement.m_lastChangeWasUserEdit; |
| 1027 HTMLFormControlElement::copyNonAttributePropertiesFromElement(source); | 1025 HTMLFormControlElement::copyNonAttributePropertiesFromElement(source); |
| 1028 } | 1026 } |
| 1029 | 1027 |
| 1030 } // namespace blink | 1028 } // namespace blink |
| OLD | NEW |