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

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 Created 6 years, 5 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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 end = std::max(end, 0); 285 int textLength = innerEditorValue().length();
286 start = std::min(std::max(start, 0), end); 286 end = std::max(std::min(end, textLength), 0);
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);
287 291
288 if (!hasVisibleTextArea(renderer(), innerEditorElement())) { 292 if (!hasVisibleTextArea(renderer(), innerEditorElement()))
289 cacheSelection(start, end, direction);
290 return; 293 return;
291 } 294
295 LocalFrame* frame = document().frame();
296
297 if (!frame || !shouldSetSelection)
298 return;
299
292 VisiblePosition startPosition = visiblePositionForIndex(start); 300 VisiblePosition startPosition = visiblePositionForIndex(start);
293 VisiblePosition endPosition; 301 VisiblePosition endPosition;
294 if (start == end) 302 if (start == end)
295 endPosition = startPosition; 303 endPosition = startPosition;
296 else 304 else
297 endPosition = visiblePositionForIndex(end); 305 endPosition = visiblePositionForIndex(end);
298 306
299 // startPosition and endPosition can be null position for example when 307 // startPosition and endPosition can be null position for example when
300 // "-webkit-user-select: none" style attribute is specified. 308 // "-webkit-user-select: none" style attribute is specified.
301 if (startPosition.isNotNull() && endPosition.isNotNull()) { 309 if (startPosition.isNotNull() && endPosition.isNotNull()) {
302 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowHost() == this 310 ASSERT(startPosition.deepEquivalent().deprecatedNode()->shadowHost() == this
303 && endPosition.deepEquivalent().deprecatedNode()->shadowHost() == th is); 311 && endPosition.deepEquivalent().deprecatedNode()->shadowHost() == th is);
304 } 312 }
305 VisibleSelection newSelection; 313 VisibleSelection newSelection;
306 if (direction == SelectionHasBackwardDirection) 314 if (direction == SelectionHasBackwardDirection)
307 newSelection = VisibleSelection(endPosition, startPosition); 315 newSelection = VisibleSelection(endPosition, startPosition);
308 else 316 else
309 newSelection = VisibleSelection(startPosition, endPosition); 317 newSelection = VisibleSelection(startPosition, endPosition);
310 newSelection.setIsDirectional(direction != SelectionHasNoDirection); 318 newSelection.setIsDirectional(direction != SelectionHasNoDirection);
311 319
312 if (LocalFrame* frame = document().frame()) 320 frame->selection().setSelection(newSelection);
313 frame->selection().setSelection(newSelection);
314 } 321 }
315 322
316 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c onst 323 VisiblePosition HTMLTextFormControlElement::visiblePositionForIndex(int index) c onst
317 { 324 {
318 if (index <= 0) 325 if (index <= 0)
319 return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNST REAM); 326 return VisiblePosition(firstPositionInNode(innerEditorElement()), DOWNST REAM);
320 RefPtrWillBeRawPtr<Range> range = Range::create(document()); 327 RefPtrWillBeRawPtr<Range> range = Range::create(document());
321 range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION); 328 range->selectNodeContents(innerEditorElement(), ASSERT_NO_EXCEPTION);
322 CharacterIterator it(range.get()); 329 CharacterIterator it(range.get());
323 it.advance(index - 1); 330 it.advance(index - 1);
(...skipping 11 matching lines...) Expand all
335 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer Node(), ASSERT_NO_EXCEPTION); 342 range->setEnd(indexPosition.containerNode(), indexPosition.offsetInContainer Node(), ASSERT_NO_EXCEPTION);
336 return TextIterator::rangeLength(range.get()); 343 return TextIterator::rangeLength(range.get());
337 } 344 }
338 345
339 int HTMLTextFormControlElement::selectionStart() const 346 int HTMLTextFormControlElement::selectionStart() const
340 { 347 {
341 if (!isTextFormControl()) 348 if (!isTextFormControl())
342 return 0; 349 return 0;
343 if (document().focusedElement() != this) 350 if (document().focusedElement() != this)
344 return m_cachedSelectionStart; 351 return m_cachedSelectionStart;
345
tkent 2014/07/08 00:34:48 nit: This blank line change is unnecessary.
harpreet.sk 2014/07/08 06:07:59 Done.
346 return computeSelectionStart(); 352 return computeSelectionStart();
347 } 353 }
348 354
349 int HTMLTextFormControlElement::computeSelectionStart() const 355 int HTMLTextFormControlElement::computeSelectionStart() const
350 { 356 {
351 ASSERT(isTextFormControl()); 357 ASSERT(isTextFormControl());
352 LocalFrame* frame = document().frame(); 358 LocalFrame* frame = document().frame();
353 if (!frame) 359 if (!frame)
354 return 0; 360 return 0;
355 361
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 void HTMLTextFormControlElement::restoreCachedSelection() 476 void HTMLTextFormControlElement::restoreCachedSelection()
471 { 477 {
472 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele ctionDirection); 478 setSelectionRange(m_cachedSelectionStart, m_cachedSelectionEnd, m_cachedSele ctionDirection);
473 } 479 }
474 480
475 void HTMLTextFormControlElement::selectionChanged(bool userTriggered) 481 void HTMLTextFormControlElement::selectionChanged(bool userTriggered)
476 { 482 {
477 if (!renderer() || !isTextFormControl()) 483 if (!renderer() || !isTextFormControl())
478 return; 484 return;
479 485
480 // selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus 486 if (document().focusedElement() == this)
481 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelect ionDirection()); 487 cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSe lectionDirection());
482 488
483 if (LocalFrame* frame = document().frame()) { 489 if (LocalFrame* frame = document().frame()) {
484 if (frame->selection().isRange() && userTriggered) 490 if (frame->selection().isRange() && userTriggered)
485 dispatchEvent(Event::createBubble(EventTypeNames::select)); 491 dispatchEvent(Event::createBubble(EventTypeNames::select));
486 } 492 }
487 } 493 }
488 494
489 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 495 void HTMLTextFormControlElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
490 { 496 {
491 if (name == placeholderAttr) { 497 if (name == placeholderAttr) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 659
654 return "ltr"; 660 return "ltr";
655 } 661 }
656 662
657 HTMLElement* HTMLTextFormControlElement::innerEditorElement() const 663 HTMLElement* HTMLTextFormControlElement::innerEditorElement() const
658 { 664 {
659 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName s::innerEditor())); 665 return toHTMLElement(userAgentShadowRoot()->getElementById(ShadowElementName s::innerEditor()));
660 } 666 }
661 667
662 } // namespace Webcore 668 } // namespace Webcore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698