Fixes Select elements drop-down doesn't follow update of the element position/size
Prior to this fix, when a select element's popup is open, a script in the background can modify the page's DOM that changes the position of select element on the screen. However, select popup remains stationary thus appearing disconnect from the select element. The select popup also doesn't update to the correct size if the script adds an new option with a long text. The reason is that select element doesn't check to see if the position or size of the select element popup relative to the document changed. For example, after the popup is displayed, a script could modify the document that changes the position of the select element. It doesn't notify its popup, thus makes them appear as disconnected. The fix is to update the select popup, its position and size, at the end of frame's life-cycle phase. This will guarantee that all elements in the frame have been styled and layout correctly. At this point, we can update the popup if its owner's position and size has been changed. The fix also removes the PostTask as a performance and simplicity optimization. An alternative proposal, use intersection observer on the owner element, was discussed. However, it still has the draw backs of post task. Plus, it may not capture all cases. In addition, I also considered and tried using PostTask within the UpdateLifecycle method. However, that's not optimal since within the popup's update method, it requires another call to UpdateStyleAndLayout because the layout could have been dirtied since the time PostTask was added into the queue. InternalPopupMenu::Update() also updates the select element's internal state, options. I saw some intermittent failures in couple of tests that validate options index. These tests use SetTimeout(), which may partly be aggravate by PostTask. I didn't investigate further as this is not the approach to take. This fix works for both Linux and Windows. I updated test popup-menu-resize-after-open to reflect that. In addition, I removed the (TODO) in listPicker.js. This fixes select popup when placed inside an iframe. For platforms that use external_popup_menu, mac and android, will be migrated to use internal_popup_menu when forms-refresh is rolled out to those platforms in M83. One of the biggest problem I encountered when doing this fix is that popup content doesn't updated when the popup is moved only. This is the same issue as crbug.com/633140. This review, https://codereview.chromium.org/2228093003, goes into more details on popup bounds synchronization between browser and renderer. Regardless, I had to make a similar fix in web_page_popup_impl.cc, calling SetWindowRect() when force_update is true. Bug: 137495 Change-Id: I7ef4c09a6d3d7bee3ef8988c815e07efa72d4a79 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2013470 Commit-Queue: Yu Han <yuzhehan@chromium.org> Reviewed-by:Chris Harrelson <chrishtr@chromium.org> Cr-Commit-Position: refs/heads/master@{#740964}
Showing
Please register or sign in to comment