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

Side by Side Diff: Source/web/PopupListBox.cpp

Issue 1013303004: Fix issue on <select> style change when popup is visible (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fixed test expectation Created 5 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « Source/web/PopupListBox.h ('k') | Source/web/PopupMenuImpl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2011, Google Inc. All rights reserved. 2 * Copyright (c) 2011, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 66
67 using namespace WTF::Unicode; 67 using namespace WTF::Unicode;
68 68
69 const int PopupListBox::defaultMaxHeight = 500; 69 const int PopupListBox::defaultMaxHeight = 500;
70 static const int maxVisibleRows = 20; 70 static const int maxVisibleRows = 20;
71 static const int minEndOfLinePadding = 2; 71 static const int minEndOfLinePadding = 2;
72 static const TimeStamp typeAheadTimeoutMs = 1000; 72 static const TimeStamp typeAheadTimeoutMs = 1000;
73 73
74 PopupListBox::PopupListBox(PopupMenuClient* client, bool deviceSupportsTouch, Po pupContainer* container) 74 PopupListBox::PopupListBox(PopupMenuClient* client, bool deviceSupportsTouch, Po pupContainer* container)
75 : m_deviceSupportsTouch(deviceSupportsTouch) 75 : m_deviceSupportsTouch(deviceSupportsTouch)
76 , m_originalIndex(0)
77 , m_selectedIndex(0) 76 , m_selectedIndex(0)
78 , m_acceptedIndexOnAbandon(-1)
79 , m_visibleRows(0) 77 , m_visibleRows(0)
80 , m_baseWidth(0) 78 , m_baseWidth(0)
81 , m_maxHeight(defaultMaxHeight) 79 , m_maxHeight(defaultMaxHeight)
82 , m_popupClient(client) 80 , m_popupClient(client)
83 , m_repeatingChar(0) 81 , m_repeatingChar(0)
84 , m_lastCharTime(0) 82 , m_lastCharTime(0)
85 , m_maxWindowWidth(std::numeric_limits<int>::max()) 83 , m_maxWindowWidth(std::numeric_limits<int>::max())
86 , m_container(container) 84 , m_container(container)
87 { 85 {
88 } 86 }
(...skipping 21 matching lines...) Expand all
110 bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event) 108 bool PopupListBox::handleMouseDownEvent(const PlatformMouseEvent& event)
111 { 109 {
112 Scrollbar* scrollbar = scrollbarAtRootFramePoint(event.position()); 110 Scrollbar* scrollbar = scrollbarAtRootFramePoint(event.position());
113 if (scrollbar) { 111 if (scrollbar) {
114 m_capturingScrollbar = scrollbar; 112 m_capturingScrollbar = scrollbar;
115 m_capturingScrollbar->mouseDown(event); 113 m_capturingScrollbar->mouseDown(event);
116 return true; 114 return true;
117 } 115 }
118 116
119 if (!isPointInBounds(event.position())) 117 if (!isPointInBounds(event.position()))
120 abandon(); 118 cancel();
121 119
122 return true; 120 return true;
123 } 121 }
124 122
125 bool PopupListBox::handleMouseMoveEvent(const PlatformMouseEvent& event) 123 bool PopupListBox::handleMouseMoveEvent(const PlatformMouseEvent& event)
126 { 124 {
127 if (m_capturingScrollbar) { 125 if (m_capturingScrollbar) {
128 m_capturingScrollbar->mouseMoved(event); 126 m_capturingScrollbar->mouseMoved(event);
129 return true; 127 return true;
130 } 128 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 // which is called before dispatchMouseEvent() is called. 166 // which is called before dispatchMouseEvent() is called.
169 m_focusedElement = nullptr; 167 m_focusedElement = nullptr;
170 } 168 }
171 169
172 return true; 170 return true;
173 } 171 }
174 172
175 bool PopupListBox::handleWheelEvent(const PlatformWheelEvent& event) 173 bool PopupListBox::handleWheelEvent(const PlatformWheelEvent& event)
176 { 174 {
177 if (!isPointInBounds(event.position())) { 175 if (!isPointInBounds(event.position())) {
178 abandon(); 176 cancel();
179 return true; 177 return true;
180 } 178 }
181 179
182 ScrollableArea::handleWheelEvent(event); 180 ScrollableArea::handleWheelEvent(event);
183 return true; 181 return true;
184 } 182 }
185 183
186 bool PopupListBox::handleTouchEvent(const PlatformTouchEvent&) 184 bool PopupListBox::handleTouchEvent(const PlatformTouchEvent&)
187 { 185 {
188 return false; 186 return false;
(...skipping 16 matching lines...) Expand all
205 bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event) 203 bool PopupListBox::handleKeyEvent(const PlatformKeyboardEvent& event)
206 { 204 {
207 if (event.type() == PlatformEvent::KeyUp) 205 if (event.type() == PlatformEvent::KeyUp)
208 return true; 206 return true;
209 207
210 if (!numItems() && event.windowsVirtualKeyCode() != VKEY_ESCAPE) 208 if (!numItems() && event.windowsVirtualKeyCode() != VKEY_ESCAPE)
211 return true; 209 return true;
212 210
213 switch (event.windowsVirtualKeyCode()) { 211 switch (event.windowsVirtualKeyCode()) {
214 case VKEY_ESCAPE: 212 case VKEY_ESCAPE:
215 abandon(); // may delete this 213 cancel(); // may delete this
216 return true; 214 return true;
217 case VKEY_RETURN: 215 case VKEY_RETURN:
218 if (m_selectedIndex == -1) { 216 if (m_selectedIndex == -1) {
219 hidePopup(); 217 hidePopup();
220 // Don't eat the enter if nothing is selected. 218 // Don't eat the enter if nothing is selected.
221 return false; 219 return false;
222 } 220 }
223 acceptIndex(m_selectedIndex); // may delete this 221 acceptIndex(m_selectedIndex); // may delete this
224 return true; 222 return true;
225 case VKEY_UP: 223 case VKEY_UP:
(...skipping 20 matching lines...) Expand all
246 && isCharacterTypeEvent(event)) 244 && isCharacterTypeEvent(event))
247 typeAheadFind(event); 245 typeAheadFind(event);
248 break; 246 break;
249 } 247 }
250 248
251 if (event.altKey() && (event.keyIdentifier() == "Down" || event.keyIdentifie r() == "Up")) { 249 if (event.altKey() && (event.keyIdentifier() == "Down" || event.keyIdentifie r() == "Up")) {
252 hidePopup(); 250 hidePopup();
253 return true; 251 return true;
254 } 252 }
255 253
256 if (m_originalIndex != m_selectedIndex) { 254 m_popupClient->provisionalSelectionChanged(m_selectedIndex);
257 // Keyboard events should update the selection immediately (but we don't
258 // want to fire the onchange event until the popup is closed, to match
259 // IE). We change the original index so we revert to that when the
260 // popup is closed.
261 m_acceptedIndexOnAbandon = m_selectedIndex;
262
263 setOriginalIndex(m_selectedIndex);
264 m_popupClient->setTextFromItem(m_selectedIndex);
265 }
266 if (event.windowsVirtualKeyCode() == VKEY_TAB) { 255 if (event.windowsVirtualKeyCode() == VKEY_TAB) {
267 // TAB is a special case as it should select the current item if any and 256 // TAB is a special case as it should select the current item if any and
268 // advance focus. 257 // advance focus.
269 if (m_selectedIndex >= 0) { 258 if (m_selectedIndex >= 0) {
270 acceptIndex(m_selectedIndex); // May delete us. 259 acceptIndex(m_selectedIndex); // May delete us.
271 // Return false so the TAB key event is propagated to the page. 260 // Return false so the TAB key event is propagated to the page.
272 return false; 261 return false;
273 } 262 }
274 // Call abandon() so we honor m_acceptedIndexOnAbandon if set. 263 cancel();
275 abandon();
276 // Return false so the TAB key event is propagated to the page. 264 // Return false so the TAB key event is propagated to the page.
277 return false; 265 return false;
278 } 266 }
279 267
280 return true; 268 return true;
281 } 269 }
282 270
283 HostWindow* PopupListBox::hostWindow() const 271 HostWindow* PopupListBox::hostWindow() const
284 { 272 {
285 // Our parent is the root FrameView, so it is the one that has a 273 // Our parent is the root FrameView, so it is the one that has a
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 FontDescription d = itemFont.fontDescription(); 479 FontDescription d = itemFont.fontDescription();
492 d.setWeight(FontWeightBold); 480 d.setWeight(FontWeightBold);
493 Font font(d); 481 Font font(d);
494 font.update(nullptr); 482 font.update(nullptr);
495 return font; 483 return font;
496 } 484 }
497 485
498 return itemFont; 486 return itemFont;
499 } 487 }
500 488
501 void PopupListBox::abandon() 489 void PopupListBox::cancel()
502 { 490 {
503 RefPtrWillBeRawPtr<PopupListBox> protect(this); 491 RefPtrWillBeRawPtr<PopupListBox> protect(this);
504 492
505 m_selectedIndex = m_originalIndex;
506
507 hidePopup(); 493 hidePopup();
508 494
509 if (m_acceptedIndexOnAbandon >= 0) { 495 if (m_popupClient)
510 if (m_popupClient) 496 m_popupClient->popupDidCancel();
511 m_popupClient->valueChanged(m_acceptedIndexOnAbandon);
512 m_acceptedIndexOnAbandon = -1;
513 }
514 } 497 }
515 498
516 int PopupListBox::pointToRowIndex(const IntPoint& point) 499 int PopupListBox::pointToRowIndex(const IntPoint& point)
517 { 500 {
518 int y = scrollY() + point.y(); 501 int y = scrollY() + point.y();
519 502
520 // FIXME: binary search if perf matters. 503 // FIXME: binary search if perf matters.
521 for (int i = 0; i < numItems(); ++i) { 504 for (int i = 0; i < numItems(); ++i) {
522 if (y < m_items[i]->yOffset) 505 if (y < m_items[i]->yOffset)
523 return i-1; 506 return i-1;
524 } 507 }
525 508
526 // Last item? 509 // Last item?
527 if (y < contentsSize().height()) 510 if (y < contentsSize().height())
528 return m_items.size()-1; 511 return m_items.size()-1;
529 512
530 return -1; 513 return -1;
531 } 514 }
532 515
533 bool PopupListBox::acceptIndex(int index) 516 bool PopupListBox::acceptIndex(int index)
534 { 517 {
535 // Clear m_acceptedIndexOnAbandon once user accepts the selected index.
536 if (m_acceptedIndexOnAbandon >= 0)
537 m_acceptedIndexOnAbandon = -1;
538
539 if (index >= numItems()) 518 if (index >= numItems())
540 return false; 519 return false;
541 520
542 if (index < 0) { 521 if (index < 0) {
543 if (m_popupClient) { 522 if (m_popupClient) {
544 // Enter pressed with no selection, just close the popup. 523 // Enter pressed with no selection, just close the popup.
545 hidePopup(); 524 hidePopup();
546 } 525 }
547 return false; 526 return false;
548 } 527 }
(...skipping 23 matching lines...) Expand all
572 invalidateRow(m_selectedIndex); 551 invalidateRow(m_selectedIndex);
573 m_selectedIndex = index; 552 m_selectedIndex = index;
574 invalidateRow(m_selectedIndex); 553 invalidateRow(m_selectedIndex);
575 554
576 scrollToRevealSelection(); 555 scrollToRevealSelection();
577 m_popupClient->selectionChanged(m_selectedIndex); 556 m_popupClient->selectionChanged(m_selectedIndex);
578 } else if (!isSelectable) 557 } else if (!isSelectable)
579 clearSelection(); 558 clearSelection();
580 } 559 }
581 560
582 void PopupListBox::setOriginalIndex(int index)
583 {
584 m_originalIndex = m_selectedIndex = index;
585 }
586
587 int PopupListBox::getRowHeight(int index) const 561 int PopupListBox::getRowHeight(int index) const
588 { 562 {
589 int minimumHeight = m_deviceSupportsTouch ? optionRowHeightForTouch : minRow Height; 563 int minimumHeight = m_deviceSupportsTouch ? optionRowHeightForTouch : minRow Height;
590 564
591 if (index < 0 || m_popupClient->itemStyle(index).isDisplayNone()) 565 if (index < 0 || m_popupClient->itemStyle(index).isDisplayNone())
592 return minimumHeight; 566 return minimumHeight;
593 567
594 // Separator row height is the same size as itself. 568 // Separator row height is the same size as itself.
595 if (m_popupClient->itemIsSeparator(index)) 569 if (m_popupClient->itemIsSeparator(index))
596 return max(separatorHeight, minimumHeight); 570 return max(separatorHeight, minimumHeight);
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 else 700 else
727 type = PopupItem::TypeOption; 701 type = PopupItem::TypeOption;
728 m_items.append(adoptPtr(new PopupItem(m_popupClient->itemText(i), type)) ); 702 m_items.append(adoptPtr(new PopupItem(m_popupClient->itemText(i), type)) );
729 m_items[i]->enabled = isSelectableItem(i); 703 m_items[i]->enabled = isSelectableItem(i);
730 PopupMenuStyle style = m_popupClient->itemStyle(i); 704 PopupMenuStyle style = m_popupClient->itemStyle(i);
731 m_items[i]->textDirection = style.textDirection(); 705 m_items[i]->textDirection = style.textDirection();
732 m_items[i]->hasTextDirectionOverride = style.hasTextDirectionOverride(); 706 m_items[i]->hasTextDirectionOverride = style.hasTextDirectionOverride();
733 m_items[i]->displayNone = style.isDisplayNone(); 707 m_items[i]->displayNone = style.isDisplayNone();
734 } 708 }
735 709
736 if (m_originalIndex != m_popupClient->selectedIndex() || m_selectedIndex >= static_cast<int>(m_items.size())) 710 if (m_selectedIndex >= static_cast<int>(m_items.size()))
737 setOriginalIndex(m_popupClient->selectedIndex()); 711 m_selectedIndex = m_popupClient->selectedIndex();
738 712
739 layout(); 713 layout();
740 } 714 }
741 715
742 void PopupListBox::setMaxWidthAndLayout(int maxWidth) 716 void PopupListBox::setMaxWidthAndLayout(int maxWidth)
743 { 717 {
744 m_maxWindowWidth = maxWidth; 718 m_maxWindowWidth = maxWidth;
745 layout(); 719 layout();
746 } 720 }
747 721
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 maximumOffset.clampNegativeToZero(); 1025 maximumOffset.clampNegativeToZero();
1052 return maximumOffset; 1026 return maximumOffset;
1053 } 1027 }
1054 1028
1055 IntPoint PopupListBox::minimumScrollPosition() const 1029 IntPoint PopupListBox::minimumScrollPosition() const
1056 { 1030 {
1057 return IntPoint(-scrollOrigin().x(), -scrollOrigin().y()); 1031 return IntPoint(-scrollOrigin().x(), -scrollOrigin().y());
1058 } 1032 }
1059 1033
1060 } // namespace blink 1034 } // namespace blink
OLDNEW
« no previous file with comments | « Source/web/PopupListBox.h ('k') | Source/web/PopupMenuImpl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698