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

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 changes asked for LayoutTests in patch set 3 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 272
273 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField SelectionDirection direction) 273 void HTMLTextFormControlElement::setSelectionRange(int start, int end, TextField SelectionDirection direction)
274 { 274 {
275 document().updateLayoutIgnorePendingStylesheets(); 275 document().updateLayoutIgnorePendingStylesheets();
276 276
277 if (!renderer() || !renderer()->isTextControl()) 277 if (!renderer() || !renderer()->isTextControl())
278 return; 278 return;
279 279
280 end = max(end, 0); 280 end = max(end, 0);
281 start = min(max(start, 0), end); 281 start = min(max(start, 0), end);
282 cacheSelection(start, end, direction);
282 283
283 if (!hasVisibleTextArea(renderer(), innerTextElement())) { 284 if (!hasVisibleTextArea(renderer(), innerTextElement()))
284 cacheSelection(start, end, direction);
285 return; 285 return;
286 }
287 VisiblePosition startPosition = visiblePositionForIndex(start); 286 VisiblePosition startPosition = visiblePositionForIndex(start);
288 VisiblePosition endPosition; 287 VisiblePosition endPosition;
289 if (start == end) 288 if (start == end)
290 endPosition = startPosition; 289 endPosition = startPosition;
291 else 290 else
292 endPosition = visiblePositionForIndex(end); 291 endPosition = visiblePositionForIndex(end);
293 292
294 // startPosition and endPosition can be null position for example when 293 // startPosition and endPosition can be null position for example when
295 // "-webkit-user-select: none" style attribute is specified. 294 // "-webkit-user-select: none" style attribute is specified.
296 if (startPosition.isNotNull() && endPosition.isNotNull()) { 295 if (startPosition.isNotNull() && endPosition.isNotNull()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document()); 327 RefPtrWillBeRawPtr<Range> range = Range::create(*indexPosition.document());
329 range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION); 328 range->setStart(innerTextElement(), 0, ASSERT_NO_EXCEPTION);
330 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer Node(), ASSERT_NO_EXCEPTION); 329 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer Node(), ASSERT_NO_EXCEPTION);
331 return TextIterator::rangeLength(range.get()); 330 return TextIterator::rangeLength(range.get());
332 } 331 }
333 332
334 int HTMLTextFormControlElement::selectionStart() const 333 int HTMLTextFormControlElement::selectionStart() const
335 { 334 {
336 if (!isTextFormControl()) 335 if (!isTextFormControl())
337 return 0; 336 return 0;
337 if (document().focusedElement() != this) {
338 int innerTextLength = innerTextValue().length();
339 if (innerTextLength < m_cachedSelectionStart)
340 return innerTextLength;
341 return m_cachedSelectionStart;
342 }
343
344 return computeSelectionStart();
345 }
346
347 int HTMLTextFormControlElement::selectionStartForJavascriptBindings() const
348 {
349 if (!isTextFormControl())
350 return 0;
338 if (document().focusedElement() != this) 351 if (document().focusedElement() != this)
339 return m_cachedSelectionStart; 352 return m_cachedSelectionStart;
340 353
341 return computeSelectionStart(); 354 return computeSelectionStart();
342 } 355 }
343 356
344 int HTMLTextFormControlElement::computeSelectionStart() const 357 int HTMLTextFormControlElement::computeSelectionStart() const
345 { 358 {
346 ASSERT(isTextFormControl()); 359 ASSERT(isTextFormControl());
347 LocalFrame* frame = document().frame(); 360 LocalFrame* frame = document().frame();
348 if (!frame) 361 if (!frame)
349 return 0; 362 return 0;
350 363
351 return indexForVisiblePosition(VisiblePosition(frame->selection().start())); 364 return indexForVisiblePosition(VisiblePosition(frame->selection().start()));
352 } 365 }
353 366
354 int HTMLTextFormControlElement::selectionEnd() const 367 int HTMLTextFormControlElement::selectionEnd() const
355 { 368 {
356 if (!isTextFormControl()) 369 if (!isTextFormControl())
357 return 0; 370 return 0;
371 if (document().focusedElement() != this) {
372 int innerTextLength = innerTextValue().length();
373 if (innerTextLength < m_cachedSelectionEnd)
374 return innerTextLength;
375 return m_cachedSelectionEnd;
376 }
377 return computeSelectionEnd();
378 }
379
380 int HTMLTextFormControlElement::selectionEndForJavascriptBindings() const
381 {
382 if (!isTextFormControl())
383 return 0;
358 if (document().focusedElement() != this) 384 if (document().focusedElement() != this)
359 return m_cachedSelectionEnd; 385 return m_cachedSelectionEnd;
386
360 return computeSelectionEnd(); 387 return computeSelectionEnd();
361 } 388 }
362 389
363 int HTMLTextFormControlElement::computeSelectionEnd() const 390 int HTMLTextFormControlElement::computeSelectionEnd() const
364 { 391 {
365 ASSERT(isTextFormControl()); 392 ASSERT(isTextFormControl());
366 LocalFrame* frame = document().frame(); 393 LocalFrame* frame = document().frame();
367 if (!frame) 394 if (!frame)
368 return 0; 395 return 0;
369 396
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 void HTMLTextFormControlElement::restoreCachedSelection() 492 void HTMLTextFormControlElement::restoreCachedSelection()
466 { 493 {
467 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele ctionDirection); 494 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele ctionDirection);
468 } 495 }
469 496
470 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) 497 void HTMLTextFormControlElement::selectionChanged(bool userTriggered)
471 { 498 {
472 if (!renderer() || !isTextFormControl()) 499 if (!renderer() || !isTextFormControl())
473 return; 500 return;
474 501
475 // selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus
476 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelect ionDirection());
477
478 if (LocalFrame* frame = document().frame()) { 502 if (LocalFrame* frame = document().frame()) {
479 if (frame->selection().isRange() && userTriggered) 503 if (frame->selection().isRange() && userTriggered)
480 dispatchEvent(Event::createBubble(EventTypeNames::select)); 504 dispatchEvent(Event::createBubble(EventTypeNames::select));
481 } 505 }
482 } 506 }
483 507
484 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 508 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
485 { 509 {
486 if (name == placeholderAttr) { 510 if (name == placeholderAttr) {
487 updatePlaceholderVisibility(true); 511 updatePlaceholderVisibility(true);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 669
646 return "ltr"; 670 return "ltr";
647 } 671 }
648 672
649 HTMLElement* HTMLTextFormControlElement::innerTextElement() const 673 HTMLElement* HTMLTextFormControlElement::innerTextElement() const
650 { 674 {
651 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName s::innerEditor())); 675 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName s::innerEditor()));
652 } 676 }
653 677
654 } // namespace Webcore 678 } // namespace Webcore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698