Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
buschtoens authored and willviles committed Aug 1, 2018
1 parent 0495e22 commit f7ce57a
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 171 deletions.
27 changes: 27 additions & 0 deletions addon/instance-initializers/user-agent.js
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
};
197 changes: 113 additions & 84 deletions addon/services/user-agent.js
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');
}
});
1 change: 1 addition & 0 deletions app/instance-initializers/user-agent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default, initialize } from 'ember-useragent/instance-initializers/user-agent';
59 changes: 7 additions & 52 deletions index.js
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));
}
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,8 @@
"test:all": "ember try:each"
},
"dependencies": {
"broccoli-debug": "^0.6.4",
"broccoli-funnel": "^2.0.1",
"broccoli-merge-trees": "^3.0.0",
"ember-cli-babel": "^6.16.0",
"fastboot-transform": "^0.1.3",
"ember-cli-cjs-transform": "^1.3.0",
"ua-parser-js": "^0.7.18"
},
"devDependencies": {
Expand Down
32 changes: 32 additions & 0 deletions tests/unit/instance-initializers/user-agent-test.js
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);
});
});
Loading

0 comments on commit f7ce57a

Please sign in to comment.