Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(454)

Side by Side Diff: Source/core/html/HTMLTextFormControlElement.cpp

Issue 258063005: Blink does not respect input.selectionStart and input.selectionEnd for some cases (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Addressing changes asked in patch set 5 Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698