From dbeb0f78aea594d17bd6dd519a2dad58b4730c1e Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Wed, 2 Dec 2015 10:34:29 -0600 Subject: [PATCH] fix(platform): update ripple activator fn Closes #671 --- .../nav/test/nav-controller.spec.ts | 18 ++++- ionic/config/test/config.spec.ts | 66 +++++++++++++++++++ ionic/platform/platform.ts | 28 +++++--- ionic/platform/registry.ts | 21 +++++- 4 files changed, 120 insertions(+), 13 deletions(-) diff --git a/ionic/components/nav/test/nav-controller.spec.ts b/ionic/components/nav/test/nav-controller.spec.ts index 7a7b99a327..98d8d8af4f 100644 --- a/ionic/components/nav/test/nav-controller.spec.ts +++ b/ionic/components/nav/test/nav-controller.spec.ts @@ -163,14 +163,28 @@ export function run() { describe("insert", () => { it('insert page at the specified index', () => { - nav._views = [{}, {}, {}]; + let view1 = new ViewController(); + view1._loaded = true; + let view2 = new ViewController(); + view2._loaded = true; + let view3 = new ViewController(); + view3._loaded = true; + + nav._views = [view1, view2, view3]; expect(nav._views[2].componentType).toBeUndefined(); nav.insert(2, FirstPage); expect(nav._views[2].componentType).toBe(FirstPage); }); it('push page if index >= _views.length', () => { - nav._views = [{}, {}, {}]; + let view1 = new ViewController(); + view1._loaded = true; + let view2 = new ViewController(); + view2._loaded = true; + let view3 = new ViewController(); + view3._loaded = true; + + nav._views = [view1, view2, view3]; spyOn(nav, 'push').and.callThrough(); nav.insert(2, FirstPage); expect(nav.push).not.toHaveBeenCalled(); diff --git a/ionic/config/test/config.spec.ts b/ionic/config/test/config.spec.ts index d751a51028..a348c75cee 100644 --- a/ionic/config/test/config.spec.ts +++ b/ionic/config/test/config.spec.ts @@ -2,6 +2,72 @@ import {Config, Platform, ionicProviders} from 'ionic/ionic'; export function run() { + it('should set activator setting to none for old Android Browser on a linux device', () => { + let config = new Config(); + let platform = new Platform(); + platform.userAgent('Mozilla/5.0 (Linux; U; Android 4.2.2; nl-nl; GT-I9505 Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'); + platform.navigatorPlatform('linux'); + platform.load(); + config.setPlatform(platform); + + expect(config.get('activator')).toEqual('none'); + }); + + it('should set activator setting to ripple for Android dev tools simulation on a mac', () => { + let config = new Config(); + let platform = new Platform(); + platform.userAgent('Mozilla/5.0 (Linux; U; Android 4.2.2; nl-nl; GT-I9505 Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30'); + platform.navigatorPlatform('MacIntel'); + platform.load(); + config.setPlatform(platform); + + expect(config.get('activator')).toEqual('ripple'); + }); + + it('should set activator setting to none for Android Chrome versions below v36 on a linux device', () => { + let config = new Config(); + let platform = new Platform(); + platform.userAgent('Mozilla/5.0 (Linux; Android 4.2.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1650.59 Mobile Safari/537.36'); + platform.navigatorPlatform('linux'); + platform.load(); + config.setPlatform(platform); + + expect(config.get('activator')).toEqual('none'); + }); + + it('should set activator setting to ripple for Android Chrome v36 and above on a linux device', () => { + let config = new Config(); + let platform = new Platform(); + platform.userAgent('Mozilla/5.0 (Linux; Android 4.2.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1650.59 Mobile Safari/537.36'); + platform.navigatorPlatform('linux'); + platform.load(); + config.setPlatform(platform); + + expect(config.get('activator')).toEqual('ripple'); + }); + + it('should set activator setting to ripple for Android v5.0 and above on a linux device not using Chrome', () => { + let config = new Config(); + let platform = new Platform(); + platform.userAgent('Mozilla/5.0 (Android 5.0; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0'); + platform.navigatorPlatform('linux'); + platform.load(); + config.setPlatform(platform); + + expect(config.get('activator')).toEqual('ripple'); + }); + + it('should set activator setting to none for Android versions below v5.0 on a linux device not using Chrome', () => { + let config = new Config(); + let platform = new Platform(); + platform.userAgent('Mozilla/5.0 (Android 4.4; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0'); + platform.navigatorPlatform('linux'); + platform.load(); + config.setPlatform(platform); + + expect(config.get('activator')).toEqual('none'); + }); + it('should create a new Config instace when no confg passed in ionicProviders', () => { let providers = ionicProviders(); diff --git a/ionic/platform/platform.ts b/ionic/platform/platform.ts index c1176c0cc5..cba958b23e 100644 --- a/ionic/platform/platform.ts +++ b/ionic/platform/platform.ts @@ -7,8 +7,8 @@ +*/ -import * as util from '../util/util'; -import * as dom from '../util/dom'; +import {getQuerystring, extend} from '../util/util'; +import {ready, windowDimensions, flushDimensionCache} from '../util/dom'; /** @@ -162,7 +162,7 @@ export class Platform { } else { // there is no custom ready method from the engine // use the default dom ready - dom.ready(resolve); + ready(resolve); } } @@ -186,7 +186,7 @@ export class Platform { url(val) { if (arguments.length) { this._url = val; - this._qs = util.getQuerystring(val); + this._qs = getQuerystring(val); } return this._url; } @@ -204,17 +204,17 @@ export class Platform { navigatorPlatform(val) { if (arguments.length) { - this._bPlt = (val || '').toLowerCase(); + this._bPlt = val; } return this._bPlt || ''; } width() { - return dom.windowDimensions().width; + return windowDimensions().width; } height() { - return dom.windowDimensions().height; + return windowDimensions().height; } isPortrait() { @@ -230,7 +230,7 @@ export class Platform { clearTimeout(self._resizeTimer); self._resizeTimer = setTimeout(() => { - dom.flushDimensionCache(); + flushDimensionCache(); for (let i = 0; i < self._onResizes.length; i++) { try { @@ -295,6 +295,16 @@ export class Platform { return rgx.test(this._ua || ''); } + /** + * TODO + * @param {TODO} navigatorPlatformExpression TODO + * @returns {boolean} TODO + */ + testNavigatorPlatform(navigatorPlatformExpression) { + let rgx = new RegExp(navigatorPlatformExpression, 'i'); + return rgx.test(this._bPlt || ''); + } + /** * TODO * @param {TODO} userAgentExpression TODO @@ -388,7 +398,7 @@ export class Platform { let engineMethods = engineNode.methods(); engineMethods._engineReady = engineMethods.ready; delete engineMethods.ready; - util.extend(this, engineMethods); + extend(this, engineMethods); } let platformNode = rootPlatformNode; diff --git a/ionic/platform/registry.ts b/ionic/platform/registry.ts index 286c297e5b..f9481695b8 100644 --- a/ionic/platform/registry.ts +++ b/ionic/platform/registry.ts @@ -48,7 +48,24 @@ Platform.register({ ], settings: { activator: function(p) { - return (p.version().major < 5 && p.navigatorPlatform().indexOf('linux') > -1) ? 'none' : 'ripple'; + // md mode defaults to use ripple activator + // however, under-powered devices shouldn't use ripple + // if this a linux device, and is using Android Chrome v36 (Android 5.0) + // or above then use ripple, otherwise do not use a ripple effect + if (p.testNavigatorPlatform('linux')) { + let chromeVersion = p.matchUserAgentVersion(/Chrome\/(\d+).(\d+)?/); + if (chromeVersion) { + // linux android device using modern android chrome browser gets ripple + return (parseInt(chromeVersion.major, 10) < 36 ? 'none' : 'ripple'); + } + // linux android device not using chrome browser checks just android's version + if (p.version().major < 5) { + return 'none'; + } + } + + // fallback to always use ripple + return 'ripple'; }, hoverCSS: false, keyboardHeight: 300, @@ -158,5 +175,5 @@ function isIOSDevice(p) { // checks navigator.platform to see if it's an actual iOS device // this does not use the user-agent string because it is often spoofed // an actual iPad will return true, a chrome dev tools iPad will return false - return /iphone|ipad|ipod/i.test(p.navigatorPlatform()); + return p.testNavigatorPlatform(/iphone|ipad|ipod/); }