-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0495e22
commit f7ce57a
Showing
7 changed files
with
281 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/* global FastBoot */ | ||
|
||
import { get, set } from '@ember/object'; | ||
import { assert } from '@ember/debug'; | ||
|
||
function getUserAgent(appInstance) { | ||
if (typeof FastBoot === 'undefined') { | ||
const userAgent = get(window, 'navigator.userAgent'); | ||
assert('No `userAgent` present in window.navigator', userAgent); | ||
return userAgent; | ||
} else { | ||
const fastboot = appInstance.lookup('service:fastboot'); | ||
const headers = get(fastboot, 'request.headers'); | ||
const userAgent = headers.get('user-agent'); | ||
assert('No `user-agent` present in FastBoot headers.', userAgent); | ||
return userAgent; | ||
} | ||
} | ||
|
||
export function initialize(appInstance) { | ||
const service = appInstance.lookup('service:user-agent'); | ||
set(service, 'userAgent', getUserAgent(appInstance)); | ||
} | ||
|
||
export default { | ||
initialize | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,135 @@ | ||
/* global FastBoot */ | ||
|
||
import Service from '@ember/service'; | ||
import { computed, get, observer, setProperties } from '@ember/object'; | ||
import { readOnly } from '@ember/object/computed'; | ||
import { assign } from '@ember/polyfills'; | ||
import { isEqual } from '@ember/utils'; | ||
import { assert } from '@ember/debug'; | ||
import { computed, get, set } from '@ember/object'; | ||
import { getOwner } from '@ember/application'; | ||
import { deprecate } from '@ember/application/deprecations'; | ||
import UAParser from 'ua-parser-js'; | ||
|
||
export default Service.extend({ | ||
_parser: computed(() => new UAParser), | ||
|
||
fastboot: computed(function() { | ||
return getOwner(this).lookup('service:fastboot'); | ||
}), | ||
parser: computed('extensions', { | ||
get() { | ||
deprecate( | ||
'Usage of the private property `parser` is deprecated. If you need to fiddle around with this private property, please open an issue and we can discuss.', | ||
false, | ||
{ id: 'ember-useragent.service.parser', until: '1.0.0' } | ||
); | ||
|
||
isFastBoot: readOnly('fastboot.isFastBoot'), | ||
return get(this, '_parser'); | ||
} | ||
}).readOnly(), | ||
|
||
userAgent: computed(function() { | ||
if (get(this, 'isFastBoot')) { | ||
let headers = get(this, 'fastboot.request.headers'); | ||
let userAgent = headers.get('user-agent'); | ||
UAParser: computed(function () { | ||
deprecate( | ||
'Usage of the property `UAParser` is deprecated. To get the UAParser class, import it as `import UAParser from \'ua-parser-js\';`. To get the instance of that class used by this service, as this property previously incorrectly returned, get the `parser` property.', | ||
false, | ||
{ id: 'ember-useragent.service.UAParser', until: '1.0.0' } | ||
); | ||
|
||
assert('No userAgent present in ember-useragent/services/user-agent (FastBoot)', userAgent); | ||
return userAgent; | ||
} else { | ||
if (window && window.navigator) { | ||
let userAgent = window.navigator.userAgent; | ||
return get(this, '_parser'); | ||
}), | ||
|
||
assert('No userAgent present in ember-useragent/services/user-agent (Browser)', userAgent); | ||
return userAgent; | ||
} | ||
userAgent: computed({ | ||
get() { | ||
const parser = get(this, '_parser'); | ||
return parser.getUA(); | ||
}, | ||
set(key, value) { | ||
const parser = get(this, '_parser'); | ||
parser.setUA(value); | ||
set(this, '_parser', parser); | ||
|
||
return value; | ||
} | ||
}), | ||
|
||
UAParser: computed('userAgent', function() { | ||
let userAgent = get(this, 'userAgent'); | ||
fastboot: computed(function () { | ||
deprecate( | ||
'Usage of the private property `fastboot` is deprecated. Inject the `fastboot` service yourself instead.', | ||
false, | ||
{ id: 'ember-useragent.service.fastboot', until: '1.0.0' } | ||
); | ||
|
||
if (get(this, 'isFastBoot')) { | ||
let UAParser = FastBoot.require('ua-parser-js'); | ||
return new UAParser(userAgent); | ||
} | ||
return getOwner(this).lookup('service:fastboot'); | ||
}), | ||
|
||
isFastBoot: computed(function () { | ||
deprecate( | ||
'Usage of the private property `isFastBoot` is deprecated. Inject the `fastboot` service yourself and get `fastboot.isFastBoot` instead.', | ||
false, | ||
{ id: 'ember-useragent.service.isFastBoot', until: '1.0.0' } | ||
); | ||
|
||
const fastboot = getOwner(this).lookup('service:fastboot'); | ||
return Boolean(fastboot && get(fastboot, 'isFastBoot')); | ||
}), | ||
|
||
browser: computed('_parser', function() { | ||
const browser = get(this, '_parser').getBrowser(); | ||
|
||
return { | ||
info: browser, | ||
isChrome: browser.name === 'Chrome', | ||
isChromeHeadless: browser.name === 'Chrome Headless', | ||
isEdge: browser.name === 'Edge', | ||
isFirefox: browser.name === 'Firefox', | ||
isIE: browser.name === 'IE' || | ||
browser.name === 'IE Mobile', | ||
isSafari: browser.name === 'Safari' || | ||
browser.name === 'Mobile Safari' | ||
}; | ||
}), | ||
|
||
return new UAParser(userAgent); | ||
cpu: computed('_parser', function() { | ||
return get(this, '_parser').getCPU(); | ||
}), | ||
|
||
setupService: observer('UAParser', function() { | ||
const parser = get(this, 'UAParser'); | ||
|
||
const browser = parser.getBrowser(); | ||
const device = parser.getDevice(); | ||
const engine = parser.getEngine(); | ||
const os = parser.getOS(); | ||
|
||
setProperties(this, assign({ | ||
|
||
browser: { | ||
info: browser, | ||
isChrome: isEqual(browser.name, 'Chrome'), | ||
isChromeHeadless: isEqual(browser.name, 'Chrome Headless'), | ||
isEdge: isEqual(browser.name, 'Edge'), | ||
isFirefox: isEqual(browser.name, 'Firefox'), | ||
isIE: isEqual(browser.name, 'IE') || | ||
isEqual(browser.name, 'IE Mobile'), | ||
isSafari: isEqual(browser.name, 'Safari') || | ||
isEqual(browser.name, 'Mobile Safari') | ||
}, | ||
|
||
device: { | ||
info: device, | ||
isConsole: isEqual(device.type, 'console'), | ||
isDesktop: !device.type, | ||
isMobile: isEqual(device.type, 'mobile'), | ||
isTablet: isEqual(device.type, 'tablet') | ||
}, | ||
|
||
engine: { | ||
info: engine, | ||
isWebkit: isEqual(engine.name, 'WebKit') | ||
}, | ||
|
||
os: { | ||
info: os, | ||
isAndroid: isEqual(os.name, 'Android'), | ||
isIOS: isEqual(os.name, 'iOS'), | ||
isLinux: [ | ||
'CentOS', 'Fedora', 'Linpus', 'Linux', 'MeeGo', | ||
'PCLinuxOS', 'RedHat', 'SUSE', 'Ubuntu', 'VectorLinux' | ||
].indexOf(os.name) > -1, | ||
isMacOS: isEqual(os.name, 'Mac OS'), | ||
isWindows: [ | ||
'Windows', 'Windows Phone', 'Windows Mobile' | ||
].indexOf(os.name) > -1 | ||
} | ||
|
||
}, parser)); | ||
device: computed('_parser', function() { | ||
const device = get(this, '_parser').getDevice(); | ||
|
||
return { | ||
info: device, | ||
isConsole: device.type === 'console', | ||
isDesktop: !device.type, | ||
isMobile: device.type === 'mobile', | ||
isTablet: device.type === 'tablet' | ||
}; | ||
}), | ||
|
||
init() { | ||
this._super(...arguments); | ||
this.setupService(); | ||
} | ||
engine: computed('_parser', function() { | ||
const engine = get(this, '_parser').getEngine(); | ||
|
||
return { | ||
info: engine, | ||
isWebkit: engine.name === 'WebKit' | ||
}; | ||
}), | ||
|
||
os: computed('_parser', function() { | ||
const os = get(this, '_parser').getOS(); | ||
|
||
return { | ||
info: os, | ||
isAndroid: os.name === 'Android', | ||
isIOS: os.name === 'iOS', | ||
isLinux: [ | ||
'CentOS', 'Fedora', 'Linpus', 'Linux', 'MeeGo', | ||
'PCLinuxOS', 'RedHat', 'SUSE', 'Ubuntu', 'VectorLinux' | ||
].indexOf(os.name) > -1, | ||
isMacOS: os.name === 'Mac OS', | ||
isWindows: [ | ||
'Windows', 'Windows Phone', 'Windows Mobile' | ||
].indexOf(os.name) > -1 | ||
}; | ||
}), | ||
|
||
setupService() { | ||
deprecate( | ||
'Usage of the private method `setupService` is deprecated. To force an update, set the `userAgent` property.', | ||
false, | ||
{ id: 'ember-useragent.service.setupService', until: '1.0.0' } | ||
); | ||
|
||
this.notifyPropertyChange('userAgent'); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default, initialize } from 'ember-useragent/instance-initializers/user-agent'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,17 @@ | ||
'use strict'; | ||
|
||
const BroccoliDebug = require('broccoli-debug'); | ||
const Funnel = require('broccoli-funnel'); | ||
const mergeTrees = require('broccoli-merge-trees'); | ||
const path = require('path'); | ||
const fastbootTransform = require('fastboot-transform'); | ||
|
||
module.exports = { | ||
name: 'ember-useragent', | ||
|
||
included(app) { | ||
this.importDependencies(app); | ||
return this._super.included.apply(this, arguments); | ||
}, | ||
|
||
importDependencies(app) { | ||
if (arguments.length < 1) { | ||
throw new Error('Application instance must be passed to import'); | ||
} | ||
|
||
app.import(this.treePaths.vendor + '/ua-parser-js/ua-parser.js'); | ||
|
||
app.import('vendor/shims/ua-parser-js.js', { | ||
exports: { | ||
['ua-parser-js']: ['default'] | ||
} | ||
// https://github.com/rwjblue/ember-cli-cjs-transform/issues/23#issuecomment-408665511 | ||
const modulePath = require.resolve('ua-parser-js').match(/node_modules\/.*$/)[0]; | ||
app.import(modulePath, { | ||
using: [ | ||
{ transformation: 'cjs', as: 'ua-parser-js' } | ||
] | ||
}); | ||
|
||
}, | ||
|
||
treeForVendor(vendorTree) { | ||
let debugTree = BroccoliDebug.buildDebugCallback(this.name), | ||
trees = []; | ||
|
||
if (vendorTree) { | ||
trees.push( | ||
debugTree(vendorTree, 'vendorTree') | ||
); | ||
} | ||
|
||
let js = fastbootTransform( | ||
moduleToFunnel('ua-parser-js') | ||
); | ||
|
||
trees.push( | ||
debugTree(js, 'js') | ||
); | ||
|
||
return mergeTrees(trees); | ||
return this._super.included.apply(this, arguments); | ||
} | ||
}; | ||
|
||
function moduleToFunnel(moduleName, destination) { | ||
return new Funnel(resolveModulePath(moduleName), { | ||
destDir: destination || moduleName | ||
}); | ||
} | ||
|
||
function resolveModulePath(moduleName) { | ||
return path.dirname(require.resolve(moduleName)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import Application from '@ember/application'; | ||
|
||
import { initialize } from 'dummy/instance-initializers/user-agent'; | ||
import { module, test } from 'qunit'; | ||
import { run } from '@ember/runloop'; | ||
import { get } from '@ember/object'; | ||
import Service from '@ember/service'; | ||
|
||
module('Unit | Instance Initializer | user-agent', function(hooks) { | ||
hooks.beforeEach(function() { | ||
this.TestApplication = Application.extend(); | ||
this.TestApplication.instanceInitializer({ | ||
name: 'initializer under test', | ||
initialize | ||
}); | ||
this.application = this.TestApplication.create({ autoboot: false }); | ||
this.application.register('service:user-agent', Service.extend()); | ||
this.instance = this.application.buildInstance(); | ||
this.service = this.instance.lookup('service:user-agent'); | ||
}); | ||
hooks.afterEach(function() { | ||
run(this.application, 'destroy'); | ||
run(this.instance, 'destroy'); | ||
}); | ||
|
||
// Replace this with your real tests. | ||
test('it works', async function(assert) { | ||
await this.instance.boot(); | ||
|
||
assert.strictEqual(get(this.service, 'userAgent'), window.navigator.userAgent); | ||
}); | ||
}); |
Oops, something went wrong.