From 9dfa8dc622519374a57a0b24ab9d7f73afe160ed Mon Sep 17 00:00:00 2001 From: Ben Murdoch Date: Fri, 15 Oct 2010 17:12:52 +0100 Subject: Implement the document.createTouch and document.createTouchList APIs These are Apple extensions to the document object present on iOS and are used by several sites to detect touch event support. See http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html for Apple's documentation. Upstreaming to webkit being tracked in https://bugs.webkit.org/show_bug.cgi?id=47676 Bug: 2996106 Change-Id: I761b1494af60b5095ad9c47d54eb7240d47ae985 --- .../touch/document-create-touch-expected.txt | 24 +++++++++++ .../touch/document-create-touch-list-expected.txt | 14 +++++++ .../events/touch/document-create-touch-list.html | 19 +++++++++ .../fast/events/touch/document-create-touch.html | 19 +++++++++ .../script-tests/document-create-touch-list.js | 12 ++++++ .../touch/script-tests/document-create-touch.js | 31 ++++++++++++++ WebCore/Android.jscbindings.mk | 2 + WebCore/CMakeLists.txt | 2 + WebCore/GNUmakefile.am | 2 + WebCore/WebCore.gypi | 2 + WebCore/WebCore.pro | 2 + WebCore/bindings/js/JSBindingsAllInOne.cpp | 2 + WebCore/bindings/js/JSTouchCustom.cpp | 47 ++++++++++++++++++++++ WebCore/bindings/js/JSTouchListCustom.cpp | 47 ++++++++++++++++++++++ WebCore/bindings/scripts/CodeGeneratorJS.pm | 11 ++++- WebCore/dom/Document.cpp | 13 ++++++ WebCore/dom/Document.h | 10 +++++ WebCore/dom/Document.idl | 12 ++++++ 18 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 LayoutTests/fast/events/touch/document-create-touch-expected.txt create mode 100644 LayoutTests/fast/events/touch/document-create-touch-list-expected.txt create mode 100644 LayoutTests/fast/events/touch/document-create-touch-list.html create mode 100644 LayoutTests/fast/events/touch/document-create-touch.html create mode 100644 LayoutTests/fast/events/touch/script-tests/document-create-touch-list.js create mode 100644 LayoutTests/fast/events/touch/script-tests/document-create-touch.js create mode 100644 WebCore/bindings/js/JSTouchCustom.cpp create mode 100644 WebCore/bindings/js/JSTouchListCustom.cpp diff --git a/LayoutTests/fast/events/touch/document-create-touch-expected.txt b/LayoutTests/fast/events/touch/document-create-touch-expected.txt new file mode 100644 index 0000000..c1c647f --- /dev/null +++ b/LayoutTests/fast/events/touch/document-create-touch-expected.txt @@ -0,0 +1,24 @@ +This tests support for the document.createTouch API. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS "createTouch" in document is true +PASS touch is non-null. +PASS touch.target is box +PASS touch.identifier is 1 +PASS touch.pageX is 100 +PASS touch.pageY is 101 +PASS touch.screenX is 102 +PASS touch.screenY is 103 +PASS emptyTouch is non-null. +PASS emptyTouch.target is null +PASS emptyTouch.identifier is 0 +PASS emptyTouch.pageX is 0 +PASS emptyTouch.pageY is 0 +PASS emptyTouch.screenX is 0 +PASS emptyTouch.screenY is 0 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/events/touch/document-create-touch-list-expected.txt b/LayoutTests/fast/events/touch/document-create-touch-list-expected.txt new file mode 100644 index 0000000..99d578c --- /dev/null +++ b/LayoutTests/fast/events/touch/document-create-touch-list-expected.txt @@ -0,0 +1,14 @@ +This tests support for the document.createTouchList API. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS "createTouchList" in document is true +PASS touchList is non-null. +PASS touchList.length is 0 +PASS touchList.item(0) is null +PASS touchList.item(1) is null +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/events/touch/document-create-touch-list.html b/LayoutTests/fast/events/touch/document-create-touch-list.html new file mode 100644 index 0000000..bb81531 --- /dev/null +++ b/LayoutTests/fast/events/touch/document-create-touch-list.html @@ -0,0 +1,19 @@ + + + + + + + + + +

+
+ + + diff --git a/LayoutTests/fast/events/touch/document-create-touch.html b/LayoutTests/fast/events/touch/document-create-touch.html new file mode 100644 index 0000000..ef586fb --- /dev/null +++ b/LayoutTests/fast/events/touch/document-create-touch.html @@ -0,0 +1,19 @@ + + + + + + + + + +

+
+ + + diff --git a/LayoutTests/fast/events/touch/script-tests/document-create-touch-list.js b/LayoutTests/fast/events/touch/script-tests/document-create-touch-list.js new file mode 100644 index 0000000..9c87c9a --- /dev/null +++ b/LayoutTests/fast/events/touch/script-tests/document-create-touch-list.js @@ -0,0 +1,12 @@ +description("This tests support for the document.createTouchList API."); + +shouldBeTrue('"createTouchList" in document'); + +var touchList = document.createTouchList(); +shouldBeNonNull("touchList"); +shouldBe("touchList.length", "0"); +shouldBeNull("touchList.item(0)"); +shouldBeNull("touchList.item(1)"); + +successfullyParsed = true; +isSuccessfullyParsed(); diff --git a/LayoutTests/fast/events/touch/script-tests/document-create-touch.js b/LayoutTests/fast/events/touch/script-tests/document-create-touch.js new file mode 100644 index 0000000..dd383ac --- /dev/null +++ b/LayoutTests/fast/events/touch/script-tests/document-create-touch.js @@ -0,0 +1,31 @@ +description("This tests support for the document.createTouch API."); + +shouldBeTrue('"createTouch" in document'); + +var box = document.createElement("div"); +box.id = "box"; +box.style.width = "100px"; +box.style.height = "100px"; +document.body.appendChild(box); + +var target = document.getElementById("box"); +var touch = document.createTouch(window, target, 1, 100, 101, 102, 103); +shouldBeNonNull("touch"); +shouldBe("touch.target", "box"); +shouldBe("touch.identifier", "1"); +shouldBe("touch.pageX", "100"); +shouldBe("touch.pageY", "101"); +shouldBe("touch.screenX", "102"); +shouldBe("touch.screenY", "103"); + +var emptyTouch = document.createTouch(); +shouldBeNonNull("emptyTouch"); +shouldBeNull("emptyTouch.target"); +shouldBe("emptyTouch.identifier", "0"); +shouldBe("emptyTouch.pageX", "0"); +shouldBe("emptyTouch.pageY", "0"); +shouldBe("emptyTouch.screenX", "0"); +shouldBe("emptyTouch.screenY", "0"); + +successfullyParsed = true; +isSuccessfullyParsed(); diff --git a/WebCore/Android.jscbindings.mk b/WebCore/Android.jscbindings.mk index e87ca3d..9e89e2c 100644 --- a/WebCore/Android.jscbindings.mk +++ b/WebCore/Android.jscbindings.mk @@ -157,6 +157,8 @@ LOCAL_SRC_FILES += \ bindings/js/JSStyleSheetCustom.cpp \ bindings/js/JSStyleSheetListCustom.cpp \ bindings/js/JSTextCustom.cpp \ + bindings/js/JSTouchCustom.cpp \ + bindings/js/JSTouchListCustom.cpp \ bindings/js/JSTreeWalkerCustom.cpp \ bindings/js/JSWebKitCSSMatrixCustom.cpp \ bindings/js/JSWebKitPointCustom.cpp \ diff --git a/WebCore/CMakeLists.txt b/WebCore/CMakeLists.txt index 210244e..2219e4f 100644 --- a/WebCore/CMakeLists.txt +++ b/WebCore/CMakeLists.txt @@ -669,6 +669,8 @@ SET(WebCore_SOURCES bindings/js/JSStyleSheetCustom.cpp bindings/js/JSStyleSheetListCustom.cpp bindings/js/JSTextCustom.cpp + bindings/js/JSTouchCustom.cpp + bindings/js/JSTouchListCustom.cpp bindings/js/JSTreeWalkerCustom.cpp bindings/js/JSWebKitCSSMatrixCustom.cpp bindings/js/JSWebKitPointCustom.cpp diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am index c80e8ed..c98f971 100644 --- a/WebCore/GNUmakefile.am +++ b/WebCore/GNUmakefile.am @@ -788,6 +788,8 @@ webcore_sources += \ WebCore/bindings/js/JSSVGPODListCustom.h \ WebCore/bindings/js/JSSVGPODTypeWrapper.h \ WebCore/bindings/js/JSTextCustom.cpp \ + WebCore/bindings/js/JSTouchCustom.cpp \ + WebCore/bindings/js/JSTouchListCustom.cpp \ WebCore/bindings/js/JSTreeWalkerCustom.cpp \ WebCore/bindings/js/JSWebKitCSSMatrixCustom.cpp \ WebCore/bindings/js/JSWebKitPointCustom.cpp \ diff --git a/WebCore/WebCore.gypi b/WebCore/WebCore.gypi index 8e6af6b..d666ebd 100644 --- a/WebCore/WebCore.gypi +++ b/WebCore/WebCore.gypi @@ -670,6 +670,8 @@ 'bindings/js/JSSVGPODListCustom.h', 'bindings/js/JSSVGPODTypeWrapper.h', 'bindings/js/JSTextCustom.cpp', + 'bindings/js/JSTouchCustom.cpp', + 'bindings/js/JSTouchListCustom.cpp', 'bindings/js/JSTreeWalkerCustom.cpp', 'bindings/js/JSWebKitCSSMatrixCustom.cpp', 'bindings/js/JSWebKitPointCustom.cpp', diff --git a/WebCore/WebCore.pro b/WebCore/WebCore.pro index e595f3b..34dc9d0 100644 --- a/WebCore/WebCore.pro +++ b/WebCore/WebCore.pro @@ -552,6 +552,8 @@ v8 { bindings/js/JSStyleSheetCustom.cpp \ bindings/js/JSStyleSheetListCustom.cpp \ bindings/js/JSTextCustom.cpp \ + bindings/js/JSTouchCustom.cpp \ + bindings/js/JSTouchListCustom.cpp \ bindings/js/JSTreeWalkerCustom.cpp \ bindings/js/JSWebKitCSSMatrixCustom.cpp \ bindings/js/JSWebKitPointCustom.cpp \ diff --git a/WebCore/bindings/js/JSBindingsAllInOne.cpp b/WebCore/bindings/js/JSBindingsAllInOne.cpp index 6e1cc1e..cf08ca9 100644 --- a/WebCore/bindings/js/JSBindingsAllInOne.cpp +++ b/WebCore/bindings/js/JSBindingsAllInOne.cpp @@ -124,6 +124,8 @@ #include "JSStyleSheetCustom.cpp" #include "JSStyleSheetListCustom.cpp" #include "JSTextCustom.cpp" +#include "JSTouchCustom.cpp" +#include "JSTouchListCustom.cpp" #include "JSTreeWalkerCustom.cpp" #include "JSWebKitCSSMatrixCustom.cpp" #include "JSWebKitPointCustom.cpp" diff --git a/WebCore/bindings/js/JSTouchCustom.cpp b/WebCore/bindings/js/JSTouchCustom.cpp new file mode 100644 index 0000000..83c2b83 --- /dev/null +++ b/WebCore/bindings/js/JSTouchCustom.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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. + */ + +#include "config.h" +#include "JSTouch.h" + +#if ENABLE(TOUCH_EVENTS) + +#include "Touch.h" + +using namespace JSC; + +namespace WebCore { + +JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, Touch* touch) +{ + if (!touch) + return jsNull(); + + return CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, Touch, touch); +} + +} // namespace WebCore + +#endif diff --git a/WebCore/bindings/js/JSTouchListCustom.cpp b/WebCore/bindings/js/JSTouchListCustom.cpp new file mode 100644 index 0000000..22e0f95 --- /dev/null +++ b/WebCore/bindings/js/JSTouchListCustom.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2010, The Android Open Source Project + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, 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. + */ + +#include "config.h" +#include "JSTouchList.h" + +#if ENABLE(TOUCH_EVENTS) + +#include "TouchList.h" + +using namespace JSC; + +namespace WebCore { + +JSValue toJSNewlyCreated(ExecState* exec, JSDOMGlobalObject* globalObject, TouchList* touchList) +{ + if (!touchList) + return jsNull(); + + return CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, TouchList, touchList); +} + +} // namespace WebCore + +#endif diff --git a/WebCore/bindings/scripts/CodeGeneratorJS.pm b/WebCore/bindings/scripts/CodeGeneratorJS.pm index 803542e..710ac3f 100644 --- a/WebCore/bindings/scripts/CodeGeneratorJS.pm +++ b/WebCore/bindings/scripts/CodeGeneratorJS.pm @@ -610,6 +610,15 @@ sub GenerateImplementationContentHeader return @implContentHeader; } +my %usesToJSNewlyCreated = ( + "CDATASection" => 1, + "Element" => 1, + "Node" => 1, + "Text" => 1, + "Touch" => 1, + "TouchList" => 1 +); + sub GenerateHeader { my $object = shift; @@ -943,7 +952,7 @@ sub GenerateHeader push(@headerContent, "$implClassName* to${interfaceName}(JSC::JSValue);\n"); } } - if ($interfaceName eq "Node" or $interfaceName eq "Element" or $interfaceName eq "Text" or $interfaceName eq "CDATASection") { + if ($usesToJSNewlyCreated{$interfaceName}) { push(@headerContent, "JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject*, $interfaceName*);\n"); } diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp index 333b8db..bffc07c 100644 --- a/WebCore/dom/Document.cpp +++ b/WebCore/dom/Document.cpp @@ -4826,4 +4826,17 @@ void Document::decrementLoadEventDelayCount() frame()->loader()->checkCompleted(); } +#if ENABLE(TOUCH_EVENTS) +PassRefPtr Document::createTouch(DOMWindow* window, Node* target, int identifier, int pageX, int pageY, int screenX, int screenY, ExceptionCode&) const +{ + Frame* frame = window ? window->frame() : this->frame(); + return Touch::create(frame, target, identifier, screenX, screenY, pageX, pageY); +} + +PassRefPtr Document::createTouchList(ExceptionCode&) const +{ + return TouchList::create(); +} +#endif + } // namespace WebCore diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h index fa3d9fb..41a486a 100644 --- a/WebCore/dom/Document.h +++ b/WebCore/dom/Document.h @@ -136,6 +136,11 @@ class XPathResult; struct DashboardRegionValue; #endif +#if ENABLE(TOUCH_EVENTS) +class Touch; +class TouchList; +#endif + typedef int ExceptionCode; class FormElementKey { @@ -1041,6 +1046,11 @@ public: void decrementLoadEventDelayCount(); bool isDelayingLoadEvent() const { return m_loadEventDelayCount; } +#if ENABLE(TOUCH_EVENTS) + PassRefPtr createTouch(DOMWindow*, Node*, int identifier, int pageX, int pageY, int screenX, int screenY, ExceptionCode&) const; + PassRefPtr createTouchList(ExceptionCode&) const; +#endif + protected: Document(Frame*, const KURL& url, bool isXHTML, bool isHTML, const KURL& baseURL = KURL()); diff --git a/WebCore/dom/Document.idl b/WebCore/dom/Document.idl index e551f88..02eb30d 100644 --- a/WebCore/dom/Document.idl +++ b/WebCore/dom/Document.idl @@ -321,6 +321,18 @@ module core { attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchmove; attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchend; attribute [DontEnum,Conditional=TOUCH_EVENTS,EnabledAtRuntime] EventListener ontouchcancel; +#if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS + [ReturnsNew] Touch createTouch(in DOMWindow window, + in Node target, + in long identifier, + in long pageX, + in long pageY, + in long ScreenX, + in long screenY) + raises (DOMException); + [ReturnsNew] TouchList createTouchList() + raises (DOMException); +#endif attribute [DontEnum, Conditional=FULLSCREEN_API] EventListener onwebkitfullscreenchange; #endif -- cgit v1.1