mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 11:41:20 +08:00
make it work with latest angular
This commit is contained in:
11
gulpfile.js
11
gulpfile.js
@ -90,16 +90,7 @@ gulp.task('ng2', ['ng2-rename'], function() {
|
|||||||
var builder = new SystemJsBuilder();
|
var builder = new SystemJsBuilder();
|
||||||
return builder.loadConfig('jspm-config.js')
|
return builder.loadConfig('jspm-config.js')
|
||||||
.then(function() {
|
.then(function() {
|
||||||
builder.config({
|
return builder.build('dist/lib/angular2/angular2', 'dist/lib/angular2.js');
|
||||||
map: {
|
|
||||||
'angular2': 'dist/lib/angular2',
|
|
||||||
'rtts_assert': 'dist/lib/rtts_assert'
|
|
||||||
},
|
|
||||||
paths: {
|
|
||||||
dist: undefined,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return builder.build('angular2/angular2', 'dist/lib/angular2.js');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
System.config({
|
System.config({
|
||||||
"paths": {
|
"paths": {
|
||||||
"*": "*.js",
|
"*": "*.js",
|
||||||
"dist": "/dist"
|
"dist/*": "/dist",
|
||||||
|
"node_modules/*": "/node_modules/*",
|
||||||
},
|
},
|
||||||
"traceurOptions": {
|
"traceurOptions": {
|
||||||
"sourceMaps": true,
|
"sourceMaps": true,
|
||||||
@ -16,9 +17,10 @@ System.config({
|
|||||||
System.config({
|
System.config({
|
||||||
"map": {
|
"map": {
|
||||||
"angular2": "dist/lib/angular2",
|
"angular2": "dist/lib/angular2",
|
||||||
"hammer": "/node_modules/hammerjs/hammer",
|
"hammer": "node_modules/hammerjs/hammer.js",
|
||||||
|
"rtts_assert": "dist/lib/rtts_assert",
|
||||||
|
"rx": "node_modules/rx",
|
||||||
"ionic2": "/src",
|
"ionic2": "/src",
|
||||||
"rtts_assert": "dist/lib/rtts_assert"
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
"jasmine-core": "^2.2.0",
|
"jasmine-core": "^2.2.0",
|
||||||
"karma-chrome-launcher": "^0.1.7",
|
"karma-chrome-launcher": "^0.1.7",
|
||||||
"karma-jasmine": "^0.3.5",
|
"karma-jasmine": "^0.3.5",
|
||||||
|
"rx": "^2.4.6",
|
||||||
"systemjs": "~0.11.0",
|
"systemjs": "~0.11.0",
|
||||||
"traceur": "0.0.87",
|
"traceur": "0.0.87",
|
||||||
"zone.js": "0.4.1"
|
"zone.js": "0.4.1"
|
||||||
|
@ -1 +1,8 @@
|
|||||||
export * from './components/aside/aside';
|
//BUNDLE ONLY
|
||||||
|
|
||||||
|
import {Aside, AsideParent} from './components/aside/aside';
|
||||||
|
|
||||||
|
export let ionicComponents = [
|
||||||
|
Aside,
|
||||||
|
AsideParent
|
||||||
|
];
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import {Decorator, NgElement, Template, Component} from 'angular2/angular2';
|
import {Component, NgElement, Template} from 'angular2/angular2';
|
||||||
|
|
||||||
@Decorator({
|
@Component({
|
||||||
selector: '[red-bg]'
|
selector: '[red-bg]'
|
||||||
})
|
})
|
||||||
@Template({
|
@Template({
|
||||||
inline: 'test'
|
inline: 'red template'
|
||||||
})
|
})
|
||||||
export class TestRedDecorator {
|
export class RedBgStyler {
|
||||||
constructor(
|
constructor(
|
||||||
element:NgElement
|
element:NgElement
|
||||||
) {
|
) {
|
||||||
@ -15,11 +15,11 @@ export class TestRedDecorator {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decorator({
|
@Component({
|
||||||
selector: '[blue-bg]'
|
selector: '[blue-bg]'
|
||||||
})
|
})
|
||||||
@Template({
|
@Template({
|
||||||
inline: 'test'
|
inline: 'blue template'
|
||||||
})
|
})
|
||||||
export class BlueTextStyler {
|
export class BlueTextStyler {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
import {DynamicComponent, Component, Template, bootstrap} from 'angular2/angular2';
|
import {DynamicComponent, Component, Template, bootstrap, NgElement} from 'angular2/angular2';
|
||||||
|
import {Inject} from 'angular2/di';
|
||||||
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
import {PrivateComponentLoader} from 'angular2/src/core/compiler/private_component_loader';
|
||||||
import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location';
|
import {PrivateComponentLocation} from 'angular2/src/core/compiler/private_component_location';
|
||||||
|
import {RedBgStyler, BlueTextStyler} from './components/stylers';
|
||||||
|
|
||||||
|
class Testy {
|
||||||
|
constructor(@Inject() element: NgElement) {
|
||||||
|
element.domElement.style.border = '3px solid pink;'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@DynamicComponent({
|
@DynamicComponent({
|
||||||
selector: 'dynamic-component',
|
selector: 'dynamic-component',
|
||||||
@ -12,8 +20,12 @@ class MyDynamic {
|
|||||||
loader:PrivateComponentLoader,
|
loader:PrivateComponentLoader,
|
||||||
location:PrivateComponentLocation
|
location:PrivateComponentLocation
|
||||||
) {
|
) {
|
||||||
loader.load(RedBgStyler, location);
|
// loader.load(RedBgStyler, location);
|
||||||
loader.load(BlueTextStyler, location);
|
// loader.load(BlueTextStyler, location);
|
||||||
|
Testy.annotations = [
|
||||||
|
new Component({ selector: 'testy' }),
|
||||||
|
new Template({ inline: 'testy-template' })
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,6 +40,9 @@ class MyDynamic {
|
|||||||
directives: [MyDynamic],
|
directives: [MyDynamic],
|
||||||
})
|
})
|
||||||
class MyApp {
|
class MyApp {
|
||||||
|
constructor() {
|
||||||
|
console.log('MyApp loaded');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap(MyApp);
|
bootstrap(MyApp);
|
||||||
|
@ -89,7 +89,7 @@ class AsideSlideGesture extends SlideEdgeGesture {
|
|||||||
super(slideElement, {
|
super(slideElement, {
|
||||||
direction: (aside.side === 'left' || aside.side === 'right') ? 'x' : 'y',
|
direction: (aside.side === 'left' || aside.side === 'right') ? 'x' : 'y',
|
||||||
edge: aside.side || 'left',
|
edge: aside.side || 'left',
|
||||||
threshold: aside.dragThreshold || 100
|
threshold: /*aside.dragThreshold || */150
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
import {Aside, AsideParent} from 'ionic2/components/aside/aside';
|
import {ionicComponents} from 'ionic2/components';
|
||||||
import {Template, Component, bootstrap} from 'angular2/angular2';
|
import {Template, Component, bootstrap} from 'angular2/angular2';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'aside-app'
|
selector: 'aside-app'
|
||||||
})
|
})
|
||||||
@Template({
|
@Template({
|
||||||
// Inlined version of main.html
|
directives: ionicComponents,
|
||||||
inline: `
|
inline: `<ion-aside-parent>
|
||||||
<ion-aside-parent>
|
|
||||||
<ion-aside side="left">
|
<ion-aside side="left">
|
||||||
LEFT
|
LEFT
|
||||||
<p>...</p>
|
<p>...</p>
|
||||||
@ -42,13 +40,9 @@ import {Template, Component, bootstrap} from 'angular2/angular2';
|
|||||||
<button class="button" (click)="openLeft()">
|
<button class="button" (click)="openLeft()">
|
||||||
Open Left Menu
|
Open Left Menu
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>`
|
||||||
`,
|
|
||||||
directives: [Aside, AsideParent]
|
|
||||||
})
|
})
|
||||||
class AsideApp {
|
class AsideApp {
|
||||||
constructor() {
|
|
||||||
}
|
|
||||||
openLeft() {
|
openLeft() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
180
src/core/config/config.js
Normal file
180
src/core/config/config.js
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
import getPlatform from '../platform/platform';
|
||||||
|
import * as util from '../../util';
|
||||||
|
|
||||||
|
// TODO stop hardcoding platforms and media sizes
|
||||||
|
|
||||||
|
/*
|
||||||
|
config
|
||||||
|
.set({ side: 'left' })
|
||||||
|
.set('threshold', 50)
|
||||||
|
.platform('ios')
|
||||||
|
.set('side', 'top')
|
||||||
|
.unset('threshold')
|
||||||
|
.media('lg')
|
||||||
|
.set('side', 'right')
|
||||||
|
|
||||||
|
config.platform('ios')
|
||||||
|
.behavior(function() {
|
||||||
|
do something
|
||||||
|
})
|
||||||
|
.defaults({
|
||||||
|
side: 'right'
|
||||||
|
})
|
||||||
|
|
||||||
|
config.platform('ios').media('tablet')
|
||||||
|
.defaults({
|
||||||
|
side: 'bottom'
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
User wants to remove the default behavior for sidemenu, but that's stuck under `.platform('ios').`
|
||||||
|
|
||||||
|
config.platform('ios').media('tablet') === config.media('tablet').platform('ios')
|
||||||
|
*/
|
||||||
|
var QUERIES = {
|
||||||
|
sm: true,
|
||||||
|
md: true,
|
||||||
|
lg: true
|
||||||
|
};
|
||||||
|
var PLATFORMS = {
|
||||||
|
ios: true,
|
||||||
|
android: true
|
||||||
|
};
|
||||||
|
|
||||||
|
function isPlatform(key = '') {
|
||||||
|
return key.toLowerCase() in PLATFORMS;
|
||||||
|
}
|
||||||
|
function isMedia(key = '') {
|
||||||
|
return key.toLowerCase() in QUERIES;
|
||||||
|
}
|
||||||
|
class ConfigCase {
|
||||||
|
constructor({ root, parent, path }) {
|
||||||
|
this._root = root;
|
||||||
|
this._parent = parent;
|
||||||
|
this._path = path || [];
|
||||||
|
this._values = {};
|
||||||
|
this.behaviors = [];
|
||||||
|
}
|
||||||
|
platform(key = '') {
|
||||||
|
if (isPlatform(key)) return this._root._addCase(key, this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
media(key = '') {
|
||||||
|
if (isMedia(key)) return this._root._addCase(key, this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
when(condition = '') {
|
||||||
|
if (isPlatform(condition) || isMedia(condition)) {
|
||||||
|
return this._root._addCase(condition, this);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
behavior(fn) {
|
||||||
|
this.behaviors.push(fn);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
set(a, b) {
|
||||||
|
if (util.isString(a)) {
|
||||||
|
this._values[a] = b;
|
||||||
|
} else {
|
||||||
|
util.extend(this._values, a || {});
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
unset(key) {
|
||||||
|
delete this._values[key];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
get(key) {
|
||||||
|
return util.isDefined(this._values[key]) ?
|
||||||
|
this._values[key] :
|
||||||
|
(this._parent ? this._parent.get(key) : undefined);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IonConfig extends ConfigCase {
|
||||||
|
constructor() {
|
||||||
|
this._root = this;
|
||||||
|
this._cases = {};
|
||||||
|
super({
|
||||||
|
root: this,
|
||||||
|
parent: null,
|
||||||
|
path: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
invoke(instance) {
|
||||||
|
return invokeConfig(this, instance);
|
||||||
|
}
|
||||||
|
_addCase(key, baseCase) {
|
||||||
|
var path = baseCase._path.slice();
|
||||||
|
path.push(key);
|
||||||
|
|
||||||
|
// Remove empties & duplicates
|
||||||
|
path = path
|
||||||
|
.filter((value, index) => {
|
||||||
|
return value && path.indexOf(value) === index;
|
||||||
|
})
|
||||||
|
.sort();
|
||||||
|
|
||||||
|
if (path.join(' ') === baseCase._path.join(' ')) {
|
||||||
|
return baseCase;
|
||||||
|
}
|
||||||
|
return this._createCase(path);
|
||||||
|
}
|
||||||
|
_createCase(path) {
|
||||||
|
if (!path.length) return this;
|
||||||
|
var pathStr = path.join(' ');
|
||||||
|
var configCase = this._cases[pathStr];
|
||||||
|
if (!configCase) {
|
||||||
|
var parentPath = path.slice(0, path.length - 1);
|
||||||
|
configCase = this._cases[pathStr] = new ConfigCase({
|
||||||
|
root: this,
|
||||||
|
parent: this._createCase(parentPath),
|
||||||
|
path: path
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return configCase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function invokeConfig(config, object, opts = {}) {
|
||||||
|
util.defaults(opts, { media: 'lg', platform: 'ios' });
|
||||||
|
var { platform, media } = opts;
|
||||||
|
|
||||||
|
var passedCases = [config].concat(
|
||||||
|
Object.keys(config._cases)
|
||||||
|
.map(name => config._cases[name])
|
||||||
|
.filter(configCasePasses)
|
||||||
|
.sort(function(a,b) {
|
||||||
|
return a._path.length < b._path.length ? -1 : 1;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// Extend the given object with the values of all the passed cases, starting with the
|
||||||
|
// most specific.
|
||||||
|
var defaults = [object];
|
||||||
|
var behaviors = [];
|
||||||
|
for (let i = 0, ii = passedCases.length; i < ii; i++) {
|
||||||
|
defaults.push(passedCases[i]._values);
|
||||||
|
// Avoid allocating a new array for each passed case's array of behaviors
|
||||||
|
behaviors.push.apply(behaviors, passedCases[i].behaviors);
|
||||||
|
}
|
||||||
|
|
||||||
|
util.defaults.apply(null, defaults);
|
||||||
|
|
||||||
|
for (let i = 0, ii = behaviors.length; i < ii; i++) {
|
||||||
|
behaviors[i].call(object, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
function configCasePasses(configCase) {
|
||||||
|
var path = configCase._path;
|
||||||
|
var key;
|
||||||
|
for (let i = 0, ii = path.length; i < ii; i++) {
|
||||||
|
if (!(media === path[i] || platform === path[i])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
138
src/core/config/config_spec.js
Normal file
138
src/core/config/config_spec.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
import {Config} from './config';
|
||||||
|
|
||||||
|
// TODO stop hardcoding platforms and media sizes
|
||||||
|
export function main() {
|
||||||
|
var rootConfig;
|
||||||
|
beforeEach(() => {
|
||||||
|
rootConfig = new Config();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a config one level down', () => {
|
||||||
|
var sub = rootConfig.platform('ios');
|
||||||
|
expect(sub._parent).toBe(rootConfig);
|
||||||
|
expect(sub._path).toEqual(['ios']);
|
||||||
|
expect(rootConfig._cases.ios).toBe(sub);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create a config two levels down', () => {
|
||||||
|
var sub1 = rootConfig.platform('ios');
|
||||||
|
var sub2 = sub1.media('lg');
|
||||||
|
expect(sub2._parent).toBe(sub1);
|
||||||
|
expect(sub1._parent).toBe(rootConfig);
|
||||||
|
expect(rootConfig._cases['ios lg']).toBe(sub2);
|
||||||
|
expect(rootConfig._cases.ios).toBe(sub1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set should be chainable', () => {
|
||||||
|
expect(rootConfig.set()).toBe(rootConfig);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set values on the root', () => {
|
||||||
|
rootConfig.set({
|
||||||
|
letter: 'a'
|
||||||
|
});
|
||||||
|
expect(rootConfig.get('letter')).toBe('a');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should always return the same object for the same key', () => {
|
||||||
|
expect(rootConfig.platform('android')).toBe(rootConfig.platform('android'));
|
||||||
|
expect(rootConfig.platform('ios')).toBe(rootConfig.platform('ios'));
|
||||||
|
expect(rootConfig.media('lg')).toBe(rootConfig.media('lg'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the same object when nesting in different order', () => {
|
||||||
|
var sub1 = rootConfig.platform('ios').media('sm');
|
||||||
|
var sub2 = rootConfig.media('sm').platform('ios');
|
||||||
|
expect(sub1).toBe(sub2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the same object when nesting in different order for huge queries', () => {
|
||||||
|
var sub1 = rootConfig.platform('ios').media('sm').platform('android').media('lg');
|
||||||
|
var sub2 = rootConfig.media('sm').media('lg').platform('android').platform('ios');
|
||||||
|
expect(sub1).toBe(sub2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set values one level down and be chainable', () => {
|
||||||
|
rootConfig.set({ letter: 'a' });
|
||||||
|
var sub1 = rootConfig.platform('ios');
|
||||||
|
expect(sub1.get('letter')).toBe('a');
|
||||||
|
expect( sub1.set({ letter: 'b' }) ).toBe(sub1);
|
||||||
|
expect(sub1.get('letter')).toBe('b');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set values two levels down and be chainable', () => {
|
||||||
|
rootConfig.set({ letter: 'a' });
|
||||||
|
var sub1 = rootConfig.platform('ios');
|
||||||
|
sub1.set({ letter: 'b' });
|
||||||
|
var sub2 = sub1.media('lg');
|
||||||
|
expect(sub2.get('letter')).toBe('b');
|
||||||
|
expect( sub2.set({ letter: 'c' }) ).toBe(sub2);
|
||||||
|
expect(sub2.get('letter')).toBe('c');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should use parent\'s value if its later set to undefined', () => {
|
||||||
|
rootConfig.set({ letter: 'a' });
|
||||||
|
var sub1 = rootConfig.platform('ios');
|
||||||
|
sub1.set({ letter: 'b' });
|
||||||
|
expect(sub1.get('letter')).toBe('b');
|
||||||
|
expect( sub1.unset('letter') ).toBe(sub1);
|
||||||
|
expect(sub1.get('letter')).toBe('a');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when() as alias for media()', () => {
|
||||||
|
expect(rootConfig.when('lg')).toBe(rootConfig.media('lg'));
|
||||||
|
expect(rootConfig.when('bad')).toBe(rootConfig);
|
||||||
|
expect(rootConfig.when('lg')).not.toBe(rootConfig.when('ios'));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('when() as alias for platform()', () => {
|
||||||
|
expect(rootConfig.platform('ios')).toBe(rootConfig.when('ios'));
|
||||||
|
expect(rootConfig.when('bad')).toBe(rootConfig);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('invokeConfig', function() {
|
||||||
|
|
||||||
|
it('should invoke defaults', () => {
|
||||||
|
var obj = {};
|
||||||
|
rootConfig.set('foo', 'bar');
|
||||||
|
rootConfig.invoke(obj);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should invoke defaults in nested whens', () => {
|
||||||
|
var obj = {};
|
||||||
|
rootConfig.set({ a: 'root', b: 'root' });
|
||||||
|
rootConfig.when('ios').set({b: 'ios', c: 'ios'});
|
||||||
|
rootConfig.when('ios').when('lg').set({ c: 'ios-lg', d: 'ios-lg' });
|
||||||
|
|
||||||
|
rootConfig.invoke(obj);
|
||||||
|
expect(obj).toEqual({
|
||||||
|
a: 'root',
|
||||||
|
b: 'ios',
|
||||||
|
c: 'ios-lg',
|
||||||
|
d: 'ios-lg'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should run behaviors', () => {
|
||||||
|
var obj = {};
|
||||||
|
rootConfig.behavior(instance => {
|
||||||
|
instance.foo = 'bar';
|
||||||
|
});
|
||||||
|
rootConfig.invoke(obj);
|
||||||
|
expect(obj.foo).toBe('bar');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should invoke behaviors in nested whens', () => {
|
||||||
|
var obj = {};
|
||||||
|
rootConfig.when('ios')
|
||||||
|
.behavior(o => o.ios = true)
|
||||||
|
.when('lg')
|
||||||
|
.behavior(o => o.lg = true)
|
||||||
|
rootConfig.invoke(obj);
|
||||||
|
expect(obj).toEqual({
|
||||||
|
ios: true,
|
||||||
|
lg: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
0
src/core/media/media.js
Normal file
0
src/core/media/media.js
Normal file
0
src/core/platform/detect.js
Normal file
0
src/core/platform/detect.js
Normal file
54
src/core/platform/platform.js
Normal file
54
src/core/platform/platform.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
var platforms = [];
|
||||||
|
|
||||||
|
// TODO(ajoslin): move this to a facade somewhere else?
|
||||||
|
var ua = window.navigator.userAgent;
|
||||||
|
|
||||||
|
class Platform {
|
||||||
|
constructor({
|
||||||
|
name,
|
||||||
|
matcher
|
||||||
|
}) {
|
||||||
|
this.name = name;
|
||||||
|
this.matcher = matcher;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlatformController {
|
||||||
|
constructor() {
|
||||||
|
this.registry = [];
|
||||||
|
}
|
||||||
|
set(platform) {
|
||||||
|
this.current = platform;
|
||||||
|
}
|
||||||
|
get() {
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
register(platform) {
|
||||||
|
this.registry.push(platform);
|
||||||
|
}
|
||||||
|
detect() {
|
||||||
|
for (let platform of this.registry) {
|
||||||
|
if (platform.matcher()) {
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export let platform = new PlatformController();
|
||||||
|
|
||||||
|
platform.register(new Platform({
|
||||||
|
name: 'android',
|
||||||
|
matcher: () => {
|
||||||
|
return /android/i.test(ua)
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
platform.register(new Platform({
|
||||||
|
name: 'ios',
|
||||||
|
matcher: () => {
|
||||||
|
return /iPhone|iPad|iPod/.test(ua)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function detectPlatform() {
|
||||||
|
}
|
Reference in New Issue
Block a user