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 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 return setSelectionRange(start, end, direction); | 277 return setSelectionRange(start, end, direction); |
278 } | 278 } |
279 | 279 |
280 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) | 280 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) |
281 { | 281 { |
282 document().updateLayoutIgnorePendingStylesheets(); | 282 document().updateLayoutIgnorePendingStylesheets(); |
283 | 283 |
284 if (!renderer() || !renderer()->isTextControl()) | 284 if (!renderer() || !renderer()->isTextControl()) |
285 return; | 285 return; |
286 | 286 |
287 int textLength = innerEditorValue().length(); | 287 end = std::max(end, 0); |
288 end = std::max(std::min(end, textLength), 0); | 288 start = std::min(std::max(start, 0), end); |
289 start = std::max(std::min(start, end), 0); | |
290 cacheSelection(start, end, direction); | |
291 bool isCaretSelection = start == end; | |
292 bool shouldSetSelection = document().focusedElement() == this || (!isCaretSe
lection && start < textLength); | |
293 | 289 |
294 if (!hasVisibleTextArea(renderer(), innerEditorElement())) | 290 if (!hasVisibleTextArea(renderer(), innerEditorElement())) { |
| 291 cacheSelection(start, end, direction); |
295 return; | 292 return; |
296 | 293 } |
297 LocalFrame* frame = document().frame(); | |
298 | |
299 if (!frame || !shouldSetSelection) | |
300 return; | |
301 | |
302 VisiblePosition startPosition = visiblePositionForIndex(start); | 294 VisiblePosition startPosition = visiblePositionForIndex(start); |
303 VisiblePosition endPosition; | 295 VisiblePosition endPosition; |
304 if (start == end) | 296 if (start == end) |
305 endPosition = startPosition; | 297 endPosition = startPosition; |
306 else | 298 else |
307 endPosition = visiblePositionForIndex(end); | 299 endPosition = visiblePositionForIndex(end); |
308 | 300 |
309 // startPosition and endPosition can be null position for example when | 301 // startPosition and endPosition can be null position for example when |
310 // "-webkit-user-select: none" style attribute is specified. | 302 // "-webkit-user-select: none" style attribute is specified. |
311 if (startPosition.isNotNull() && endPosition.isNotNull()) { | 303 if (startPosition.isNotNull() && endPosition.isNotNull()) { |
312 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowHost() ==
this | 304 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowHost() ==
this |
313 && endPosition.deepEquivalent().deprecatedNode()->shadowHost() == th
is); | 305 && endPosition.deepEquivalent().deprecatedNode()->shadowHost() == th
is); |
314 } | 306 } |
315 VisibleSelection newSelection; | 307 VisibleSelection newSelection; |
316 if (direction == SelectionHasBackwardDirection) | 308 if (direction == SelectionHasBackwardDirection) |
317 newSelection = VisibleSelection(endPosition, startPosition); | 309 newSelection = VisibleSelection(endPosition, startPosition); |
318 else | 310 else |
319 newSelection = VisibleSelection(startPosition, endPosition); | 311 newSelection = VisibleSelection(startPosition, endPosition); |
320 newSelection.setIsDirectional(direction != SelectionHasNoDirection); | 312 newSelection.setIsDirectional(direction != SelectionHasNoDirection); |
321 | 313 |
322 frame->selection().setSelection(newSelection); | 314 if (LocalFrame* frame = document().frame()) |
| 315 frame->selection().setSelection(newSelection); |
323 } | 316 } |
324 | 317 |
325 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c
onst | 318 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c
onst |
326 { | 319 { |
327 if (index <= 0) | 320 if (index <= 0) |
328 return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNST
REAM); | 321 return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNST
REAM); |
329 RefPtrWillBeRawPtr<Range> range = Range::create(document()); | 322 RefPtrWillBeRawPtr<Range> range = Range::create(document()); |
330 range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION); | 323 range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION); |
331 CharacterIterator it(range.get()); | 324 CharacterIterator it(range.get()); |
332 it.advance(index - 1); | 325 it.advance(index - 1); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 void HTMLTextFormControlElement::restoreCachedSelection() | 472 void HTMLTextFormControlElement::restoreCachedSelection() |
480 { | 473 { |
481 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele
ctionDirection); | 474 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele
ctionDirection); |
482 } | 475 } |
483 | 476 |
484 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) | 477 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) |
485 { | 478 { |
486 if (!renderer() || !isTextFormControl()) | 479 if (!renderer() || !isTextFormControl()) |
487 return; | 480 return; |
488 | 481 |
489 if (document().focusedElement() == this) | 482 // selectionStart() or selectionEnd() will return cached selection when this
node doesn't have focus |
490 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSe
lectionDirection()); | 483 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelect
ionDirection()); |
491 | 484 |
492 if (LocalFrame* frame = document().frame()) { | 485 if (LocalFrame* frame = document().frame()) { |
493 if (frame->selection().isRange() && userTriggered) | 486 if (frame->selection().isRange() && userTriggered) |
494 dispatchEvent(Event::createBubble(EventTypeNames::select)); | 487 dispatchEvent(Event::createBubble(EventTypeNames::select)); |
495 } | 488 } |
496 } | 489 } |
497 | 490 |
498 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const
AtomicString& value) | 491 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const
AtomicString& value) |
499 { | 492 { |
500 if (name == placeholderAttr) { | 493 if (name == placeholderAttr) { |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 Text* textNode = toText(node); | 894 Text* textNode = toText(node); |
902 size_t firstLineBreak = textNode->data().find('\n', isPivotNode ? pi
votPosition.offsetInContainerNode() : 0); | 895 size_t firstLineBreak = textNode->data().find('\n', isPivotNode ? pi
votPosition.offsetInContainerNode() : 0); |
903 if (firstLineBreak != kNotFound) | 896 if (firstLineBreak != kNotFound) |
904 return Position(textNode, firstLineBreak + 1); | 897 return Position(textNode, firstLineBreak + 1); |
905 } | 898 } |
906 } | 899 } |
907 return endOfInnerText(textFormControl); | 900 return endOfInnerText(textFormControl); |
908 } | 901 } |
909 | 902 |
910 } // namespace Webcore | 903 } // namespace Webcore |
OLD | NEW |