mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +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();
|
||||
return builder.loadConfig('jspm-config.js')
|
||||
.then(function() {
|
||||
builder.config({
|
||||
map: {
|
||||
'angular2': 'dist/lib/angular2',
|
||||
'rtts_assert': 'dist/lib/rtts_assert'
|
||||
},
|
||||
paths: {
|
||||
dist: undefined,
|
||||
}
|
||||
});
|
||||
return builder.build('angular2/angular2', 'dist/lib/angular2.js');
|
||||
return builder.build('dist/lib/angular2/angular2', 'dist/lib/angular2.js');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
System.config({
|
||||
"paths": {
|
||||
"*": "*.js",
|
||||
"dist": "/dist"
|
||||
"dist/*": "/dist",
|
||||
"node_modules/*": "/node_modules/*",
|
||||
},
|
||||
"traceurOptions": {
|
||||
"sourceMaps": true,
|
||||
@ -16,9 +17,10 @@ System.config({
|
||||
System.config({
|
||||
"map": {
|
||||
"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",
|
||||
"rtts_assert": "dist/lib/rtts_assert"
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
"jasmine-core": "^2.2.0",
|
||||
"karma-chrome-launcher": "^0.1.7",
|
||||
"karma-jasmine": "^0.3.5",
|
||||
"rx": "^2.4.6",
|
||||
"systemjs": "~0.11.0",
|
||||
"traceur": "0.0.87",
|
||||
"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]'
|
||||
})
|
||||
@Template({
|
||||
inline: 'test'
|
||||
inline: 'red template'
|
||||
})
|
||||
export class TestRedDecorator {
|
||||
export class RedBgStyler {
|
||||
constructor(
|
||||
element:NgElement
|
||||
) {
|
||||
@ -15,11 +15,11 @@ export class TestRedDecorator {
|
||||
|
||||
}
|
||||
|
||||
@Decorator({
|
||||
@Component({
|
||||
selector: '[blue-bg]'
|
||||
})
|
||||
@Template({
|
||||
inline: 'test'
|
||||
inline: 'blue template'
|
||||
})
|
||||
export class BlueTextStyler {
|
||||
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 {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({
|
||||
selector: 'dynamic-component',
|
||||
@ -12,8 +20,12 @@ class MyDynamic {
|
||||
loader:PrivateComponentLoader,
|
||||
location:PrivateComponentLocation
|
||||
) {
|
||||
loader.load(RedBgStyler, location);
|
||||
loader.load(BlueTextStyler, location);
|
||||
// loader.load(RedBgStyler, location);
|
||||
// loader.load(BlueTextStyler, location);
|
||||
Testy.annotations = [
|
||||
new Component({ selector: 'testy' }),
|
||||
new Template({ inline: 'testy-template' })
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +40,9 @@ class MyDynamic {
|
||||
directives: [MyDynamic],
|
||||
})
|
||||
class MyApp {
|
||||
constructor() {
|
||||
console.log('MyApp loaded');
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap(MyApp);
|
||||
|
@ -89,7 +89,7 @@ class AsideSlideGesture extends SlideEdgeGesture {
|
||||
super(slideElement, {
|
||||
direction: (aside.side === 'left' || aside.side === 'right') ? 'x' : 'y',
|
||||
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';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'aside-app'
|
||||
})
|
||||
@Template({
|
||||
// Inlined version of main.html
|
||||
inline: `
|
||||
<ion-aside-parent>
|
||||
directives: ionicComponents,
|
||||
inline: `<ion-aside-parent>
|
||||
<ion-aside side="left">
|
||||
LEFT
|
||||
<p>...</p>
|
||||
@ -42,13 +40,9 @@ import {Template, Component, bootstrap} from 'angular2/angular2';
|
||||
<button class="button" (click)="openLeft()">
|
||||
Open Left Menu
|
||||
</button>
|
||||
</div>
|
||||
`,
|
||||
directives: [Aside, AsideParent]
|
||||
</div>`
|
||||
})
|
||||
class AsideApp {
|
||||
constructor() {
|
||||
}
|
||||
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