Diff
Modified: trunk/LayoutTests/ChangeLog (258049 => 258050)
--- trunk/LayoutTests/ChangeLog 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/LayoutTests/ChangeLog 2020-03-07 03:04:32 UTC (rev 258050)
@@ -1,3 +1,28 @@
+2020-03-06 Daniel Bates <[email protected]>
+
+ Add support for inserting and removing a text placeholder
+ https://bugs.webkit.org/show_bug.cgi?id=208661
+ <rdar://problem/59371073>
+
+ Reviewed by Simon Fraser and Ryosuke Niwa.
+
+ Add tests to ensure that inserting and removing a placeholder work.
+
+ * editing/text-placeholder/insert-and-remove-into-text-field-expected.html: Added.
+ * editing/text-placeholder/insert-and-remove-into-text-field.html: Added.
+ * editing/text-placeholder/insert-into-content-editable-expected.html: Added.
+ * editing/text-placeholder/insert-into-content-editable.html: Added.
+ * editing/text-placeholder/insert-into-empty-text-field-expected.html: Added.
+ * editing/text-placeholder/insert-into-empty-text-field.html: Added.
+ * editing/text-placeholder/insert-into-text-field-expected.html: Added.
+ * editing/text-placeholder/insert-into-text-field-in-iframe-expected.html: Added.
+ * editing/text-placeholder/insert-into-text-field-in-iframe.html: Added.
+ * editing/text-placeholder/insert-into-text-field.html: Added.
+ * editing/text-placeholder/resources/insert-into-text-field-in-iframe.html: Added.
+ * editing/text-placeholder/resources/test.css: Added.
+ (@font-face):
+ (.test):
+
2020-03-06 Jacob Uphoff <[email protected]>
[ iOS ] two http/tests/resourceLoadStatistics/third-party-cookie-blocking are flaky timing out
Added: trunk/LayoutTests/editing/text-placeholder/insert-and-remove-into-text-field-expected.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-and-remove-into-text-field-expected.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-and-remove-into-text-field-expected.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,12 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that a text placeholder that is inserted and removed from a text field visually looks as if it never was inserted to begin with. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<input id="input" class="test" type="text" value="Hello from Cupertino!">
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-and-remove-into-text-field.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-and-remove-into-text-field.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-and-remove-into-text-field.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,46 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that a text placeholder that is inserted and removed from a text field visually looks as if it never was inserted to begin with. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<input id="input" class="test" type="text" value="Hello from Cupertino!">
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+async function runTest()
+{
+ let input = document.getElementById("input");
+ if (window.testRunner)
+ await UIHelper.activateElementAndWaitForInputSession(input);
+ else
+ await UIHelper.callFunctionAndWaitForEvent(() => input.focus(), input, "focus");
+
+ let positionOfFrom = input.value.indexOf("from");
+ input.setSelectionRange(positionOfFrom, positionOfFrom);
+
+ let placeholderElement = null;
+ if (window.internals) {
+ // Because we are using the Ahem font almost all glyphs have the same width.
+ let glyphWidth = parseInt(window.getComputedStyle(input, null).fontSize, 10);
+ placeholderElement = internals.insertTextPlaceholder(5 * glyphWidth, 0 /* height */);
+ console.assert(placeholderElement);
+ }
+
+ // Defocus field to hide the cursor.
+ await UIHelper.callFunctionAndWaitForEvent(() => input.blur(), input, "blur");
+
+ if (window.internals)
+ internals.removeTextPlaceholder(placeholderElement);
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+runTest();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-into-content-editable-expected.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-into-content-editable-expected.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-into-content-editable-expected.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,12 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that a text placeholder is inserted into a <code>contenteditable</code> element. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<div id="test" class="test" style="width: 200px; height: 200px; border: 1px solid black" contenteditable="true">Hello from Cupertino!</div>
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-into-content-editable.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-into-content-editable.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-into-content-editable.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,41 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that a text placeholder is inserted into a <code>contenteditable</code> element. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<div id="test" class="test" style="width: 200px; height: 200px; border: 1px solid black" contenteditable="true">Hello from Cupertino!</div>
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+async function runTest()
+{
+ let testElement = document.getElementById("test");
+ if (window.testRunner)
+ await UIHelper.activateElementAndWaitForInputSession(testElement);
+ else
+ await UIHelper.callFunctionAndWaitForEvent(() => testElement.focus(), testElement, "focus");
+
+ let positionOfFrom = testElement.textContent.indexOf("from");
+ window.getSelection().setBaseAndExtent(testElement.firstChild, positionOfFrom, testElement.firstChild, positionOfFrom);
+
+ if (window.internals) {
+ // Because we are using the Ahem font almost all glyphs have the same width.
+ let glyphWidth = parseInt(window.getComputedStyle(testElement, null).fontSize, 10);
+ internals.insertTextPlaceholder(2 * glyphWidth, 0 /* height */);
+ }
+
+ // Defocus field to hide the cursor.
+ await UIHelper.callFunctionAndWaitForEvent(() => testElement.blur(), testElement, "blur");
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+runTest();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-into-empty-text-field-expected.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-into-empty-text-field-expected.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-into-empty-text-field-expected.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,12 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that the placeholder is hidden when a text placeholder is inserted into a text field. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<input id="input" class="test" type="text" value=" ">
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-into-empty-text-field.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-into-empty-text-field.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-into-empty-text-field.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,40 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that the placeholder is hidden when a text placeholder is inserted into a text field. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<input id="input" class="test" type="text" placeholder="FAIL">
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+async function runTest()
+{
+ let input = document.getElementById("input");
+ if (window.testRunner)
+ await UIHelper.activateElementAndWaitForInputSession(input);
+ else
+ await UIHelper.callFunctionAndWaitForEvent(() => input.focus(), input, "focus");
+
+ input.setSelectionRange(0, 0);
+
+ if (window.internals) {
+ // Because we are using the Ahem font almost all glyphs have the same width.
+ let glyphWidth = parseInt(window.getComputedStyle(input, null).fontSize, 10);
+ internals.insertTextPlaceholder(5 * glyphWidth, 0 /* height */);
+ }
+
+ // Defocus field to hide the cursor.
+ await UIHelper.callFunctionAndWaitForEvent(() => input.blur(), input, "blur");
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+runTest();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-expected.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-expected.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-expected.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,12 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that a text placeholder is inserted into a text field. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<input id="input" class="test" type="text" value="Hello from Cupertino!">
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-in-iframe-expected.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-in-iframe-expected.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-in-iframe-expected.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,12 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that a text placeholder is inserted into a text field inside an iframe. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<iframe srcdoc='<!DOCTYPE html><html><head><link rel="stylesheet" href="" id="input" class="test" type="text" value="Hello from Cupertino!"></body></html>' width="600" height="200"></iframe>
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-in-iframe.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-in-iframe.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-into-text-field-in-iframe.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,16 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+</script>
+</head>
+<body>
+<p>This tests that a text placeholder is inserted into a text field inside an iframe. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<iframe src="" width="600" height="200"></iframe>
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/insert-into-text-field.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/insert-into-text-field.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/insert-into-text-field.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,41 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<p>This tests that a text placeholder is inserted into a text field. This test can only be run in WebKitTestRunner or DumpRenderTree.</p>
+<input id="input" class="test" type="text" value="Hello from Cupertino!">
+<script>
+if (window.testRunner)
+ testRunner.waitUntilDone();
+
+async function runTest()
+{
+ let input = document.getElementById("input");
+ if (window.testRunner)
+ await UIHelper.activateElementAndWaitForInputSession(input);
+ else
+ await UIHelper.callFunctionAndWaitForEvent(() => input.focus(), input, "focus");
+
+ let positionOfFrom = input.value.indexOf("from");
+ input.setSelectionRange(positionOfFrom, positionOfFrom);
+
+ if (window.internals) {
+ // Because we are using the Ahem font almost all glyphs have the same width.
+ let glyphWidth = parseInt(window.getComputedStyle(input, null).fontSize, 10);
+ internals.insertTextPlaceholder(5 * glyphWidth, 0 /* height */);
+ }
+
+ // Defocus field to hide the cursor.
+ await UIHelper.callFunctionAndWaitForEvent(() => input.blur(), input, "blur");
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+runTest();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/resources/insert-into-text-field-in-iframe.html (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/resources/insert-into-text-field-in-iframe.html (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/resources/insert-into-text-field-in-iframe.html 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,37 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+<html>
+<head>
+<meta name="viewport" content="initial-scale=1.0">
+<script src=""
+<link rel="stylesheet" href=""
+</head>
+<body>
+<input id="input" class="test" type="text" value="Hello from Cupertino!">
+<pre id="console"></pre>
+<script>
+async function runTest()
+{
+ let input = document.getElementById("input");
+
+ // FIXME: Use UIHelper.activateElementAndWaitForInputSession(input). See <https://bugs.webkit.org/show_bug.cgi?id=208749>.
+ await UIHelper.callFunctionAndWaitForEvent(() => input.focus(), input, "focus");
+
+ let positionOfFrom = input.value.indexOf("from");
+ input.setSelectionRange(positionOfFrom, positionOfFrom);
+
+ if (window.internals) {
+ // Because we are using the Ahem font almost all glyphs have the same width.
+ let glyphWidth = parseInt(window.getComputedStyle(input, null).fontSize, 10);
+ internals.insertTextPlaceholder(5 * glyphWidth, 0 /* height */);
+ }
+
+ // Defocus field to hide the cursor.
+ await UIHelper.callFunctionAndWaitForEvent(() => input.blur(), input, "blur");
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+runTest();
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/editing/text-placeholder/resources/test.css (0 => 258050)
--- trunk/LayoutTests/editing/text-placeholder/resources/test.css (rev 0)
+++ trunk/LayoutTests/editing/text-placeholder/resources/test.css 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,12 @@
+@font-face {
+ font-family: Ahem;
+ src: url("../../../resources/Ahem.ttf");
+}
+
+.test {
+ font: 25px/1 Ahem;
+ -webkit-text-size-adjust: 100%%;
+ /* To make debugging easier, make the caret stand out. */
+ caret-color: blue;
+ color: yellow;
+}
Modified: trunk/Source/WebCore/ChangeLog (258049 => 258050)
--- trunk/Source/WebCore/ChangeLog 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/ChangeLog 2020-03-07 03:04:32 UTC (rev 258050)
@@ -1,3 +1,47 @@
+2020-03-06 Daniel Bates <[email protected]>
+
+ Add support for inserting and removing a text placeholder
+ https://bugs.webkit.org/show_bug.cgi?id=208661
+ <rdar://problem/59371073>
+
+ Reviewed by Simon Fraser and Ryosuke Niwa.
+
+ Implements the concept of a text placeholder, which is an element that acts like whitespace:
+ it takes up space in the page layout, but has no visual appearance.
+
+ Tests: editing/text-placeholder/insert-and-remove-into-text-field.html
+ editing/text-placeholder/insert-into-content-editable.html
+ editing/text-placeholder/insert-into-empty-text-field.html
+ editing/text-placeholder/insert-into-text-field-in-iframe.html
+ editing/text-placeholder/insert-into-text-field.html
+
+ * Sources.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/Element.h:
+ (WebCore::Element::isTextPlaceholderElement const): Added. Defaults to false. I override this
+ in TextPlaceholderElement.h.
+
+ * editing/Editor.cpp:
+ (WebCore::Editor::insertTextPlaceholder):
+ (WebCore::Editor::removeTextPlaceholder):
+ Insert a new placeholder or remove an existing one.
+
+ * editing/Editor.h:
+ * html/shadow/TextPlaceholderElement.cpp: Added.
+ (WebCore::TextPlaceholderElement::create):
+ (WebCore::TextPlaceholderElement::TextPlaceholderElement): Set inline styles to size the placeholder.
+ (WebCore::TextPlaceholderElement::insertedIntoAncestor): If the placeholder is inserted inside an
+ HTMLTextFormControlElement (e.g. <input> or <textarea>) then hide the HTML placeholder text.
+ (WebCore::TextPlaceholderElement::removedFromAncestor): If the placeholder was removed from inside
+ an HTMLTextFormControlElement then show the HTML placeholder text.
+ * html/shadow/TextPlaceholderElement.h:
+ (isType):
+ * testing/Internals.cpp:
+ (WebCore::Internals::insertTextPlaceholder): Added.
+ (WebCore::Internals::removeTextPlaceholder): Added.
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2020-03-06 Andres Gonzalez <[email protected]>
Implementation of AccessibilitySupport AXSIsolatedTreeMode.
Modified: trunk/Source/WebCore/Sources.txt (258049 => 258050)
--- trunk/Source/WebCore/Sources.txt 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/Sources.txt 2020-03-07 03:04:32 UTC (rev 258050)
@@ -1348,6 +1348,7 @@
html/shadow/SliderThumbElement.cpp
html/shadow/SpinButtonElement.cpp
html/shadow/TextControlInnerElements.cpp
+html/shadow/TextPlaceholderElement.cpp
inspector/CommandLineAPIHost.cpp
inspector/CommandLineAPIModule.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (258049 => 258050)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2020-03-07 03:04:32 UTC (rev 258050)
@@ -4241,6 +4241,7 @@
CE08C3D2152B599A0021B8C2 /* AlternativeTextController.h in Headers */ = {isa = PBXBuildFile; fileRef = CE08C3D0152B599A0021B8C2 /* AlternativeTextController.h */; settings = {ATTRIBUTES = (); }; };
CE1866451F72E5B400A0CAB6 /* MarkedText.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1866431F72E5B400A0CAB6 /* MarkedText.h */; settings = {ATTRIBUTES = (Private, ); }; };
CE1A501F22D5350900CBC927 /* DOMTimerHoldingTank.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1A501D22D5350900CBC927 /* DOMTimerHoldingTank.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ CE212158240DBEB9006ED443 /* TextPlaceholderElement.h in Headers */ = {isa = PBXBuildFile; fileRef = CE212153240DBD30006ED443 /* TextPlaceholderElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
CE2849871CA360DF00B4A57F /* ContentSecurityPolicyDirectiveNames.h in Headers */ = {isa = PBXBuildFile; fileRef = CE2849861CA360DF00B4A57F /* ContentSecurityPolicyDirectiveNames.h */; };
CE5169E721F1B84700EA4F78 /* ColorIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = CE5169E521F1B84700EA4F78 /* ColorIOS.h */; settings = {ATTRIBUTES = (Private, ); }; };
CE5FA255209E48C50051D700 /* ContentSecurityPolicyClient.h in Headers */ = {isa = PBXBuildFile; fileRef = CE5FA253209E48C50051D700 /* ContentSecurityPolicyClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -14146,6 +14147,8 @@
CE1866431F72E5B400A0CAB6 /* MarkedText.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MarkedText.h; sourceTree = "<group>"; };
CE1A501D22D5350900CBC927 /* DOMTimerHoldingTank.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DOMTimerHoldingTank.h; sourceTree = "<group>"; };
CE1A501E22D5350900CBC927 /* DOMTimerHoldingTank.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DOMTimerHoldingTank.cpp; sourceTree = "<group>"; };
+ CE212153240DBD30006ED443 /* TextPlaceholderElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextPlaceholderElement.h; sourceTree = "<group>"; };
+ CE212154240DBD30006ED443 /* TextPlaceholderElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TextPlaceholderElement.cpp; sourceTree = "<group>"; };
CE2849861CA360DF00B4A57F /* ContentSecurityPolicyDirectiveNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ContentSecurityPolicyDirectiveNames.h; path = csp/ContentSecurityPolicyDirectiveNames.h; sourceTree = "<group>"; };
CE2849881CA3614600B4A57F /* ContentSecurityPolicyDirectiveNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ContentSecurityPolicyDirectiveNames.cpp; path = csp/ContentSecurityPolicyDirectiveNames.cpp; sourceTree = "<group>"; };
CE5169E521F1B84700EA4F78 /* ColorIOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ColorIOS.h; sourceTree = "<group>"; };
@@ -18073,6 +18076,8 @@
4512502115DCE37D002F84E2 /* SpinButtonElement.h */,
142B97C713138943008BEF4B /* TextControlInnerElements.cpp */,
142B97C813138943008BEF4B /* TextControlInnerElements.h */,
+ CE212154240DBD30006ED443 /* TextPlaceholderElement.cpp */,
+ CE212153240DBD30006ED443 /* TextPlaceholderElement.h */,
A5416FE318810EF80009FC5F /* YouTubeEmbedShadowElement.cpp */,
A5416FE418810EF80009FC5F /* YouTubeEmbedShadowElement.h */,
);
@@ -32799,6 +32804,7 @@
E4D988B417BFD1F60084FB88 /* TextNodeTraversal.h in Headers */,
1C18DA59181AF6A500C4EF22 /* TextPainter.h in Headers */,
E4C91A0E1802343100A17F6D /* TextPaintStyle.h in Headers */,
+ CE212158240DBEB9006ED443 /* TextPlaceholderElement.h in Headers */,
93F198F608245E59001E9ABC /* TextResourceDecoder.h in Headers */,
A824B4650E2EF2EA0081A7B7 /* TextRun.h in Headers */,
414460A22412994500814BE7 /* MediaSessionIdentifier.h in Headers */,
Modified: trunk/Source/WebCore/dom/Element.h (258049 => 258050)
--- trunk/Source/WebCore/dom/Element.h 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/dom/Element.h 2020-03-07 03:04:32 UTC (rev 258050)
@@ -461,6 +461,7 @@
virtual bool isSpinButtonElement() const { return false; }
virtual bool isTextFormControlElement() const { return false; }
virtual bool isTextField() const { return false; }
+ virtual bool isTextPlaceholderElement() const { return false; }
virtual bool isOptionalFormControl() const { return false; }
virtual bool isRequiredFormControl() const { return false; }
virtual bool isInRange() const { return false; }
Modified: trunk/Source/WebCore/editing/Editor.cpp (258049 => 258050)
--- trunk/Source/WebCore/editing/Editor.cpp 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/editing/Editor.cpp 2020-03-07 03:04:32 UTC (rev 258050)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2020 Apple Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
@@ -110,6 +110,7 @@
#include "TextCheckingHelper.h"
#include "TextEvent.h"
#include "TextIterator.h"
+#include "TextPlaceholderElement.h"
#include "TypingCommand.h"
#include "UserTypingGestureIndicator.h"
#include "VisibleUnits.h"
@@ -3309,6 +3310,48 @@
return plainText(selection.start(), selection.end(), behavior).replaceWithLiteral('\0', "");
}
+RefPtr<TextPlaceholderElement> Editor::insertTextPlaceholder(const IntSize& size)
+{
+ if (m_frame.selection().isNone() || !m_frame.selection().selection().isContentEditable())
+ return nullptr;
+
+ Ref<Document> document { this->document() };
+
+ // FIXME: Write in terms of replaceSelectionWithFragment(). See <https://bugs.webkit.org/show_bug.cgi?id=208744>.
+ deleteSelectionWithSmartDelete(false);
+
+ auto range = m_frame.selection().toNormalizedRange();
+ if (!range)
+ return nullptr;
+
+ auto placeholder = TextPlaceholderElement::create(document, size);
+ range->insertNode(placeholder.copyRef());
+
+ VisibleSelection newSelection { positionBeforeNode(placeholder.ptr()), positionAfterNode(placeholder.ptr()) };
+ m_frame.selection().setSelection(newSelection, FrameSelection::defaultSetSelectionOptions(UserTriggered));
+
+ return placeholder;
+}
+
+void Editor::removeTextPlaceholder(TextPlaceholderElement& placeholder)
+{
+ ASSERT(placeholder.isConnected());
+
+ Ref<Document> document { this->document() };
+
+ // Save off state so that we can set the text insertion position to just before the placeholder element after removal.
+ auto savedRootEditableElement = makeRefPtr(placeholder.rootEditableElement());
+ auto savedPositionBeforePlaceholder = positionBeforeNode(&placeholder).parentAnchoredEquivalent();
+
+ // FIXME: Save the current selection if it has changed since the placeholder was inserted
+ // and restore it after text insertion.
+ placeholder.remove();
+
+ // To match the Legacy WebKit implementation, set the text insertion point to be before where the placeholder use to be.
+ if (m_frame.selection().isFocusedAndActive() && document->focusedElement() == savedRootEditableElement)
+ m_frame.selection().setSelection(VisibleSelection { savedPositionBeforePlaceholder, SEL_DEFAULT_AFFINITY }, FrameSelection::defaultSetSelectionOptions(UserTriggered));
+}
+
static inline void collapseCaretWidth(IntRect& rect)
{
// FIXME: Width adjustment doesn't work for rotated text.
Modified: trunk/Source/WebCore/editing/Editor.h (258049 => 258050)
--- trunk/Source/WebCore/editing/Editor.h 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/editing/Editor.h 2020-03-07 03:04:32 UTC (rev 258050)
@@ -82,6 +82,7 @@
class Text;
class TextCheckerClient;
class TextEvent;
+class TextPlaceholderElement;
struct CompositionHighlight;
struct FontAttributes;
@@ -549,6 +550,9 @@
WEBCORE_EXPORT RefPtr<HTMLImageElement> insertEditableImage();
+ WEBCORE_EXPORT RefPtr<TextPlaceholderElement> insertTextPlaceholder(const IntSize&);
+ WEBCORE_EXPORT void removeTextPlaceholder(TextPlaceholderElement&);
+
private:
Document& document() const;
Added: trunk/Source/WebCore/html/shadow/TextPlaceholderElement.cpp (0 => 258050)
--- trunk/Source/WebCore/html/shadow/TextPlaceholderElement.cpp (rev 0)
+++ trunk/Source/WebCore/html/shadow/TextPlaceholderElement.cpp 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 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
+ * 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 "TextPlaceholderElement.h"
+
+#include "HTMLNames.h"
+#include "HTMLTextFormControlElement.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(TextPlaceholderElement);
+
+Ref<TextPlaceholderElement> TextPlaceholderElement::create(Document& document, const LayoutSize& size)
+{
+ return adoptRef(*new TextPlaceholderElement { document, size });
+}
+
+TextPlaceholderElement::TextPlaceholderElement(Document& document, const LayoutSize& size)
+ : HTMLDivElement { HTMLNames::divTag, document }
+{
+ // FIXME: Move to User Agent stylesheet. See <https://webkit.org/b/208745>.
+ setInlineStyleProperty(CSSPropertyDisplay, CSSValueInlineBlock, false);
+ setInlineStyleProperty(CSSPropertyVerticalAlign, CSSValueBottom, false);
+ setInlineStyleProperty(CSSPropertyVisibility, CSSValueHidden, true);
+ setInlineStyleProperty(CSSPropertyWidth, size.width(), CSSUnitType::CSS_PX);
+ setInlineStyleProperty(CSSPropertyHeight, size.height(), CSSUnitType::CSS_PX);
+}
+
+auto TextPlaceholderElement::insertedIntoAncestor(InsertionType insertionType, ContainerNode& parentOfInsertedTree) -> InsertedIntoAncestorResult
+{
+ if (insertionType.treeScopeChanged) {
+ if (auto shadowHost = makeRefPtr(parentOfInsertedTree.shadowHost()); is<HTMLTextFormControlElement>(shadowHost))
+ downcast<HTMLTextFormControlElement>(*shadowHost).setCanShowPlaceholder(false);
+ }
+ return HTMLDivElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
+}
+
+void TextPlaceholderElement::removedFromAncestor(RemovalType removalType, ContainerNode& oldParentOfRemovedTree)
+{
+ if (removalType.treeScopeChanged) {
+ if (auto shadowHost = makeRefPtr(oldParentOfRemovedTree.shadowHost()); is<HTMLTextFormControlElement>(shadowHost))
+ downcast<HTMLTextFormControlElement>(*shadowHost).setCanShowPlaceholder(true);
+ }
+ HTMLDivElement::removedFromAncestor(removalType, oldParentOfRemovedTree);
+}
+
+} // namespace WebCore
Copied: trunk/Source/WebCore/html/shadow/TextPlaceholderElement.h (from rev 258049, trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.h) (0 => 258050)
--- trunk/Source/WebCore/html/shadow/TextPlaceholderElement.h (rev 0)
+++ trunk/Source/WebCore/html/shadow/TextPlaceholderElement.h 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 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
+ * 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
+
+#include "HTMLDivElement.h"
+
+namespace WebCore {
+
+class TextPlaceholderElement final : public HTMLDivElement {
+ WTF_MAKE_ISO_ALLOCATED(TextPlaceholderElement);
+public:
+ static Ref<TextPlaceholderElement> create(Document&, const LayoutSize&);
+
+private:
+ explicit TextPlaceholderElement(Document&, const LayoutSize&);
+
+ bool isTextPlaceholderElement() const final { return true; }
+
+ InsertedIntoAncestorResult insertedIntoAncestor(InsertionType, ContainerNode& parentOfInsertedTree) final;
+ void removedFromAncestor(RemovalType, ContainerNode& oldParentOfRemovedTree) final;
+};
+
+} // namespace WebCore
+
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::TextPlaceholderElement)
+ static bool isType(const WebCore::Element& element) { return element.isTextPlaceholderElement(); }
+ static bool isType(const WebCore::Node& node) { return is<WebCore::Element>(node) && isType(downcast<WebCore::Element>(node)); }
+SPECIALIZE_TYPE_TRAITS_END()
Modified: trunk/Source/WebCore/testing/Internals.cpp (258049 => 258050)
--- trunk/Source/WebCore/testing/Internals.cpp 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/testing/Internals.cpp 2020-03-07 03:04:32 UTC (rev 258050)
@@ -185,6 +185,7 @@
#include "StyleScope.h"
#include "StyleSheetContents.h"
#include "TextIterator.h"
+#include "TextPlaceholderElement.h"
#include "TreeScope.h"
#include "TypeConversions.h"
#include "UserGestureIndicator.h"
@@ -1436,6 +1437,17 @@
downcast<HTMLTextFormControlElement>(element).setCanShowPlaceholder(canShowPlaceholder);
}
+Element* Internals::insertTextPlaceholder(int width, int height)
+{
+ return frame()->editor().insertTextPlaceholder(IntSize { width, height }).get();
+}
+
+void Internals::removeTextPlaceholder(Element& element)
+{
+ if (is<TextPlaceholderElement>(element))
+ frame()->editor().removeTextPlaceholder(downcast<TextPlaceholderElement>(element));
+}
+
void Internals::selectColorInColorChooser(HTMLInputElement& element, const String& colorValue)
{
element.selectColor(colorValue);
Modified: trunk/Source/WebCore/testing/Internals.h (258049 => 258050)
--- trunk/Source/WebCore/testing/Internals.h 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/testing/Internals.h 2020-03-07 03:04:32 UTC (rev 258050)
@@ -238,6 +238,9 @@
String visiblePlaceholder(Element&);
void setCanShowPlaceholder(Element&, bool);
+ Element* insertTextPlaceholder(int width, int height);
+ void removeTextPlaceholder(Element&);
+
void selectColorInColorChooser(HTMLInputElement&, const String& colorValue);
ExceptionOr<Vector<String>> formControlStateOfPreviousHistoryItem();
ExceptionOr<void> setFormControlStateOfPreviousHistoryItem(const Vector<String>&);
Modified: trunk/Source/WebCore/testing/Internals.idl (258049 => 258050)
--- trunk/Source/WebCore/testing/Internals.idl 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebCore/testing/Internals.idl 2020-03-07 03:04:32 UTC (rev 258050)
@@ -309,6 +309,9 @@
void setCanShowPlaceholder(Element element, boolean canShowPlaceholder);
+ Element insertTextPlaceholder(long width, long height);
+ void removeTextPlaceholder(Element element);
+
[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);
Modified: trunk/Source/WebKit/ChangeLog (258049 => 258050)
--- trunk/Source/WebKit/ChangeLog 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/ChangeLog 2020-03-07 03:04:32 UTC (rev 258050)
@@ -1,3 +1,41 @@
+2020-03-06 Daniel Bates <[email protected]>
+
+ Add support for inserting and removing a text placeholder
+ https://bugs.webkit.org/show_bug.cgi?id=208661
+ <rdar://problem/59371073>
+
+ Reviewed by Simon Fraser and Ryosuke Niwa.
+
+ Implements the UITextInput protocol functions -insertTextPlaceholderWithSize and -removeTextPlaceholder.
+
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentViewInteraction.mm:
+ (-[WKContentView insertTextPlaceholderWithSize:completionHandler:]):
+ (-[WKContentView removeTextPlaceholder:willInsertText:completionHandler:]):
+ Implement more of the UITextInput protocol. These functions turn around and call
+ the corresponding WebPageProxy functions.
+
+ * UIProcess/ios/WKTextPlaceholder.h:
+ * UIProcess/ios/WKTextPlaceholder.mm: Added.
+ (-[WKTextPlaceholder initWithElementContext:]):
+ (-[WKTextPlaceholder elementContext]):
+ (-[WKTextPlaceholder rects]):
+ * UIProcess/ios/WKTextSelectionRect.h: Remove an unncessary #pragma once since I am here.
+ This file is only included from Objective-C/C++ files so that #pragma is unnecessary.
+
+ * UIProcess/ios/WKTextSelectionRect.mm:
+ (-[WKTextSelectionRect initWithCGRect:]): Added.
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::insertTextPlaceholder): Added
+ (WebKit::WebPageProxy::removeTextPlaceholder): Added.
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in: Add new messages to insert and remove a placeholder.
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::insertTextPlaceholder):
+ (WebKit::WebPage::removeTextPlaceholder):
+ Turn around and call the corresponding Editor functions.
+
2020-03-06 Andres Gonzalez <[email protected]>
Implementation of AccessibilitySupport AXSIsolatedTreeMode.
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (258049 => 258050)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2020-03-07 03:04:32 UTC (rev 258050)
@@ -711,6 +711,9 @@
#if PLATFORM(IOS_FAMILY)
void setShouldRevealCurrentSelectionAfterInsertion(bool);
+ void insertTextPlaceholder(const WebCore::IntSize&, CompletionHandler<void(const Optional<WebCore::ElementContext>&)>&&);
+ void removeTextPlaceholder(const WebCore::ElementContext&, CompletionHandler<void()>&&);
+
double displayedContentScale() const { return m_lastVisibleContentRectUpdate.scale(); }
const WebCore::FloatRect& exposedContentRect() const { return m_lastVisibleContentRectUpdate.exposedContentRect(); }
const WebCore::FloatRect& unobscuredContentRect() const { return m_lastVisibleContentRectUpdate.unobscuredContentRect(); }
Modified: trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm (258049 => 258050)
--- trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm 2020-03-07 03:04:32 UTC (rev 258050)
@@ -65,6 +65,7 @@
#import "WKSelectMenuListViewController.h"
#import "WKSyntheticFlagsChangedWebEvent.h"
#import "WKTextInputListViewController.h"
+#import "WKTextPlaceholder.h"
#import "WKTextSelectionRect.h"
#import "WKTimePickerViewController.h"
#import "WKUIDelegatePrivate.h"
@@ -291,7 +292,6 @@
@end
-
@interface WKAutocorrectionRects : UIWKAutocorrectionRects
+ (WKAutocorrectionRects *)autocorrectionRectsWithFirstCGRect:(CGRect)firstRect lastCGRect:(CGRect)lastRect;
@end
@@ -7436,6 +7436,27 @@
#endif
+- (void)insertTextPlaceholderWithSize:(CGSize)size completionHandler:(void (^)(UITextPlaceholder *))completionHandler
+{
+ _page->insertTextPlaceholder(WebCore::IntSize { size }, [weakSelf = WeakObjCPtr<WKContentView>(self), completionHandler = makeBlockPtr(completionHandler)](const Optional<WebCore::ElementContext>& placeholder) {
+ auto strongSelf = weakSelf.get();
+ if (!strongSelf || ![strongSelf webView] || !placeholder) {
+ completionHandler(nil);
+ return;
+ }
+ WebCore::ElementContext placeholderToUse { *placeholder };
+ placeholderToUse.boundingRect = [strongSelf convertRect:placeholderToUse.boundingRect fromView:[strongSelf webView]];
+ completionHandler([[[WKTextPlaceholder alloc] initWithElementContext:placeholderToUse] autorelease]);
+ });
+}
+
+- (void)removeTextPlaceholder:(UITextPlaceholder *)placeholder willInsertText:(BOOL)willInsertText completionHandler:(void (^)(void))completionHandler
+{
+ // FIXME: Implement support for willInsertText. See <https://bugs.webkit.org/show_bug.cgi?id=208747>.
+ if (auto* wkTextPlaceholder = dynamic_objc_cast<WKTextPlaceholder>(placeholder))
+ _page->removeTextPlaceholder(wkTextPlaceholder.elementContext, makeBlockPtr(completionHandler));
+}
+
static Vector<WebCore::IntSize> sizesOfPlaceholderElementsToInsertWhenDroppingItems(NSArray<NSItemProvider *> *itemProviders)
{
Vector<WebCore::IntSize> sizes;
Copied: trunk/Source/WebKit/UIProcess/ios/WKTextPlaceholder.h (from rev 258049, trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.h) (0 => 258050)
--- trunk/Source/WebKit/UIProcess/ios/WKTextPlaceholder.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/ios/WKTextPlaceholder.h 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 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
+ * 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.
+ */
+
+#if PLATFORM(IOS_FAMILY)
+
+#import <UIKit/UIKit.h>
+
+namespace WebCore {
+struct ElementContext;
+}
+
+@interface WKTextPlaceholder : UITextPlaceholder
+
+- (instancetype)initWithElementContext:(const WebCore::ElementContext&)context;
+
+@property (nonatomic, readonly) const WebCore::ElementContext& elementContext;
+
+@end
+
+#endif // PLATFORM(IOS_FAMILY)
Copied: trunk/Source/WebKit/UIProcess/ios/WKTextPlaceholder.mm (from rev 258049, trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.h) (0 => 258050)
--- trunk/Source/WebKit/UIProcess/ios/WKTextPlaceholder.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/ios/WKTextPlaceholder.mm 2020-03-07 03:04:32 UTC (rev 258050)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 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
+ * 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.
+ */
+
+#import "config.h"
+#import "WKTextPlaceholder.h"
+
+#if PLATFORM(IOS_FAMILY)
+
+#import "WKTextSelectionRect.h"
+#import <WebCore/ElementContext.h>
+
+@implementation WKTextPlaceholder {
+ WebCore::ElementContext _elementContext;
+}
+
+- (instancetype)initWithElementContext:(const WebCore::ElementContext&)context
+{
+ if (!(self = [self init]))
+ return nil;
+ _elementContext = context;
+ return self;
+}
+
+- (const WebCore::ElementContext&)elementContext
+{
+ return _elementContext;
+}
+
+- (NSArray<UITextSelectionRect *> *)rects
+{
+ return @[ [[[WKTextSelectionRect alloc] initWithCGRect:_elementContext.boundingRect] autorelease] ];
+}
+
+@end
+
+#endif // PLATFORM(IOS_FAMILY)
Modified: trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.h (258049 => 258050)
--- trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.h 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.h 2020-03-07 03:04:32 UTC (rev 258050)
@@ -23,8 +23,6 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#pragma once
-
#if PLATFORM(IOS_FAMILY)
#import <UIKit/UIKit.h>
@@ -35,6 +33,7 @@
@interface WKTextSelectionRect : UITextSelectionRect
+- (instancetype)initWithCGRect:(CGRect)rect;
- (instancetype)initWithSelectionRect:(const WebCore::SelectionRect&)selectionRect;
@end
Modified: trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.mm (258049 => 258050)
--- trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.mm 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/UIProcess/ios/WKTextSelectionRect.mm 2020-03-07 03:04:32 UTC (rev 258050)
@@ -34,6 +34,13 @@
WebCore::SelectionRect _selectionRect;
}
+- (instancetype)initWithCGRect:(CGRect)rect
+{
+ WebCore::SelectionRect selectionRect;
+ selectionRect.setRect(WebCore::enclosingIntRect(rect));
+ return [self initWithSelectionRect:WTFMove(selectionRect)];
+}
+
- (instancetype)initWithSelectionRect:(const WebCore::SelectionRect&)selectionRect
{
if (!(self = [super init]))
Modified: trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm (258049 => 258050)
--- trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm 2020-03-07 03:04:32 UTC (rev 258050)
@@ -460,6 +460,24 @@
m_process->send(Messages::WebPage::ReplaceSelectedText(oldText, newText), m_webPageID);
}
+void WebPageProxy::insertTextPlaceholder(const IntSize& size, CompletionHandler<void(const Optional<ElementContext>&)>&& completionHandler)
+{
+ if (!hasRunningProcess()) {
+ completionHandler({ });
+ return;
+ }
+ m_process->connection()->sendWithAsyncReply(Messages::WebPage::InsertTextPlaceholder { size }, WTFMove(completionHandler), m_webPageID);
+}
+
+void WebPageProxy::removeTextPlaceholder(const ElementContext& placeholder, CompletionHandler<void()>&& completionHandler)
+{
+ if (!hasRunningProcess()) {
+ completionHandler();
+ return;
+ }
+ m_process->connection()->sendWithAsyncReply(Messages::WebPage::RemoveTextPlaceholder { placeholder }, WTFMove(completionHandler), m_webPageID);
+}
+
void WebPageProxy::requestAutocorrectionData(const String& textForAutocorrection, CompletionHandler<void(WebAutocorrectionData)>&& callback)
{
if (!hasRunningProcess()) {
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (258049 => 258050)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2020-03-07 03:04:32 UTC (rev 258050)
@@ -1753,6 +1753,8 @@
CE1A0BD21A48E6C60054EF74 /* AssertionServicesSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1A0BCC1A48E6C60054EF74 /* AssertionServicesSPI.h */; };
CE1A0BD61A48E6C60054EF74 /* TCCSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1A0BD01A48E6C60054EF74 /* TCCSPI.h */; };
CE1A0BD71A48E6C60054EF74 /* TextInputSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = CE1A0BD11A48E6C60054EF74 /* TextInputSPI.h */; };
+ CE21215F240EE571006ED443 /* WKTextPlaceholder.h in Headers */ = {isa = PBXBuildFile; fileRef = CE21215D240EE571006ED443 /* WKTextPlaceholder.h */; };
+ CE212160240EE571006ED443 /* WKTextPlaceholder.mm in Sources */ = {isa = PBXBuildFile; fileRef = CE21215E240EE571006ED443 /* WKTextPlaceholder.mm */; };
CE45945C240F88550078019F /* WKTextSelectionRect.h in Headers */ = {isa = PBXBuildFile; fileRef = CE45945A240F85B90078019F /* WKTextSelectionRect.h */; };
CE550E152283752200D28791 /* InsertTextOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = CE550E12228373C800D28791 /* InsertTextOptions.h */; };
CE5B4C8821B73D870022E64F /* WKSyntheticFlagsChangedWebEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = CE5B4C8621B73D870022E64F /* WKSyntheticFlagsChangedWebEvent.h */; };
@@ -5149,6 +5151,8 @@
CE1A0BCC1A48E6C60054EF74 /* AssertionServicesSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssertionServicesSPI.h; sourceTree = "<group>"; };
CE1A0BD01A48E6C60054EF74 /* TCCSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TCCSPI.h; sourceTree = "<group>"; };
CE1A0BD11A48E6C60054EF74 /* TextInputSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextInputSPI.h; sourceTree = "<group>"; };
+ CE21215D240EE571006ED443 /* WKTextPlaceholder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKTextPlaceholder.h; path = ios/WKTextPlaceholder.h; sourceTree = "<group>"; };
+ CE21215E240EE571006ED443 /* WKTextPlaceholder.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKTextPlaceholder.mm; path = ios/WKTextPlaceholder.mm; sourceTree = "<group>"; };
CE45945A240F85B90078019F /* WKTextSelectionRect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = WKTextSelectionRect.h; path = ios/WKTextSelectionRect.h; sourceTree = "<group>"; };
CE45945B240F85B90078019F /* WKTextSelectionRect.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = WKTextSelectionRect.mm; path = ios/WKTextSelectionRect.mm; sourceTree = "<group>"; };
CE550E12228373C800D28791 /* InsertTextOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InsertTextOptions.h; sourceTree = "<group>"; };
@@ -6943,6 +6947,8 @@
26F10BE719187E2E001D0E68 /* WKSyntheticTapGestureRecognizer.mm */,
316B8B622054B55800BD4A62 /* WKSystemPreviewView.h */,
316B8B612054B55800BD4A62 /* WKSystemPreviewView.mm */,
+ CE21215D240EE571006ED443 /* WKTextPlaceholder.h */,
+ CE21215E240EE571006ED443 /* WKTextPlaceholder.mm */,
CE45945A240F85B90078019F /* WKTextSelectionRect.h */,
CE45945B240F85B90078019F /* WKTextSelectionRect.mm */,
71A676A422C62318007D6295 /* WKTouchActionGestureRecognizer.h */,
@@ -11539,6 +11545,7 @@
2DD67A351BD861060053B251 /* WKTextFinderClient.h in Headers */,
F4D5F51D206087A10038BBA8 /* WKTextInputListViewController.h in Headers */,
0FCB4E6818BBE3D9000FCFC9 /* WKTextInputWindowController.h in Headers */,
+ CE21215F240EE571006ED443 /* WKTextPlaceholder.h in Headers */,
CE45945C240F88550078019F /* WKTextSelectionRect.h in Headers */,
2EB6FC01203021960017E619 /* WKTimePickerViewController.h in Headers */,
71A676A622C62325007D6295 /* WKTouchActionGestureRecognizer.h in Headers */,
@@ -12841,6 +12848,7 @@
5CA26D83217AD1B800F97A35 /* WKSafeBrowsingWarning.mm in Sources */,
1DB01944211CF005009FB3E8 /* WKShareSheet.mm in Sources */,
7A78FF332241919B0096483E /* WKStorageAccessAlert.mm in Sources */,
+ CE212160240EE571006ED443 /* WKTextPlaceholder.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (258049 => 258050)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2020-03-07 03:04:32 UTC (rev 258050)
@@ -643,6 +643,9 @@
bool shouldRevealCurrentSelectionAfterInsertion() const { return m_shouldRevealCurrentSelectionAfterInsertion; }
void setShouldRevealCurrentSelectionAfterInsertion(bool);
+ void insertTextPlaceholder(const WebCore::IntSize&, CompletionHandler<void(const Optional<WebCore::ElementContext>&)>&&);
+ void removeTextPlaceholder(const WebCore::ElementContext&, CompletionHandler<void()>&&);
+
WebCore::FloatSize screenSize() const;
WebCore::FloatSize availableScreenSize() const;
WebCore::FloatSize overrideScreenSize() const;
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (258049 => 258050)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2020-03-07 03:04:32 UTC (rev 258050)
@@ -119,6 +119,8 @@
RequestDocumentEditingContext(struct WebKit::DocumentEditingContextRequest request) -> (struct WebKit::DocumentEditingContext response) Async
GenerateSyntheticEditingCommand(enum:uint8_t WebKit::SyntheticEditingCommandType command)
SetShouldRevealCurrentSelectionAfterInsertion(bool shouldRevealCurrentSelectionAfterInsertion)
+ InsertTextPlaceholder(WebCore::IntSize size) -> (Optional<WebCore::ElementContext> placeholder) Async
+ RemoveTextPlaceholder(struct WebCore::ElementContext placeholder) -> () Async
#endif
SetControlledByAutomation(bool controlled)
Modified: trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm (258049 => 258050)
--- trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2020-03-07 03:02:43 UTC (rev 258049)
+++ trunk/Source/WebKit/WebProcess/WebPage/ios/WebPageIOS.mm 2020-03-07 03:04:32 UTC (rev 258050)
@@ -127,6 +127,7 @@
#import <WebCore/StyleProperties.h>
#import <WebCore/TextIndicator.h>
#import <WebCore/TextIterator.h>
+#import <WebCore/TextPlaceholderElement.h>
#import <WebCore/UserAgent.h>
#import <WebCore/VisibleUnits.h>
#import <WebCore/WebEvent.h>
@@ -3981,6 +3982,24 @@
#endif
}
+void WebPage::insertTextPlaceholder(const IntSize& size, CompletionHandler<void(const Optional<WebCore::ElementContext>&)>&& completionHandler)
+{
+ // Inserting the placeholder may run _javascript_, which can do anything, including frame destruction.
+ Ref<Frame> frame = corePage()->focusController().focusedOrMainFrame();
+ auto placeholder = frame->editor().insertTextPlaceholder(size);
+ completionHandler(placeholder ? contextForElement(*placeholder) : WTF::nullopt);
+}
+
+void WebPage::removeTextPlaceholder(const WebCore::ElementContext& placeholder, CompletionHandler<void()>&& completionHandler)
+{
+ if (RefPtr<Element> element = elementForContext(placeholder)) {
+ RELEASE_ASSERT(is<TextPlaceholderElement>(element));
+ if (RefPtr<Frame> frame = element->document().frame())
+ frame->editor().removeTextPlaceholder(downcast<TextPlaceholderElement>(*element));
+ }
+ completionHandler();
+}
+
void WebPage::updateSelectionWithDelta(int64_t locationDelta, int64_t lengthDelta, CompletionHandler<void()>&& completionHandler)
{
Ref<Frame> frame = corePage()->focusController().focusedOrMainFrame();