make it work with latest angular

This commit is contained in:
Andrew
2015-03-24 15:35:14 -06:00
parent 2d81e1020d
commit 1549876988
13 changed files with 416 additions and 34 deletions

View File

@ -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');
});
});

View File

@ -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"
}
});

View File

@ -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"

View File

@ -1 +1,8 @@
export * from './components/aside/aside';
//BUNDLE ONLY
import {Aside, AsideParent} from './components/aside/aside';
export let ionicComponents = [
Aside,
AsideParent
];

View File

@ -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(

View File

@ -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);

View File

@ -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
});
}

View File

@ -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
View 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;
}
}

View 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
View File

View File

View 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() {
}