Add library jquery-ui-for-ipad-and-iphone that maps touch events to mouse events...
[bookreader.git] / BookReader / jquery.ui.ipad.js
1 /**
2 * jQuery.UI.iPad plugin
3 * Copyright (c) 2010 Stephen von Takach
4 * licensed under MIT.
5 * Date: 27/8/2010
6 *
7 * Project Home: 
8 * http://code.google.com/p/jquery-ui-for-ipad-and-iphone/
9 */\r
10 \r
11 \r
12 $(function() {\r
13         //\r
14         // Extend jQuery feature detection\r
15         //\r
16         $.extend($.support, {\r
17                 touch: typeof Touch == "object"\r
18         });\r
19         \r
20         //\r
21         // Hook up touch events\r
22         //\r
23         if ($.support.touch) {\r
24                 document.addEventListener("touchstart", iPadTouchHandler, false);\r
25                 document.addEventListener("touchmove", iPadTouchHandler, false);\r
26                 document.addEventListener("touchend", iPadTouchHandler, false);\r
27                 document.addEventListener("touchcancel", iPadTouchHandler, false);\r
28         }\r
29 });\r
30 \r
31 \r
32 var lastTap = null;                     // Holds last tapped element (so we can compare for double tap)\r
33 var tapValid = false;                   // Are we still in the .6 second window where a double tap can occur\r
34 var tapTimeout = null;                  // The timeout reference\r
35 \r
36 function cancelTap() {\r
37         tapValid = false;\r
38 }\r
39 \r
40 \r
41 var rightClickPending = false;  // Is a right click still feasible\r
42 var rightClickEvent = null;             // the original event\r
43 var holdTimeout = null;                 // timeout reference\r
44 var cancelMouseUp = false;              // prevents a click from occuring as we want the context menu\r
45 \r
46 \r
47 function cancelHold() {\r
48         if (rightClickPending) {\r
49                 window.clearTimeout(holdTimeout);\r
50                 rightClickPending = false;\r
51                 rightClickEvent = null;\r
52         }\r
53 }\r
54 \r
55 function startHold(event) {\r
56         if (rightClickPending)\r
57                 return;\r
58 \r
59         rightClickPending = true; // We could be performing a right click\r
60         rightClickEvent = (event.changedTouches)[0];\r
61         holdTimeout = window.setTimeout("doRightClick();", 800);\r
62 }\r
63 \r
64 \r
65 function doRightClick() {\r
66         rightClickPending = false;\r
67 \r
68         //\r
69         // We need to mouse up (as we were down)\r
70         //\r
71         var first = rightClickEvent,\r
72                 simulatedEvent = document.createEvent("MouseEvent");\r
73         simulatedEvent.initMouseEvent("mouseup", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,\r
74                         false, false, false, false, 0, null);\r
75         first.target.dispatchEvent(simulatedEvent);\r
76 \r
77         //\r
78         // emulate a right click\r
79         //\r
80         simulatedEvent = document.createEvent("MouseEvent");\r
81         simulatedEvent.initMouseEvent("mousedown", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,\r
82                         false, false, false, false, 2, null);\r
83         first.target.dispatchEvent(simulatedEvent);\r
84 \r
85         //\r
86         // Show a context menu\r
87         //\r
88         simulatedEvent = document.createEvent("MouseEvent");\r
89         simulatedEvent.initMouseEvent("contextmenu", true, true, window, 1, first.screenX + 50, first.screenY + 5, first.clientX + 50, first.clientY + 5,\r
90                                   false, false, false, false, 2, null);\r
91         first.target.dispatchEvent(simulatedEvent);\r
92 \r
93 \r
94         //\r
95         // Note:: I don't mouse up the right click here however feel free to add if required\r
96         //\r
97 \r
98 \r
99         cancelMouseUp = true;\r
100         rightClickEvent = null; // Release memory\r
101 }\r
102 \r
103 \r
104 //\r
105 // mouse over event then mouse down\r
106 //\r
107 function iPadTouchStart(event) {\r
108         var touches = event.changedTouches,\r
109                 first = touches[0],\r
110                 type = "mouseover",\r
111                 simulatedEvent = document.createEvent("MouseEvent");\r
112         //\r
113         // Mouse over first - I have live events attached on mouse over\r
114         //\r
115         simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,\r
116                             false, false, false, false, 0, null);\r
117         first.target.dispatchEvent(simulatedEvent);\r
118 \r
119         type = "mousedown";\r
120         simulatedEvent = document.createEvent("MouseEvent");\r
121 \r
122         simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,\r
123                             false, false, false, false, 0, null);\r
124         first.target.dispatchEvent(simulatedEvent);\r
125 \r
126 \r
127         if (!tapValid) {\r
128                 lastTap = first.target;\r
129                 tapValid = true;\r
130                 tapTimeout = window.setTimeout("cancelTap();", 600);\r
131                 startHold(event);\r
132         }\r
133         else {\r
134                 window.clearTimeout(tapTimeout);\r
135 \r
136                 //\r
137                 // If a double tap is still a possibility and the elements are the same\r
138                 //      Then perform a double click\r
139                 //\r
140                 if (first.target == lastTap) {\r
141                         lastTap = null;\r
142                         tapValid = false;\r
143 \r
144                         type = "click";\r
145                         simulatedEvent = document.createEvent("MouseEvent");\r
146 \r
147                         simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,\r
148                                 false, false, false, false, 0/*left*/, null);\r
149                         first.target.dispatchEvent(simulatedEvent);\r
150 \r
151                         type = "dblclick";\r
152                         simulatedEvent = document.createEvent("MouseEvent");\r
153 \r
154                         simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,\r
155                                 false, false, false, false, 0/*left*/, null);\r
156                         first.target.dispatchEvent(simulatedEvent);\r
157                 }\r
158                 else {\r
159                         lastTap = first.target;\r
160                         tapValid = true;\r
161                         tapTimeout = window.setTimeout("cancelTap();", 600);\r
162                         startHold(event);\r
163                 }\r
164         }\r
165 }\r
166 \r
167 function iPadTouchHandler(event) {\r
168         var type = "",\r
169                 button = 0; /*left*/\r
170 \r
171         if (event.touches.length > 1)\r
172                 return;\r
173 \r
174         switch (event.type) {\r
175                 case "touchstart":\r
176                         if ($(event.changedTouches[0].target).is("select")) {\r
177                                 return;\r
178                         }\r
179                         iPadTouchStart(event); /*We need to trigger two events here to support one touch drag and drop*/\r
180                         event.preventDefault();\r
181                         return false;\r
182                         break;\r
183 \r
184                 case "touchmove":\r
185                         cancelHold();\r
186                         type = "mousemove";\r
187                         event.preventDefault();\r
188                         break;\r
189 \r
190                 case "touchend":\r
191                         if (cancelMouseUp) {\r
192                                 cancelMouseUp = false;\r
193                                 event.preventDefault();\r
194                                 return false;\r
195                         }\r
196                         cancelHold();\r
197                         type = "mouseup";\r
198                         break;\r
199 \r
200                 default:\r
201                         return;\r
202         }\r
203 \r
204         var touches = event.changedTouches,\r
205                 first = touches[0],\r
206                 simulatedEvent = document.createEvent("MouseEvent");\r
207 \r
208         simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,\r
209                             false, false, false, false, button, null);\r
210 \r
211         first.target.dispatchEvent(simulatedEvent);\r
212 \r
213         if (type == "mouseup" && tapValid && first.target == lastTap) { // This actually emulates the ipads default behaviour (which we prevented)\r
214                 simulatedEvent = document.createEvent("MouseEvent");            // This check avoids click being emulated on a double tap\r
215 \r
216                 simulatedEvent.initMouseEvent("click", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY,\r
217                             false, false, false, false, button, null);\r
218 \r
219                 first.target.dispatchEvent(simulatedEvent);\r
220         }\r
221 }\r
222 \r
223 \r