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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 return setSelectionRange(start, end, direction); | 275 return setSelectionRange(start, end, direction); |
276 } | 276 } |
277 | 277 |
278 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) | 278 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) |
279 { | 279 { |
280 document().updateLayoutIgnorePendingStylesheets(); | 280 document().updateLayoutIgnorePendingStylesheets(); |
281 | 281 |
282 if (!renderer() || !renderer()->isTextControl()) | 282 if (!renderer() || !renderer()->isTextControl()) |
283 return; | 283 return; |
284 | 284 |
285 int textLength = innerEditorValue().length(); | 285 end = std::max(end, 0); |
286 end = std::max(std::min(end, textLength), 0); | 286 start = std::min(std::max(start, 0), end); |
287 start = std::max(std::min(start, end), 0); | |
288 cacheSelection(start, end, direction); | |
289 bool isCaretSelection = start == end; | |
290 bool shouldSetSelection = document().focusedElement() == this || (!isCaretSe
lection && start < textLength); | |
291 | 287 |
292 if (!hasVisibleTextArea(renderer(), innerEditorElement())) | 288 if (!hasVisibleTextArea(renderer(), innerEditorElement())) { |
| 289 cacheSelection(start, end, direction); |
293 return; | 290 return; |
294 | 291 } |
295 LocalFrame* frame = document().frame(); | |
296 | |
297 if (!frame || !shouldSetSelection) | |
298 return; | |
299 | |
300 VisiblePosition startPosition = visiblePositionForIndex(start); | 292 VisiblePosition startPosition = visiblePositionForIndex(start); |
301 VisiblePosition endPosition; | 293 VisiblePosition endPosition; |
302 if (start == end) | 294 if (start == end) |
303 endPosition = startPosition; | 295 endPosition = startPosition; |
304 else | 296 else |
305 endPosition = visiblePositionForIndex(end); | 297 endPosition = visiblePositionForIndex(end); |
306 | 298 |
307 // startPosition and endPosition can be null position for example when | 299 // startPosition and endPosition can be null position for example when |
308 // "-webkit-user-select: none" style attribute is specified. | 300 // "-webkit-user-select: none" style attribute is specified. |
309 if (startPosition.isNotNull() && endPosition.isNotNull()) { | 301 if (startPosition.isNotNull() && endPosition.isNotNull()) { |
310 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowHost() ==
this | 302 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowHost() ==
this |
311 && endPosition.deepEquivalent().deprecatedNode()->shadowHost() == th
is); | 303 && endPosition.deepEquivalent().deprecatedNode()->shadowHost() == th
is); |
312 } | 304 } |
313 VisibleSelection newSelection; | 305 VisibleSelection newSelection; |
314 if (direction == SelectionHasBackwardDirection) | 306 if (direction == SelectionHasBackwardDirection) |
315 newSelection = VisibleSelection(endPosition, startPosition); | 307 newSelection = VisibleSelection(endPosition, startPosition); |
316 else | 308 else |
317 newSelection = VisibleSelection(startPosition, endPosition); | 309 newSelection = VisibleSelection(startPosition, endPosition); |
318 newSelection.setIsDirectional(direction != SelectionHasNoDirection); | 310 newSelection.setIsDirectional(direction != SelectionHasNoDirection); |
319 | 311 |
320 frame->selection().setSelection(newSelection); | 312 if (LocalFrame* frame = document().frame()) |
| 313 frame->selection().setSelection(newSelection); |
321 } | 314 } |
322 | 315 |
323 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c
onst | 316 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c
onst |
324 { | 317 { |
325 if (index <= 0) | 318 if (index <= 0) |
326 return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNST
REAM); | 319 return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNST
REAM); |
327 RefPtrWillBeRawPtr<Range> range = Range::create(document()); | 320 RefPtrWillBeRawPtr<Range> range = Range::create(document()); |
328 range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION); | 321 range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION); |
329 CharacterIterator it(range.get()); | 322 CharacterIterator it(range.get()); |
330 it.advance(index - 1); | 323 it.advance(index - 1); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 void HTMLTextFormControlElement::restoreCachedSelection() | 470 void HTMLTextFormControlElement::restoreCachedSelection() |
478 { | 471 { |
479 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele
ctionDirection); | 472 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele
ctionDirection); |
480 } | 473 } |
481 | 474 |
482 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) | 475 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) |
483 { | 476 { |
484 if (!renderer() || !isTextFormControl()) | 477 if (!renderer() || !isTextFormControl()) |
485 return; | 478 return; |
486 | 479 |
487 if (document().focusedElement() == this) | 480 // selectionStart() or selectionEnd() will return cached selection when this
node doesn't have focus |
488 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSe
lectionDirection()); | 481 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelect
ionDirection()); |
489 | 482 |
490 if (LocalFrame* frame = document().frame()) { | 483 if (LocalFrame* frame = document().frame()) { |
491 if (frame->selection().isRange() && userTriggered) | 484 if (frame->selection().isRange() && userTriggered) |
492 dispatchEvent(Event::createBubble(EventTypeNames::select)); | 485 dispatchEvent(Event::createBubble(EventTypeNames::select)); |
493 } | 486 } |
494 } | 487 } |
495 | 488 |
496 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const
AtomicString& value) | 489 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const
AtomicString& value) |
497 { | 490 { |
498 if (name == placeholderAttr) { | 491 if (name == placeholderAttr) { |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 | 653 |
661 return "ltr"; | 654 return "ltr"; |
662 } | 655 } |
663 | 656 |
664 HTMLElement* HTMLTextFormControlElement::innerEditorElement() const | 657 HTMLElement* HTMLTextFormControlElement::innerEditorElement() const |
665 { | 658 { |
666 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName
s::innerEditor())); | 659 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName
s::innerEditor())); |
667 } | 660 } |
668 | 661 |
669 } // namespace Webcore | 662 } // namespace Webcore |
OLD | NEW |