Add Legacy WebKit SPI and WebKit IPI to show and hide placeholder
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Jan 2020 23:10:27 +0000 (23:10 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Jan 2020 23:10:27 +0000 (23:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=206459
<rdar://problem/58700534>

Reviewed by Wenson Hsieh.

Source/WebCore:

Adds setter and getter to update whether the placeholder can be shown.

Test: fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder.html

* html/HTMLTextFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::HTMLTextFormControlElement): Initialize state. Default to can show
the placeholder to keep the behavior we have currently.
(WebCore::HTMLTextFormControlElement::placeholderShouldBeVisible const): Modified to account for m_canShowPlaceholder.
(WebCore::HTMLTextFormControlElement::setCanShowPlaceholder): Added. Update state and invalidate style.
* html/HTMLTextFormControlElement.h:
(WebCore::HTMLTextFormControlElement::canShowPlaceholder const): Added.
* testing/Internals.cpp:
(WebCore::Internals::setCanShowPlaceholder): Added. For testing purposes.
* testing/Internals.h:
* testing/Internals.idl:

Source/WebKit:

Add Modern WebKit IPI to control whether the placeholder can be shown or not when a form
control is empty. This is for aesthetics.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::setCanShowPlaceholder): Added.
* UIProcess/WebPageProxy.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setCanShowPlaceholder): Added. Maps the input text to its element. If it's
a HTML text form control element then calls through to HTMLTextFormControlElement::setCanShowPlaceholder().
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
Added new message.

Source/WebKitLegacy/mac:

Add Legacy WebKit SPI to allow a client to control whether the placeholder can be shown or
not when a form control is empty. This is for aesthetics.

* DOM/DOMHTMLInputElement.mm:
(-[DOMHTMLInputElement canShowPlaceholder]): Added.
(-[DOMHTMLInputElement setCanShowPlaceholder:]): Added.
* DOM/DOMHTMLInputElementPrivate.h:
* DOM/DOMHTMLTextAreaElement.mm:
(-[DOMHTMLTextAreaElement canShowPlaceholder]): Added.
(-[DOMHTMLTextAreaElement setCanShowPlaceholder:]): Added.
* DOM/DOMHTMLTextAreaElementPrivate.h:

LayoutTests:

Adds a new test to ensure that HTMLTextFormControlElement::setCanShowPlaceholder() works.

* fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder-expected.txt: Added.
* fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@254886 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder-expected.txt [new file with mode: 0644]
LayoutTests/fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/HTMLTextFormControlElement.cpp
Source/WebCore/html/HTMLTextFormControlElement.h
Source/WebCore/testing/Internals.cpp
Source/WebCore/testing/Internals.h
Source/WebCore/testing/Internals.idl
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Source/WebKit/WebProcess/WebPage/WebPage.h
Source/WebKit/WebProcess/WebPage/WebPage.messages.in
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/DOM/DOMHTMLInputElement.mm
Source/WebKitLegacy/mac/DOM/DOMHTMLInputElementPrivate.h
Source/WebKitLegacy/mac/DOM/DOMHTMLTextAreaElement.mm
Source/WebKitLegacy/mac/DOM/DOMHTMLTextAreaElementPrivate.h

index 7fd1ca9..665b97f 100644 (file)
@@ -1,3 +1,16 @@
+2020-01-21  Daniel Bates  <dabates@apple.com>
+
+        Add Legacy WebKit SPI and WebKit IPI to show and hide placeholder
+        https://bugs.webkit.org/show_bug.cgi?id=206459
+        <rdar://problem/58700534>
+
+        Reviewed by Wenson Hsieh.
+
+        Adds a new test to ensure that HTMLTextFormControlElement::setCanShowPlaceholder() works.
+
+        * fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder-expected.txt: Added.
+        * fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder.html: Added.
+
 2020-01-21  Justin Fan  <justin_fan@apple.com>
 
         [WebGL2] Sampler objects
diff --git a/LayoutTests/fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder-expected.txt b/LayoutTests/fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder-expected.txt
new file mode 100644 (file)
index 0000000..c1133f6
--- /dev/null
@@ -0,0 +1,16 @@
+Tests that the placeholder can be hidden and shown for empty fields via setCanShowPlaceholder().
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Disallow showing of placeholder:
+PASS internals.visiblePlaceholder(document.querySelector("input")) is ""
+PASS internals.visiblePlaceholder(document.querySelector("textarea")) is ""
+
+Allow showing of placeholder:
+PASS internals.visiblePlaceholder(document.querySelector("input")) is "first"
+PASS internals.visiblePlaceholder(document.querySelector("textarea")) is "second"
+PASS successfullyParsed is true
+
+TEST COMPLETE
diff --git a/LayoutTests/fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder.html b/LayoutTests/fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder.html
new file mode 100644 (file)
index 0000000..9ae0466
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../resources/js-test.js"></script>
+</head>
+<body>
+<input type="text" placeholder="first">
+<textarea placeholder="second"></textarea>
+<script>
+description("Tests that the placeholder can be hidden and shown for empty fields via setCanShowPlaceholder().");
+
+function testThatPlaceholderIsHidden(tagName)
+{
+    let element = document.querySelector(tagName);
+    internals.setCanShowPlaceholder(element, false);
+    shouldBeEqualToString(`internals.visiblePlaceholder(document.querySelector("${tagName}"))`, "");
+}
+
+function testThatPlaceholderIsEqualToString(tagName, expectedText)
+{
+    let element = document.querySelector(tagName);
+    internals.setCanShowPlaceholder(element, true);
+    shouldBeEqualToString(`internals.visiblePlaceholder(document.querySelector("${tagName}"))`, expectedText);
+}
+
+function runTest()
+{
+    if (!window.internals) {
+        testFailed("Must have window.internals.");
+        return;
+    }
+
+    debug("Disallow showing of placeholder:");
+    testThatPlaceholderIsHidden("input");
+    testThatPlaceholderIsHidden("textarea");
+
+    debug("<br>Allow showing of placeholder:");
+    testThatPlaceholderIsEqualToString("input", "first");
+    testThatPlaceholderIsEqualToString("textarea", "second");
+}
+
+runTest();
+</script>
+</body>
+</html>
index e6aa3d7..4595b4a 100644 (file)
@@ -1,3 +1,27 @@
+2020-01-21  Daniel Bates  <dabates@apple.com>
+
+        Add Legacy WebKit SPI and WebKit IPI to show and hide placeholder
+        https://bugs.webkit.org/show_bug.cgi?id=206459
+        <rdar://problem/58700534>
+
+        Reviewed by Wenson Hsieh.
+
+        Adds setter and getter to update whether the placeholder can be shown.
+
+        Test: fast/forms/placeholder-show-and-hide-via-setCanShowPlaceholder.html
+
+        * html/HTMLTextFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::HTMLTextFormControlElement): Initialize state. Default to can show
+        the placeholder to keep the behavior we have currently.
+        (WebCore::HTMLTextFormControlElement::placeholderShouldBeVisible const): Modified to account for m_canShowPlaceholder.
+        (WebCore::HTMLTextFormControlElement::setCanShowPlaceholder): Added. Update state and invalidate style.
+        * html/HTMLTextFormControlElement.h:
+        (WebCore::HTMLTextFormControlElement::canShowPlaceholder const): Added.
+        * testing/Internals.cpp:
+        (WebCore::Internals::setCanShowPlaceholder): Added. For testing purposes.
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2020-01-21  Rob Buis  <rbuis@igalia.com>
 
         Add build flag for stale-while-revalidate
index f5342f5..723228b 100644 (file)
@@ -65,6 +65,7 @@ HTMLTextFormControlElement::HTMLTextFormControlElement(const QualifiedName& tagN
     , m_cachedSelectionDirection(SelectionHasNoDirection)
     , m_lastChangeWasUserEdit(false)
     , m_isPlaceholderVisible(false)
+    , m_canShowPlaceholder(true)
     , m_cachedSelectionStart(-1)
     , m_cachedSelectionEnd(-1)
 {
@@ -158,7 +159,7 @@ bool HTMLTextFormControlElement::placeholderShouldBeVisible() const
 {
     // This function is used by the style resolver to match the :placeholder-shown pseudo class.
     // Since it is used for styling, it must not use any value depending on the style.
-    return supportsPlaceholder() && isEmptyValue() && !isPlaceholderEmpty();
+    return supportsPlaceholder() && isEmptyValue() && !isPlaceholderEmpty() && m_canShowPlaceholder;
 }
 
 void HTMLTextFormControlElement::updatePlaceholderVisibility()
@@ -172,6 +173,12 @@ void HTMLTextFormControlElement::updatePlaceholderVisibility()
     invalidateStyleForSubtree();
 }
 
+void HTMLTextFormControlElement::setCanShowPlaceholder(bool canShowPlaceholder)
+{
+    m_canShowPlaceholder = canShowPlaceholder;
+    updatePlaceholderVisibility();
+}
+
 void HTMLTextFormControlElement::setSelectionStart(int start)
 {
     setSelectionRange(start, std::max(start, selectionEnd()), selectionDirection());
index 7494d25..407894f 100644 (file)
@@ -62,6 +62,9 @@ public:
     virtual HTMLElement* placeholderElement() const = 0;
     void updatePlaceholderVisibility();
 
+    WEBCORE_EXPORT void setCanShowPlaceholder(bool);
+    bool canShowPlaceholder() const { return m_canShowPlaceholder; }
+
     int indexForVisiblePosition(const VisiblePosition&) const;
     WEBCORE_EXPORT VisiblePosition visiblePositionForIndex(int index) const;
     WEBCORE_EXPORT int selectionStart() const;
@@ -160,6 +163,7 @@ private:
     unsigned m_cachedSelectionDirection : 2;
     unsigned m_lastChangeWasUserEdit : 1;
     unsigned m_isPlaceholderVisible : 1;
+    unsigned m_canShowPlaceholder : 1;
 
     String m_textAsOfLastFormControlChangeEvent;
 
index a60f9cf..57954ce 100644 (file)
@@ -1420,6 +1420,12 @@ String Internals::visiblePlaceholder(Element& element)
     return String();
 }
 
+void Internals::setCanShowPlaceholder(Element& element, bool canShowPlaceholder)
+{
+    if (is<HTMLTextFormControlElement>(element))
+        downcast<HTMLTextFormControlElement>(element).setCanShowPlaceholder(canShowPlaceholder);
+}
+
 void Internals::selectColorInColorChooser(HTMLInputElement& element, const String& colorValue)
 {
     element.selectColor(colorValue);
index 5bdb0e3..09d2495 100644 (file)
@@ -236,6 +236,8 @@ public:
     Node* parentTreeScope(Node&);
 
     String visiblePlaceholder(Element&);
+    void setCanShowPlaceholder(Element&, bool);
+
     void selectColorInColorChooser(HTMLInputElement&, const String& colorValue);
     ExceptionOr<Vector<String>> formControlStateOfPreviousHistoryItem();
     ExceptionOr<void> setFormControlStateOfPreviousHistoryItem(const Vector<String>&);
index 119e40f..3493872 100644 (file)
@@ -307,6 +307,8 @@ enum CompositingPolicy {
     AutoFillButtonType autoFillButtonType(HTMLInputElement inputElement);
     AutoFillButtonType lastAutoFillButtonType(HTMLInputElement inputElement);
 
+    void setCanShowPlaceholder(Element element, boolean canShowPlaceholder);
+
     [MayThrowException] Range? rangeOfString(DOMString text, Range? referenceRange, sequence<DOMString> findOptions);
     [MayThrowException] unsigned long countMatchesForText(DOMString text, sequence<DOMString> findOptions, DOMString markMatches);
     [MayThrowException] unsigned long countFindMatches(DOMString text, sequence<DOMString> findOptions);
index 3e07ebc..847913b 100644 (file)
@@ -1,3 +1,24 @@
+2020-01-21  Daniel Bates  <dabates@apple.com>
+
+        Add Legacy WebKit SPI and WebKit IPI to show and hide placeholder
+        https://bugs.webkit.org/show_bug.cgi?id=206459
+        <rdar://problem/58700534>
+
+        Reviewed by Wenson Hsieh.
+
+        Add Modern WebKit IPI to control whether the placeholder can be shown or not when a form
+        control is empty. This is for aesthetics.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::setCanShowPlaceholder): Added.
+        * UIProcess/WebPageProxy.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::setCanShowPlaceholder): Added. Maps the input text to its element. If it's
+        a HTML text form control element then calls through to HTMLTextFormControlElement::setCanShowPlaceholder().
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        Added new message.
+
 2020-01-21  Jiewen Tan  <jiewen_tan@apple.com>
 
         ProvisionalPageProxy::loadData should pass last navigation's shouldOpenExternalURLsPolicy flag to WebPageProxy
index 5e203b3..6f1a3ea 100644 (file)
@@ -9664,6 +9664,12 @@ void WebPageProxy::focusTextInputContext(const WebCore::ElementContext& context,
     sendWithAsyncReply(Messages::WebPage::FocusTextInputContext(context), WTFMove(completionHandler));
 }
 
+void WebPageProxy::setCanShowPlaceholder(const WebCore::ElementContext& context, bool canShowPlaceholder)
+{
+    if (hasRunningProcess())
+        send(Messages::WebPage::SetCanShowPlaceholder(context, canShowPlaceholder));
+}
+
 Logger& WebPageProxy::logger()
 {
     if (!m_logger) {
index 6c49ecd..477cd3f 100644 (file)
@@ -687,6 +687,7 @@ public:
 
     void textInputContextsInRect(WebCore::FloatRect, CompletionHandler<void(const Vector<WebCore::ElementContext>&)>&&);
     void focusTextInputContext(const WebCore::ElementContext&, CompletionHandler<void(bool)>&&);
+    void setCanShowPlaceholder(const WebCore::ElementContext&, bool);
 
 #if ENABLE(UI_SIDE_COMPOSITING)
     void updateVisibleContentRects(const VisibleContentRectUpdateInfo&);
index e3ea52c..862b13a 100644 (file)
@@ -6827,6 +6827,13 @@ void WebPage::focusTextInputContext(const WebCore::ElementContext& textInputCont
     completionHandler(element);
 }
 
+void WebPage::setCanShowPlaceholder(const WebCore::ElementContext& elementContext, bool canShowPlaceholder)
+{
+    RefPtr<Element> element = elementForContext(elementContext);
+    if (is<HTMLTextFormControlElement>(element))
+        downcast<HTMLTextFormControlElement>(*element).setCanShowPlaceholder(canShowPlaceholder);
+}
+
 Element* WebPage::elementForContext(const WebCore::ElementContext& elementContext) const
 {
     if (elementContext.webPageIdentifier != m_identifier)
index d48817c..044a1ac 100644 (file)
@@ -631,6 +631,7 @@ public:
 
     void textInputContextsInRect(WebCore::FloatRect, CompletionHandler<void(const Vector<WebCore::ElementContext>&)>&&);
     void focusTextInputContext(const WebCore::ElementContext&, CompletionHandler<void(bool)>&&);
+    void setCanShowPlaceholder(const WebCore::ElementContext&, bool);
 
 #if PLATFORM(IOS_FAMILY)
     WebCore::FloatSize screenSize() const;
index 211b093..229a300 100644 (file)
@@ -574,6 +574,7 @@ GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType
 
     TextInputContextsInRect(WebCore::FloatRect rect) -> (Vector<struct WebCore::ElementContext> contexts) Async
     FocusTextInputContext(struct WebCore::ElementContext context) -> (bool success) Async
+    SetCanShowPlaceholder(struct WebCore::ElementContext context, bool canShowPlaceholder)
 
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
     WasLoadedWithDataTransferFromPrevalentResource()
index 06c3936..b4c39f2 100644 (file)
@@ -1,3 +1,23 @@
+2020-01-21  Daniel Bates  <dabates@apple.com>
+
+        Add Legacy WebKit SPI and WebKit IPI to show and hide placeholder
+        https://bugs.webkit.org/show_bug.cgi?id=206459
+        <rdar://problem/58700534>
+
+        Reviewed by Wenson Hsieh.
+
+        Add Legacy WebKit SPI to allow a client to control whether the placeholder can be shown or
+        not when a form control is empty. This is for aesthetics.
+
+        * DOM/DOMHTMLInputElement.mm:
+        (-[DOMHTMLInputElement canShowPlaceholder]): Added.
+        (-[DOMHTMLInputElement setCanShowPlaceholder:]): Added.
+        * DOM/DOMHTMLInputElementPrivate.h:
+        * DOM/DOMHTMLTextAreaElement.mm:
+        (-[DOMHTMLTextAreaElement canShowPlaceholder]): Added.
+        (-[DOMHTMLTextAreaElement setCanShowPlaceholder:]): Added.
+        * DOM/DOMHTMLTextAreaElementPrivate.h:
+
 2020-01-21  Rob Buis  <rbuis@igalia.com>
 
         Add build flag for stale-while-revalidate
index 7ae5e06..c3f42e1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 }
 #endif // TARGET_OS_IPHONE
 
+- (BOOL)canShowPlaceholder
+{
+    WebCore::JSMainThreadNullState state;
+    return IMPL->canShowPlaceholder();
+}
+
+- (void)setCanShowPlaceholder:(BOOL)canShowPlaceholder
+{
+    WebCore::JSMainThreadNullState state;
+    IMPL->setCanShowPlaceholder(canShowPlaceholder);
+}
+
 @end
 
 WebCore::HTMLInputElement* core(DOMHTMLInputElement *wrapper)
index 18d9376..480d5d2 100644 (file)
@@ -53,6 +53,7 @@
 @property (copy) NSString *selectionDirection;
 @property BOOL incremental;
 @property BOOL capture;
+@property (nonatomic) BOOL canShowPlaceholder;
 
 - (void)stepUp:(int)n;
 - (void)stepDown:(int)n;
index fb32bc2..089982a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2004-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2004-2016, 2020 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -323,4 +323,16 @@ DOMHTMLTextAreaElement *kit(WebCore::HTMLTextAreaElement* value)
     unwrap(*self).setSelectionRange(start, end);
 }
 
+- (BOOL)canShowPlaceholder
+{
+    WebCore::JSMainThreadNullState state;
+    return unwrap(*self).canShowPlaceholder();
+}
+
+- (void)setCanShowPlaceholder:(BOOL)canShowPlaceholder
+{
+    WebCore::JSMainThreadNullState state;
+    unwrap(*self).setCanShowPlaceholder(canShowPlaceholder);
+}
+
 @end
index aa22829..0fc21a6 100644 (file)
@@ -39,6 +39,7 @@
 @property (readonly, strong) DOMNodeList *labels;
 @property (copy) NSString *selectionDirection;
 @property (copy) NSString *autocomplete;
+@property (nonatomic) BOOL canShowPlaceholder;
 - (void)setRangeText:(NSString *)replacement;
 - (void)setRangeText:(NSString *)replacement start:(unsigned)start end:(unsigned)end selectionMode:(NSString *)selectionMode;
 @end