Merge lp:~abreu-alexandre/ubuntu-html5-theme/fix-touch-detection-on-desktop-and-tabs into lp:ubuntu-html5-theme

Proposed by Alexandre Abreu
Status: Merged
Approved by: Alexandre Abreu
Approved revision: 130
Merged at revision: 138
Proposed branch: lp:~abreu-alexandre/ubuntu-html5-theme/fix-touch-detection-on-desktop-and-tabs
Merge into: lp:ubuntu-html5-theme
Diff against target: 173 lines (+60/-21)
2 files modified
0.1/ambiance/js/core.js (+18/-6)
0.1/ambiance/js/tabs.js (+42/-15)
To merge this branch: bzr merge lp:~abreu-alexandre/ubuntu-html5-theme/fix-touch-detection-on-desktop-and-tabs
Reviewer Review Type Date Requested Status
Alexandre Abreu Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+206212@code.launchpad.net

Commit message

Fix touch detection on UbuntuTouch & Desktop: we handle both. Touch detection does not work reliably, we should embrace the dual world.

Description of the change

Fix touch detection on UbuntuTouch & Desktop: we handle both. Touch detection does not work reliably, we should embrace the dual world.

To post a comment you must log in.
130. By Alexandre Abreu

untabify

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alexandre Abreu (abreu-alexandre) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '0.1/ambiance/js/core.js'
--- 0.1/ambiance/js/core.js 2014-01-27 18:42:31 +0000
+++ 0.1/ambiance/js/core.js 2014-02-13 15:55:07 +0000
@@ -103,10 +103,10 @@
103 var U = this;103 var U = this;
104 U.isTouch = "ontouchstart" in window;104 U.isTouch = "ontouchstart" in window;
105 U.touchEvents = {105 U.touchEvents = {
106 touchStart: U.isTouch ? 'touchstart' : 'mousedown',106 touchStart: ['touchstart','mousedown'],
107 touchMove: U.isTouch ? 'touchmove' : 'mousemove',107 touchMove: ['touchmove','mousemove'],
108 touchEnd: U.isTouch ? 'touchend' : 'mouseup',108 touchEnd: ['touchend','mouseup'],
109 touchLeave: U.isTouch ? null : 'mouseleave' //we manually detect leave on touch devices, so null event here109 touchLeave: ['mouseleave'],
110 };110 };
111 };111 };
112112
@@ -187,6 +187,20 @@
187 get isTouch() {187 get isTouch() {
188 return self.isTouch;188 return self.isTouch;
189 },189 },
190 registerTouchEvent: function(eventId,
191 element,
192 callback) {
193 if ( ! eventId
194 || typeof(eventId) !== 'object'
195 || eventId.length === 0) {
196 console.log('Invalid or empty eventId for registerTouchEvent: ' + eventId.toString() + ' ' + typeof(eventId));
197 return;
198 }
199
200 for (var i = 0; i < eventId.length; ++i) {
201 element.addEventListener(eventId[i], callback);
202 }
203 },
190 touchEvents: {204 touchEvents: {
191 get touchStart() {205 get touchStart() {
192 return self.touchEvents.touchStart;206 return self.touchEvents.touchStart;
@@ -202,8 +216,6 @@
202 },216 },
203 },217 },
204 translateTouchEvent: function(event) {218 translateTouchEvent: function(event) {
205 if (self.isTouch)
206 return event;
207 var touch = __createTouchObject(event);219 var touch = __createTouchObject(event);
208 var translatedTouchEvent = event;220 var translatedTouchEvent = event;
209 translatedTouchEvent.changedTouches = [touch];221 translatedTouchEvent.changedTouches = [touch];
210222
=== modified file '0.1/ambiance/js/tabs.js'
--- 0.1/ambiance/js/tabs.js 2014-01-30 19:56:22 +0000
+++ 0.1/ambiance/js/tabs.js 2014-02-13 15:55:07 +0000
@@ -75,6 +75,7 @@
75 if (tabs == null || touchInfoDelegate == null) {75 if (tabs == null || touchInfoDelegate == null) {
76 return;76 return;
77 }77 }
78 this._touchDown = false;
78 this._tabs = tabs;79 this._tabs = tabs;
7980
80 this._infos = {81 this._infos = {
@@ -84,16 +85,21 @@
84 this._touchInfoDelegate = touchInfoDelegate;85 this._touchInfoDelegate = touchInfoDelegate;
8586
86 var touchEvents = touchInfoDelegate.touchEvents;87 var touchEvents = touchInfoDelegate.touchEvents;
87 this._tabs.addEventListener(touchEvents.touchStart,88
88 this.__onTouchStart.bind(this));89 touchInfoDelegate.registerTouchEvent(
89 this._tabs.addEventListener(touchEvents.touchMove, this.__onTouchMove.bind(this));90 touchEvents.touchStart,
90 this._tabs.addEventListener(touchEvents.touchEnd, this.__onTouchEnd.bind(this));91 this._tabs,
9192 this.__onTouchStart.bind(this));
92 // we only have leave events on desktop, we manually calcuate93
93 // leave on touch as its not supported in webkit94 touchInfoDelegate.registerTouchEvent(
94 if (touchEvents.touchLeave) {95 touchEvents.touchMove,
95 this._tabs.addEventListener(touchEvents.touchLeave, this.__onTouchLeave.bind(this));96 this._tabs,
96 }97 this.__onTouchMove.bind(this));
98
99 touchInfoDelegate.registerTouchEvent(
100 touchEvents.touchEnd,
101 this._tabs,
102 this.__onTouchEnd.bind(this));
97103
98 // initialize default page104 // initialize default page
99 this.__setupInitialTabVisibility();105 this.__setupInitialTabVisibility();
@@ -156,6 +162,7 @@
156 if (targetPage)162 if (targetPage)
157 targetPage.style.display=value;163 targetPage.style.display=value;
158 };164 };
165 updateDisplayStyle(tab, 'block');
159 [].slice.166 [].slice.
160 call(this._tabs.querySelectorAll('[data-role="tabitem"]:not(:first-child)')).167 call(this._tabs.querySelectorAll('[data-role="tabitem"]:not(:first-child)')).
161 forEach(function(element) {168 forEach(function(element) {
@@ -203,8 +210,10 @@
203 * @private210 * @private
204 */211 */
205 __onTouchStart: function (e) {212 __onTouchStart: function (e) {
206 console.log('touchstart');
207 if (!this._tabs) return;213 if (!this._tabs) return;
214
215 e.preventDefault();
216
208 this.__clearInternalState();217 this.__clearInternalState();
209218
210 if (state === STATES.basic) {219 if (state === STATES.basic) {
@@ -219,12 +228,20 @@
219 startTimestamp = _e.timeStamp;228 startTimestamp = _e.timeStamp;
220229
221 this._tabs.style['-webkit-transition-duration'] = 0;230 this._tabs.style['-webkit-transition-duration'] = 0;
231
232 this._touchDown = true;
222 },233 },
223234
224 /**235 /**
225 * @private236 * @private
226 */237 */
227 __onTouchMove: function (e) {238 __onTouchMove: function (e) {
239 if (!this._touchDown) {
240 return;
241 }
242
243 e.preventDefault();
244
228 var _e = this._touchInfoDelegate.translateTouchEvent(e);245 var _e = this._touchInfoDelegate.translateTouchEvent(e);
229 deltaX = _e.touches[0].pageX - pageX;246 deltaX = _e.touches[0].pageX - pageX;
230 deltaY = _e.touches[0].pageY - pageY;247 deltaY = _e.touches[0].pageY - pageY;
@@ -242,11 +259,17 @@
242259
243 offsetX = (deltaX / resistance) + this.__getScroll();260 offsetX = (deltaX / resistance) + this.__getScroll();
244261
245 var maxLeftReached = this._tabs.querySelector('li:first-child').getBoundingClientRect().left >= 0 &&262 var firstTab = this._tabs.querySelector('li:first-child');
263 var maxRightScrollReached =
264 firstTab.getBoundingClientRect().left >= 0 &&
246 deltaX > 0;265 deltaX > 0;
247 var maxRightReached = this._tabs.querySelector('li:last-child').getBoundingClientRect().right <= this.__getHeaderWidth() &&266
267 var lastTab = this._tabs.querySelector('li:last-child');
268 var maxLeftScrollReached =
269 lastTab.getBoundingClientRect().right <= this.__getHeaderWidth() &&
248 deltaX < 0;270 deltaX < 0;
249 if (this.__getTabHeadersWidth() > this.__getHeaderWidth() && !maxLeftReached && !maxRightReached) {271
272 if (!maxRightScrollReached && !maxLeftScrollReached) {
250 this._tabs.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';273 this._tabs.style.webkitTransform = 'translate3d(' + offsetX + 'px,0,0)';
251 }274 }
252 },275 },
@@ -257,13 +280,17 @@
257 __onTouchEnd: function (e) {280 __onTouchEnd: function (e) {
258 if (!this._tabs || isScrolling) return;281 if (!this._tabs || isScrolling) return;
259282
283 e.preventDefault();
284 this._touchDown = false;
285
260 var _e = this._touchInfoDelegate.translateTouchEvent(e);286 var _e = this._touchInfoDelegate.translateTouchEvent(e);
261287
262 var MIN_JITTER_THRESHOLD = 20;288 var MIN_JITTER_THRESHOLD = 20;
263 if (state === STATES.transitioning_to_navigation) {289 if (state === STATES.transitioning_to_navigation) {
264 state = STATES.navigating;290 state = STATES.navigating;
265 }291 }
266 else if (state === STATES.navigating && Math.abs((_e.changedTouches[0].pageX - pageX)) < MIN_JITTER_THRESHOLD) {292 else if (state === STATES.navigating &&
293 Math.abs((_e.changedTouches[0].pageX - pageX)) < MIN_JITTER_THRESHOLD) {
267 this.__onClicked(_e);294 this.__onClicked(_e);
268 // Timer should have been cancelled, back to basic295 // Timer should have been cancelled, back to basic
269 state = STATES.basic;296 state = STATES.basic;

Subscribers

People subscribed via source and target branches