Skip to content

Commit ff55c80

Browse files
feat(resources): register resources by class (#354)
BREAKING CHANGE - default resources are no longer reexported, need to be explicitly included when bundling
1 parent ceefb50 commit ff55c80

File tree

9 files changed

+76
-77
lines changed

9 files changed

+76
-77
lines changed

package.json

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232
"build:commonjs": "cross-env tsc --project tsconfig.build.json --outDir dist/commonjs --module commonjs",
3333
"postbuild:commonjs": "cross-env copyfiles --up 1 src/**/*.html src/**/*.css dist/commonjs",
3434
"prebuild:es2015": "cross-env rimraf dist/es2015",
35-
"build:es2015": "cross-env tsc --project tsconfig.build.json --outDir dist/es2015 --module es2015 --target es2015",
35+
"build:es2015": "cross-env tsc --project tsconfig.build.json --outDir dist/es2015 --module esnext --target es2015",
3636
"postbuild:es2015": "cross-env copyfiles --up 1 src/**/*.html src/**/*.css dist/es2015",
3737
"prebuild:native-modules": "cross-env rimraf dist/native-modules",
38-
"build:native-modules": "cross-env tsc --project tsconfig.build.json --outDir dist/native-modules --module es2015",
38+
"build:native-modules": "cross-env tsc --project tsconfig.build.json --outDir dist/native-modules --module esnext",
3939
"postbuild:native-modules": "cross-env copyfiles --up 1 src/**/*.html src/**/*.css dist/native-modules",
4040
"prebuild:system": "cross-env rimraf dist/system",
4141
"build:system": "cross-env tsc --project tsconfig.build.json --outDir dist/system --module system",
@@ -110,24 +110,5 @@
110110
"tslint": "5.7.0",
111111
"typedoc": "0.8.0",
112112
"typescript": "^2.5.3"
113-
},
114-
"aurelia": {
115-
"documentation": {
116-
"articles": [
117-
{
118-
"title": "Dialog: Basics",
119-
"href": "doc/article/en-US/dialog-basics.md"
120-
}
121-
]
122-
},
123-
"build": {
124-
"resources": [
125-
"aurelia-dialog/ux-dialog",
126-
"aurelia-dialog/ux-dialog-header",
127-
"aurelia-dialog/ux-dialog-body",
128-
"aurelia-dialog/ux-dialog-footer",
129-
"aurelia-dialog/attach-focus"
130-
]
131-
}
132113
}
133114
}

src/aurelia-dialog.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,17 @@ import { DialogConfiguration } from './dialog-configuration';
33

44
export function configure(
55
frameworkConfig: FrameworkConfiguration,
6-
callback?: (config: DialogConfiguration) => void): void {
7-
let applyConfig: () => void = null as any;
6+
callback?: (config: DialogConfiguration) => void): void | Promise<void> {
7+
let applyConfig: () => void | Promise<void> = null as any;
88
const config = new DialogConfiguration(frameworkConfig, (apply: () => void) => { applyConfig = apply; });
99
if (typeof callback === 'function') {
1010
callback(config);
1111
} else {
1212
config.useDefaults();
1313
}
14-
applyConfig();
14+
return applyConfig();
1515
}
1616

17-
export * from './ux-dialog';
18-
export * from './ux-dialog-header';
19-
export * from './ux-dialog-body';
20-
export * from './ux-dialog-footer';
21-
export * from './attach-focus';
2217
export * from './interfaces';
2318
export * from './dialog-settings';
2419
export * from './dialog-configuration';

src/dialog-configuration.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ import { FrameworkConfiguration } from 'aurelia-framework';
22
import { Renderer, RendererStatic } from './renderer';
33
import { DialogSettings, DefaultDialogSettings } from './dialog-settings';
44
import { DialogRenderer } from './dialog-renderer';
5-
import { DOM, PLATFORM } from 'aurelia-pal';
5+
import { DOM } from 'aurelia-pal';
66

77
const defaultRenderer: RendererStatic = DialogRenderer;
88

9-
const resources: { [key: string]: string } = {
10-
'ux-dialog': PLATFORM.moduleName('./ux-dialog'),
11-
'ux-dialog-header': PLATFORM.moduleName('./ux-dialog-header'),
12-
'ux-dialog-body': PLATFORM.moduleName('./ux-dialog-body'),
13-
'ux-dialog-footer': PLATFORM.moduleName('./ux-dialog-footer'),
14-
'attach-focus': PLATFORM.moduleName('./attach-focus')
9+
const resources: { [key: string]: () => Promise<any> } = {
10+
'ux-dialog': () => import('./resources/ux-dialog'),
11+
'ux-dialog-header': () => import('./resources/ux-dialog-header'),
12+
'ux-dialog-body': () => import('./resources/ux-dialog-body'),
13+
'ux-dialog-footer': () => import('./resources/ux-dialog-footer'),
14+
'attach-focus': () => import('./resources/attach-focus')
1515
};
1616

1717
// tslint:disable-next-line:max-line-length
@@ -34,19 +34,28 @@ export class DialogConfiguration {
3434
*/
3535
public settings: DialogSettings;
3636

37-
constructor(frameworkConfiguration: FrameworkConfiguration, applySetter: (apply: () => void) => void) {
37+
constructor(
38+
frameworkConfiguration: FrameworkConfiguration,
39+
applySetter: (apply: () => void | Promise<void>) => void
40+
) {
3841
this.fwConfig = frameworkConfiguration;
3942
this.settings = this.fwConfig.container.get(DefaultDialogSettings);
4043
applySetter(() => this._apply());
4144
}
4245

43-
private _apply(): void {
46+
private _apply(): void | Promise<void> {
4447
this.fwConfig.transient(Renderer, this.renderer);
45-
this.resources.forEach(resourceName => this.fwConfig.globalResources(resources[resourceName]));
4648

4749
if (this.cssText) {
4850
DOM.injectStyles(this.cssText);
4951
}
52+
53+
if (this.resources.length) {
54+
return Promise.all(this.resources.map(name => resources[name]()))
55+
.then(modules => {
56+
this.fwConfig.globalResources(modules.map(m => m.default as () => void));
57+
});
58+
}
5059
}
5160

5261
/**

src/attach-focus.ts renamed to src/resources/attach-focus.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { customAttribute, ComponentAttached } from 'aurelia-templating';
22
import { DOM } from 'aurelia-pal';
33

44
@customAttribute('attach-focus')
5-
export class AttachFocus implements ComponentAttached {
5+
export default class AttachFocus implements ComponentAttached {
66
public value: boolean | string;
77

88
/**

src/ux-dialog-body.ts renamed to src/resources/ux-dialog-body.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import { customElement, inlineView } from 'aurelia-templating';
66
<slot></slot>
77
</template>
88
`)
9-
export class UxDialogBody {
9+
export default class UxDialogBody {
1010

1111
}

src/ux-dialog-footer.ts renamed to src/resources/ux-dialog-footer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { customElement, bindable, inlineView } from 'aurelia-templating';
2-
import { DialogController } from './dialog-controller';
2+
import { DialogController } from '../dialog-controller';
33

44
/**
55
* View-model for footer of Dialog.
@@ -19,7 +19,7 @@ import { DialogController } from './dialog-controller';
1919
</template>
2020
`)
2121

22-
export class UxDialogFooter {
22+
export default class UxDialogFooter {
2323
public static isCancelButton(value: string) {
2424
return value === 'Cancel';
2525
}

src/ux-dialog-header.ts renamed to src/resources/ux-dialog-header.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { customElement, bindable, inlineView, ComponentBind } from 'aurelia-templating';
2-
import { DialogController } from './dialog-controller';
2+
import { DialogController } from '../dialog-controller';
33

44
@customElement('ux-dialog-header')
55
@inlineView(`
@@ -19,7 +19,7 @@ import { DialogController } from './dialog-controller';
1919
</template>
2020
`)
2121

22-
export class UxDialogHeader implements ComponentBind {
22+
export default class UxDialogHeader implements ComponentBind {
2323
@bindable() public showCloseButton: boolean | undefined;
2424

2525
/**

src/ux-dialog.ts renamed to src/resources/ux-dialog.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import { customElement, inlineView } from 'aurelia-templating';
66
<slot></slot>
77
</template>
88
`)
9-
export class UxDialog {
9+
export default class UxDialog {
1010

1111
}

test/unit/dialog-configuration.spec.ts

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,27 @@ import { DOM } from 'aurelia-pal';
44
import { DialogConfiguration, Renderer } from '../../src/aurelia-dialog';
55
import { DefaultDialogSettings } from '../../src/dialog-settings';
66
import { DialogRenderer } from '../../src/dialog-renderer';
7+
import UxDialog from '../../src/resources/ux-dialog';
78

8-
describe('DialogConfiguration', () => {
9+
fdescribe('DialogConfiguration', () => {
910
const frameworkConfig: FrameworkConfiguration = {
1011
container: new Container(),
1112
globalResources: () => { return; },
1213
transient: () => { return; }
1314
} as any;
1415
let configuration: DialogConfiguration;
15-
let applyConfig: () => void;
16+
let applyConfig: () => Promise<void>;
1617
const applySetterSpy = jasmine.createSpy('applySetter')
1718
.and
18-
.callFake((apply: () => void) => { applyConfig = apply; });
19+
.callFake((apply: () => Promise<void>) => { applyConfig = apply; });
20+
21+
async function whenConfigured(configuration: () => (void | Promise<void>), done: DoneFn): Promise<void> {
22+
try {
23+
await configuration();
24+
} catch (e) {
25+
done.fail(e);
26+
}
27+
}
1928

2029
beforeEach(() => {
2130
frameworkConfig.container.unregister(DefaultDialogSettings);
@@ -32,101 +41,106 @@ describe('DialogConfiguration', () => {
3241
});
3342

3443
describe('even when ".useDefaults" is not called', () => {
35-
it('a default Renderer should be registered', () => {
36-
let applyConfig: () => void = null as any;
44+
it('a default Renderer should be registered', async done => {
45+
let applyConfig: () => void | Promise<void> = null as any;
3746
// tslint:disable-next-line:no-unused-expression
3847
new DialogConfiguration(frameworkConfig, apply => { applyConfig = apply; });
3948
spyOn(frameworkConfig, 'transient');
40-
applyConfig();
49+
await whenConfigured(applyConfig, done);
4150
expect(frameworkConfig.transient).toHaveBeenCalledWith(Renderer, DialogRenderer);
51+
done();
4252
});
4353

44-
it('the default css styles should be applied', () => {
45-
let applyConfig: () => void = null as any;
54+
it('the default css styles should be applied', async done => {
55+
let applyConfig: () => void | Promise<void> = null as any;
4656
// tslint:disable-next-line:no-unused-expression
4757
new DialogConfiguration(frameworkConfig, apply => { applyConfig = apply; });
4858
spyOn(DOM, 'injectStyles');
49-
applyConfig();
59+
await whenConfigured(applyConfig, done);
5060
expect(DOM.injectStyles).toHaveBeenCalledWith(jasmine.any(String));
61+
done();
5162
});
5263
});
5364

5465
describe('useRenderer', () => {
55-
it('should register a renderer as a transient', () => {
66+
it('should register a renderer as a transient', async done => {
5667
const renderer = {} as any;
5768
spyOn(frameworkConfig, 'transient');
5869
configuration.useRenderer(renderer);
59-
applyConfig();
70+
await whenConfigured(applyConfig, done);
6071
expect(frameworkConfig.transient).toHaveBeenCalledWith(Renderer, renderer);
72+
done();
6173
});
6274

63-
it('should export settings', () => {
75+
it('should export settings', async done => {
6476
const first = 'first';
6577
const second = 'second';
6678
configuration.useRenderer({} as any, { first, second });
67-
applyConfig();
79+
await whenConfigured(applyConfig, done);
6880
expect(configuration.settings[first]).toBe(first);
6981
expect(configuration.settings[second]).toBe(second);
82+
done();
7083
});
7184
});
7285

7386
describe('useResource', () => {
74-
it('should call globalResources', () => {
87+
it('should call globalResources', async done => {
7588
spyOn(frameworkConfig, 'globalResources');
7689
configuration.useResource('ux-dialog');
77-
applyConfig();
78-
expect(frameworkConfig.globalResources).toHaveBeenCalled();
90+
await whenConfigured(applyConfig, done);
91+
expect(frameworkConfig.globalResources).toHaveBeenCalledWith(jasmine.arrayContaining([UxDialog]));
92+
done();
7993
});
8094
});
8195

8296
describe('useDefaults', () => {
83-
it('should call useRenderer with the default renderer', () => {
97+
it('should call useRenderer with the default renderer', async done => {
8498
spyOn(configuration, 'useRenderer').and.callThrough();
8599
spyOn(configuration, 'useResource').and.callThrough();
86-
87100
configuration.useDefaults();
88-
applyConfig();
101+
await whenConfigured(applyConfig, done);
89102
expect(configuration.useRenderer).toHaveBeenCalledWith(DialogRenderer);
90103
expect(configuration.useResource).toHaveBeenCalledWith('ux-dialog');
91104
expect(configuration.useResource).toHaveBeenCalledWith('ux-dialog-header');
92105
expect(configuration.useResource).toHaveBeenCalledWith('ux-dialog-footer');
93106
expect(configuration.useResource).toHaveBeenCalledWith('ux-dialog-body');
94107
expect(configuration.useResource).toHaveBeenCalledWith('attach-focus');
108+
done();
95109
});
96110

97-
it('should inject default style', () => {
111+
it('should inject default style', async done => {
98112
spyOn(DOM, 'injectStyles').and.callThrough();
99-
100113
configuration.useDefaults();
101-
applyConfig();
114+
await whenConfigured(applyConfig, done);
102115
expect((DOM.injectStyles as jasmine.Spy).calls.any()).toEqual(true);
116+
done();
103117
});
104118
});
105119

106120
describe('useCSS', () => {
107121
describe('should skip injecting', () => {
108-
it('undefined css', () => {
122+
it('undefined css', async done => {
109123
spyOn(DOM, 'injectStyles').and.callThrough();
110-
111124
configuration.useCSS(undefined as any);
112-
applyConfig();
125+
await whenConfigured(applyConfig, done);
113126
expect((DOM.injectStyles as jasmine.Spy).calls.any()).toEqual(false);
127+
done();
114128
});
115129

116-
it('null css', () => {
130+
it('null css', async done => {
117131
spyOn(DOM, 'injectStyles').and.callThrough();
118-
119132
configuration.useCSS(null as any);
120-
applyConfig();
133+
await whenConfigured(applyConfig, done);
121134
expect((DOM.injectStyles as jasmine.Spy).calls.any()).toEqual(false);
135+
done();
122136
});
123137

124-
it('empty string', () => {
138+
it('empty string', async done => {
125139
spyOn(DOM, 'injectStyles').and.callThrough();
126-
127140
configuration.useCSS('');
128-
applyConfig();
141+
await whenConfigured(applyConfig, done);
129142
expect((DOM.injectStyles as jasmine.Spy).calls.any()).toEqual(false);
143+
done();
130144
});
131145
});
132146
});

0 commit comments

Comments
 (0)