Skip to content

Commit 0333bc2

Browse files
author
andriyha
committed
Refactoring device detection a little bit
1 parent da29ae2 commit 0333bc2

File tree

8 files changed

+47
-26
lines changed

8 files changed

+47
-26
lines changed

features/system-tests/safari-iphone.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Feature: Safari iPhone
1717

1818
Examples:
1919
| device | os-ver | ua-ver | ua-mode | screen-l | win-init-l | win-swiped-l | screen-p | win-init-p | win-swiped-p | user-agent-string |
20-
| iPhone 7 | 10.2 | 10 | | 375 x 667 | 667 x 331 | 667 x 375 | 375 x 667 | 375 x 559 | 375 x 627 | "1Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Version/10.0 Mobile/14D27 Safari/602.1" |
20+
| iPhone 7 | 10.2 | 10 | | 375 x 667 | 667 x 331 | 667 x 375 | 375 x 667 | 375 x 559 | 375 x 627 | "Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Version/10.0 Mobile/14D27 Safari/602.1" |
2121
| iPhone 6S Plus | 10.1 | 10 | | 414 x 736 | 736 x 370 | 736 x 414 | 414 x 736 | 414 x 628 | 414 x 696 | "Mozilla/5.0 (iPhone; CPU iPhone OS 10_1_1 like Mac OS X) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0 Mobile/14B100 Safari/602.1" |
2222
| iPhone 6S Plus | 10.1 | 10 | "Show tab bar" is on | 414 x 736 | 736 x 337 | 736 x 414 | 414 x 736 | 414 x 628 | 414 x 696 | "Mozilla/5.0 (iPhone; CPU iPhone OS 10_1_1 like Mac OS X) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0 Mobile/14B100 Safari/602.1" |
2323
| iPhone 5S | 9.3 | 9 | | 320 x 568 | 568 x 232 | 568 x 320 | 320 x 568 | 320 x 460 | 320 x 529 | "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.0 Mobile/14G60 Safari/602.1" |

features/unit-tests/step_definitions/state-provider.steps.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {defineSupportCode} from 'cucumber'
22
import {should} from 'chai'; should();
33
import StateProvider from '../../../src/browser-ui-state/state-providers/state-provider'
44
import {Orientation} from '../../../src/browser-ui-state/device-detectors/device-orientation-detector'
5+
import DeviceDetector from '../../../src/browser-ui-state/device-detectors/device-detector'
56

67
defineSupportCode(function(context) {
78
let Given = context.Given
@@ -20,7 +21,8 @@ defineSupportCode(function(context) {
2021

2122
Then('stateProvider.viewportAspectRatio should be equal {int}/{int}', function (width, height) {
2223
let widthAdjusted = this.stateProvider.orientation === Orientation.LANDSCAPE &&
23-
this.stateProvider._isIphoneX() ? this.win.screen.height : width
24+
DeviceDetector.isIphoneX(this.win.navigator.userAgent, this.win.screen.height) ?
25+
this.win.screen.height : width
2426

2527
this.stateProvider.viewportAspectRatio.should.be.equal(widthAdjusted/height)
2628
})
@@ -54,13 +56,15 @@ defineSupportCode(function(context) {
5456
})
5557

5658
Then('stateProvider._viewportWidthAdjustedIfNeeded should be correct', function () {
57-
let width = this.stateProvider._isIphoneX() ? this.win.screen.height : this.win.innerWidth
59+
let width = DeviceDetector.isIphoneX(this.win.navigator.userAgent, this.win.screen.height) ?
60+
this.win.screen.height : this.win.innerWidth
61+
5862
this.stateProvider._viewportWidthAdjustedIfNeeded.should.be.equal(width)
5963
})
6064

6165
Then('stateProvider._isIphoneX should correspond to {string}', function (device) {
6266
if (device === 'iPhone X') {
63-
this.stateProvider._isIphoneX().should.be.true
67+
DeviceDetector.isIphoneX(this.win.navigator.userAgent, this.win.screen.height).should.be.true
6468
}
6569
})
6670
})

src/browser-ui-state/device-detectors/device-detector.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,28 @@ export default class DeviceDetector {
3131
}
3232
}
3333
}
34+
35+
static isIos(userAgent) {
36+
return /\W(?:iPhone|iPod|iPad)\W/i.test(userAgent)
37+
}
38+
39+
static isIpad(userAgent) {
40+
return /\WiPad\W/i.test(userAgent)
41+
}
42+
43+
static isIphone(userAgent) {
44+
return /\WiPhone\W/i.test(userAgent)
45+
}
46+
47+
static isIphoneX(userAgent, screenHeight) {
48+
return DeviceDetector.isIphone(userAgent) && screenHeight === 812
49+
}
50+
51+
static isIphone4(userAgent, screenHeight) {
52+
return DeviceDetector.isIphone(userAgent) && screenHeight === 480
53+
}
54+
55+
static isIphone4WithUcCn(userAgent, screenHeight) {
56+
return /\WiPhone\W.*\Wzh-CN\W.*\WUCBrowser\W/i.test(userAgent) && screenHeight === 480
57+
}
3458
}

src/browser-ui-state/device-detectors/device-orientation-detector.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import KeyboardNoResizeDetector from './keyboard-no-resize-detector'
2+
import DeviceDetector from './device-detector'
23

34
export const Orientation = {
45
LANDSCAPE: 'LANDSCAPE',
@@ -43,7 +44,7 @@ export default class DeviceOrientationDetector {
4344
}
4445

4546
_getOrientationLegacy(width, height) {
46-
if (/\W(?:iPhone|iPod|iPad)\W/i.test(this._win.navigator.userAgent)) {
47+
if (DeviceDetector.isIos(this._win.navigator.userAgent)) {
4748
return Math.abs(this._win.orientation) === 90 ? Orientation.LANDSCAPE : Orientation.PORTRAIT
4849
} else if (this._initialOrientation) {
4950
return this._currentOrientation
@@ -53,7 +54,7 @@ export default class DeviceOrientationDetector {
5354
}
5455

5556
_isSplitMode() {
56-
if (/\WiPad\W/i.test(this._win.navigator.userAgent)) {
57+
if (DeviceDetector.isIpad(this._win.navigator.userAgent)) {
5758
if (this.orientation === Orientation.LANDSCAPE) {
5859
return Math.max(this._win.screen.width, this._win.screen.height) - this._win.innerWidth > splitModeThreshold
5960
} else {

src/browser-ui-state/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import UcbrowserIosStateProvider from './state-providers/ucbrowser-ios-state-pro
1212
import StaticStateProvider from './state-providers/static-state-provider'
1313
import OperaMiniIphoneStateProvider from './state-providers/opera-mini-iphone-state-provider'
1414
import QqCnIphoneStateProvider from './state-providers/qq-cn-iphone-state-provider'
15+
import DeviceDetector from './device-detectors/device-detector'
1516

1617
class BrowserUiState {
1718
constructor(initialOrientation = null, win = window) {
@@ -50,9 +51,9 @@ class BrowserUiState {
5051
}
5152

5253
//Thanx Opera Mini iOS for this :( It has completely the same user-agent as Safari on homescreen/standalone
53-
if (win.navigator.standalone && /\WiPhone\W/i.test(win.navigator.userAgent)) {
54+
if (win.navigator.standalone && DeviceDetector.isIphone(win.navigator.userAgent)) {
5455
this._provider = new SafariIphoneStateProvider(win, initialOrientation)
55-
} else if (win.navigator.standalone && /\WiPad\W/i.test(win.navigator.userAgent)) {
56+
} else if (win.navigator.standalone && DeviceDetector.isIpad(win.navigator.userAgent)) {
5657
this._provider = new SafariIpadStateProvider(win, initialOrientation)
5758
}
5859
}

src/browser-ui-state/state-providers/qq-cn-iphone-state-provider.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import KeyboardNoResizeStateProvider from './keyboard-no-resize-state-provider'
2+
import DeviceDetector from '../device-detectors/device-detector'
23

34
export default class QqCnIphoneStateProvider extends KeyboardNoResizeStateProvider {
45
constructor(win, initialOrientation) {
@@ -13,7 +14,7 @@ export default class QqCnIphoneStateProvider extends KeyboardNoResizeStateProvid
1314
}
1415
}
1516

16-
if (isIphone4()) {
17+
if (DeviceDetector.isIphone4()) {
1718
thresholds = {
1819
landscape : {
1920
collapsed: 9.65,
@@ -26,11 +27,7 @@ export default class QqCnIphoneStateProvider extends KeyboardNoResizeStateProvid
2627
}
2728
}
2829

29-
function isIphone4() {
30-
return win.screen.height === 480
31-
}
32-
3330
super(win, thresholds, initialOrientation)
34-
this._device = `isIphone4=${isIphone4()}`
31+
this._device = `isIphone4=${DeviceDetector.isIphone4()}`
3532
}
3633
}

src/browser-ui-state/state-providers/state-provider.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import fscreen from 'fscreen'
22
import States from './states'
33
import DeviceOrientationDetector, {Orientation} from '../device-detectors/device-orientation-detector'
4+
import DeviceDetector from '../device-detectors/device-detector'
45

56
export default class StateProvider {
67
constructor(win, thresholds, initialOrientation) {
@@ -78,10 +79,7 @@ export default class StateProvider {
7879
* Relevant only for landscape
7980
*/
8081
get _viewportWidthAdjustedIfNeeded() {
81-
return this._isIphoneX() ? this._win.screen.height : this._win.innerWidth
82-
}
83-
84-
_isIphoneX() {
85-
return /\WiPhone\W/i.test(this._win.navigator.userAgent) && this._win.screen.height === 812
82+
return DeviceDetector.isIphoneX(this._win.navigator.userAgent, this._win.screen.height) ?
83+
this._win.screen.height : this._win.innerWidth
8684
}
8785
}

src/browser-ui-state/state-providers/ucbrowser-ios-state-provider.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import KeyboardNoResizeStateProvider from './keyboard-no-resize-state-provider'
2+
import DeviceDetector from '../device-detectors/device-detector'
23

34
/**
45
* The fact this class extends KeyboardNoResizeStateProvider is not 100% accurate due to:
@@ -20,7 +21,7 @@ export default class UcbrowserIosStateProvider extends KeyboardNoResizeStateProv
2021
}
2122
}
2223

23-
if (isIphone4WithUcCN()) {
24+
if (DeviceDetector.isIphone4WithUcCn()) {
2425
thresholds = {
2526
landscape : {
2627
collapsed: 42.35,
@@ -33,12 +34,7 @@ export default class UcbrowserIosStateProvider extends KeyboardNoResizeStateProv
3334
}
3435
}
3536

36-
function isIphone4WithUcCN() {
37-
return /\WiPhone\W.*\Wzh-CN\W.*\WUCBrowser\W/i.test(win.navigator.userAgent) &&
38-
win.screen.height === 480
39-
}
40-
4137
super(win, thresholds, initialOrientation)
42-
this._device = `isIphone4WithUcCN=${isIphone4WithUcCN()}`
38+
this._device = `isIphone4WithUcCN=${DeviceDetector.isIphone4WithUcCn()}`
4339
}
4440
}

0 commit comments

Comments
 (0)