Changeset 261815 in webkit
- Timestamp:
- May 18, 2020 9:23:30 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r261813 r261815 1 2020-05-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Single selection <select> with <optgroups> shows multiple selected options 4 https://bugs.webkit.org/show_bug.cgi?id=199485 5 <rdar://problem/52757531> 6 7 Reviewed by Megan Gardner. 8 9 Add a layout test to verify that we don't leave behind a checked select item after scrolling it offscreen and 10 then checking a different item. 11 12 * fast/forms/ios/no-stale-checked-items-in-select-picker-expected.txt: Added. 13 * fast/forms/ios/no-stale-checked-items-in-select-picker.html: Added. 14 * platform/ipad/TestExpectations: 15 * resources/ui-helper.js: 16 (window.UIHelper.selectFormAccessoryPickerRow): 17 (window.UIHelper.selectFormAccessoryHasCheckedItemAtRow): 18 1 19 2020-05-18 Youenn Fablet <youenn@apple.com> 2 20 -
trunk/LayoutTests/platform/ipad/TestExpectations
r259782 r261815 8 8 fast/forms/ios/user-scalable-scales-for-keyboard-focus-with-no-author-defined-scale.html [ Skip ] 9 9 fast/visual-viewport/ios/caret-after-focus-in-fixed.html [ Skip ] 10 11 # The select picker input view is not displayed on iPad. 12 fast/forms/ios/no-stale-checked-items-in-select-picker.html 10 13 11 14 # These tests are designed for iPhone and crash on iPad -
trunk/LayoutTests/resources/ui-helper.js
r261812 r261815 723 723 static selectFormAccessoryPickerRow(rowIndex) 724 724 { 725 const selectRowScript = ` (() => uiController.selectFormAccessoryPickerRow(${rowIndex}))()`;725 const selectRowScript = `uiController.selectFormAccessoryPickerRow(${rowIndex})`; 726 726 return new Promise(resolve => testRunner.runUIScript(selectRowScript, resolve)); 727 } 728 729 static selectFormAccessoryHasCheckedItemAtRow(rowIndex) 730 { 731 return new Promise(resolve => testRunner.runUIScript(`uiController.selectFormAccessoryHasCheckedItemAtRow(${rowIndex})`, result => { 732 resolve(result === "true"); 733 })); 727 734 } 728 735 -
trunk/Source/WebKit/ChangeLog
r261812 r261815 1 2020-05-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Single selection <select> with <optgroups> shows multiple selected options 4 https://bugs.webkit.org/show_bug.cgi?id=199485 5 <rdar://problem/52757531> 6 7 Reviewed by Megan Gardner. 8 9 Fixes a long-standing bug in WKMultipleSelectPicker. Prior to this patch, we rely on the delegate method 10 `-pickerView:row:column:checked:` to be called twice whenever an item is selected: one time for the item that is 11 no longer checked, and another for the newly checked item. This method is responsible for updating the cached 12 `FocusedElementInformation` that determines the data model for the select menu, with the expectation that the 13 unchecked item would be updated to have `isSelected = false;`, and the new checked item would have `isSelected` 14 `= true;`. 15 16 However, `-pickerView:row:column:checked:` is only called for visible item cells. This means that if the user 17 checks an item, scrolls the select menu items down so that the checked item is offscreen, and then checks a 18 different item, we only get notified that the new item is checked, and as a result, fail to uncheck the previous 19 item. 20 21 To address this, tweak our logic for handling a single select so that when an item is checked, we additionally 22 update the previously checked item to not be selected. Also, fix what seems to be a bug in the logic for 23 updating `_singleSelectionIndex`, which is currently updated even when the item is unchecked. It seems to work 24 out at the moment, because `-pickerView:row:column:checked:` seems to be called with `checked := YES` after the 25 previous item was unchecked (assuming that it was visible). 26 27 Test: fast/forms/ios/no-stale-checked-items-in-select-picker.html 28 29 * UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h: 30 * UIProcess/API/ios/WKWebViewTestingIOS.mm: 31 (-[WKWebView selectFormAccessoryHasCheckedItemAtRow:]): 32 * UIProcess/ios/WKContentViewInteraction.h: 33 * UIProcess/ios/WKContentViewInteraction.mm: 34 (-[WKContentView selectFormAccessoryHasCheckedItemAtRow:]): 35 36 Add plumbing for a new testing hook. 37 38 * UIProcess/ios/forms/WKFormSelectControl.h: 39 * UIProcess/ios/forms/WKFormSelectControl.mm: 40 (-[WKFormSelectControl selectFormAccessoryHasCheckedItemAtRow:]): 41 * UIProcess/ios/forms/WKFormSelectPicker.mm: 42 (-[WKMultipleSelectPicker pickerView:viewForRow:forComponent:reusingView:]): 43 (-[WKMultipleSelectPicker pickerView:row:column:checked:]): 44 (-[WKMultipleSelectPicker selectRow:inComponent:extendingSelection:]): 45 46 Also, fix an existing bug in this testing helper method that crashed the test runner due to calling an 47 unimplemented selector. Instead of trying to invoke `-pickerView:didSelectRow:inComponent:`, we should be using 48 `-pickerView:row:column:checked:` instead for multiple select pickers (which, somewhat confusingly, are still 49 used for single select elements that have `optgroup`s.) 50 51 (-[WKMultipleSelectPicker selectFormAccessoryHasCheckedItemAtRow:]): 52 1 53 2020-05-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 54 -
trunk/Source/WebKit/UIProcess/API/ios/WKWebViewPrivateForTestingIOS.h
r261638 r261815 49 49 - (void)_dismissFilePicker; 50 50 - (void)selectFormAccessoryPickerRow:(int)rowIndex; 51 - (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex; 51 52 52 53 - (BOOL)_mayContainEditableElementsInRect:(CGRect)rect; -
trunk/Source/WebKit/UIProcess/API/ios/WKWebViewTestingIOS.mm
r261638 r261815 145 145 } 146 146 147 - (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex 148 { 149 return [_contentView selectFormAccessoryHasCheckedItemAtRow:rowIndex]; 150 } 151 147 152 - (NSString *)selectFormPopoverTitle 148 153 { -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
r261658 r261815 620 620 - (void)_simulateTextEntered:(NSString *)text; 621 621 - (void)selectFormAccessoryPickerRow:(NSInteger)rowIndex; 622 - (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex; 622 623 - (void)setTimePickerValueToHour:(NSInteger)hour minute:(NSInteger)minute; 623 624 - (double)timePickerValueHour; -
trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm
r261812 r261815 8758 8758 } 8759 8759 8760 - (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex 8761 { 8762 #if !PLATFORM(WATCHOS) 8763 if ([_inputPeripheral isKindOfClass:[WKFormSelectControl self]]) 8764 return [(WKFormSelectControl *)_inputPeripheral selectFormAccessoryHasCheckedItemAtRow:rowIndex]; 8765 #endif 8766 return NO; 8767 } 8768 8760 8769 - (NSString *)textContentTypeForTesting 8761 8770 { -
trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.h
r244955 r261815 42 42 @interface WKFormSelectControl(WKTesting) 43 43 - (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection; 44 - (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex; 44 45 @property (nonatomic, readonly) NSString *selectFormPopoverTitle; 45 46 @end … … 48 49 @optional 49 50 - (void)selectRow:(NSInteger)rowIndex inComponent:(NSInteger)componentIndex extendingSelection:(BOOL)extendingSelection; 51 - (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex; 50 52 @end 51 53 -
trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectControl.mm
r253661 r261815 102 102 } 103 103 104 - (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex 105 { 106 return [self.control respondsToSelector:@selector(selectFormAccessoryHasCheckedItemAtRow:)] 107 && [id<WKSelectTesting>(self.control) selectFormAccessoryHasCheckedItemAtRow:rowIndex]; 108 } 109 104 110 @end 105 111 -
trunk/Source/WebKit/UIProcess/ios/forms/WKFormSelectPicker.mm
r245272 r261815 220 220 - (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)rowIndex forComponent:(NSInteger)columnIndex reusingView:(UIView *)view 221 221 { 222 const OptionItem& item = [_view focusedSelectElementOptions][rowIndex];223 UIPickerContentView *pickerItem = item.isGroup ? [[[WKOptionGroupPickerCell alloc] initWithOptionItem:item] autorelease] : [[[WKOptionPickerCell alloc] initWithOptionItem:item] autorelease];222 auto& item = [_view focusedSelectElementOptions][rowIndex]; 223 UIPickerContentView *pickerItem = item.isGroup ? [[[WKOptionGroupPickerCell alloc] initWithOptionItem:item] autorelease] : [[[WKOptionPickerCell alloc] initWithOptionItem:item] autorelease]; 224 224 225 225 // The cell starts out with a null frame. We need to set its frame now so we can find the right font size. … … 273 273 - (void)pickerView:(UIPickerView *)pickerView row:(int)rowIndex column:(int)columnIndex checked:(BOOL)isChecked 274 274 { 275 if ((size_t)rowIndex >= [_view focusedSelectElementOptions].size()) 275 auto numberOfOptions = static_cast<NSUInteger>([_view focusedSelectElementOptions].size()); 276 if (numberOfOptions <= static_cast<NSUInteger>(rowIndex)) 276 277 return; 277 278 278 OptionItem& item = [_view focusedSelectElementOptions][rowIndex];279 auto& item = [_view focusedSelectElementOptions][rowIndex]; 279 280 280 281 // FIXME: Remove this workaround once <rdar://problem/18745253> is fixed. … … 292 293 [_view page]->setFocusedElementSelectedIndex([self findItemIndexAt:rowIndex], true); 293 294 item.isSelected = isChecked; 294 } else {295 } else if (isChecked) { 295 296 // Single selection. 296 item.isSelected = NO; 297 if (_singleSelectionIndex < numberOfOptions) 298 [_view focusedSelectElementOptions][_singleSelectionIndex].isSelected = false; 299 297 300 _singleSelectionIndex = rowIndex; 298 301 299 302 // This private delegate often gets called for multiple rows in the picker, 300 303 // so we only activate and set as selected the checked item in single selection. 301 if (isChecked) { 302 [_view page]->setFocusedElementSelectedIndex([self findItemIndexAt:rowIndex]); 303 item.isSelected = YES; 304 } 305 } 304 [_view page]->setFocusedElementSelectedIndex([self findItemIndexAt:rowIndex]); 305 item.isSelected = true; 306 } else 307 item.isSelected = false; 306 308 } 307 309 … … 312 314 [self selectRow:rowIndex inComponent:0 animated:NO]; 313 315 // Progammatic selection changes don't call the delegate, so do that manually. 314 [self.delegate pickerView:self didSelectRow:rowIndex inComponent:0]; 316 [self pickerView:self row:rowIndex column:0 checked:YES]; 317 } 318 319 - (BOOL)selectFormAccessoryHasCheckedItemAtRow:(long)rowIndex 320 { 321 auto numberOfRows = [self numberOfRowsInComponent:0]; 322 if (rowIndex >= numberOfRows) 323 return NO; 324 325 return [(UIPickerContentView *)[self viewForRow:rowIndex forComponent:0] isChecked]; 315 326 } 316 327 -
trunk/Tools/ChangeLog
r261812 r261815 1 2020-05-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 3 Single selection <select> with <optgroups> shows multiple selected options 4 https://bugs.webkit.org/show_bug.cgi?id=199485 5 <rdar://problem/52757531> 6 7 Reviewed by Megan Gardner. 8 9 Add a new helper method to check whether the currently presented form accessory is a select menu, and has a 10 checked menu item at the given row. 11 12 * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl: 13 * TestRunnerShared/UIScriptContext/UIScriptController.h: 14 (WTR::UIScriptController::selectFormAccessoryHasCheckedItemAtRow const): 15 * WebKitTestRunner/ios/UIScriptControllerIOS.h: 16 * WebKitTestRunner/ios/UIScriptControllerIOS.mm: 17 (WTR::UIScriptControllerIOS::selectFormAccessoryHasCheckedItemAtRow const): 18 1 19 2020-05-18 Wenson Hsieh <wenson_hsieh@apple.com> 2 20 -
trunk/Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
r261812 r261815 213 213 // <select> picker 214 214 void selectFormAccessoryPickerRow(long rowIndex); 215 boolean selectFormAccessoryHasCheckedItemAtRow(long rowIndex); 215 216 readonly attribute DOMString selectFormPopoverTitle; 216 217 readonly attribute DOMString formInputLabel; -
trunk/Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
r261812 r261815 206 206 virtual void dismissFormAccessoryView() { notImplemented(); } 207 207 virtual void selectFormAccessoryPickerRow(long) { notImplemented(); } 208 virtual bool selectFormAccessoryHasCheckedItemAtRow(long) const { return false; } 208 209 virtual JSRetainPtr<JSStringRef> textContentType() const { notImplemented(); return nullptr; } 209 210 virtual JSRetainPtr<JSStringRef> selectFormPopoverTitle() const { notImplemented(); return nullptr; } -
trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h
r261812 r261815 89 89 JSRetainPtr<JSStringRef> formInputLabel() const override; 90 90 void selectFormAccessoryPickerRow(long rowIndex) override; 91 bool selectFormAccessoryHasCheckedItemAtRow(long rowIndex) const override; 91 92 void setTimePickerValue(long hour, long minute) override; 92 93 double timePickerValueHour() const override; -
trunk/Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm
r261812 r261815 607 607 } 608 608 609 bool UIScriptControllerIOS::selectFormAccessoryHasCheckedItemAtRow(long rowIndex) const 610 { 611 return [webView() selectFormAccessoryHasCheckedItemAtRow:rowIndex]; 612 } 613 609 614 void UIScriptControllerIOS::setTimePickerValue(long hour, long minute) 610 615 {
Note: See TracChangeset
for help on using the changeset viewer.