[WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
authorwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 12 Nov 2016 00:20:00 +0000 (00:20 +0000)
committerwenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 12 Nov 2016 00:20:00 +0000 (00:20 +0000)
https://bugs.webkit.org/show_bug.cgi?id=164538
<rdar://problem/8418711>

Reviewed by Ryosuke Niwa.

Source/WebCore:

Adds autocorrect and autocapitalize getters and setters to HTMLElements. These check the `autocorrect` and
`autocapitalize` attributes and return whether or not the element supports autocorrect, and the
autocapitalization type, respectively. By default, autocorrection is enabled and autocapitalization is enabled
on the sentence level for elements. Also refactors/renames WebAutocapitalizeType so that in WebCore, we deal
solely with AutocapitalizeTypes and WebKit1 converts from AutocapitalizeType to WebAutocapitalizeType as needed
for UIKit.

Tests: fast/events/ios/contenteditable-autocapitalize.html
       fast/events/ios/contenteditable-autocorrect.html

* WebCore.xcodeproj/project.pbxproj:
* html/Autocapitalize.cpp:
(WebCore::autocapitalizeTypeForAttributeValue):
(WebCore::stringForAutocapitalizeType):
* html/Autocapitalize.h:
* html/AutocapitalizeTypes.h: Renamed from Source/WebCore/html/WebAutocapitalize.h.

Move WebAutocapitalizeType into AutocapitalizeTypes.h as simply AutocapitalizeType.

* html/HTMLElement.cpp:
(WebCore::HTMLElement::autocapitalize):
(WebCore::HTMLElement::autocapitalizeType):
(WebCore::HTMLElement::setAutocapitalize):
(WebCore::HTMLElement::shouldAutocorrect):
(WebCore::HTMLElement::setAutocorrect):
* html/HTMLElement.h:
(WebCore::HTMLElement::autocorrect):
* html/HTMLElement.idl:
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLFormControlElement::shouldAutocorrect):
(WebCore::HTMLFormControlElement::autocapitalizeType):
(WebCore::HTMLFormControlElement::autocorrect): Deleted.
(WebCore::HTMLFormControlElement::setAutocorrect): Deleted.
(WebCore::HTMLFormControlElement::autocapitalize): Deleted.
(WebCore::HTMLFormControlElement::setAutocapitalize): Deleted.

Fold autocorrect/autocapitalize member functions into HTMLElement and remove element-specific code in
HTML(FormControl|Form)Element.cpp.

* html/HTMLFormControlElement.h:
* html/HTMLFormElement.cpp:
(WebCore::HTMLFormElement::shouldAutocorrect):
(WebCore::HTMLFormElement::autocorrect): Deleted.
(WebCore::HTMLFormElement::setAutocorrect): Deleted.
(WebCore::HTMLFormElement::autocapitalizeType): Deleted.
(WebCore::HTMLFormElement::autocapitalize): Deleted.
(WebCore::HTMLFormElement::setAutocapitalize): Deleted.
* html/HTMLFormElement.h:
* html/HTMLFormElement.idl:
* html/HTMLInputElement.idl:
* html/HTMLTextAreaElement.idl:

Source/WebKit:

Introduce WebAutocapitalizeTypes.h to WebKit.

* WebKit.xcodeproj/project.pbxproj:

Source/WebKit/mac:

Account for renaming HTMLElement::autocorrect to HTMLElement::shouldAutocorrect, as well as moving
WebAutocapitalizeType to WebKit from WebCore. Additionally, moves the -autocorrect and -autocapitalize SPIs out
of HTML(Input|Form|TextArea)ElementPrivate.h and into HTMLElementPrivate.h. This also means removing redundant
code for interfacing with the unwrapped HTMLElement's autocorrect and autocapitalize attributes.

* DOM/DOMHTML.mm:
(webAutocapitalizeType):
(-[DOMHTMLInputElement _autocapitalizeType]):
(-[DOMHTMLTextAreaElement _autocapitalizeType]):
* DOM/DOMHTMLElement.mm:
(-[DOMHTMLElement autocorrect]):
(-[DOMHTMLElement setAutocorrect:]):
(-[DOMHTMLElement autocapitalize]):
(-[DOMHTMLElement setAutocapitalize:]):
* DOM/DOMHTMLElementPrivate.h: Copied from Source/WebCore/html/Autocapitalize.h.
* DOM/DOMHTMLFormElement.mm:
(-[DOMHTMLFormElement autocorrect]): Deleted.
(-[DOMHTMLFormElement setAutocorrect:]): Deleted.
(-[DOMHTMLFormElement autocapitalize]): Deleted.
(-[DOMHTMLFormElement setAutocapitalize:]): Deleted.
* DOM/DOMHTMLInputElement.mm:
(-[DOMHTMLInputElement autocorrect]): Deleted.
(-[DOMHTMLInputElement setAutocorrect:]): Deleted.
(-[DOMHTMLInputElement autocapitalize]): Deleted.
(-[DOMHTMLInputElement setAutocapitalize:]): Deleted.
* DOM/DOMHTMLInputElementPrivate.h:
* DOM/DOMHTMLTextAreaElement.mm:
(-[DOMHTMLTextAreaElement autocorrect]): Deleted.
(-[DOMHTMLTextAreaElement setAutocorrect:]): Deleted.
(-[DOMHTMLTextAreaElement autocapitalize]): Deleted.
(-[DOMHTMLTextAreaElement setAutocapitalize:]): Deleted.
* DOM/DOMHTMLTextAreaElementPrivate.h:

We need to import DOMHTMLElementPrivate.h here to avoid breaking UIKit. We should follow this up with a UIKit
change to import DOMHTMLElementPrivate.h directly.

* DOM/DOMPrivate.h:
* DOM/WebAutocapitalizeTypes.h: Copied from Tools/WebKitTestRunner/ios/UIKitSPI.h.
* MigrateHeaders.make:

Source/WebKit2:

Consult HTMLElement::autocorrect() and HTMLElement::autocapitalizeType() when assembling the assisted node
information for the currently assisted node.

* Shared/AssistedNodeInformation.h:
* UIProcess/ios/WKContentViewInteraction.mm:
(toUITextAutocapitalize):
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::getAssistedNodeInformation):

Tools:

Adds support for being able to test autocorrect and autocapitalize attributes in contenteditable areas. To do
this, we add removeAllDynamicDictionaries to UIScriptController in order to ensure that autocorrect suggestions
are reset to their defaults prior to running contenteditable-autocorrect-off.html.

* DumpRenderTree/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::removeAllDynamicDictionaries):
* Scripts/webkitpy/port/ios.py:
(IOSSimulatorPort._createSimulatorApp):
* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.cpp:
(WTR::UIScriptController::removeAllDynamicDictionaries):
* TestRunnerShared/UIScriptContext/UIScriptController.h:
* WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
(-[TestRunnerWKWebView _keyboardDidShow:]):
(-[TestRunnerWKWebView _keyboardDidHide:]):

Work around an issue where consecutive UIKeyboardDidShowNotification would cause keyboard appearance callbacks
to be fired multiple times. This was causing a single key press to cause two characters to be typed. While this
does not affect the correctness of existing tests, the new autocorrection test requires this workaround.

* WebKitTestRunner/ios/UIKitSPI.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex):
(WTR::UIScriptController::removeAllDynamicDictionaries):

LayoutTests:

Adds new layout tests verifying that `autocorrect` and `autocapitalize` attributes can be used to opt out of
autocapitalization and autocorrection in a contenteditable area in WK2. Additionally, tests that autocorrection
and autocapitalization attributes may be changed by setting `element.autocorrect` and `element.autocapitalize`,
respectively.

* fast/events/ios/contenteditable-autocapitalize-none-expected.txt: Added.
* fast/events/ios/contenteditable-autocapitalize-none.html: Added.
* fast/events/ios/contenteditable-autocorrect-off-expected.txt: Added.
* fast/events/ios/contenteditable-autocorrect-off.html: Added.

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

46 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/events/ios/contenteditable-autocapitalize-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/contenteditable-autocapitalize.html [new file with mode: 0644]
LayoutTests/fast/events/ios/contenteditable-autocorrect-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/contenteditable-autocorrect.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/html/Autocapitalize.cpp
Source/WebCore/html/Autocapitalize.h
Source/WebCore/html/AutocapitalizeTypes.h [moved from Source/WebCore/html/WebAutocapitalize.h with 82% similarity]
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLElement.h
Source/WebCore/html/HTMLElement.idl
Source/WebCore/html/HTMLFormControlElement.cpp
Source/WebCore/html/HTMLFormControlElement.h
Source/WebCore/html/HTMLFormElement.cpp
Source/WebCore/html/HTMLFormElement.h
Source/WebCore/html/HTMLFormElement.idl
Source/WebCore/html/HTMLInputElement.idl
Source/WebCore/html/HTMLTextAreaElement.idl
Source/WebKit/ChangeLog
Source/WebKit/WebKit.xcodeproj/project.pbxproj
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/DOM/DOMHTML.mm
Source/WebKit/mac/DOM/DOMHTMLElement.mm
Source/WebKit/mac/DOM/DOMHTMLElementPrivate.h [new file with mode: 0644]
Source/WebKit/mac/DOM/DOMHTMLFormElement.mm
Source/WebKit/mac/DOM/DOMHTMLInputElement.mm
Source/WebKit/mac/DOM/DOMHTMLInputElementPrivate.h
Source/WebKit/mac/DOM/DOMHTMLTextAreaElement.mm
Source/WebKit/mac/DOM/DOMHTMLTextAreaElementPrivate.h
Source/WebKit/mac/DOM/DOMPrivate.h
Source/WebKit/mac/DOM/WebAutocapitalizeTypes.h [new file with mode: 0644]
Source/WebKit/mac/MigrateHeaders.make
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/AssistedNodeInformation.h
Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm
Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm
Tools/ChangeLog
Tools/DumpRenderTree/ios/UIScriptControllerIOS.mm
Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
Tools/TestRunnerShared/UIScriptContext/UIScriptController.cpp
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/cocoa/TestRunnerWKWebView.mm
Tools/WebKitTestRunner/ios/UIKitSPI.h
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

index a3e7d9a..db186e3 100644 (file)
@@ -1,3 +1,21 @@
+2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
+        https://bugs.webkit.org/show_bug.cgi?id=164538
+        <rdar://problem/8418711>
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds new layout tests verifying that `autocorrect` and `autocapitalize` attributes can be used to opt out of
+        autocapitalization and autocorrection in a contenteditable area in WK2. Additionally, tests that autocorrection
+        and autocapitalization attributes may be changed by setting `element.autocorrect` and `element.autocapitalize`,
+        respectively.
+
+        * fast/events/ios/contenteditable-autocapitalize-none-expected.txt: Added.
+        * fast/events/ios/contenteditable-autocapitalize-none.html: Added.
+        * fast/events/ios/contenteditable-autocorrect-off-expected.txt: Added.
+        * fast/events/ios/contenteditable-autocorrect-off.html: Added.
+
 2016-11-11  Antti Koivisto  <antti@apple.com>
 
         Updating class name doesn't update the slotted content's style
@@ -67,7 +85,7 @@
 
         * platform/ios-simulator/compositing/tiling/visiblerect-accumulated-offset-expected.txt: Added.
 
-2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+2016-11-10  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Composition state should be cleared when changing focus to a non-editable element
         https://bugs.webkit.org/show_bug.cgi?id=164595
diff --git a/LayoutTests/fast/events/ios/contenteditable-autocapitalize-expected.txt b/LayoutTests/fast/events/ios/contenteditable-autocapitalize-expected.txt
new file mode 100644 (file)
index 0000000..ac53358
--- /dev/null
@@ -0,0 +1,6 @@
+To manually test, type 't' into the contenteditable. The 't' should not be autocapitalized.
+
+With autocapitalize: none, the output is: "to"
+With autocapitalize: sentences, the output is: "To"
+With autocapitalize: characters, the output is: "TO"
+
diff --git a/LayoutTests/fast/events/ios/contenteditable-autocapitalize.html b/LayoutTests/fast/events/ios/contenteditable-autocapitalize.html
new file mode 100644 (file)
index 0000000..0f3362f
--- /dev/null
@@ -0,0 +1,76 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+
+<head>
+    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+    <script>
+        let write = message => output.innerHTML += message + "<br>";
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        let remainingInputEventCount = 0;
+        let resolveExpectedInputEvents = null;
+        function handleInput() {
+            remainingInputEventCount--;
+            if (resolveExpectedInputEvents && !remainingInputEventCount)
+                resolveExpectedInputEvents();
+        }
+
+        function runUIScriptAndExpectInputEvents(inputEventCount, nextAutocapitalizeType)
+        {
+            remainingInputEventCount = inputEventCount;
+            resolveExpectedInputEvents = () => {
+                write(`With autocapitalize: ${editable.autocapitalize}, the output is: "${editable.textContent}"`);
+                editable.autocapitalize = nextAutocapitalizeType;
+                editable.textContent = "";
+                editable.blur();
+            };
+
+            return new Promise(function(resolve) {
+                let rect = editable.getBoundingClientRect();
+                testRunner.runUIScript(`(function() {
+                    uiController.didShowKeyboardCallback = function() {
+                        uiController.typeCharacterUsingHardwareKeyboard("t", function() {
+                            uiController.typeCharacterUsingHardwareKeyboard("o", function() {});
+                        });
+                    }
+                    uiController.didHideKeyboardCallback = function() {
+                        uiController.uiScriptComplete();
+                    }
+                    uiController.singleTapAtPoint(${rect.left + rect.width / 2}, ${rect.top + rect.height / 2}, function() {});
+                })();`, resolve);
+            });
+        }
+
+        function runTest()
+        {
+            if (!window.testRunner || !testRunner.runUIScript)
+                return;
+
+            runUIScriptAndExpectInputEvents(2, "sentences")
+                .then(() => runUIScriptAndExpectInputEvents(2, "characters"))
+                .then(() => runUIScriptAndExpectInputEvents(2, null))
+                .then(() => testRunner.notifyDone());
+        }
+    </script>
+    <style>
+    #editable {
+        width: 200px;
+        height: 100px;
+        top: 0;
+        left: 0;
+        position: absolute;
+    }
+    </style>
+</head>
+
+<body onload=runTest()>
+    <div contenteditable autocapitalize="none" id="editable" oninput=handleInput()></div>
+    <p>To manually test, type 't' into the contenteditable. The 't' should not be autocapitalized.</p>
+    <div id="output"></div>
+</body>
+
+</html>
diff --git a/LayoutTests/fast/events/ios/contenteditable-autocorrect-expected.txt b/LayoutTests/fast/events/ios/contenteditable-autocorrect-expected.txt
new file mode 100644 (file)
index 0000000..bf1139c
--- /dev/null
@@ -0,0 +1,5 @@
+To manually test, type 'Ti' into the contenteditable and a space. The 'Ti' should not be autocorrected.
+
+With autocorrect off, the result is: "Ti"
+With autocorrect on, the result is: "To"
+
diff --git a/LayoutTests/fast/events/ios/contenteditable-autocorrect.html b/LayoutTests/fast/events/ios/contenteditable-autocorrect.html
new file mode 100644 (file)
index 0000000..e8bfc0e
--- /dev/null
@@ -0,0 +1,78 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->
+
+<html>
+
+<head>
+    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
+    <script>
+        let write = message => output.innerHTML += message + "<br>";
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        let remainingInputEventCount = 0;
+        let resolveExpectedInputEvents = null;
+        function handleInput() {
+            remainingInputEventCount--;
+            if (resolveExpectedInputEvents && !remainingInputEventCount)
+                resolveExpectedInputEvents();
+        }
+
+        function runUIScriptAndExpectInputEvents(inputEventCount, nextAutocorrectValue)
+        {
+            remainingInputEventCount = inputEventCount;
+            resolveExpectedInputEvents = () => {
+                write(`With autocorrect ${editable.autocorrect ? "on" : "off"}, the result is: "${editable.textContent.trim()}"`);
+                editable.textContent = "";
+                editable.autocorrect = nextAutocorrectValue;
+                editable.blur();
+            };
+
+            return new Promise(function(resolve) {
+                let rect = editable.getBoundingClientRect();
+                testRunner.runUIScript(`(function() {
+                    uiController.removeAllDynamicDictionaries();
+                    uiController.didShowKeyboardCallback = function() {
+                        uiController.typeCharacterUsingHardwareKeyboard("t", function() {
+                            uiController.typeCharacterUsingHardwareKeyboard("i", function() {
+                                uiController.typeCharacterUsingHardwareKeyboard(" ", function() { });
+                            });
+                        });
+                    }
+                    uiController.didHideKeyboardCallback = function() {
+                        uiController.uiScriptComplete();
+                    }
+                    uiController.singleTapAtPoint(${rect.left + rect.width / 2}, ${rect.top + rect.height / 2}, function() {});
+                })();`, resolve);
+            });
+        }
+
+        function runTest()
+        {
+            if (!window.testRunner || !testRunner.runUIScript)
+                return;
+
+            runUIScriptAndExpectInputEvents(3, "on")
+                .then(() => runUIScriptAndExpectInputEvents(4, null))
+                .then(() => testRunner.notifyDone());
+        }
+    </script>
+    <style>
+    #editable {
+        width: 200px;
+        height: 100px;
+        top: 0;
+        left: 0;
+        position: absolute;
+    }
+    </style>
+</head>
+
+<body onload=runTest()>
+    <div style="font-size: 24px;" contenteditable autocorrect="off" id="editable" oninput=handleInput()></div>
+    <p>To manually test, type 'Ti' into the contenteditable and a space. The 'Ti' should not be autocorrected.</p>
+    <code><div id="output"></div></code>
+</body>
+
+</html>
index 0af31bc..b316192 100644 (file)
@@ -1,3 +1,63 @@
+2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
+        https://bugs.webkit.org/show_bug.cgi?id=164538
+        <rdar://problem/8418711>
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds autocorrect and autocapitalize getters and setters to HTMLElements. These check the `autocorrect` and
+        `autocapitalize` attributes and return whether or not the element supports autocorrect, and the
+        autocapitalization type, respectively. By default, autocorrection is enabled and autocapitalization is enabled
+        on the sentence level for elements. Also refactors/renames WebAutocapitalizeType so that in WebCore, we deal
+        solely with AutocapitalizeTypes and WebKit1 converts from AutocapitalizeType to WebAutocapitalizeType as needed
+        for UIKit.
+
+        Tests: fast/events/ios/contenteditable-autocapitalize.html
+               fast/events/ios/contenteditable-autocorrect.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * html/Autocapitalize.cpp:
+        (WebCore::autocapitalizeTypeForAttributeValue):
+        (WebCore::stringForAutocapitalizeType):
+        * html/Autocapitalize.h:
+        * html/AutocapitalizeTypes.h: Renamed from Source/WebCore/html/WebAutocapitalize.h.
+
+        Move WebAutocapitalizeType into AutocapitalizeTypes.h as simply AutocapitalizeType.
+
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::autocapitalize):
+        (WebCore::HTMLElement::autocapitalizeType):
+        (WebCore::HTMLElement::setAutocapitalize):
+        (WebCore::HTMLElement::shouldAutocorrect):
+        (WebCore::HTMLElement::setAutocorrect):
+        * html/HTMLElement.h:
+        (WebCore::HTMLElement::autocorrect):
+        * html/HTMLElement.idl:
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLFormControlElement::shouldAutocorrect):
+        (WebCore::HTMLFormControlElement::autocapitalizeType):
+        (WebCore::HTMLFormControlElement::autocorrect): Deleted.
+        (WebCore::HTMLFormControlElement::setAutocorrect): Deleted.
+        (WebCore::HTMLFormControlElement::autocapitalize): Deleted.
+        (WebCore::HTMLFormControlElement::setAutocapitalize): Deleted.
+
+        Fold autocorrect/autocapitalize member functions into HTMLElement and remove element-specific code in
+        HTML(FormControl|Form)Element.cpp.
+
+        * html/HTMLFormControlElement.h:
+        * html/HTMLFormElement.cpp:
+        (WebCore::HTMLFormElement::shouldAutocorrect):
+        (WebCore::HTMLFormElement::autocorrect): Deleted.
+        (WebCore::HTMLFormElement::setAutocorrect): Deleted.
+        (WebCore::HTMLFormElement::autocapitalizeType): Deleted.
+        (WebCore::HTMLFormElement::autocapitalize): Deleted.
+        (WebCore::HTMLFormElement::setAutocapitalize): Deleted.
+        * html/HTMLFormElement.h:
+        * html/HTMLFormElement.idl:
+        * html/HTMLInputElement.idl:
+        * html/HTMLTextAreaElement.idl:
+
 2016-11-11  Dave Hyatt  <hyatt@apple.com>
 
         [CSS Parser] Add support for paths as basic shapes.
         * css/parser/CSSPropertyParser.cpp:
         (WebCore::CSSPropertyParser::parseShorthand):
 
-2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+2016-11-10  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Composition state should be cleared when changing focus to a non-editable element
         https://bugs.webkit.org/show_bug.cgi?id=164595
index 1f5a705..5bb2d2f 100644 (file)
                A593CF8B1840535200BFCE27 /* InspectorWebAgentBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A593CF8A1840535200BFCE27 /* InspectorWebAgentBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A5A2AF0B1829734300DE1729 /* PageDebuggable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5A2AF091829734300DE1729 /* PageDebuggable.cpp */; };
                A5A2AF0C1829734300DE1729 /* PageDebuggable.h in Headers */ = {isa = PBXBuildFile; fileRef = A5A2AF0A1829734300DE1729 /* PageDebuggable.h */; };
-               A5A7AA43132F0ECC00D3A3C2 /* WebAutocapitalize.h in Headers */ = {isa = PBXBuildFile; fileRef = A5A7AA42132F0ECC00D3A3C2 /* WebAutocapitalize.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               A5A7AA43132F0ECC00D3A3C2 /* AutocapitalizeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A5A7AA42132F0ECC00D3A3C2 /* AutocapitalizeTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A5AFB34F115151A700B045CB /* StepRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5AFB34D115151A700B045CB /* StepRange.cpp */; };
                A5AFB350115151A700B045CB /* StepRange.h in Headers */ = {isa = PBXBuildFile; fileRef = A5AFB34E115151A700B045CB /* StepRange.h */; settings = {ATTRIBUTES = (Private, ); }; };
                A5DEBDA316FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5DEBD9F16FB908700836FE0 /* WebKitPlaybackTargetAvailabilityEvent.cpp */; };
                A593CF8A1840535200BFCE27 /* InspectorWebAgentBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorWebAgentBase.h; sourceTree = "<group>"; };
                A5A2AF091829734300DE1729 /* PageDebuggable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageDebuggable.cpp; sourceTree = "<group>"; };
                A5A2AF0A1829734300DE1729 /* PageDebuggable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageDebuggable.h; sourceTree = "<group>"; };
-               A5A7AA42132F0ECC00D3A3C2 /* WebAutocapitalize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAutocapitalize.h; sourceTree = "<group>"; };
+               A5A7AA42132F0ECC00D3A3C2 /* AutocapitalizeTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutocapitalizeTypes.h; sourceTree = "<group>"; };
                A5AFB34D115151A700B045CB /* StepRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StepRange.cpp; sourceTree = "<group>"; };
                A5AFB34E115151A700B045CB /* StepRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StepRange.h; sourceTree = "<group>"; };
                A5C974CF11485FF10066F2AB /* KeyEventCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyEventCocoa.h; sourceTree = "<group>"; };
                                B1AD4E7713A12A7200846B27 /* track */,
                                A5F6E16C132ED46E008EDAE3 /* Autocapitalize.cpp */,
                                A501920C132EBF2E008BFE55 /* Autocapitalize.h */,
+                               A5A7AA42132F0ECC00D3A3C2 /* AutocapitalizeTypes.h */,
                                7C1843FB1C8B7283002EB973 /* Autofill.cpp */,
                                7C1843FC1C8B7283002EB973 /* Autofill.h */,
                                379E61C5126CA5C300B63E8D /* BaseButtonInputType.cpp */,
                                15C77089100D3C6A005BA267 /* ValidityState.idl */,
                                E44613B40CD6344E00FADA75 /* VoidCallback.h */,
                                E44613A00CD6331000FADA75 /* VoidCallback.idl */,
-                               A5A7AA42132F0ECC00D3A3C2 /* WebAutocapitalize.h */,
                                2D1932171DA64E1900A54A08 /* WebKitMediaKeyError.h */,
                                2D1932181DA64E1900A54A08 /* WebKitMediaKeyError.idl */,
                                F55B3DAB1251F12D003EF269 /* WeekInputType.cpp */,
                                AA478A7F16CD70C3007D1BB4 /* WebAccessibilityObjectWrapperMac.h in Headers */,
                                2D3EF4481917915C00034184 /* WebActionDisablingCALayerDelegate.h in Headers */,
                                07D637401BB0B11300256CE9 /* WebAudioSourceProviderAVFObjC.h in Headers */,
-                               A5A7AA43132F0ECC00D3A3C2 /* WebAutocapitalize.h in Headers */,
+                               A5A7AA43132F0ECC00D3A3C2 /* AutocapitalizeTypes.h in Headers */,
                                A56C5B9B189F34570082D13C /* WebConsoleAgent.h in Headers */,
                                419BE7591BC7F42B00E1C85B /* WebCoreBuiltinNames.h in Headers */,
                                2D3EF44A1917915C00034184 /* WebCoreCALayerExtras.h in Headers */,
index 2186ef9..1402d45 100644 (file)
 
 namespace WebCore {
 
-WebAutocapitalizeType autocapitalizeTypeForAttributeValue(const AtomicString& attributeValue)
+AutocapitalizeType autocapitalizeTypeForAttributeValue(const AtomicString& attributeValue)
 {
     // Omitted / missing values are the Default state.
     if (attributeValue.isEmpty())
-        return WebAutocapitalizeTypeDefault;
+        return AutocapitalizeTypeDefault;
 
     if (equalLettersIgnoringASCIICase(attributeValue, "on") || equalLettersIgnoringASCIICase(attributeValue, "sentences"))
-        return WebAutocapitalizeTypeSentences;
+        return AutocapitalizeTypeSentences;
     if (equalLettersIgnoringASCIICase(attributeValue, "off") || equalLettersIgnoringASCIICase(attributeValue, "none"))
-        return WebAutocapitalizeTypeNone;
+        return AutocapitalizeTypeNone;
     if (equalLettersIgnoringASCIICase(attributeValue, "words"))
-        return WebAutocapitalizeTypeWords;
+        return AutocapitalizeTypeWords;
     if (equalLettersIgnoringASCIICase(attributeValue, "characters"))
-        return WebAutocapitalizeTypeAllCharacters;
+        return AutocapitalizeTypeAllCharacters;
 
     // Unrecognized values fall back to "on".
-    return WebAutocapitalizeTypeSentences;
+    return AutocapitalizeTypeSentences;
 }
 
-const AtomicString& stringForAutocapitalizeType(WebAutocapitalizeType type)
+const AtomicString& stringForAutocapitalizeType(AutocapitalizeType type)
 {
     switch (type) {
-    case WebAutocapitalizeTypeDefault:
+    case AutocapitalizeTypeDefault:
         return nullAtom;
-    case WebAutocapitalizeTypeNone: {
+    case AutocapitalizeTypeNone: {
         static NeverDestroyed<const AtomicString> valueNone("none", AtomicString::ConstructFromLiteral);
         return valueNone;
     }
-    case WebAutocapitalizeTypeSentences: {
+    case AutocapitalizeTypeSentences: {
         static NeverDestroyed<const AtomicString> valueSentences("sentences", AtomicString::ConstructFromLiteral);
         return valueSentences;
     }
-    case WebAutocapitalizeTypeWords: {
+    case AutocapitalizeTypeWords: {
         static NeverDestroyed<const AtomicString> valueWords("words", AtomicString::ConstructFromLiteral);
         return valueWords;
     }
-    case WebAutocapitalizeTypeAllCharacters: {
+    case AutocapitalizeTypeAllCharacters: {
         static NeverDestroyed<const AtomicString> valueAllCharacters("characters", AtomicString::ConstructFromLiteral);
         return valueAllCharacters;
     }
index eac30d6..1c32579 100644 (file)
 
 #pragma once
 
-#include "WebAutocapitalize.h"
+#include "AutocapitalizeTypes.h"
 #include <wtf/text/AtomicString.h>
 
 namespace WebCore {
 
-WebAutocapitalizeType autocapitalizeTypeForAttributeValue(const AtomicString&);
-const AtomicString& stringForAutocapitalizeType(WebAutocapitalizeType);
+AutocapitalizeType autocapitalizeTypeForAttributeValue(const AtomicString&);
+const AtomicString& stringForAutocapitalizeType(AutocapitalizeType);
 
 } // namespace WebCore
similarity index 82%
rename from Source/WebCore/html/WebAutocapitalize.h
rename to Source/WebCore/html/AutocapitalizeTypes.h
index b76dda5..01a0eac 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef WebAutocapitalize_h
-#define WebAutocapitalize_h
+#pragma once
 
 typedef enum {
-    WebAutocapitalizeTypeDefault,
-    WebAutocapitalizeTypeNone,
-    WebAutocapitalizeTypeWords,
-    WebAutocapitalizeTypeSentences,
-    WebAutocapitalizeTypeAllCharacters
-} WebAutocapitalizeType;
-
-#endif // WebAutocapitalize_h
+    AutocapitalizeTypeDefault,
+    AutocapitalizeTypeNone,
+    AutocapitalizeTypeWords,
+    AutocapitalizeTypeSentences,
+    AutocapitalizeTypeAllCharacters
+} AutocapitalizeType;
index ed38a1c..e009801 100644 (file)
@@ -1059,6 +1059,37 @@ bool HTMLElement::isActuallyDisabled() const
     return canBeActuallyDisabled() && isDisabledFormControl();
 }
 
+#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
+
+const AtomicString& HTMLElement::autocapitalize() const
+{
+    return stringForAutocapitalizeType(autocapitalizeType());
+}
+
+AutocapitalizeType HTMLElement::autocapitalizeType() const
+{
+    return autocapitalizeTypeForAttributeValue(attributeWithoutSynchronization(HTMLNames::autocapitalizeAttr));
+}
+
+void HTMLElement::setAutocapitalize(const AtomicString& value)
+{
+    setAttributeWithoutSynchronization(autocapitalizeAttr, value);
+}
+
+bool HTMLElement::shouldAutocorrect() const
+{
+    auto autocorrectValue = attributeWithoutSynchronization(HTMLNames::autocorrectAttr);
+    // Unrecognized values fall back to "on".
+    return !equalLettersIgnoringASCIICase(autocorrectValue, "off");
+}
+
+void HTMLElement::setAutocorrect(bool autocorrect)
+{
+    setAttributeWithoutSynchronization(autocorrectAttr, autocorrect ? AtomicString("on", AtomicString::ConstructFromLiteral) : AtomicString("off", AtomicString::ConstructFromLiteral));
+}
+
+#endif
+
 } // namespace WebCore
 
 #ifndef NDEBUG
index 62d4e3e..39d4cb7 100644 (file)
 
 #pragma once
 
+#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
+#include "Autocapitalize.h"
+#endif
+
 #include "StyledElement.h"
 
 namespace WebCore {
@@ -92,6 +96,16 @@ public:
     bool canBeActuallyDisabled() const;
     bool isActuallyDisabled() const;
 
+#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
+    WEBCORE_EXPORT virtual AutocapitalizeType autocapitalizeType() const;
+    WEBCORE_EXPORT const AtomicString& autocapitalize() const;
+    WEBCORE_EXPORT void setAutocapitalize(const AtomicString& value);
+
+    bool autocorrect() const { return shouldAutocorrect(); }
+    WEBCORE_EXPORT virtual bool shouldAutocorrect() const;
+    WEBCORE_EXPORT void setAutocorrect(bool);
+#endif
+
 protected:
     HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
 
index fbcc579..347f11f 100644 (file)
@@ -47,6 +47,9 @@
 
     [CEReactions] attribute boolean spellcheck;
 
+    [Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE] attribute boolean autocorrect;
+    [Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE, TreatNullAs=EmptyString] attribute DOMString autocapitalize;
+
     void click();
 
     void focus();
index eca3a7a..a59219b 100644 (file)
@@ -602,41 +602,26 @@ HTMLFormElement* HTMLFormControlElement::virtualForm() const
 
 // FIXME: We should look to share this code with class HTMLFormElement instead of duplicating the logic.
 
-bool HTMLFormControlElement::autocorrect() const
+bool HTMLFormControlElement::shouldAutocorrect() const
 {
     const AtomicString& autocorrectValue = attributeWithoutSynchronization(autocorrectAttr);
     if (!autocorrectValue.isEmpty())
         return !equalLettersIgnoringASCIICase(autocorrectValue, "off");
     if (HTMLFormElement* form = this->form())
-        return form->autocorrect();
+        return form->shouldAutocorrect();
     return true;
 }
 
-void HTMLFormControlElement::setAutocorrect(bool autocorrect)
+AutocapitalizeType HTMLFormControlElement::autocapitalizeType() const
 {
-    setAttributeWithoutSynchronization(autocorrectAttr, autocorrect ? AtomicString("on", AtomicString::ConstructFromLiteral) : AtomicString("off", AtomicString::ConstructFromLiteral));
-}
-
-WebAutocapitalizeType HTMLFormControlElement::autocapitalizeType() const
-{
-    WebAutocapitalizeType type = autocapitalizeTypeForAttributeValue(attributeWithoutSynchronization(autocapitalizeAttr));
-    if (type == WebAutocapitalizeTypeDefault) {
+    AutocapitalizeType type = HTMLElement::autocapitalizeType();
+    if (type == AutocapitalizeTypeDefault) {
         if (HTMLFormElement* form = this->form())
             return form->autocapitalizeType();
     }
     return type;
 }
 
-const AtomicString& HTMLFormControlElement::autocapitalize() const
-{
-    return stringForAutocapitalizeType(autocapitalizeType());
-}
-
-void HTMLFormControlElement::setAutocapitalize(const AtomicString& value)
-{
-    setAttributeWithoutSynchronization(autocapitalizeAttr, value);
-}
-
 #endif
 
 HTMLFormControlElement* HTMLFormControlElement::enclosingFormControlElement(Node* node)
index d960d8f..d0ff84d 100644 (file)
@@ -92,12 +92,8 @@ public:
     virtual void setActivatedSubmit(bool) { }
 
 #if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
-    WEBCORE_EXPORT bool autocorrect() const;
-    WEBCORE_EXPORT void setAutocorrect(bool);
-
-    WEBCORE_EXPORT WebAutocapitalizeType autocapitalizeType() const;
-    WEBCORE_EXPORT const AtomicString& autocapitalize() const;
-    WEBCORE_EXPORT void setAutocapitalize(const AtomicString&);
+    WEBCORE_EXPORT bool shouldAutocorrect() const final;
+    WEBCORE_EXPORT AutocapitalizeType autocapitalizeType() const final;
 #endif
 
     WEBCORE_EXPORT bool willValidate() const final;
index f207127..7dceb2b 100644 (file)
@@ -386,36 +386,16 @@ void HTMLFormElement::reset()
 
 // FIXME: We should look to share this code with class HTMLFormControlElement instead of duplicating the logic.
 
-bool HTMLFormElement::autocorrect() const
+bool HTMLFormElement::shouldAutocorrect() const
 {
     const AtomicString& autocorrectValue = attributeWithoutSynchronization(autocorrectAttr);
     if (!autocorrectValue.isEmpty())
         return !equalLettersIgnoringASCIICase(autocorrectValue, "off");
     if (HTMLFormElement* form = this->form())
-        return form->autocorrect();
+        return form->shouldAutocorrect();
     return true;
 }
 
-void HTMLFormElement::setAutocorrect(bool autocorrect)
-{
-    setAttributeWithoutSynchronization(autocorrectAttr, autocorrect ? AtomicString("on", AtomicString::ConstructFromLiteral) : AtomicString("off", AtomicString::ConstructFromLiteral));
-}
-
-WebAutocapitalizeType HTMLFormElement::autocapitalizeType() const
-{
-    return autocapitalizeTypeForAttributeValue(attributeWithoutSynchronization(autocapitalizeAttr));
-}
-
-const AtomicString& HTMLFormElement::autocapitalize() const
-{
-    return stringForAutocapitalizeType(autocapitalizeType());
-}
-
-void HTMLFormElement::setAutocapitalize(const AtomicString& value)
-{
-    setAttributeWithoutSynchronization(autocapitalizeAttr, value);
-}
-
 #endif
 
 #if ENABLE(REQUEST_AUTOCOMPLETE)
index 43fa7f7..79b0587 100644 (file)
@@ -63,12 +63,7 @@ public:
     WEBCORE_EXPORT const AtomicString& autocomplete() const;
 
 #if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
-    WEBCORE_EXPORT bool autocorrect() const;
-    WEBCORE_EXPORT void setAutocorrect(bool);
-
-    WEBCORE_EXPORT WebAutocapitalizeType autocapitalizeType() const;
-    WEBCORE_EXPORT const AtomicString& autocapitalize() const;
-    WEBCORE_EXPORT void setAutocapitalize(const AtomicString&);
+    WEBCORE_EXPORT bool shouldAutocorrect() const final;
 #endif
 
     // FIXME: Should rename these two functions to say "form control" or "form-associated element" instead of "form element".
index 0912a7d..ee1f124 100644 (file)
 
     getter Element (unsigned long index);
 
-    [Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE] attribute boolean autocorrect;
-
-    [Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE, TreatNullAs=EmptyString] attribute DOMString autocapitalize;
-
     [ImplementedAs=submitFromJavaScript] void submit();
     void reset();
     boolean checkValidity();
index 26af00c..a6d8f9f 100644 (file)
     [Reflect] attribute DOMString useMap;
     [Reflect] attribute boolean incremental;
 
-    [Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE] attribute boolean autocorrect;
-
-    [Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE, TreatNullAs=EmptyString] attribute DOMString autocapitalize;
-
     // See http://www.w3.org/TR/html-media-capture/
     [Conditional=MEDIA_CAPTURE, Reflect] attribute DOMString capture;
 };
index 181d700..2bcb656 100644 (file)
@@ -58,7 +58,5 @@ interface HTMLTextAreaElement : HTMLElement {
 
     void setSelectionRange(optional long start = 0, optional long end = 0, optional DOMString direction);
 
-    [Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE] attribute boolean autocorrect;
-    [Conditional=IOS_AUTOCORRECT_AND_AUTOCAPITALIZE, TreatNullAs=EmptyString] attribute DOMString autocapitalize;
     attribute DOMString autocomplete;
 };
index 187a2ff..5edf61f 100644 (file)
@@ -1,3 +1,15 @@
+2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
+        https://bugs.webkit.org/show_bug.cgi?id=164538
+        <rdar://problem/8418711>
+
+        Reviewed by Ryosuke Niwa.
+
+        Introduce WebAutocapitalizeTypes.h to WebKit.
+
+        * WebKit.xcodeproj/project.pbxproj:
+
 2016-11-10  Alex Christensen  <achristensen@webkit.org>
 
         Move SecurityOrigin::databaseIdentifier() to SecurityOriginData
index 6647725..6e3ec25 100644 (file)
                E4AEF97C1C0DF4BC00B01727 /* WebResourceLoadScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AEF97A1C0DF4BC00B01727 /* WebResourceLoadScheduler.h */; };
                ED5B9524111B725A00472298 /* WebLocalizableStrings.mm in Sources */ = {isa = PBXBuildFile; fileRef = ED5B9523111B725A00472298 /* WebLocalizableStrings.mm */; };
                ED7F6D8B0980683500C235ED /* WebNSDataExtrasPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = ED7F6D8A0980683500C235ED /* WebNSDataExtrasPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               F4C98E5D1DD6476F0012FDEC /* DOMHTMLElementPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = F4C98E5C1DD6476F0012FDEC /* DOMHTMLElementPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               F4F665C21DD67672007714B4 /* WebAutocapitalizeTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F4F665C11DD67672007714B4 /* WebAutocapitalizeTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                F834AAD70E64B1C700E2737C /* WebTextIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = F834AAD50E64B1C700E2737C /* WebTextIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                F834AAD80E64B1C700E2737C /* WebTextIterator.mm in Sources */ = {isa = PBXBuildFile; fileRef = F834AAD60E64B1C700E2737C /* WebTextIterator.mm */; };
 /* End PBXBuildFile section */
                EDD1A5C605C83987008E3150 /* WebNSPrintOperationExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSPrintOperationExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                EDD1A5C705C83987008E3150 /* WebNSPrintOperationExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebNSPrintOperationExtras.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                EDE850CD06ECC79E005FAB05 /* WebPreferenceKeysPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebPreferenceKeysPrivate.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
+               F4C98E5C1DD6476F0012FDEC /* DOMHTMLElementPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMHTMLElementPrivate.h; sourceTree = "<group>"; };
+               F4F665C11DD67672007714B4 /* WebAutocapitalizeTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebAutocapitalizeTypes.h; sourceTree = "<group>"; };
                F508946902B71D59018A9CD4 /* WebNSViewExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = WebNSViewExtras.h; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                F508946A02B71D59018A9CD4 /* WebNSViewExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.c.objc; path = WebNSViewExtras.m; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                F5143A370221DCCE01A80181 /* WebFrame.mm */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebFrame.mm; sourceTree = "<group>"; tabWidth = 8; usesTabs = 0; };
                                93D435821D57ABEE00AB85EA /* DOMHTMLElement.h */,
                                93D435831D57ABEE00AB85EA /* DOMHTMLElement.mm */,
                                93D435841D57ABEE00AB85EA /* DOMHTMLElementInternal.h */,
+                               F4C98E5C1DD6476F0012FDEC /* DOMHTMLElementPrivate.h */,
                                93D435851D57ABEE00AB85EA /* DOMHTMLEmbedElement.h */,
                                93D435861D57ABEE00AB85EA /* DOMHTMLEmbedElement.mm */,
                                93D435871D57ABEE00AB85EA /* DOMHTMLFieldSetElement.h */,
                                93D4364A1D57ABEE00AB85EA /* ObjCEventListener.mm */,
                                93D4364B1D57ABEE00AB85EA /* ObjCNodeFilterCondition.h */,
                                93D4364C1D57ABEE00AB85EA /* ObjCNodeFilterCondition.mm */,
+                               F4F665C11DD67672007714B4 /* WebAutocapitalizeTypes.h */,
                                846171F90624AE5B0071A4A3 /* WebDOMOperations.h */,
                                846171FA0624AE5B0071A4A3 /* WebDOMOperations.mm */,
                                AB9FBBBA0F8582B0006ADC43 /* WebDOMOperationsInternal.h */,
                                93D4364D1D57ABEE00AB85EA /* DOM.h in Headers */,
                                93D4364F1D57ABEE00AB85EA /* DOMAbstractView.h in Headers */,
                                93D436511D57ABEE00AB85EA /* DOMAbstractViewFrame.h in Headers */,
+                               F4F665C21DD67672007714B4 /* WebAutocapitalizeTypes.h in Headers */,
                                93D436521D57ABEE00AB85EA /* DOMAbstractViewInternal.h in Headers */,
                                93D436531D57ABEE00AB85EA /* DOMAttr.h in Headers */,
                                93D436551D57ABEE00AB85EA /* DOMAttrInternal.h in Headers */,
                                93D4367D1D57ABEE00AB85EA /* DOMCSSStyleRule.h in Headers */,
                                93D4367F1D57ABEE00AB85EA /* DOMCSSStyleSheet.h in Headers */,
                                93D436811D57ABEE00AB85EA /* DOMCSSStyleSheetInternal.h in Headers */,
+                               F4C98E5D1DD6476F0012FDEC /* DOMHTMLElementPrivate.h in Headers */,
                                93D436821D57ABEE00AB85EA /* DOMCSSUnknownRule.h in Headers */,
                                93D436841D57ABEE00AB85EA /* DOMCSSValue.h in Headers */,
                                93D436861D57ABEE00AB85EA /* DOMCSSValueInternal.h in Headers */,
index da7e060..eebde42 100644 (file)
@@ -1,3 +1,51 @@
+2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
+        https://bugs.webkit.org/show_bug.cgi?id=164538
+        <rdar://problem/8418711>
+
+        Reviewed by Ryosuke Niwa.
+
+        Account for renaming HTMLElement::autocorrect to HTMLElement::shouldAutocorrect, as well as moving
+        WebAutocapitalizeType to WebKit from WebCore. Additionally, moves the -autocorrect and -autocapitalize SPIs out
+        of HTML(Input|Form|TextArea)ElementPrivate.h and into HTMLElementPrivate.h. This also means removing redundant
+        code for interfacing with the unwrapped HTMLElement's autocorrect and autocapitalize attributes.
+
+        * DOM/DOMHTML.mm:
+        (webAutocapitalizeType):
+        (-[DOMHTMLInputElement _autocapitalizeType]):
+        (-[DOMHTMLTextAreaElement _autocapitalizeType]):
+        * DOM/DOMHTMLElement.mm:
+        (-[DOMHTMLElement autocorrect]):
+        (-[DOMHTMLElement setAutocorrect:]):
+        (-[DOMHTMLElement autocapitalize]):
+        (-[DOMHTMLElement setAutocapitalize:]):
+        * DOM/DOMHTMLElementPrivate.h: Copied from Source/WebCore/html/Autocapitalize.h.
+        * DOM/DOMHTMLFormElement.mm:
+        (-[DOMHTMLFormElement autocorrect]): Deleted.
+        (-[DOMHTMLFormElement setAutocorrect:]): Deleted.
+        (-[DOMHTMLFormElement autocapitalize]): Deleted.
+        (-[DOMHTMLFormElement setAutocapitalize:]): Deleted.
+        * DOM/DOMHTMLInputElement.mm:
+        (-[DOMHTMLInputElement autocorrect]): Deleted.
+        (-[DOMHTMLInputElement setAutocorrect:]): Deleted.
+        (-[DOMHTMLInputElement autocapitalize]): Deleted.
+        (-[DOMHTMLInputElement setAutocapitalize:]): Deleted.
+        * DOM/DOMHTMLInputElementPrivate.h:
+        * DOM/DOMHTMLTextAreaElement.mm:
+        (-[DOMHTMLTextAreaElement autocorrect]): Deleted.
+        (-[DOMHTMLTextAreaElement setAutocorrect:]): Deleted.
+        (-[DOMHTMLTextAreaElement autocapitalize]): Deleted.
+        (-[DOMHTMLTextAreaElement setAutocapitalize:]): Deleted.
+        * DOM/DOMHTMLTextAreaElementPrivate.h:
+
+        We need to import DOMHTMLElementPrivate.h here to avoid breaking UIKit. We should follow this up with a UIKit
+        change to import DOMHTMLElementPrivate.h directly.
+
+        * DOM/DOMPrivate.h:
+        * DOM/WebAutocapitalizeTypes.h: Copied from Tools/WebKitTestRunner/ios/UIKitSPI.h.
+        * MigrateHeaders.make:
+
 2016-11-11  Beth Dakin  <bdakin@apple.com>
 
         Move to modern TouchBar methods
index 3973ab8..2743038 100644 (file)
@@ -241,12 +241,28 @@ using namespace WebCore;
 
 @end
 
+static WebAutocapitalizeType webAutocapitalizeType(AutocapitalizeType type)
+{
+    switch (type) {
+    case AutocapitalizeTypeDefault:
+        return WebAutocapitalizeTypeDefault;
+    case AutocapitalizeTypeNone:
+        return WebAutocapitalizeTypeNone;
+    case AutocapitalizeTypeWords:
+        return WebAutocapitalizeTypeWords;
+    case AutocapitalizeTypeSentences:
+        return WebAutocapitalizeTypeSentences;
+    case AutocapitalizeTypeAllCharacters:
+        return WebAutocapitalizeTypeAllCharacters;
+    }
+}
+
 @implementation DOMHTMLInputElement (AutocapitalizeAdditions)
 
 - (WebAutocapitalizeType)_autocapitalizeType
 {
     WebCore::HTMLInputElement* inputElement = core(self);
-    return static_cast<WebAutocapitalizeType>(inputElement->autocapitalizeType());
+    return webAutocapitalizeType(inputElement->autocapitalizeType());
 }
 
 @end
@@ -256,7 +272,7 @@ using namespace WebCore;
 - (WebAutocapitalizeType)_autocapitalizeType
 {
     WebCore::HTMLTextAreaElement* textareaElement = core(self);
-    return static_cast<WebAutocapitalizeType>(textareaElement->autocapitalizeType());
+    return webAutocapitalizeType(textareaElement->autocapitalizeType());
 }
 
 @end
index a47694c..7330dc1 100644 (file)
     IMPL->click();
 }
 
+#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
+
+- (BOOL)autocorrect
+{
+    WebCore::JSMainThreadNullState state;
+    return IMPL->shouldAutocorrect();
+}
+
+- (void)setAutocorrect:(BOOL)newAutocorrect
+{
+    WebCore::JSMainThreadNullState state;
+    IMPL->setAutocorrect(newAutocorrect);
+}
+
+- (NSString *)autocapitalize
+{
+    WebCore::JSMainThreadNullState state;
+    return IMPL->autocapitalize();
+}
+
+- (void)setAutocapitalize:(NSString *)newAutocapitalize
+{
+    WebCore::JSMainThreadNullState state;
+    IMPL->setAutocapitalize(newAutocapitalize);
+}
+
+#endif
+
 @end
 
 WebCore::HTMLElement* core(DOMHTMLElement *wrapper)
diff --git a/Source/WebKit/mac/DOM/DOMHTMLElementPrivate.h b/Source/WebKit/mac/DOM/DOMHTMLElementPrivate.h
new file mode 100644 (file)
index 0000000..bc17023
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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. ``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
+ * 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 <WebKitLegacy/DOMHTMLElement.h>
+
+@interface DOMHTMLElement (DOMHTMLElementPrivate)
+
+@property BOOL autocorrect;
+@property (copy) NSString *autocapitalize;
+
+@end
index 54b68ac..032fa1c 100644 (file)
     return IMPL->length();
 }
 
-#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
-- (BOOL)autocorrect
-{
-    WebCore::JSMainThreadNullState state;
-    return IMPL->autocorrect();
-}
-
-- (void)setAutocorrect:(BOOL)newAutocorrect
-{
-    WebCore::JSMainThreadNullState state;
-    IMPL->setAutocorrect(newAutocorrect);
-}
-#endif
-
-#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
-- (NSString *)autocapitalize
-{
-    WebCore::JSMainThreadNullState state;
-    return IMPL->autocapitalize();
-}
-
-- (void)setAutocapitalize:(NSString *)newAutocapitalize
-{
-    WebCore::JSMainThreadNullState state;
-    IMPL->setAutocapitalize(newAutocapitalize);
-}
-#endif
-
 - (void)submit
 {
     WebCore::JSMainThreadNullState state;
index c10ca0f..9bc803c 100644 (file)
     return [self _getURLAttribute:@"src"];
 }
 
-#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
-- (BOOL)autocorrect
-{
-    WebCore::JSMainThreadNullState state;
-    return IMPL->autocorrect();
-}
-
-- (void)setAutocorrect:(BOOL)newAutocorrect
-{
-    WebCore::JSMainThreadNullState state;
-    IMPL->setAutocorrect(newAutocorrect);
-}
-#endif
-
-#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
-- (NSString *)autocapitalize
-{
-    WebCore::JSMainThreadNullState state;
-    return IMPL->autocapitalize();
-}
-
-- (void)setAutocapitalize:(NSString *)newAutocapitalize
-{
-    WebCore::JSMainThreadNullState state;
-    IMPL->setAutocapitalize(newAutocapitalize);
-}
-#endif
-
 #if ENABLE(MEDIA_CAPTURE)
 - (BOOL)capture
 {
index 3536c1e..18d9376 100644 (file)
@@ -23,6 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#import <WebKitLegacy/DOMHTMLElementPrivate.h>
 #import <WebKitLegacy/DOMHTMLInputElement.h>
 
 @class DOMHTMLElement;
@@ -51,8 +52,6 @@
 @property (readonly, strong) DOMNodeList *labels;
 @property (copy) NSString *selectionDirection;
 @property BOOL incremental;
-@property BOOL autocorrect;
-@property (copy) NSString *autocapitalize;
 @property BOOL capture;
 
 - (void)stepUp:(int)n;
index 1533c4e..14935af 100644 (file)
@@ -325,32 +325,4 @@ DOMHTMLTextAreaElement *kit(HTMLTextAreaElement* value)
     unwrap(*self).setSelectionRange(start, end);
 }
 
-#if ENABLE(IOS_AUTOCORRECT_AND_AUTOCAPITALIZE)
-
-- (BOOL)autocorrect
-{
-    JSMainThreadNullState state;
-    return unwrap(*self).autocorrect();
-}
-
-- (void)setAutocorrect:(BOOL)newAutocorrect
-{
-    JSMainThreadNullState state;
-    unwrap(*self).setAutocorrect(newAutocorrect);
-}
-
-- (NSString *)autocapitalize
-{
-    JSMainThreadNullState state;
-    return unwrap(*self).autocapitalize();
-}
-
-- (void)setAutocapitalize:(NSString *)newAutocapitalize
-{
-    JSMainThreadNullState state;
-    unwrap(*self).setAutocapitalize(newAutocapitalize);
-}
-
-#endif
-
 @end
index 2d9997c..aa22829 100644 (file)
@@ -23,6 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#import <WebKitLegacy/DOMHTMLElementPrivate.h>
 #import <WebKitLegacy/DOMHTMLTextAreaElement.h>
 
 @class DOMNodeList;
@@ -37,8 +38,6 @@
 @property (readonly) unsigned textLength;
 @property (readonly, strong) DOMNodeList *labels;
 @property (copy) NSString *selectionDirection;
-@property BOOL autocorrect;
-@property (copy) NSString *autocapitalize;
 @property (copy) NSString *autocomplete;
 - (void)setRangeText:(NSString *)replacement;
 - (void)setRangeText:(NSString *)replacement start:(unsigned)start end:(unsigned)end selectionMode:(NSString *)selectionMode;
index c6bfd08..f89ab74 100644 (file)
@@ -25,9 +25,9 @@
  */
 
 #import <WebKitLegacy/DOM.h>
+#import <WebKitLegacy/WebAutocapitalizeTypes.h>
 
 #if TARGET_OS_IPHONE
-#import <WebKitLegacy/WebAutocapitalize.h>
 #import <CoreText/CoreText.h>
 #endif
 
diff --git a/Source/WebKit/mac/DOM/WebAutocapitalizeTypes.h b/Source/WebKit/mac/DOM/WebAutocapitalizeTypes.h
new file mode 100644 (file)
index 0000000..038c804
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+typedef enum {
+    WebAutocapitalizeTypeDefault,
+    WebAutocapitalizeTypeNone,
+    WebAutocapitalizeTypeWords,
+    WebAutocapitalizeTypeSentences,
+    WebAutocapitalizeTypeAllCharacters
+} WebAutocapitalizeType;
index 828fe86..02051fe 100644 (file)
@@ -200,7 +200,6 @@ all : \
     $(PRIVATE_HEADERS_DIR)/WKGraphics.h \
     $(PRIVATE_HEADERS_DIR)/WKTypes.h \
     $(PRIVATE_HEADERS_DIR)/WKUtilities.h \
-    $(PRIVATE_HEADERS_DIR)/WebAutocapitalize.h \
     $(PRIVATE_HEADERS_DIR)/WebCoreFrameView.h \
     $(PRIVATE_HEADERS_DIR)/WebCoreThread.h \
     $(PRIVATE_HEADERS_DIR)/WebCoreThreadMessage.h \
index 45f5d6d..395e0e3 100644 (file)
@@ -1,3 +1,20 @@
+2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
+        https://bugs.webkit.org/show_bug.cgi?id=164538
+        <rdar://problem/8418711>
+
+        Reviewed by Ryosuke Niwa.
+
+        Consult HTMLElement::autocorrect() and HTMLElement::autocapitalizeType() when assembling the assisted node
+        information for the currently assisted node.
+
+        * Shared/AssistedNodeInformation.h:
+        * UIProcess/ios/WKContentViewInteraction.mm:
+        (toUITextAutocapitalize):
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::getAssistedNodeInformation):
+
 2016-11-11  Beth Dakin  <bdakin@apple.com>
 
         Move to modern TouchBar methods
index 9709730..a24618d 100644 (file)
@@ -27,9 +27,9 @@
 #define AssistedNodeInformation_h
 
 #include "ArgumentCoders.h"
+#include <WebCore/AutocapitalizeTypes.h>
 #include <WebCore/Autofill.h>
 #include <WebCore/IntRect.h>
-#include <WebCore/WebAutocapitalize.h>
 #include <wtf/text/WTFString.h>
 
 namespace WebKit {
@@ -102,7 +102,7 @@ struct AssistedNodeInformation {
     bool allowsUserScaling { false };
     bool allowsUserScalingIgnoringAlwaysScalable { false };
     bool insideFixedPosition { false };
-    WebAutocapitalizeType autocapitalizeType { WebAutocapitalizeTypeDefault };
+    AutocapitalizeType autocapitalizeType { AutocapitalizeTypeDefault };
     InputType elementType { InputType::None };
     String formAction;
     Vector<OptionItem> selectOptions;
index ac839ed..20d904a 100644 (file)
@@ -2894,18 +2894,18 @@ static void selectionChangedWithTouch(WKContentView *view, const WebCore::IntPoi
 
 // end of UITextInput protocol implementation
 
-static UITextAutocapitalizationType toUITextAutocapitalize(WebAutocapitalizeType webkitType)
+static UITextAutocapitalizationType toUITextAutocapitalize(AutocapitalizeType webkitType)
 {
     switch (webkitType) {
-    case WebAutocapitalizeTypeDefault:
+    case AutocapitalizeTypeDefault:
         return UITextAutocapitalizationTypeSentences;
-    case WebAutocapitalizeTypeNone:
+    case AutocapitalizeTypeNone:
         return UITextAutocapitalizationTypeNone;
-    case WebAutocapitalizeTypeWords:
+    case AutocapitalizeTypeWords:
         return UITextAutocapitalizationTypeWords;
-    case WebAutocapitalizeTypeSentences:
+    case AutocapitalizeTypeSentences:
         return UITextAutocapitalizationTypeSentences;
-    case WebAutocapitalizeTypeAllCharacters:
+    case AutocapitalizeTypeAllCharacters:
         return UITextAutocapitalizationTypeAllCharacters;
     }
 
index aa4857b..479c0e2 100644 (file)
@@ -66,6 +66,7 @@
 #import <WebCore/GeometryUtilities.h>
 #import <WebCore/HTMLAreaElement.h>
 #import <WebCore/HTMLAttachmentElement.h>
+#import <WebCore/HTMLElement.h>
 #import <WebCore/HTMLElementTypeHelpers.h>
 #import <WebCore/HTMLFormElement.h>
 #import <WebCore/HTMLImageElement.h>
@@ -2577,8 +2578,8 @@ void WebPage::getAssistedNodeInformation(AssistedNodeInformation& information)
         information.isMultiSelect = element.multiple();
     } else if (is<HTMLTextAreaElement>(*m_assistedNode)) {
         HTMLTextAreaElement& element = downcast<HTMLTextAreaElement>(*m_assistedNode);
-        information.autocapitalizeType = static_cast<WebAutocapitalizeType>(element.autocapitalizeType());
-        information.isAutocorrect = element.autocorrect();
+        information.autocapitalizeType = element.autocapitalizeType();
+        information.isAutocorrect = element.shouldAutocorrect();
         information.elementType = InputType::TextArea;
         information.isReadOnly = element.isReadOnly();
         information.value = element.value();
@@ -2588,8 +2589,8 @@ void WebPage::getAssistedNodeInformation(AssistedNodeInformation& information)
         HTMLFormElement* form = element.form();
         if (form)
             information.formAction = form->getURLAttribute(WebCore::HTMLNames::actionAttr);
-        information.autocapitalizeType = static_cast<WebAutocapitalizeType>(element.autocapitalizeType());
-        information.isAutocorrect = element.autocorrect();
+        information.autocapitalizeType = element.autocapitalizeType();
+        information.isAutocorrect = element.shouldAutocorrect();
         if (element.isPasswordField())
             information.elementType = InputType::Password;
         else if (element.isSearchField())
@@ -2633,8 +2634,14 @@ void WebPage::getAssistedNodeInformation(AssistedNodeInformation& information)
         information.autofillFieldName = WebCore::toAutofillFieldName(element.autofillData().fieldName);
     } else if (m_assistedNode->hasEditableStyle()) {
         information.elementType = InputType::ContentEditable;
-        information.isAutocorrect = true;   // FIXME: Should we look at the attribute?
-        information.autocapitalizeType = WebAutocapitalizeTypeSentences; // FIXME: Should we look at the attribute?
+        if (is<HTMLElement>(*m_assistedNode)) {
+            auto& assistedElement = downcast<HTMLElement>(*m_assistedNode);
+            information.isAutocorrect = assistedElement.shouldAutocorrect();
+            information.autocapitalizeType = assistedElement.autocapitalizeType();
+        } else {
+            information.isAutocorrect = true;
+            information.autocapitalizeType = AutocapitalizeTypeDefault;
+        }
         information.isReadOnly = false;
     }
 }
index 205465a..70a3a8e 100644 (file)
@@ -1,3 +1,36 @@
+2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+
+        [WK2] autocorrect and autocapitalize attributes do not work in contenteditable elements
+        https://bugs.webkit.org/show_bug.cgi?id=164538
+        <rdar://problem/8418711>
+
+        Reviewed by Ryosuke Niwa.
+
+        Adds support for being able to test autocorrect and autocapitalize attributes in contenteditable areas. To do
+        this, we add removeAllDynamicDictionaries to UIScriptController in order to ensure that autocorrect suggestions
+        are reset to their defaults prior to running contenteditable-autocorrect-off.html.
+
+        * DumpRenderTree/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::removeAllDynamicDictionaries):
+        * Scripts/webkitpy/port/ios.py:
+        (IOSSimulatorPort._createSimulatorApp):
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.cpp:
+        (WTR::UIScriptController::removeAllDynamicDictionaries):
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        * WebKitTestRunner/cocoa/TestRunnerWKWebView.mm:
+        (-[TestRunnerWKWebView _keyboardDidShow:]):
+        (-[TestRunnerWKWebView _keyboardDidHide:]):
+
+        Work around an issue where consecutive UIKeyboardDidShowNotification would cause keyboard appearance callbacks
+        to be fired multiple times. This was causing a single key press to cause two characters to be typed. While this
+        does not affect the correctness of existing tests, the new autocorrection test requires this workaround.
+
+        * WebKitTestRunner/ios/UIKitSPI.h:
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex):
+        (WTR::UIScriptController::removeAllDynamicDictionaries):
+
 2016-11-11  Alex Christensen  <achristensen@webkit.org>
 
         Build all Mac API tests
@@ -18,7 +51,7 @@
         * TestWebKitAPI/Tests/WTF/HashMap.cpp:
         (TestWebKitAPI::TEST):
 
-2016-11-11  Wenson Hsieh  <wenson_hsieh@apple.com>
+2016-11-10  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Composition state should be cleared when changing focus to a non-editable element
         https://bugs.webkit.org/show_bug.cgi?id=164595
index 5eac8d8..18e2f3a 100644 (file)
@@ -215,6 +215,10 @@ JSObjectRef UIScriptController::selectionRangeViewRects() const
     return nullptr;
 }
 
+void UIScriptController::removeAllDynamicDictionaries()
+{
+}
+
 }
 
 #endif // PLATFORM(IOS)
index 30f617f..c533850 100644 (file)
@@ -157,6 +157,7 @@ interface UIScriptController {
     readonly attribute object selectionRangeViewRects; // An array of objects with 'left', 'top', 'width', and 'height' properties.
 
     void insertText(DOMString text, long location, long length);
+    void removeAllDynamicDictionaries();
 
     void uiScriptComplete(DOMString result);
 };
index 288fd3f..89c3108 100644 (file)
@@ -278,6 +278,10 @@ JSObjectRef UIScriptController::selectionRangeViewRects() const
     return nullptr;
 }
 
+void UIScriptController::removeAllDynamicDictionaries()
+{
+}
+
 void UIScriptController::platformSetDidStartFormControlInteractionCallback()
 {
 }
index 1c16133..a6e58bd 100644 (file)
@@ -118,6 +118,7 @@ public:
     JSObjectRef selectionRangeViewRects() const;
 
     void insertText(JSStringRef, int location, int length);
+    void removeAllDynamicDictionaries();
 
     void uiScriptComplete(JSStringRef result);
 
index d86358d..9699747 100644 (file)
@@ -46,6 +46,7 @@
 @interface TestRunnerWKWebView ()
 @property (nonatomic, copy) void (^zoomToScaleCompletionHandler)(void);
 @property (nonatomic, copy) void (^showKeyboardCompletionHandler)(void);
+@property (nonatomic) BOOL isShowingKeyboard;
 @end
 
 @implementation TestRunnerWKWebView
 
 - (void)_keyboardDidShow:(NSNotification *)notification
 {
+    if (self.isShowingKeyboard)
+        return;
+
+    self.isShowingKeyboard = YES;
     if (self.didShowKeyboardCallback)
         self.didShowKeyboardCallback();
 }
 
 - (void)_keyboardDidHide:(NSNotification *)notification
 {
+    if (!self.isShowingKeyboard)
+        return;
+
+    self.isShowingKeyboard = NO;
     if (self.didHideKeyboardCallback)
         self.didHideKeyboardCallback();
 }
index 600b937..bb4dc2f 100644 (file)
@@ -35,6 +35,7 @@
 #if USE(APPLE_INTERNAL_SDK)
 
 #import <UIKit/UIApplication_Private.h>
+#import <UIKit/UIKeyboard.h>
 #import <UIKit/UIWindow_Private.h>
 
 @interface UIKeyboardPredictionView : UIView
 - (uint32_t)_contextId;
 @end
 
+@interface UIKeyboard : UIView
++ (void)removeAllDynamicDictionaries;
+@end
+
 #endif // USE(APPLE_INTERNAL_SDK)
 
 #endif // PLATFORM(IOS)
index c159ef2..8d376cd 100644 (file)
@@ -33,6 +33,7 @@
 #import "StringFunctions.h"
 #import "TestController.h"
 #import "TestRunnerWKWebView.h"
+#import "UIKitSPI.h"
 #import "UIScriptContext.h"
 #import <JavaScriptCore/JavaScriptCore.h>
 #import <JavaScriptCore/OpaqueJSString.h>
@@ -276,7 +277,8 @@ void UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex(lon
         return;
 
 #if USE(APPLE_INTERNAL_SDK)
-    if (![[UIKeyboardPredictionViewClass activeInstance] hasPredictions]) {
+    UIKeyboardPredictionView *predictionView = (UIKeyboardPredictionView *)[UIKeyboardPredictionViewClass activeInstance];
+    if (![predictionView hasPredictions]) {
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), dispatch_get_main_queue(), ^() {
             waitForTextPredictionsViewAndSelectCandidateAtIndex(index, callbackID, interval);
         });
@@ -284,10 +286,10 @@ void UIScriptController::waitForTextPredictionsViewAndSelectCandidateAtIndex(lon
     }
 
     PlatformWKView webView = TestController::singleton().mainWebView()->platformView();
-    CGRect predictionViewFrame = [[UIKeyboardPredictionViewClass activeInstance] frame];
+    CGRect predictionViewFrame = [predictionView frame];
     // This assumes there are 3 predicted text cells of equal width, which is the case on iOS.
     float offsetX = (index * 2 + 1) * CGRectGetWidth(predictionViewFrame) / 6;
-    float offsetY = CGRectGetHeight(webView.window.frame) - CGRectGetHeight([[[UIKeyboardPredictionViewClass activeInstance] superview] frame]) + CGRectGetHeight(predictionViewFrame) / 2;
+    float offsetY = CGRectGetHeight(webView.window.frame) - CGRectGetHeight([[predictionView superview] frame]) + CGRectGetHeight(predictionViewFrame) / 2;
     [[HIDEventGenerator sharedHIDEventGenerator] tap:CGPointMake(offsetX, offsetY) completionBlock:^{
         if (m_context)
             m_context->asyncTaskComplete(callbackID);
@@ -392,6 +394,11 @@ JSObjectRef UIScriptController::selectionRangeViewRects() const
     return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:selectionRects inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
 }
 
+void UIScriptController::removeAllDynamicDictionaries()
+{
+    [UIKeyboard removeAllDynamicDictionaries];
+}
+
 void UIScriptController::platformSetDidStartFormControlInteractionCallback()
 {
     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();