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 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 if (!placeholderElement() || placeholderValueChanged) | 157 if (!placeholderElement() || placeholderValueChanged) |
158 updatePlaceholderText(); | 158 updatePlaceholderText(); |
159 HTMLElement* placeholder = placeholderElement(); | 159 HTMLElement* placeholder = placeholderElement(); |
160 if (!placeholder) | 160 if (!placeholder) |
161 return; | 161 return; |
162 placeholder->setInlineStyleProperty(CSSPropertyVisibility, placeholderShould
BeVisible() ? CSSValueVisible : CSSValueHidden); | 162 placeholder->setInlineStyleProperty(CSSPropertyVisibility, placeholderShould
BeVisible() ? CSSValueVisible : CSSValueHidden); |
163 } | 163 } |
164 | 164 |
165 void HTMLTextFormControlElement::setSelectionStart(int start) | 165 void HTMLTextFormControlElement::setSelectionStart(int start) |
166 { | 166 { |
167 setSelectionRange(start, max(start, selectionEnd()), selectionDirection()); | 167 setSelectionRange(start, max(start, selectionEndForJavascriptBindings()), se
lectionDirection()); |
168 } | 168 } |
169 | 169 |
170 void HTMLTextFormControlElement::setSelectionEnd(int end) | 170 void HTMLTextFormControlElement::setSelectionEnd(int end) |
171 { | 171 { |
172 setSelectionRange(min(end, selectionStart()), end, selectionDirection()); | 172 setSelectionRange(min(end, selectionStartForJavascriptBindings()), end, sele
ctionDirection()); |
173 } | 173 } |
174 | 174 |
175 void HTMLTextFormControlElement::setSelectionDirection(const String& direction) | 175 void HTMLTextFormControlElement::setSelectionDirection(const String& direction) |
176 { | 176 { |
177 setSelectionRange(selectionStart(), selectionEnd(), direction); | 177 setSelectionRange(selectionStart(), selectionEnd(), direction); |
178 } | 178 } |
179 | 179 |
180 void HTMLTextFormControlElement::select() | 180 void HTMLTextFormControlElement::select() |
181 { | 181 { |
182 setSelectionRange(0, numeric_limits<int>::max(), SelectionHasNoDirection); | 182 setSelectionRange(0, numeric_limits<int>::max(), SelectionHasNoDirection); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 | 278 |
279 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) | 279 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField
SelectionDirection direction) |
280 { | 280 { |
281 document().updateLayoutIgnorePendingStylesheets(); | 281 document().updateLayoutIgnorePendingStylesheets(); |
282 | 282 |
283 if (!renderer() || !renderer()->isTextControl()) | 283 if (!renderer() || !renderer()->isTextControl()) |
284 return; | 284 return; |
285 | 285 |
286 end = max(end, 0); | 286 end = max(end, 0); |
287 start = min(max(start, 0), end); | 287 start = min(max(start, 0), end); |
| 288 int textLength = innerTextValue().length(); |
| 289 if (textLength) { |
| 290 if (textLength < start) { |
| 291 start = textLength; |
| 292 end = textLength; |
| 293 } else if (textLength >= start && textLength < end) { |
| 294 end = textLength; |
| 295 } |
| 296 } |
| 297 cacheSelection(start, end, direction); |
288 | 298 |
289 if (!hasVisibleTextArea(renderer(), innerTextElement())) { | 299 if (!hasVisibleTextArea(renderer(), innerTextElement())) |
290 cacheSelection(start, end, direction); | |
291 return; | 300 return; |
292 } | |
293 VisiblePosition startPosition = visiblePositionForIndex(start); | 301 VisiblePosition startPosition = visiblePositionForIndex(start); |
294 VisiblePosition endPosition; | 302 VisiblePosition endPosition; |
295 if (start == end) | 303 if (start == end) |
296 endPosition = startPosition; | 304 endPosition = startPosition; |
297 else | 305 else |
298 endPosition = visiblePositionForIndex(end); | 306 endPosition = visiblePositionForIndex(end); |
299 | 307 |
300 // startPosition and endPosition can be null position for example when | 308 // startPosition and endPosition can be null position for example when |
301 // "-webkit-user-select: none" style attribute is specified. | 309 // "-webkit-user-select: none" style attribute is specified. |
302 if (startPosition.isNotNull() && endPosition.isNotNull()) { | 310 if (startPosition.isNotNull() && endPosition.isNotNull()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document()); | 342 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document()); |
335 range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION); | 343 range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION); |
336 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer
Node(), ASSERT_NO_EXCEPTION); | 344 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer
Node(), ASSERT_NO_EXCEPTION); |
337 return TextIterator::rangeLength(range.get()); | 345 return TextIterator::rangeLength(range.get()); |
338 } | 346 } |
339 | 347 |
340 int HTMLTextFormControlElement::selectionStart() const | 348 int HTMLTextFormControlElement::selectionStart() const |
341 { | 349 { |
342 if (!isTextFormControl()) | 350 if (!isTextFormControl()) |
343 return 0; | 351 return 0; |
| 352 if (document().focusedElement() != this) { |
| 353 if (!innerTextValue().length()) |
| 354 return 0; |
| 355 return m_cachedSelectionStart; |
| 356 } |
| 357 |
| 358 return computeSelectionStart(); |
| 359 } |
| 360 |
| 361 int HTMLTextFormControlElement::selectionStartForJavascriptBindings() const |
| 362 { |
| 363 if (!isTextFormControl()) |
| 364 return 0; |
344 if (document().focusedElement() != this) | 365 if (document().focusedElement() != this) |
345 return m_cachedSelectionStart; | 366 return m_cachedSelectionStart; |
346 | 367 |
347 return computeSelectionStart(); | 368 return computeSelectionStart(); |
348 } | 369 } |
349 | 370 |
350 int HTMLTextFormControlElement::computeSelectionStart() const | 371 int HTMLTextFormControlElement::computeSelectionStart() const |
351 { | 372 { |
352 ASSERT(isTextFormControl()); | 373 ASSERT(isTextFormControl()); |
353 LocalFrame* frame = document().frame(); | 374 LocalFrame* frame = document().frame(); |
354 if (!frame) | 375 if (!frame) |
355 return 0; | 376 return 0; |
356 | 377 |
357 return indexForVisiblePosition(VisiblePosition(frame->selection().start())); | 378 return indexForVisiblePosition(VisiblePosition(frame->selection().start())); |
358 } | 379 } |
359 | 380 |
360 int HTMLTextFormControlElement::selectionEnd() const | 381 int HTMLTextFormControlElement::selectionEnd() const |
361 { | 382 { |
362 if (!isTextFormControl()) | 383 if (!isTextFormControl()) |
363 return 0; | 384 return 0; |
| 385 if (document().focusedElement() != this) { |
| 386 if (!innerTextValue().length()) |
| 387 return 0; |
| 388 return m_cachedSelectionEnd; |
| 389 } |
| 390 return computeSelectionEnd(); |
| 391 } |
| 392 |
| 393 int HTMLTextFormControlElement::selectionEndForJavascriptBindings() const |
| 394 { |
| 395 if (!isTextFormControl()) |
| 396 return 0; |
364 if (document().focusedElement() != this) | 397 if (document().focusedElement() != this) |
365 return m_cachedSelectionEnd; | 398 return m_cachedSelectionEnd; |
| 399 |
366 return computeSelectionEnd(); | 400 return computeSelectionEnd(); |
367 } | 401 } |
368 | 402 |
369 int HTMLTextFormControlElement::computeSelectionEnd() const | 403 int HTMLTextFormControlElement::computeSelectionEnd() const |
370 { | 404 { |
371 ASSERT(isTextFormControl()); | 405 ASSERT(isTextFormControl()); |
372 LocalFrame* frame = document().frame(); | 406 LocalFrame* frame = document().frame(); |
373 if (!frame) | 407 if (!frame) |
374 return 0; | 408 return 0; |
375 | 409 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 void HTMLTextFormControlElement::restoreCachedSelection() | 505 void HTMLTextFormControlElement::restoreCachedSelection() |
472 { | 506 { |
473 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele
ctionDirection); | 507 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele
ctionDirection); |
474 } | 508 } |
475 | 509 |
476 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) | 510 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) |
477 { | 511 { |
478 if (!renderer() || !isTextFormControl()) | 512 if (!renderer() || !isTextFormControl()) |
479 return; | 513 return; |
480 | 514 |
481 // selectionStart() or selectionEnd() will return cached selection when this
node doesn't have focus | |
482 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelect
ionDirection()); | |
483 | |
484 if (LocalFrame* frame = document().frame()) { | 515 if (LocalFrame* frame = document().frame()) { |
485 if (frame->selection().isRange() && userTriggered) | 516 if (frame->selection().isRange() && userTriggered) |
486 dispatchEvent(Event::createBubble(EventTypeNames::select)); | 517 dispatchEvent(Event::createBubble(EventTypeNames::select)); |
487 } | 518 } |
488 } | 519 } |
489 | 520 |
490 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const
AtomicString& value) | 521 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const
AtomicString& value) |
491 { | 522 { |
492 if (name == placeholderAttr) { | 523 if (name == placeholderAttr) { |
493 updatePlaceholderVisibility(true); | 524 updatePlaceholderVisibility(true); |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 | 682 |
652 return "ltr"; | 683 return "ltr"; |
653 } | 684 } |
654 | 685 |
655 HTMLElement* HTMLTextFormControlElement::innerTextElement() const | 686 HTMLElement* HTMLTextFormControlElement::innerTextElement() const |
656 { | 687 { |
657 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName
s::innerEditor())); | 688 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName
s::innerEditor())); |
658 } | 689 } |
659 | 690 |
660 } // namespace Webcore | 691 } // namespace Webcore |
OLD | NEW |