1111// used to endorse or promote products derived from this software without specific
1212// prior written permission.
1313
14- define ( [ 'jquery' , 'jquery_hammer' , ' hammer'] , function ( $ , jqueryHammer , Hammer ) {
14+ define ( [ 'jquery' , 'hammer' ] , function ( $ , Hammer ) {
1515
1616 var gesturesHandler = function ( reader , viewport ) {
1717
18- var onSwipeLeft = function ( ) {
18+ var quiet = false ;
19+
20+ var onSwipeLeft = function ( ) {
21+ if ( ! quiet ) console . debug ( "READIUM swipeleft (openPageRight)" ) ;
1922 reader . openPageRight ( ) ;
2023 } ;
2124
22- var onSwipeRight = function ( ) {
25+ var onSwipeRight = function ( ) {
26+ if ( ! quiet ) console . debug ( "READIUM swiperight (openPageLeft)" ) ;
2327 reader . openPageLeft ( ) ;
2428 } ;
2529
2630 var isGestureHandled = function ( ) {
2731 var viewType = reader . getCurrentViewType ( ) ;
28-
29- return viewType === ReadiumSDK . Views . ReaderView . VIEW_TYPE_FIXED || viewType == ReadiumSDK . Views . ReaderView . VIEW_TYPE_COLUMNIZED ;
32+ return viewType === ReadiumSDK . Views . ReaderView . VIEW_TYPE_FIXED || viewType == ReadiumSDK . Views . ReaderView . VIEW_TYPE_COLUMNIZED ; // Excludes SCROLL
3033 } ;
3134
32- this . initialize = function ( ) {
35+ if ( navigator . msMaxTouchPoints ) {
36+ if ( / W i n d o w s P h o n e / . test ( navigator . userAgent ) ) {
37+ document . documentElement . classList . add ( 'disable-ie-back-swipe' ) ;
38+ } else {
39+ try {
40+ var metroTestElement = document . createElement ( 'div' ) ;
41+ metroTestElement . style . cssText = 'position:absolute;z-index:-1;top:0;right:0;bottom:-10px;width:1px' ;
42+ document . body . appendChild ( metroTestElement ) ;
43+ if ( Math . round ( window . outerWidth - metroTestElement . offsetLeft ) === 1 ) {
44+ document . documentElement . classList . add ( 'disable-ie-back-swipe' ) ;
45+ }
46+ document . body . removeChild ( metroTestElement ) ;
47+ } catch ( e ) { // window.outerWidth throws error if in IE showModalDialog
48+ }
49+ }
50+ }
51+
52+ var setupTouchDefaultActionSuppressor = function ( doc , isTopLevel ) {
53+
54+ var touchDown = false ;
55+ var touchIdentifier = 0 ;
56+ var touchStartX = 0 ;
57+ var touchStartY = 0 ;
58+ var lockDragX = false ;
59+ var lockDragY = false ;
60+
61+ /*
62+ if (window.navigator.msPointerEnabled) {
63+ doc.addEventListener("MSPointerCancel", function (e) {
64+ if (!quiet) console.debug("DOC MSPointerCancel");
65+ e.preventDefault();
66+ }, false);
67+ doc.addEventListener("MSGestureInit", function (e) {
68+ if (!quiet) console.debug("DOC MSGestureInit");
69+ e.preventDefault();
70+ }, false);
71+ doc.addEventListener("MSHoldVisual", function (e) {
72+ if (!quiet) console.debug("DOC MSHoldVisual");
73+ e.preventDefault();
74+ }, false);
75+ }
76+ */
77+
78+ doc . documentElement . addEventListener ( window . navigator . msPointerEnabled ? "MSPointerDown" : "touchstart" , function ( ev ) {
79+ if ( window . navigator . msPointerEnabled && ! ev . isPrimary ) return ;
80+
81+ if ( touchDown ) return ;
82+
83+ touchDown = true ;
84+
85+ lockDragX = false ;
86+ lockDragY = false ;
87+
88+ touchIdentifier = window . navigator . msPointerEnabled ? 1 : ev . touches . item ( 0 ) . identifier ;
89+
90+ touchStartX = window . navigator . msPointerEnabled ? ev . clientX : ev . touches . item ( 0 ) . clientX ;
91+ touchStartY = window . navigator . msPointerEnabled ? ev . clientY : ev . touches . item ( 0 ) . clientY ;
92+
93+ if ( ! quiet ) console . debug ( "DOC touchstart" ) ;
94+
95+ if ( isTopLevel )
96+ if ( ! quiet ) console . debug ( "isTopLevel" ) ;
97+
98+ } , false ) ; // !useCapture
99+
100+ var upOut1 = function ( ev ) {
101+ if ( window . navigator . msPointerEnabled && ! ev . isPrimary ) return ;
102+
103+ if ( window . navigator . msPointerEnabled && touchIdentifier !== 1 ) {
104+
105+ if ( ! quiet ) console . debug ( "DOC multi touch skip" ) ;
106+ return ;
107+ }
108+ if ( ! window . navigator . msPointerEnabled ) {
109+
110+ var found = false ;
111+ for ( var i = 0 ; i < ev . changedTouches . length ; i ++ ) {
112+ if ( touchIdentifier == ev . changedTouches . item ( i ) . identifier ) {
113+ found = true ;
114+ break ;
115+ }
116+ }
117+
118+ if ( ! found ) {
119+ if ( ! quiet ) console . debug ( "DOC multi touch skip" ) ;
120+ return ;
121+ }
122+ }
123+
124+ touchDown = false ;
125+ touchIdentifier = 0 ;
126+ lockDragX = false ;
127+ lockDragY = false ;
128+
129+ if ( ! quiet ) console . debug ( "DOC touchend" ) ;
130+
131+ if ( isTopLevel )
132+ if ( ! quiet ) console . debug ( "isTopLevel" ) ;
133+ } ;
134+ doc . addEventListener ( window . navigator . msPointerEnabled ? "MSPointerUp" : "touchend" , upOut1 , true ) ; // useCapture
135+ /*
136+ if (window.navigator.msPointerEnabled) {
137+ doc.addEventListener("MSPointerOut", upOut1);
138+ }
139+ */
140+
141+ doc . addEventListener ( window . navigator . msPointerEnabled ? "MSPointerMove" : "touchmove" , function ( ev ) {
142+
143+ if ( ! touchDown ) return ;
144+
145+ if ( window . navigator . msPointerEnabled && ! ev . isPrimary ) return ;
146+
147+ if ( touchIdentifier !== ( window . navigator . msPointerEnabled ? 1 : ev . touches . item ( 0 ) . identifier ) ) {
148+
149+ if ( ! quiet ) console . debug ( "DOC multi touch skip" ) ;
150+ return ;
151+ }
152+
153+ if ( ! quiet ) console . debug ( "DOC touchmove" ) ;
154+
155+ if ( ! ev . cancelable ) {
156+ if ( ! quiet ) console . debug ( "DOC !CANCELABLE" ) ;
157+ return ;
158+ }
159+
160+ if ( ev . target && ev . target . ownerDocument . allowDefault ) {
161+ ev . target . ownerDocument . allowDefault = false ;
162+
163+ if ( ! quiet ) console . debug ( "DOC allowDefault" ) ;
164+ return ;
165+ }
166+
167+ if ( ! quiet ) console . debug ( "DOC preventDefault" ) ;
168+
169+ ev . preventDefault ( ) ;
170+ } , false ) ; // NOT useCapture (so that ev.stopPropagation() can be used from a registered listener below in the DOM tree, thereby allowing the default browser action, such as scrolling of overflow containers ... otherwise, preventDefault() is invoked, which results in disabling certain browser-specific behaviours like overflow bounce / rubber banding, swipe history navigation, etc.)
171+
172+
173+ doc . documentElement . addEventListener ( window . navigator . msPointerEnabled ? "MSPointerMove" : "touchmove" , function ( ev ) {
174+
175+ if ( ! touchDown ) return ;
176+
177+ if ( window . navigator . msPointerEnabled && ! ev . isPrimary ) return ;
178+
179+ if ( touchIdentifier !== ( window . navigator . msPointerEnabled ? 1 : ev . touches . item ( 0 ) . identifier ) ) {
180+
181+ if ( ! quiet ) console . debug ( "DOC multi touch skip" ) ;
182+ return ;
183+ }
184+
185+ if ( ! quiet ) console . debug ( "touchmove" ) ;
186+
187+ if ( ! ev . cancelable ) {
188+ if ( ! quiet ) console . debug ( "!CANCELABLE" ) ;
189+ return ;
190+ }
191+
192+ if ( ! quiet ) console . debug ( "touchStartX: " + touchStartX ) ;
193+ if ( ! quiet ) console . debug ( "touchStartY: " + touchStartY ) ;
194+
195+ var touchStartX_ = window . navigator . msPointerEnabled ? ev . clientX : ev . touches . item ( 0 ) . clientX ;
196+ var touchStartY_ = window . navigator . msPointerEnabled ? ev . clientY : ev . touches . item ( 0 ) . clientY ;
197+
198+ if ( ! quiet ) console . debug ( "touchStartX_: " + touchStartX_ ) ;
199+ if ( ! quiet ) console . debug ( "touchStartY_: " + touchStartY_ ) ;
200+
201+ var touchDeltaX = touchStartX - touchStartX_ ;
202+ var touchDeltaY = touchStartY - touchStartY_ ;
203+
204+ if ( ! quiet ) console . debug ( "touchDeltaX: " + touchDeltaX ) ;
205+ if ( ! quiet ) console . debug ( "touchDeltaY: " + touchDeltaY ) ;
206+
207+ if ( Math . abs ( touchDeltaX ) <= 1 && Math . abs ( touchDeltaY ) <= 1 ) {
208+ if ( ! quiet ) console . debug ( "touchDelta too small..." ) ;
209+
210+ //ev.stopPropagation();
211+ return ;
212+ }
213+
214+ if ( Math . abs ( touchDeltaX ) > Math . abs ( touchDeltaY ) ) {
215+ lockDragX = true ;
216+ lockDragY = false ;
217+ } else {
218+ lockDragX = false ;
219+ lockDragY = true ;
220+ }
221+
222+ if ( ! quiet ) console . debug ( "lockDragX: " + lockDragX ) ;
223+ if ( ! quiet ) console . debug ( "lockDragY: " + lockDragY ) ;
224+
225+ touchStartX = touchStartX_ ;
226+ touchStartY = touchStartY_ ;
227+
228+ var target = ev . target ;
229+ while ( target ) {
230+
231+ if ( ! quiet ) console . debug ( "target: " ) ;
232+ if ( ! quiet ) console . debug ( target ) ;
233+
234+ if ( typeof target . scrollTop === "undefined" ) {
235+ if ( ! quiet ) console . debug ( "undefined target.scrollTop" ) ;
236+
237+ if ( ! isTopLevel ) {
238+ if ( ! quiet ) console . debug ( "!isTopLevel" ) ;
239+ //target.allowDefault = true;
240+ ev . stopPropagation ( ) ;
241+ }
242+
243+ break ;
244+ }
245+
246+ var $target = $ ( target ) ;
247+
248+ var scrollTop = target . scrollTop ;
249+ var scrollLeft = target . scrollLeft ;
250+
251+ var scrollBottom = scrollTop + target . offsetHeight ; //$target.height();
252+ var scrollRight = scrollLeft + target . offsetWidth ; //$target.width();
253+
254+ var needsScroll =
255+ lockDragX && touchDeltaX < 0 && scrollLeft != 0 ||
256+ lockDragX && touchDeltaX > 0 && scrollRight != target . scrollWidth ||
257+ lockDragY && touchDeltaY < 0 && scrollTop != 0 ||
258+ lockDragY && touchDeltaY > 0 && scrollBottom != target . scrollHeight ;
259+
260+ if ( needsScroll ) {
261+ if ( ! quiet ) console . debug ( "needsScroll" ) ;
262+
263+ if ( ! quiet ) console . debug ( "target: " ) ;
264+ if ( ! quiet ) console . debug ( target ) ;
265+
266+ if ( ! quiet ) console . debug ( "scrollLeft: " + scrollLeft ) ;
267+ if ( ! quiet ) console . debug ( "scrollTop: " + scrollTop ) ;
268+ if ( ! quiet ) console . debug ( "scrollBottom: " + scrollBottom ) ;
269+ if ( ! quiet ) console . debug ( "scrollRight: " + scrollRight ) ;
270+ if ( ! quiet ) console . debug ( "target.scrollWidth: " + target . scrollWidth ) ;
271+ if ( ! quiet ) console . debug ( "target.scrollHeight: " + target . scrollHeight ) ;
272+
273+
274+ //target.ownerDocument.allowDefault = true;
275+ ev . stopPropagation ( ) ;
276+ return ;
277+ }
278+
279+ target = target . parentNode ;
280+ }
281+ } ) ;
282+ }
283+
284+ this . initialize = function ( ) {
285+
286+ delete Hammer . defaults . cssProps . userSelect ;
33287
34288 reader . on ( ReadiumSDK . Events . CONTENT_DOCUMENT_LOADED , function ( iframe , s ) {
35- //set hammer's document root
36- Hammer . DOCUMENT = iframe . contents ( ) ;
37- //hammer's internal touch events need to be redefined? (doesn't work without)
38- Hammer . event . onTouch ( Hammer . DOCUMENT , Hammer . EVENT_MOVE , Hammer . detection . detect ) ;
39- Hammer . event . onTouch ( Hammer . DOCUMENT , Hammer . EVENT_END , Hammer . detection . detect ) ;
40-
41- //set up the hammer gesture events
42- //swiping handlers
43- var swipingOptions = { prevent_mouseevents : true } ;
44- Hammer ( Hammer . DOCUMENT , swipingOptions ) . on ( "swipeleft" , function ( ) {
45- onSwipeLeft ( ) ;
289+
290+ var iframeDocument = iframe [ 0 ] . contentWindow . document ;
291+ return ;
292+ setupTouchDefaultActionSuppressor ( iframeDocument , false ) ;
293+ return ;
294+ var iframeHtml = iframeDocument . documentElement ;
295+
296+ var iframeHammer = new Hammer . Manager ( iframeHtml , { touchAction : "auto" } ) ;
297+
298+ var swipe = new Hammer . Swipe ( { enable : isGestureHandled , direction : Hammer . DIRECTION_HORIZONTAL } ) ;
299+
300+ iframeHammer . add ( [ swipe ] ) ;
301+
302+ iframeHammer . on ( "swipeleft" , function ( ev ) {
303+ if ( ! quiet ) console . debug ( "HAMMER swipeleft" ) ;
304+
305+ if ( isGestureHandled ( ) ) {
306+ ev . preventDefault ( ) ;
307+
308+ onSwipeLeft ( ) ;
309+ }
46310 } ) ;
47- Hammer ( Hammer . DOCUMENT , swipingOptions ) . on ( "swiperight" , function ( ) {
48- onSwipeRight ( ) ;
311+
312+ iframeHammer . on ( "swiperight" , function ( ev ) {
313+ if ( ! quiet ) console . debug ( "HAMMER swiperight" ) ;
314+
315+ if ( isGestureHandled ( ) ) {
316+ ev . preventDefault ( ) ;
317+
318+ onSwipeRight ( ) ;
319+ }
49320 } ) ;
50-
51- //remove stupid ipad safari elastic scrolling
52- //TODO: test this with reader ScrollView and FixedView
53- $ ( Hammer . DOCUMENT ) . on (
54- 'touchmove' ,
55- function ( e ) {
56- //hack: check if we are not dealing with a scrollview
57- if ( isGestureHandled ( ) ) {
58- e . preventDefault ( ) ;
59- }
60- }
61- ) ;
62321 } ) ;
63322
64- //remove stupid ipad safari elastic scrolling (improves UX for gestures)
65- //TODO: test this with reader ScrollView and FixedView
66- $ ( viewport ) . on (
67- 'touchmove' ,
68- function ( e ) {
69- if ( isGestureHandled ( ) ) {
70- e . preventDefault ( ) ;
71- }
72- }
73- ) ;
74-
75- //handlers on viewport
76- $ ( viewport ) . hammer ( ) . on ( "swipeleft" , function ( ) {
77- onSwipeLeft ( ) ;
78- } ) ;
79- $ ( viewport ) . hammer ( ) . on ( "swiperight" , function ( ) {
80- onSwipeRight ( ) ;
81- } ) ;
323+ setupTouchDefaultActionSuppressor ( document , true ) ;
82324 } ;
83-
84325 } ;
326+
85327 return gesturesHandler ;
86328} ) ;
0 commit comments