WebKit Bugzilla
Attachment 348577 Details for
Bug 186714
: [Datalist][iOS] Add suggestions UI for TextFieldInputTypes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186714-20180830181521.patch (text/plain), 49.47 KB, created by
Aditya Keerthi
on 2018-08-30 18:15:21 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Aditya Keerthi
Created:
2018-08-30 18:15:21 PDT
Size:
49.47 KB
patch
obsolete
>Subversion Revision: 235532 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 10b5f37c73e7166341bc1b1b4cf1672d2429fd44..63192947429f718588050102b527b9d4e6e2a54f 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,25 @@ >+2018-08-30 Aditya Keerthi <akeerthi@apple.com> >+ >+ [Datalist][iOS] Add suggestions UI for TextFieldInputTypes >+ https://bugs.webkit.org/show_bug.cgi?id=186714 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ On iOS, the datalist button should appear as a downward triangle. Furthermore, the >+ button should only be displayed if the input has focus and there are suggested >+ values. >+ >+ * css/html.css: >+ (input::-webkit-list-button): Draw the triangle using an SVG. >+ * html/DataListSuggestionInformation.h: >+ * html/HTMLInputElement.h: >+ * html/TextFieldInputType.cpp: Added logic to show and hide the datalist button as necessary. >+ (WebCore::TextFieldInputType::handleFocusEvent): >+ (WebCore::TextFieldInputType::handleBlurEvent): >+ (WebCore::TextFieldInputType::didSetValueByUserEdit): >+ (WebCore::TextFieldInputType::listAttributeTargetChanged): >+ (WebCore::TextFieldInputType::displaySuggestions): >+ > 2018-08-30 Don Olmstead <don.olmstead@sony.com> > > [CMake] Replace AVFoundationSupport.py using CMake >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index c10fc048b7e074cd0dbb248efdba5d327002c374..9168bd3ffc76773f78812d6730b0b3feaded0514 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,102 @@ >+2018-08-30 Aditya Keerthi <akeerthi@apple.com> >+ >+ [Datalist][iOS] Add suggestions UI for TextFieldInputTypes >+ https://bugs.webkit.org/show_bug.cgi?id=186714 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ On iOS, we have less space to display suggestions from a datalist element compared >+ to macOS. Furthermore, iPhones and iPads have different form factors, leading to a >+ different approach on each device. The commonalities of the two implementations >+ can be found in WKDataListSuggestionsControl. This class is subclassed by the >+ device specific implementations. >+ >+ On iPhone, we display the suggestions in a UIPickerView. This view is accessible >+ only after tapping on the datalist button element to the side of the input field. >+ This approach was chosen in order to avoid tricking the user into thinking that >+ the values displayed in the picker are the only accepted values. >+ WKDataListSuggestionsPicker is responsible for managing the interface shown on >+ iPhones. >+ >+ On iPad, we display the suggestions in a popover, that is visible alongside the >+ keyboard. The suggestions in the popover update as the user types. >+ WKDataListSuggestionsPopover is responsible for managing the interface shown on >+ iPads. >+ >+ Both devices display predictive text suggestions, taking the first three values >+ from the filtered suggestions list. In order to prevent other clients from >+ overwriting the suggestions provided by the datalist element, we prevent writing >+ to the predictive text bar if an input with the list attribute is the currently >+ assisted node. >+ >+ * Shared/AssistedNodeInformation.cpp: >+ (WebKit::AssistedNodeInformation::encode const): >+ (WebKit::AssistedNodeInformation::decode): >+ * Shared/AssistedNodeInformation.h: >+ * Shared/ios/InteractionInformationAtPosition.h: >+ * Shared/ios/InteractionInformationAtPosition.mm: >+ (WebKit::InteractionInformationAtPosition::encode const): >+ (WebKit::InteractionInformationAtPosition::decode): >+ * SourcesCocoa.txt: >+ * UIProcess/WebDataListSuggestionsDropdownIOS.h: Added. >+ * UIProcess/WebDataListSuggestionsDropdownIOS.mm: Added. >+ (WebKit::WebDataListSuggestionsDropdownIOS::create): >+ (WebKit::WebDataListSuggestionsDropdownIOS::WebDataListSuggestionsDropdownIOS): >+ (WebKit::WebDataListSuggestionsDropdownIOS::show): >+ (WebKit::WebDataListSuggestionsDropdownIOS::handleKeydownWithIdentifier): >+ (WebKit::WebDataListSuggestionsDropdownIOS::close): >+ (WebKit::WebDataListSuggestionsDropdownIOS::didSelectOption): >+ (-[WKDataListSuggestionsControl initWithInformation:inView:]): >+ (-[WKDataListSuggestionsControl updateWithInformation:]): >+ (-[WKDataListSuggestionsControl showSuggestionsDropdown:activationType:]): >+ (-[WKDataListSuggestionsControl didSelectOptionAtIndex:]): >+ (-[WKDataListSuggestionsControl invalidate]): >+ (-[WKDataListSuggestionsControl textSuggestions]): >+ (-[WKDataListSuggestionsControl suggestionsCount]): >+ (-[WKDataListSuggestionsControl suggestionAtIndex:]): >+ (-[WKDataListSuggestionsControl textAlignment]): >+ (-[WKDataListSuggestionsPicker initWithInformation:inView:]): >+ (-[WKDataListSuggestionsPicker updateWithInformation:]): >+ (-[WKDataListSuggestionsPicker showSuggestionsDropdown:activationType:]): >+ (-[WKDataListSuggestionsPicker numberOfComponentsInPickerView:]): >+ (-[WKDataListSuggestionsPicker pickerView:numberOfRowsInComponent:]): >+ (-[WKDataListSuggestionsPicker pickerView:titleForRow:forComponent:]): >+ (-[WKDataListSuggestionsPicker invalidate]): >+ (-[WKDataListSuggestionsPickerView controlView]): >+ (-[WKDataListSuggestionsPickerView controlBeginEditing]): >+ (-[WKDataListSuggestionsPickerView controlEndEditing]): >+ (-[WKDataListSuggestionsPopover initWithInformation:inView:]): >+ (-[WKDataListSuggestionsPopover updateWithInformation:]): >+ (-[WKDataListSuggestionsPopover showSuggestionsDropdown:activationType:]): >+ (-[WKDataListSuggestionsPopover invalidate]): >+ (-[WKDataListSuggestionsPopover didSelectOptionAtIndex:]): >+ (-[WKDataListSuggestionsViewController reloadData]): >+ (-[WKDataListSuggestionsViewController tableView:numberOfRowsInSection:]): >+ (-[WKDataListSuggestionsViewController tableView:cellForRowAtIndexPath:]): >+ (-[WKDataListSuggestionsViewController tableView:didSelectRowAtIndexPath:]): >+ * UIProcess/WebPageProxy.cpp: >+ (WebKit::WebPageProxy::pageDidScroll): >+ * UIProcess/ios/PageClientImplIOS.mm: >+ (WebKit::PageClientImpl::createDataListSuggestionsDropdown): >+ * UIProcess/ios/WKContentViewInteraction.h: >+ * UIProcess/ios/WKContentViewInteraction.mm: >+ (-[WKFormInputSession endEditing]): >+ (-[WKFormInputSession setSuggestions:]): >+ (-[WKContentView _formInputSession]): >+ (-[WKContentView resignFirstResponderForWebView]): >+ (-[WKContentView textInteractionGesture:shouldBeginAtPoint:]): >+ (-[WKContentView accessoryTab:]): >+ (-[WKContentView insertTextSuggestion:]): >+ * UIProcess/mac/WebDataListSuggestionsDropdownMac.h: >+ * UIProcess/mac/WebDataListSuggestionsDropdownMac.mm: >+ (WebKit::WebDataListSuggestionsDropdownMac::didSelectOption): >+ * WebKit.xcodeproj/project.pbxproj: >+ * WebProcess/WebPage/WebPage.cpp: >+ (WebKit::WebPage::didCloseSuggestions): >+ * WebProcess/WebPage/ios/WebPageIOS.mm: >+ (WebKit::WebPage::getPositionInformation): >+ (WebKit::WebPage::getAssistedNodeInformation): >+ > 2018-08-30 Chris Dumez <cdumez@apple.com> > > Add WKPageLoadFile SPI variant which returns a navigation object >diff --git a/Source/WebCore/css/html.css b/Source/WebCore/css/html.css >index 26c7886a24c035ebd619900ff7aaf786df303582..47200f255921454503f1aef43952b13029a4ce9f 100644 >--- a/Source/WebCore/css/html.css >+++ b/Source/WebCore/css/html.css >@@ -626,7 +626,14 @@ input::-webkit-list-button { > flex: none; > -webkit-user-select: none; > width: 16px; >+#if defined(WTF_PLATFORM_IOS) && WTF_PLATFORM_IOS >+ content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" stroke="black" fill="black" width="16" height="16"><polygon points="8 11.031, 4.5 4.969, 11.5 4.969"/></svg>'); >+ /* Make it easier to hit the button on iOS */ >+ padding: 7px; >+ margin: -7px; >+#else > height: 100%; >+#endif > } > #endif > >diff --git a/Source/WebCore/html/DataListSuggestionInformation.h b/Source/WebCore/html/DataListSuggestionInformation.h >index 8c449ef9994c603cc4f5ec8a5ad993950a0559fe..579451a59832fddffc9b98f40cd9595568cefc6d 100644 >--- a/Source/WebCore/html/DataListSuggestionInformation.h >+++ b/Source/WebCore/html/DataListSuggestionInformation.h >@@ -26,6 +26,7 @@ > #pragma once > > #include "IntRect.h" >+#include <wtf/Vector.h> > > #if ENABLE(DATALIST_ELEMENT) > namespace WebCore { >diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h >index e32b3893eb4ac796c66e08c1bda7f3e4729ec8d3..4ce89b16003ee5efb98a0c8f7c3e39083a204a28 100644 >--- a/Source/WebCore/html/HTMLInputElement.h >+++ b/Source/WebCore/html/HTMLInputElement.h >@@ -151,7 +151,7 @@ public: > HTMLElement* placeholderElement() const final; > WEBCORE_EXPORT HTMLElement* autoFillButtonElement() const; > #if ENABLE(DATALIST_ELEMENT) >- HTMLElement* dataListButtonElement() const; >+ WEBCORE_EXPORT HTMLElement* dataListButtonElement() const; > #endif > > bool checked() const { return m_isChecked; } >diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp >index 420253fd7b2c8399fc3918e8daafeed471e94c2f..ace20af468423dd167bf4732137cef56208b535d 100644 >--- a/Source/WebCore/html/TextFieldInputType.cpp >+++ b/Source/WebCore/html/TextFieldInputType.cpp >@@ -260,8 +260,13 @@ void TextFieldInputType::handleFocusEvent(Node* oldFocusedNode, FocusDirection) > { > ASSERT(element()); > ASSERT_UNUSED(oldFocusedNode, oldFocusedNode != element()); >- if (RefPtr<Frame> frame = element()->document().frame()) >+ if (RefPtr<Frame> frame = element()->document().frame()) { > frame->editor().textFieldDidBeginEditing(element()); >+#if ENABLE(DATALIST_ELEMENT) && PLATFORM(IOS) >+ if (element()->list() && m_dataListDropdownIndicator) >+ m_dataListDropdownIndicator->setInlineStyleProperty(CSSPropertyDisplay, suggestions().size() ? CSSValueBlock : CSSValueNone, true); >+#endif >+ } > } > > void TextFieldInputType::handleBlurEvent() >@@ -269,6 +274,10 @@ void TextFieldInputType::handleBlurEvent() > InputType::handleBlurEvent(); > ASSERT(element()); > element()->endEditing(); >+#if ENABLE(DATALIST_ELEMENT) && PLATFORM(IOS) >+ if (element()->list() && m_dataListDropdownIndicator) >+ m_dataListDropdownIndicator->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone, true); >+#endif > } > > bool TextFieldInputType::shouldSubmitImplicitly(Event& event) >@@ -648,6 +657,10 @@ void TextFieldInputType::didSetValueByUserEdit() > if (RefPtr<Frame> frame = element()->document().frame()) > frame->editor().textDidChangeInTextField(element()); > #if ENABLE(DATALIST_ELEMENT) >+#if PLATFORM(IOS) >+ if (element()->list() && m_dataListDropdownIndicator) >+ m_dataListDropdownIndicator->setInlineStyleProperty(CSSPropertyDisplay, suggestions().size() ? CSSValueBlock : CSSValueNone, true); >+#endif > if (element()->list()) > displaySuggestions(DataListSuggestionActivationType::TextChanged); > #endif >@@ -804,7 +817,9 @@ void TextFieldInputType::listAttributeTargetChanged() > if (!m_dataListDropdownIndicator) > return; > >+#if !PLATFORM(IOS) > m_dataListDropdownIndicator->setInlineStyleProperty(CSSPropertyDisplay, element()->list() ? CSSValueBlock : CSSValueNone, true); >+#endif > } > > HTMLElement* TextFieldInputType::dataListButtonElement() const >@@ -875,7 +890,7 @@ void TextFieldInputType::displaySuggestions(DataListSuggestionActivationType typ > if (element()->isDisabledFormControl() || !element()->renderer()) > return; > >- if (!UserGestureIndicator::processingUserGesture()) >+ if (!UserGestureIndicator::processingUserGesture() && type != DataListSuggestionActivationType::TextChanged) > return; > > if (!m_suggestionPicker && suggestions().size() > 0) >diff --git a/Source/WebKit/Shared/AssistedNodeInformation.cpp b/Source/WebKit/Shared/AssistedNodeInformation.cpp >index 210973be5a99c93e7e3c2970cd69e275874b5f0e..c1a4335d4ddf902aad2c7f2457916077ddb751d7 100644 >--- a/Source/WebKit/Shared/AssistedNodeInformation.cpp >+++ b/Source/WebKit/Shared/AssistedNodeInformation.cpp >@@ -97,9 +97,12 @@ void AssistedNodeInformation::encode(IPC::Encoder& encoder) const > encoder << label; > encoder << ariaLabel; > encoder << assistedNodeIdentifier; >-#if ENABLE(INPUT_TYPE_COLOR) && ENABLE(DATALIST_ELEMENT) >+#if ENABLE(DATALIST_ELEMENT) >+ encoder << hasSuggestions; >+#if ENABLE(INPUT_TYPE_COLOR) > encoder << suggestedColors; > #endif >+#endif > } > > bool AssistedNodeInformation::decode(IPC::Decoder& decoder, AssistedNodeInformation& result) >@@ -206,9 +209,14 @@ bool AssistedNodeInformation::decode(IPC::Decoder& decoder, AssistedNodeInformat > if (!decoder.decode(result.assistedNodeIdentifier)) > return false; > >-#if ENABLE(INPUT_TYPE_COLOR) && ENABLE(DATALIST_ELEMENT) >+#if ENABLE(DATALIST_ELEMENT) >+ if (!decoder.decode(result.hasSuggestions)) >+ return false; >+ >+#if ENABLE(INPUT_TYPE_COLOR) > if (!decoder.decode(result.suggestedColors)) > return false; >+#endif > #endif > > return true; >diff --git a/Source/WebKit/Shared/AssistedNodeInformation.h b/Source/WebKit/Shared/AssistedNodeInformation.h >index 66716d4032911e1f1d73a039859a9663712248dd..433638b948df0978ab3c1bd1ba1a3b741ddfa6af 100644 >--- a/Source/WebKit/Shared/AssistedNodeInformation.h >+++ b/Source/WebKit/Shared/AssistedNodeInformation.h >@@ -125,8 +125,11 @@ struct AssistedNodeInformation { > String placeholder; > String label; > String ariaLabel; >-#if ENABLE(INPUT_TYPE_COLOR) && ENABLE(DATALIST_ELEMENT) >+#if ENABLE(DATALIST_ELEMENT) >+ bool hasSuggestions { false }; >+#if ENABLE(INPUT_TYPE_COLOR) > Vector<WebCore::Color> suggestedColors; >+#endif > #endif > > uint64_t assistedNodeIdentifier { 0 }; >diff --git a/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h b/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h >index 9b9533e072da80dc3ddbc1bd01c51b270cb3f29c..3d08689fe176dd7a6172a137c0583dcea7372f63 100644 >--- a/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h >+++ b/Source/WebKit/Shared/ios/InteractionInformationAtPosition.h >@@ -55,6 +55,9 @@ struct InteractionInformationAtPosition { > bool isElement { false }; > #if ENABLE(DATA_DETECTION) > bool isDataDetectorLink { false }; >+#endif >+#if ENABLE(DATALIST_ELEMENT) >+ bool preventTextInteraction { false }; > #endif > WebCore::FloatPoint adjustedPointForNodeRespondingToClickEvents; > WebCore::URL url; >diff --git a/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm b/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm >index caf3b3e578928428e7466133567e56a51d28f1cd..a39af222582aa657c27ede069c5c36e25bb61ad6 100644 >--- a/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm >+++ b/Source/WebKit/Shared/ios/InteractionInformationAtPosition.mm >@@ -82,6 +82,9 @@ void InteractionInformationAtPosition::encode(IPC::Encoder& encoder) const > IPC::encode(encoder, reinterpret_cast<CFDataRef>(archiver.get().encodedData)); > } > #endif >+#if ENABLE(DATALIST_ELEMENT) >+ encoder << preventTextInteraction; >+#endif > } > > bool InteractionInformationAtPosition::decode(IPC::Decoder& decoder, InteractionInformationAtPosition& result) >@@ -186,6 +189,11 @@ bool InteractionInformationAtPosition::decode(IPC::Decoder& decoder, Interaction > } > #endif > >+#if ENABLE(DATALIST_ELEMENT) >+ if (!decoder.decode(result.preventTextInteraction)) >+ return false; >+#endif >+ > return true; > } > >diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt >index 4b8d4806b44f2204658577eb7a9678cb8e3479bf..138e20e687510314c4a035781bc1c1d984b94cdd 100644 >--- a/Source/WebKit/SourcesCocoa.txt >+++ b/Source/WebKit/SourcesCocoa.txt >@@ -349,6 +349,7 @@ UIProcess/Gamepad/ios/UIGamepadProviderIOS.mm > UIProcess/Gamepad/mac/UIGamepadProviderMac.mm > > UIProcess/ios/DragDropInteractionState.mm >+UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm > > UIProcess/ios/forms/WKAirPlayRoutePicker.mm > UIProcess/ios/forms/WKDatePickerViewController.mm >diff --git a/Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.h b/Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.h >index f61cf6d85c105ee18eaa3eb45109555908bb7f44..29e3bbfc030ceca9dd6b5822d634dd6e5395e91f 100644 >--- a/Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.h >+++ b/Source/WebKit/UIProcess/WebDataListSuggestionsDropdown.h >@@ -40,7 +40,7 @@ public: > virtual ~Client() { } > > public: >- virtual void didSelectOption(String&) = 0; >+ virtual void didSelectOption(const String&) = 0; > virtual void didCloseSuggestions() = 0; > }; > >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index 6481081126a32fb4243bc5eff75b1da66a7a4122..b2575e623dfea9394ea49dc9826c443a19c008ea 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -4556,7 +4556,10 @@ void WebPageProxy::pageDidScroll() > if (m_isKeyboardAnimatingIn) > return; > #endif >+ >+#if !PLATFORM(IOS) > closeOverlayedViews(); >+#endif > } > > void WebPageProxy::runOpenPanel(uint64_t frameID, const SecurityOriginData& frameSecurityOrigin, const FileChooserSettings& settings) >@@ -4783,7 +4786,7 @@ void WebPageProxy::didCloseSuggestions() > m_process->send(Messages::WebPage::DidCloseSuggestions(), m_pageID); > } > >-void WebPageProxy::didSelectOption(String& selectedOption) >+void WebPageProxy::didSelectOption(const String& selectedOption) > { > if (!isValid()) > return; >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index 7be539858596bf153da70ed08d2e2212ac639879..adf54a776fa3bbce20627f49181f2e72029a805a 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -1526,7 +1526,7 @@ private: > void showDataListSuggestions(WebCore::DataListSuggestionInformation&&); > void handleKeydownInDataList(const String&); > void endDataListSuggestions(); >- void didSelectOption(String&) final; >+ void didSelectOption(const String&) final; > void didCloseSuggestions() final; > #endif > >diff --git a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >index 847c9f04f9bb0064f20a7c6e2258a7f19841b3d7..fac352902ebb382e4d4114b97acec323f2b28be1 100644 >--- a/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >+++ b/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm >@@ -48,6 +48,7 @@ > #import "WKWebViewContentProviderRegistry.h" > #import "WKWebViewInternal.h" > #import "WebContextMenuProxy.h" >+#import "WebDataListSuggestionsDropdownIOS.h" > #import "WebEditCommandProxy.h" > #import "WebProcessProxy.h" > #import "_WKDownloadInternal.h" >@@ -780,7 +781,7 @@ RefPtr<WebColorPicker> PageClientImpl::createColorPicker(WebPageProxy*, const We > #if ENABLE(DATALIST_ELEMENT) > RefPtr<WebDataListSuggestionsDropdown> PageClientImpl::createDataListSuggestionsDropdown(WebPageProxy& page) > { >- return nullptr; >+ return WebDataListSuggestionsDropdownIOS::create(page, m_contentView); > } > #endif > >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >index d8ff14294c393621487b406da31d9b2bf354c39d..cb975c84eea1693c367e2546e7779724366be12a 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h >@@ -44,6 +44,7 @@ > #import "WKKeyboardScrollingAnimator.h" > #import "WKShareSheet.h" > #import "WKSyntheticClickTapGestureRecognizer.h" >+#import "_WKFormInputSession.h" > #import <UIKit/UIView.h> > #import <WebCore/Color.h> > #import <WebCore/FloatQuad.h> >@@ -147,6 +148,16 @@ struct WKAutoCorrectionData { > > } > >+@class WKFocusedElementInfo; >+ >+@interface WKFormInputSession : NSObject <_WKFormInputSession> >+ >+- (instancetype)initWithContentView:(WKContentView *)view focusedElementInfo:(WKFocusedElementInfo *)elementInfo requiresStrongPasswordAssistance:(BOOL)requiresStrongPasswordAssistance; >+- (void)endEditing; >+- (void)invalidate; >+ >+@end >+ > @interface WKContentView () { > RetainPtr<UIWebTouchEventsGestureRecognizer> _touchEventGestureRecognizer; > >@@ -348,6 +359,7 @@ FOR_EACH_WKCONTENTVIEW_ACTION(DECLARE_WKCONTENTVIEW_ACTION_FOR_WEB_VIEW) > - (void)_accessibilityRetrieveRectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text; > - (void)_accessibilityStoreSelection; > - (void)_accessibilityClearSelection; >+- (WKFormInputSession *)_formInputSession; > > @property (nonatomic, readonly) WebKit::InteractionInformationAtPosition currentPositionInformation; > - (void)doAfterPositionInformationUpdate:(void (^)(WebKit::InteractionInformationAtPosition))action forRequest:(WebKit::InteractionInformationRequest)request; >diff --git a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >index e53595f0b451d99be8d019510ad122a6605091d7..7843d5a5308addc4f69906db400e74abb7e4ae5b 100644 >--- a/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >+++ b/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm >@@ -60,6 +60,7 @@ > #import "WKWebViewConfigurationPrivate.h" > #import "WKWebViewInternal.h" > #import "WKWebViewPrivate.h" >+#import "WebDataListSuggestionsDropdownIOS.h" > #import "WebEvent.h" > #import "WebIOSEventFactory.h" > #import "WebPageMessages.h" >@@ -67,7 +68,6 @@ > #import "_WKActivatedElementInfoInternal.h" > #import "_WKElementAction.h" > #import "_WKFocusedElementInfo.h" >-#import "_WKFormInputSession.h" > #import "_WKInputDelegate.h" > #import <CoreText/CTFont.h> > #import <CoreText/CTFontDescriptor.h> >@@ -285,13 +285,6 @@ const CGFloat minimumTapHighlightRadius = 2.0; > - (instancetype)initWithAssistedNodeInformation:(const AssistedNodeInformation&)information isUserInitiated:(BOOL)isUserInitiated userObject:(NSObject <NSSecureCoding> *)userObject; > @end > >-@interface WKFormInputSession : NSObject <_WKFormInputSession> >- >-- (instancetype)initWithContentView:(WKContentView *)view focusedElementInfo:(WKFocusedElementInfo *)elementInfo requiresStrongPasswordAssistance:(BOOL)requiresStrongPasswordAssistance; >-- (void)invalidate; >- >-@end >- > @implementation WKFormInputSession { > WeakObjCPtr<WKContentView> _contentView; > RetainPtr<WKFocusedElementInfo> _focusedElementInfo; >@@ -386,6 +379,12 @@ const CGFloat minimumTapHighlightRadius = 2.0; > [_contentView reloadInputViews]; > } > >+- (void)endEditing >+{ >+ if ([_customInputView conformsToProtocol:@protocol(WKFormControl)]) >+ [(id<WKFormControl>)_customInputView.get() controlEndEditing]; >+} >+ > - (NSArray<UITextSuggestion *> *)suggestions > { > return _suggestions.get(); >@@ -393,6 +392,12 @@ const CGFloat minimumTapHighlightRadius = 2.0; > > - (void)setSuggestions:(NSArray<UITextSuggestion *> *)suggestions > { >+ // Suggestions that come from a <datalist> should not be overwritten by other clients. >+#if ENABLE(DATALIST_ELEMENT) >+ if ([_contentView assistedNodeInformation].hasSuggestions && ![suggestions.firstObject isKindOfClass:[WKDataListTextSuggestion class]]) >+ return; >+#endif >+ > id <UITextInputSuggestionDelegate> suggestionDelegate = (id <UITextInputSuggestionDelegate>)[_contentView inputDelegate]; > _suggestions = adoptNS([suggestions copy]); > [suggestionDelegate setSuggestions:suggestions]; >@@ -596,6 +601,11 @@ static inline bool hasAssistedNode(WebKit::AssistedNodeInformation assistedNodeI > return (assistedNodeInformation.elementType != InputType::None); > } > >+- (WKFormInputSession *)_formInputSession >+{ >+ return _formInputSession.get(); >+} >+ > - (void)_createAndConfigureDoubleTapGestureRecognizer > { > _doubleTapGestureRecognizer = adoptNS([[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(_doubleTapRecognized:)]); >@@ -1004,6 +1014,8 @@ static inline bool hasAssistedNode(WebKit::AssistedNodeInformation assistedNodeI > if (!_webView->_activeFocusedStateRetainCount) { > // We need to complete the editing operation before we blur the element. > [_inputPeripheral endEditing]; >+ [_formInputSession endEditing]; >+ > _page->blurAssistedNode(); > } > >@@ -1751,6 +1763,11 @@ static inline bool isSamePair(UIGestureRecognizer *a, UIGestureRecognizer *b, UI > } > #endif > >+#if ENABLE(DATALIST_ELEMENT) >+ if (_positionInformation.preventTextInteraction) >+ return NO; >+#endif >+ > // If we're currently editing an assisted node, only allow the selection to move within that assisted node. > if (self.isAssistingNode) > return _positionInformation.nodeAtPositionIsAssistedNode; >@@ -3114,6 +3131,8 @@ static void selectionChangedWithTouch(WKContentView *view, const WebCore::IntPoi > > - (void)accessoryTab:(BOOL)isNext > { >+ [_formInputSession endEditing]; >+ > [_inputPeripheral endEditing]; > _inputPeripheral = nil; > >@@ -3124,7 +3143,6 @@ static void selectionChangedWithTouch(WKContentView *view, const WebCore::IntPoi > [view endSelectionChange]; > [view reloadInputViews]; > }); >- > } > > - (void)_becomeFirstResponderWithSelectionMovingForward:(BOOL)selectingForward completionHandler:(void (^)(BOOL didBecomeFirstResponder))completionHandler >@@ -3223,6 +3241,12 @@ static void selectionChangedWithTouch(WKContentView *view, const WebCore::IntPoi > _page->autofillLoginCredentials([(UITextAutofillSuggestion *)textSuggestion username], [(UITextAutofillSuggestion *)textSuggestion password]); > return; > } >+#if ENABLE(DATALIST_ELEMENT) >+ if ([textSuggestion isKindOfClass:[WKDataListTextSuggestion class]]) { >+ _page->setAssistedNodeValue([textSuggestion inputText]); >+ return; >+ } >+#endif > id <_WKInputDelegate> inputDelegate = [_webView _inputDelegate]; > if ([inputDelegate respondsToSelector:@selector(_webView:insertTextSuggestion:inInputSession:)]) > [inputDelegate _webView:_webView insertTextSuggestion:textSuggestion inInputSession:_formInputSession.get()]; >diff --git a/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.h b/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.h >new file mode 100644 >index 0000000000000000000000000000000000000000..9755e7a2902e78f34c2791919f1111f9146ea9cf >--- /dev/null >+++ b/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.h >@@ -0,0 +1,62 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if ENABLE(DATALIST_ELEMENT) && PLATFORM(IOS) >+ >+#import "UIKitSPI.h" >+#import "WebDataListSuggestionsDropdown.h" >+#include <wtf/RetainPtr.h> >+#include <wtf/Vector.h> >+ >+OBJC_CLASS WKContentView; >+OBJC_CLASS WKDataListSuggestionsControl; >+ >+@interface WKDataListTextSuggestion : UITextSuggestion >+@end >+ >+namespace WebKit { >+ >+class WebDataListSuggestionsDropdownIOS : public WebDataListSuggestionsDropdown { >+public: >+ static Ref<WebDataListSuggestionsDropdownIOS> create(WebDataListSuggestionsDropdown::Client&, WKContentView *); >+ >+ void didSelectOption(const String&); >+ >+private: >+ WebDataListSuggestionsDropdownIOS(WebDataListSuggestionsDropdown::Client&, WKContentView *); >+ >+ void show(WebCore::DataListSuggestionInformation&&) final; >+ void handleKeydownWithIdentifier(const String&) final; >+ void close() final; >+ >+ WKContentView *m_contentView; >+ RetainPtr<WKDataListSuggestionsControl> m_suggestionsControl; >+}; >+ >+} // namespace WebKit >+ >+#endif // ENABLE(DATALIST_ELEMENT) && PLATFORM(IOS) >diff --git a/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm b/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..704dbe7f7624f1cf7fe1e08e9da1403317a969be >--- /dev/null >+++ b/Source/WebKit/UIProcess/ios/WebDataListSuggestionsDropdownIOS.mm >@@ -0,0 +1,377 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "WebDataListSuggestionsDropdownIOS.h" >+ >+#if ENABLE(DATALIST_ELEMENT) && PLATFORM(IOS) >+ >+#import "WKContentView.h" >+#import "WKContentViewInteraction.h" >+#import "WKFormPeripheral.h" >+#import "WKFormPopover.h" >+#import "_WKFormInputSession.h" >+ >+static const CGFloat maxVisibleSuggestions = 5; >+static const CGFloat suggestionsPopoverCellHeight = 44; >+static const CGFloat suggestionsPopoverWidth = 320; >+static NSString * const suggestionCellReuseIdentifier = @"WKDataListSuggestionCell"; >+ >+@interface WKDataListSuggestionsControl : NSObject { >+ WebKit::WebDataListSuggestionsDropdownIOS* _dropdown; >+ Vector<String> _suggestions; >+} >+ >+@property (nonatomic, weak) WKContentView *view; >+ >+- (instancetype)initWithInformation:(WebCore::DataListSuggestionInformation&&)information inView:(WKContentView *)view; >+- (void)updateWithInformation:(WebCore::DataListSuggestionInformation&&)information; >+- (void)showSuggestionsDropdown:(WebKit::WebDataListSuggestionsDropdownIOS *)dropdown activationType:(WebCore::DataListSuggestionActivationType)activationType; >+- (void)didSelectOptionAtIndex:(NSInteger)index; >+- (void)invalidate; >+ >+- (NSArray<WKDataListTextSuggestion *> *)textSuggestions; >+- (NSInteger)suggestionsCount; >+- (String)suggestionAtIndex:(NSInteger)index; >+- (NSTextAlignment)textAlignment; >+@end >+ >+@interface WKDataListSuggestionsPicker : WKDataListSuggestionsControl <UIPickerViewDataSource, UIPickerViewDelegate> >+@end >+ >+@interface WKDataListSuggestionsPickerView : UIPickerView <WKFormControl> >+@property (nonatomic, weak) WKDataListSuggestionsControl *control; >+@end >+ >+@interface WKDataListSuggestionsPopover : WKDataListSuggestionsControl >+@end >+ >+@interface WKDataListSuggestionsViewController : UITableViewController >+@property (nonatomic, weak) WKDataListSuggestionsControl *control; >+ >+- (void)reloadData; >+@end >+ >+@implementation WKDataListTextSuggestion >+@end >+ >+#pragma mark - WebDataListSuggestionsDropdownIOS >+ >+namespace WebKit { >+ >+Ref<WebDataListSuggestionsDropdownIOS> WebDataListSuggestionsDropdownIOS::create(WebDataListSuggestionsDropdown::Client& client, WKContentView *view) >+{ >+ return adoptRef(*new WebDataListSuggestionsDropdownIOS(client, view)); >+} >+ >+WebDataListSuggestionsDropdownIOS::WebDataListSuggestionsDropdownIOS(WebDataListSuggestionsDropdown::Client& client, WKContentView *view) >+ : WebDataListSuggestionsDropdown(client) >+ , m_contentView(view) >+{ >+} >+ >+void WebDataListSuggestionsDropdownIOS::show(WebCore::DataListSuggestionInformation&& information) >+{ >+ if (m_suggestionsControl) { >+ [m_suggestionsControl updateWithInformation:WTFMove(information)]; >+ return; >+ } >+ >+ WebCore::DataListSuggestionActivationType type = information.activationType; >+ >+ if (currentUserInterfaceIdiomIsPad()) >+ m_suggestionsControl = adoptNS([[WKDataListSuggestionsPopover alloc] initWithInformation:WTFMove(information) inView:m_contentView]); >+ else >+ m_suggestionsControl = adoptNS([[WKDataListSuggestionsPicker alloc] initWithInformation:WTFMove(information) inView:m_contentView]); >+ >+ [m_suggestionsControl showSuggestionsDropdown:this activationType:type]; >+} >+ >+void WebDataListSuggestionsDropdownIOS::handleKeydownWithIdentifier(const String&) >+{ >+} >+ >+void WebDataListSuggestionsDropdownIOS::close() >+{ >+ [m_suggestionsControl invalidate]; >+ m_suggestionsControl = nil; >+ m_client->didCloseSuggestions(); >+} >+ >+void WebDataListSuggestionsDropdownIOS::didSelectOption(const String& selectedOption) >+{ >+ if (!m_client) >+ return; >+ >+ m_client->didSelectOption(selectedOption); >+ close(); >+} >+ >+} // namespace WebKit >+ >+#pragma mark - WKDataListSuggestionsControl >+ >+@implementation WKDataListSuggestionsControl >+ >+- (instancetype)initWithInformation:(WebCore::DataListSuggestionInformation&&)information inView:(WKContentView *)view >+{ >+ if (!(self = [super init])) >+ return nil; >+ >+ _view = view; >+ _suggestions = WTFMove(information.suggestions); >+ >+ return self; >+} >+ >+- (void)updateWithInformation:(WebCore::DataListSuggestionInformation&&)information >+{ >+ _suggestions = WTFMove(information.suggestions); >+} >+ >+- (void)showSuggestionsDropdown:(WebKit::WebDataListSuggestionsDropdownIOS *)dropdown activationType:(WebCore::DataListSuggestionActivationType)activationType >+{ >+ _dropdown = dropdown; >+} >+ >+- (void)didSelectOptionAtIndex:(NSInteger)index >+{ >+ _dropdown->didSelectOption(_suggestions[index]); >+} >+ >+- (void)invalidate >+{ >+} >+ >+- (NSArray<WKDataListTextSuggestion *> *)textSuggestions >+{ >+ NSMutableArray *suggestions = [NSMutableArray array]; >+ >+ for (auto suggestion : _suggestions) { >+ [suggestions addObject:[WKDataListTextSuggestion textSuggestionWithInputText:suggestion]]; >+ if (suggestions.count == 3) >+ break; >+ } >+ >+ return suggestions; >+} >+ >+- (NSInteger)suggestionsCount >+{ >+ return _suggestions.size(); >+} >+ >+- (String)suggestionAtIndex:(NSInteger)index >+{ >+ return _suggestions[index]; >+} >+ >+- (NSTextAlignment)textAlignment >+{ >+ return _view.assistedNodeInformation.isRTL ? NSTextAlignmentRight : NSTextAlignmentLeft; >+} >+ >+@end >+ >+#pragma mark - WKDataListSuggestionsPicker >+ >+@implementation WKDataListSuggestionsPicker { >+ RetainPtr<WKDataListSuggestionsPickerView> _pickerView; >+} >+ >+- (instancetype)initWithInformation:(WebCore::DataListSuggestionInformation&&)information inView:(WKContentView *)view >+{ >+ if (!(self = [super initWithInformation:WTFMove(information) inView:view])) >+ return nil; >+ >+ _pickerView = adoptNS([[WKDataListSuggestionsPickerView alloc] initWithFrame:CGRectZero]); >+ [_pickerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; >+ [_pickerView setDataSource:self]; >+ [_pickerView setDelegate:self]; >+ [_pickerView setControl:self]; >+ [_pickerView setSize:[UIKeyboard defaultSizeForInterfaceOrientation:UIApp.interfaceOrientation]]; >+ >+ return self; >+} >+ >+- (void)updateWithInformation:(WebCore::DataListSuggestionInformation&&)information >+{ >+ [super updateWithInformation:WTFMove(information)]; >+ if (information.activationType != WebCore::DataListSuggestionActivationType::IndicatorClicked) { >+ [[self.view _formInputSession] setCustomInputView:nil]; >+ [[self.view _formInputSession] setSuggestions:[self textSuggestions]]; >+ return; >+ } >+ >+ [[self.view _formInputSession] setCustomInputView:_pickerView.get()]; >+ >+ [_pickerView reloadAllComponents]; >+ [_pickerView selectRow:0 inComponent:0 animated:NO]; >+} >+ >+- (void)showSuggestionsDropdown:(WebKit::WebDataListSuggestionsDropdownIOS *)dropdown activationType:(WebCore::DataListSuggestionActivationType)activationType >+{ >+ [super showSuggestionsDropdown:dropdown activationType:activationType]; >+ if (activationType == WebCore::DataListSuggestionActivationType::IndicatorClicked) { >+ [[self.view _formInputSession] setCustomInputView:_pickerView.get()]; >+ [_pickerView selectRow:0 inComponent:0 animated:NO]; >+ } else >+ [[self.view _formInputSession] setSuggestions:[self textSuggestions]]; >+} >+ >+- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView >+{ >+ return 1; >+} >+ >+- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)columnIndex >+{ >+ return [self suggestionsCount]; >+} >+ >+- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component >+{ >+ return [self suggestionAtIndex:row]; >+} >+ >+- (void)invalidate >+{ >+ if ([[self.view _formInputSession] customInputView] == _pickerView.get()) >+ [[self.view _formInputSession] setCustomInputView:nil]; >+ >+ [_pickerView setDelegate:nil]; >+ [_pickerView setDataSource:nil]; >+ [_pickerView setControl:nil]; >+} >+ >+@end >+ >+@implementation WKDataListSuggestionsPickerView >+ >+- (UIView *)controlView >+{ >+ return self; >+} >+ >+- (void)controlBeginEditing >+{ >+} >+ >+- (void)controlEndEditing >+{ >+ [self.control didSelectOptionAtIndex:[self selectedRowInComponent:0]]; >+} >+ >+@end >+ >+#pragma mark - WKDataListSuggestionsPopover >+ >+@implementation WKDataListSuggestionsPopover { >+ RetainPtr<WKFormRotatingAccessoryPopover> _popover; >+ RetainPtr<WKDataListSuggestionsViewController> _suggestionsViewController; >+} >+ >+- (instancetype)initWithInformation:(WebCore::DataListSuggestionInformation&&)information inView:(WKContentView *)view >+{ >+ if (!(self = [super initWithInformation:WTFMove(information) inView:view])) >+ return nil; >+ >+ _popover = adoptNS([[WKFormRotatingAccessoryPopover alloc] initWithView:view]); >+ >+ return self; >+} >+ >+- (void)updateWithInformation:(WebCore::DataListSuggestionInformation&&)information >+{ >+ [super updateWithInformation:WTFMove(information)]; >+ [_suggestionsViewController reloadData]; >+ [[self.view _formInputSession] setSuggestions:[self textSuggestions]]; >+} >+ >+- (void)showSuggestionsDropdown:(WebKit::WebDataListSuggestionsDropdownIOS *)dropdown activationType:(WebCore::DataListSuggestionActivationType)activationType >+{ >+ [super showSuggestionsDropdown:dropdown activationType:activationType]; >+ >+ _suggestionsViewController = adoptNS([[WKDataListSuggestionsViewController alloc] initWithStyle:UITableViewStylePlain]); >+ [_suggestionsViewController setControl:self]; >+ [_suggestionsViewController reloadData]; >+ [[self.view _formInputSession] setSuggestions:[self textSuggestions]]; >+ >+#pragma clang diagnostic push >+#pragma clang diagnostic ignored "-Wdeprecated-declarations" >+ [_popover setPopoverController:[[[UIPopoverController alloc] initWithContentViewController:_suggestionsViewController.get()] autorelease]]; >+#pragma clang diagnostic pop >+ >+ [_popover presentPopoverAnimated:NO]; >+} >+ >+- (void)invalidate >+{ >+ [_suggestionsViewController setControl:nil]; >+} >+ >+- (void)didSelectOptionAtIndex:(NSInteger)index >+{ >+ [super didSelectOptionAtIndex:index]; >+ [[_popover popoverController] dismissPopoverAnimated:YES]; >+ [[self.view _formInputSession] setSuggestions:@[ [WKDataListTextSuggestion textSuggestionWithInputText:[self suggestionAtIndex:index]] ]]; >+} >+ >+@end >+ >+@implementation WKDataListSuggestionsViewController >+ >+- (void)reloadData >+{ >+ [self.tableView reloadData]; >+ [self setPreferredContentSize:CGSizeMake(suggestionsPopoverWidth, maxVisibleSuggestions * suggestionsPopoverCellHeight + suggestionsPopoverCellHeight / 2)]; >+} >+ >+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section >+{ >+ return [self.control suggestionsCount]; >+} >+ >+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath >+{ >+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:suggestionCellReuseIdentifier]; >+ if (!cell) >+ cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:suggestionCellReuseIdentifier] autorelease]; >+ >+ cell.textLabel.text = [self.control suggestionAtIndex:indexPath.row]; >+ cell.textLabel.lineBreakMode = NSLineBreakByTruncatingTail; >+ cell.textLabel.textAlignment = [self.control textAlignment]; >+ >+ return cell; >+} >+ >+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath >+{ >+ [self.control didSelectOptionAtIndex:indexPath.row]; >+} >+ >+@end >+ >+#endif // ENABLE(DATALIST_ELEMENT) && PLATFORM(IOS) >diff --git a/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.h b/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.h >index 018cc6b2cf0c15063b5c2864bb27511cf623e985..80bf94811dc244915ca55440255bf880cef0e1fb 100644 >--- a/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.h >+++ b/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.h >@@ -39,7 +39,7 @@ public: > static Ref<WebDataListSuggestionsDropdownMac> create(WebDataListSuggestionsDropdown::Client&, NSView *); > ~WebDataListSuggestionsDropdownMac(); > >- void didSelectOption(String&); >+ void didSelectOption(const String&); > > private: > WebDataListSuggestionsDropdownMac(WebDataListSuggestionsDropdown::Client&, NSView *); >diff --git a/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm b/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm >index 4e8619101bae9ee54b1384a5b045020fca84093c..3e795feb5099cad49431aff0c7a7502d0ab4a0fb 100644 >--- a/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm >+++ b/Source/WebKit/UIProcess/mac/WebDataListSuggestionsDropdownMac.mm >@@ -106,7 +106,7 @@ void WebDataListSuggestionsDropdownMac::show(WebCore::DataListSuggestionInformat > [m_dropdownUI showSuggestionsDropdown:this]; > } > >-void WebDataListSuggestionsDropdownMac::didSelectOption(String& selectedOption) >+void WebDataListSuggestionsDropdownMac::didSelectOption(const String& selectedOption) > { > if (!m_client) > return; >diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >index 938443b102c9c7a2b34858560bb0848f477b6849..d3f8b9ea9b9237b05160e572a6e850ce364597d2 100644 >--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj >+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >@@ -1811,6 +1811,7 @@ > E548EBD121015F0E00BE3C32 /* WKFormColorPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = E548EBCF21015F0E00BE3C32 /* WKFormColorPicker.h */; }; > E568B91F20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h in Headers */ = {isa = PBXBuildFile; fileRef = E568B91E20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h */; }; > E568B92220A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h in Headers */ = {isa = PBXBuildFile; fileRef = E568B92020A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h */; }; >+ E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */; }; > E5CB07DC20E1678F0022C183 /* WKFormColorControl.h in Headers */ = {isa = PBXBuildFile; fileRef = E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */; }; > ECA680D81E690E2500731D20 /* WebProcessCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = ECA680D71E690DF800731D20 /* WebProcessCocoa.h */; settings = {ATTRIBUTES = (Private, ); }; }; > ED82A7F2128C6FAF004477B3 /* WKBundlePageOverlay.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A22F0FF1289FCD90085E74F /* WKBundlePageOverlay.h */; settings = {ATTRIBUTES = (Private, ); }; }; >@@ -4656,6 +4657,8 @@ > E568B91E20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebDataListSuggestionsDropdown.h; sourceTree = "<group>"; }; > E568B92020A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebDataListSuggestionsDropdownMac.h; sourceTree = "<group>"; }; > E568B92120A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; path = WebDataListSuggestionsDropdownMac.mm; sourceTree = "<group>"; }; >+ E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebDataListSuggestionsDropdownIOS.h; path = ios/WebDataListSuggestionsDropdownIOS.h; sourceTree = "<group>"; }; >+ E5BEF6812130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebDataListSuggestionsDropdownIOS.mm; path = ios/WebDataListSuggestionsDropdownIOS.mm; sourceTree = "<group>"; }; > E5CB07DA20E1678F0022C183 /* WKFormColorControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKFormColorControl.h; path = ios/forms/WKFormColorControl.h; sourceTree = "<group>"; }; > E5CB07DB20E1678F0022C183 /* WKFormColorControl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKFormColorControl.mm; path = ios/forms/WKFormColorControl.mm; sourceTree = "<group>"; }; > ECA680D31E6904B500731D20 /* ExtraPrivateSymbolsForTAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtraPrivateSymbolsForTAPI.h; sourceTree = "<group>"; }; >@@ -5977,6 +5980,8 @@ > 2DAF06D518BD1A470081CEB1 /* SmartMagnificationController.mm */, > 2DA944A91884E9BA00ED86DB /* TextCheckerIOS.mm */, > 2DF9593418A42412009785A1 /* ViewGestureControllerIOS.mm */, >+ E5BEF6802130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.h */, >+ E5BEF6812130C47F00F31111 /* WebDataListSuggestionsDropdownIOS.mm */, > 2D3EF4411917646300034184 /* WebMemoryPressureHandlerIOS.h */, > 2D3EF4401917646300034184 /* WebMemoryPressureHandlerIOS.mm */, > 2DA944AB1884E9BA00ED86DB /* WebPageProxyIOS.mm */, >@@ -9510,6 +9515,7 @@ > 1AA83F6D1A5B63FF00026EC6 /* WebDatabaseProvider.h in Headers */, > E52CF55220A35C3A00DADA27 /* WebDataListSuggestionPicker.h in Headers */, > E568B91F20A3AB2F00E3C856 /* WebDataListSuggestionsDropdown.h in Headers */, >+ E5BEF6822130C48000F31111 /* WebDataListSuggestionsDropdownIOS.h in Headers */, > E568B92220A3AC6A00E3C856 /* WebDataListSuggestionsDropdownMac.h in Headers */, > CD19A26E1A13E834008D650E /* WebDiagnosticLoggingClient.h in Headers */, > 1A5B1C5518987EDF004FCF9B /* WebDocumentLoader.h in Headers */, >diff --git a/Source/WebKit/WebProcess/WebPage/WebPage.cpp b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >index b745aec8d754653f30244e1e5cc13e5d1d208635..3cca8210b874ca16d413ea10016b6edf6848c6fd 100644 >--- a/Source/WebKit/WebProcess/WebPage/WebPage.cpp >+++ b/Source/WebKit/WebProcess/WebPage/WebPage.cpp >@@ -3593,7 +3593,8 @@ void WebPage::didSelectDataListOption(const String& selectedOption) > > void WebPage::didCloseSuggestions() > { >- m_activeDataListSuggestionPicker->didCloseSuggestions(); >+ if (m_activeDataListSuggestionPicker) >+ m_activeDataListSuggestionPicker->didCloseSuggestions(); > m_activeDataListSuggestionPicker = nullptr; > } > >diff --git a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >index ae58e0904e8d4db9a95856d623f00205e5d8e12e..a94763bf13668e1818d8821525b7aa89db2eb7cf 100644 >--- a/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >+++ b/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm >@@ -2209,6 +2209,18 @@ void WebPage::getPositionInformation(const InteractionInformationRequest& reques > } > } > >+ // Prevent the callout bar from showing when tapping on the datalist button. >+#if ENABLE(DATALIST_ELEMENT) >+ if (is<HTMLInputElement>(*hitNode)) { >+ const HTMLInputElement& input = downcast<HTMLInputElement>(*hitNode); >+ if (input.list()) { >+ HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(request.point, HitTestRequest::ReadOnly | HitTestRequest::Active); >+ if (result.innerNode() == input.dataListButtonElement()) >+ info.preventTextInteraction = true; >+ } >+ } >+#endif >+ > #if ENABLE(DATA_INTERACTION) > info.hasSelectionAtPosition = m_page->hasSelectionAtPosition(adjustedPoint); > #endif >@@ -2477,6 +2489,9 @@ void WebPage::getAssistedNodeInformation(AssistedNodeInformation& information) > } > #endif > >+#if ENABLE(DATALIST_ELEMENT) >+ information.hasSuggestions = !!element.list(); >+#endif > information.inputMode = element.canonicalInputMode(); > information.isReadOnly = element.isReadOnly(); > information.value = element.value();
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186714
:
347585
|
347869
|
348054
|
348056
|
348221
| 348577