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

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 the expected behavior and changes asked for LayoutTests 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 cacheSelection(start, end, direction);
288 289
289 if (!hasVisibleTextArea(renderer(), innerTextElement())) { 290 if (!hasVisibleTextArea(renderer(), innerTextElement()))
290 cacheSelection(start, end, direction);
291 return; 291 return;
292 }
293 VisiblePosition startPosition = visiblePositionForIndex(start); 292 VisiblePosition startPosition = visiblePositionForIndex(start);
294 VisiblePosition endPosition; 293 VisiblePosition endPosition;
295 if (start == end) 294 if (start == end)
296 endPosition = startPosition; 295 endPosition = startPosition;
297 else 296 else
298 endPosition = visiblePositionForIndex(end); 297 endPosition = visiblePositionForIndex(end);
299 298
300 // startPosition and endPosition can be null position for example when 299 // startPosition and endPosition can be null position for example when
301 // "-webkit-user-select: none" style attribute is specified. 300 // "-webkit-user-select: none" style attribute is specified.
302 if (startPosition.isNotNull() && endPosition.isNotNull()) { 301 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()); 333 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document());
335 range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION); 334 range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION);
336 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer Node(), ASSERT_NO_EXCEPTION); 335 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer Node(), ASSERT_NO_EXCEPTION);
337 return TextIterator::rangeLength(range.get()); 336 return TextIterator::rangeLength(range.get());
338 } 337 }
339 338
340 int HTMLTextFormControlElement::selectionStart() const 339 int HTMLTextFormControlElement::selectionStart() const
341 { 340 {
342 if (!isTextFormControl()) 341 if (!isTextFormControl())
343 return 0; 342 return 0;
343 if (document().focusedElement() != this) {
tkent 2014/05/19 00:00:34 We should not need to adjust the value on getting.
harpreet.sk 2014/05/19 11:16:52 Only for given case we need to adjust value while
344 if (!innerTextValue().length())
345 return 0;
346 return m_cachedSelectionStart;
347 }
348
349 return computeSelectionStart();
350 }
351
352 int HTMLTextFormControlElement::selectionStartForJavascriptBindings() const
353 {
354 if (!isTextFormControl())
355 return 0;
344 if (document().focusedElement() != this) 356 if (document().focusedElement() != this)
345 return m_cachedSelectionStart; 357 return m_cachedSelectionStart;
346 358
347 return computeSelectionStart(); 359 return computeSelectionStart();
348 } 360 }
349 361
350 int HTMLTextFormControlElement::computeSelectionStart() const 362 int HTMLTextFormControlElement::computeSelectionStart() const
351 { 363 {
352 ASSERT(isTextFormControl()); 364 ASSERT(isTextFormControl());
353 LocalFrame* frame = document().frame(); 365 LocalFrame* frame = document().frame();
354 if (!frame) 366 if (!frame)
355 return 0; 367 return 0;
356 368
357 return indexForVisiblePosition(VisiblePosition(frame->selection().start())); 369 return indexForVisiblePosition(VisiblePosition(frame->selection().start()));
358 } 370 }
359 371
360 int HTMLTextFormControlElement::selectionEnd() const 372 int HTMLTextFormControlElement::selectionEnd() const
361 { 373 {
362 if (!isTextFormControl()) 374 if (!isTextFormControl())
363 return 0; 375 return 0;
376 if (document().focusedElement() != this) {
377 if (!innerTextValue().length())
378 return 0;
379 return m_cachedSelectionEnd;
380 }
381 return computeSelectionEnd();
382 }
383
384 int HTMLTextFormControlElement::selectionEndForJavascriptBindings() const
385 {
386 if (!isTextFormControl())
387 return 0;
364 if (document().focusedElement() != this) 388 if (document().focusedElement() != this)
365 return m_cachedSelectionEnd; 389 return m_cachedSelectionEnd;
390
366 return computeSelectionEnd(); 391 return computeSelectionEnd();
367 } 392 }
368 393
369 int HTMLTextFormControlElement::computeSelectionEnd() const 394 int HTMLTextFormControlElement::computeSelectionEnd() const
370 { 395 {
371 ASSERT(isTextFormControl()); 396 ASSERT(isTextFormControl());
372 LocalFrame* frame = document().frame(); 397 LocalFrame* frame = document().frame();
373 if (!frame) 398 if (!frame)
374 return 0; 399 return 0;
375 400
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 void HTMLTextFormControlElement::restoreCachedSelection() 496 void HTMLTextFormControlElement::restoreCachedSelection()
472 { 497 {
473 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele ctionDirection); 498 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele ctionDirection);
474 } 499 }
475 500
476 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) 501 void HTMLTextFormControlElement::selectionChanged(bool userTriggered)
477 { 502 {
478 if (!renderer() || !isTextFormControl()) 503 if (!renderer() || !isTextFormControl())
479 return; 504 return;
480 505
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()) { 506 if (LocalFrame* frame = document().frame()) {
485 if (frame->selection().isRange() && userTriggered) 507 if (frame->selection().isRange() && userTriggered)
486 dispatchEvent(Event::createBubble(EventTypeNames::select)); 508 dispatchEvent(Event::createBubble(EventTypeNames::select));
487 } 509 }
488 } 510 }
489 511
490 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 512 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
491 { 513 {
492 if (name == placeholderAttr) { 514 if (name == placeholderAttr) {
493 updatePlaceholderVisibility(true); 515 updatePlaceholderVisibility(true);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 673
652 return "ltr"; 674 return "ltr";
653 } 675 }
654 676
655 HTMLElement* HTMLTextFormControlElement::innerTextElement() const 677 HTMLElement* HTMLTextFormControlElement::innerTextElement() const
656 { 678 {
657 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName s::innerEditor())); 679 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName s::innerEditor()));
658 } 680 }
659 681
660 } // namespace Webcore 682 } // namespace Webcore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698