Skip to content

Commit 9e308a6

Browse files
committed
build: separate demo-app in its own directory. (#451)
* build: separate demo-app in its own directory. * chore: replace gulp-inline-resources with a script This also improves upon the relative path problem. All template paths now should be relative. Also, we can now include double-quotes in CSS/HTML.
1 parent 9433556 commit 9e308a6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+434
-230
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
/.idea
2626

2727
# misc
28+
.DS_Store
2829
/.sass-cache
2930
/connect.lock
3031
/coverage/*

angular-cli-build.js

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,56 @@ const path = require('path');
55
// Import the require hook. Enables us to require TS files natively.
66
require('ts-node/register');
77

8-
98
const Angular2App = require('angular-cli/lib/broccoli/angular2-app');
109
const Funnel = require('broccoli-funnel');
1110
const MergeTree = require('broccoli-merge-trees');
1211
const autoPrefixerTree = require('broccoli-autoprefixer');
1312

1413

1514
module.exports = function(defaults) {
16-
var angularAppTree = new Angular2App(defaults, {
17-
sourceDir: 'src/',
15+
// The Angular Application tree.
16+
const appTree = _buildAppTree(defaults);
17+
18+
// The CSS tree that is auto prefixed with browser support.
19+
const cssAutoprefixed = autoPrefixerTree(new Funnel(appTree, {
20+
include: [ '**/*.css' ]
21+
}));
22+
23+
return new MergeTree([appTree, cssAutoprefixed], { overwrite: true });
24+
};
25+
26+
27+
/**
28+
* Build the Broccoli Tree containing all the files used as the input to the Angular2App.
29+
*/
30+
function _buildDemoAppInputTree() {
31+
return new MergeTree([
32+
new Funnel('typings', {
33+
destDir: 'typings'
34+
}),
35+
new Funnel('src', {
36+
include: ['components/**/*', 'core/**/*'],
37+
destDir: 'src/demo-app'
38+
}),
39+
new Funnel('src/demo-app', {
40+
destDir: 'src/demo-app'
41+
})
42+
]);
43+
}
44+
45+
/**
46+
* Build the Broccoli Tree that contains the Angular2 App. This picks between E2E, Example or Demo
47+
* app.
48+
* @param defaults The default objects from AngularCLI (deprecated).
49+
* @returns {Angular2App}
50+
*/
51+
function _buildAppTree(defaults) {
52+
let inputNode = _buildDemoAppInputTree();
53+
54+
return new Angular2App(defaults, inputNode, {
55+
sourceDir: 'src/demo-app',
56+
tsCompiler: {
57+
},
1858
sassCompiler: {
1959
includePaths: [
2060
'src/core/style'
@@ -27,17 +67,7 @@ module.exports = function(defaults) {
2767
'es6-shim/es6-shim.js',
2868
'reflect-metadata/*.js',
2969
'rxjs/**/*.js',
30-
'@angular/**/*.js',
70+
'@angular/**/*.js'
3171
]
3272
});
33-
34-
const cssAutoprefixed = autoPrefixerTree(new Funnel(angularAppTree, {
35-
include: [ '**/*.css' ]
36-
}));
37-
38-
return new MergeTree([
39-
new Funnel('src', { include: ['**/*.scss']}),
40-
angularAppTree,
41-
cssAutoprefixed,
42-
], { overwrite: true });
43-
};
73+
}

config/environment.dev.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const environment = {
2+
production: false
3+
};

config/environment.prod.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export const environment = {
2+
production: true
3+
};

gulpfile.js

Lines changed: 0 additions & 19 deletions
This file was deleted.

package.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"typings": "typings install --ambient",
1717
"postinstall": "npm run typings",
1818
"e2e": "protractor test/protractor.conf.js",
19-
"inline-resources": "gulp inline-resources",
19+
"inline-resources": "node ./scripts/release/inline-resources.js ./dist/components",
2020
"deploy": "firebase deploy"
2121
},
2222
"version": "2.0.0-alpha.4",
@@ -41,7 +41,7 @@
4141
},
4242
"devDependencies": {
4343
"add-stream": "^1.0.0",
44-
"angular-cli": "0.0.37",
44+
"angular-cli": "^1.0.0-beta.4",
4545
"broccoli-autoprefixer": "^4.1.0",
4646
"broccoli-funnel": "^1.0.1",
4747
"broccoli-merge-trees": "^1.1.1",
@@ -51,8 +51,6 @@
5151
"firebase-tools": "^2.2.1",
5252
"fs-extra": "^0.26.5",
5353
"glob": "^6.0.4",
54-
"gulp": "^3.9.1",
55-
"gulp-inline-ng2-template": "^1.1.2",
5654
"jasmine-core": "^2.4.1",
5755
"js-yaml": "^3.5.2",
5856
"karma": "^0.13.15",
@@ -68,7 +66,7 @@
6866
"symlink-or-copy": "^1.0.1",
6967
"ts-node": "^0.5.5",
7068
"tslint": "^3.5.0",
71-
"typescript": "^1.8.0",
69+
"typescript": "^1.9.0-dev",
7270
"typings": "^0.8.1",
7371
"which": "^1.2.4"
7472
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/env node
2+
'use strict';
3+
4+
const fs = require('fs');
5+
const path = require('path');
6+
const glob = require('glob');
7+
8+
/**
9+
* Simple Promiseify function that takes a Node API and return a version that supports promises.
10+
* We use promises instead of synchronized functions to make the process less I/O bound and
11+
* faster. It also simplify the code.
12+
*/
13+
function promiseify(fn) {
14+
return function() {
15+
const args = [].slice.call(arguments, 0);
16+
return new Promise((resolve, reject) => {
17+
fn.apply(this, args.concat([function (err, value) {
18+
if (err) {
19+
reject(err);
20+
} else {
21+
resolve(value);
22+
}
23+
}]));
24+
});
25+
};
26+
}
27+
28+
const readFile = promiseify(fs.readFile);
29+
const writeFile = promiseify(fs.writeFile);
30+
31+
32+
/**
33+
* For every argument, inline the templates and styles under it and write the new file.
34+
*/
35+
for (let arg of process.argv.slice(2)) {
36+
if (arg.indexOf('*') < 0) {
37+
// Argument is a directory target, add glob patterns to include every files.
38+
arg = path.join(arg, '**', '*');
39+
}
40+
41+
const files = glob.sync(arg, {})
42+
.filter(name => /\.js$/.test(name)); // Matches only JavaScript files.
43+
44+
// Generate all files content with inlined templates.
45+
files.forEach(filePath => {
46+
readFile(filePath, 'utf-8')
47+
.then(content => inlineTemplate(filePath, content))
48+
.then(content => inlineStyle(filePath, content))
49+
.then(content => writeFile(filePath, content))
50+
.catch(err => {
51+
console.error('An error occured: ', err);
52+
});
53+
});
54+
}
55+
56+
57+
/**
58+
* Inline the templates for a source file. Simply search for instances of `templateUrl: ...` and
59+
* replace with `template: ...` (with the content of the file included).
60+
* @param filePath {string} The path of the source file.
61+
* @param content {string} The source file's content.
62+
* @return {string} The content with all templates inlined.
63+
*/
64+
function inlineTemplate(filePath, content) {
65+
return content.replace(/templateUrl:\s*'([^']+\.html)'/g, function(m, templateUrl) {
66+
const templateFile = path.join(path.dirname(filePath), templateUrl);
67+
const templateContent = fs.readFileSync(templateFile, 'utf-8');
68+
const shortenedTemplate = templateContent
69+
.replace(/([\n\r]\s*)+/gm, ' ')
70+
.replace(/"/g, '\\"');
71+
return `template: "${shortenedTemplate}"`;
72+
});
73+
}
74+
75+
76+
/**
77+
* Inline the styles for a source file. Simply search for instances of `styleUrls: [...]` and
78+
* replace with `styles: [...]` (with the content of the file included).
79+
* @param filePath {string} The path of the source file.
80+
* @param content {string} The source file's content.
81+
* @return {string} The content with all styles inlined.
82+
*/
83+
function inlineStyle(filePath, content) {
84+
return content.replace(/styleUrls:\s*(\[[\s\S]*?\])/gm, function(m, styleUrls) {
85+
const urls = eval(styleUrls);
86+
return 'styles: ['
87+
+ urls.map(styleUrl => {
88+
const styleFile = path.join(path.dirname(filePath), styleUrl);
89+
const styleContent = fs.readFileSync(styleFile, 'utf-8');
90+
const shortenedStyle = styleContent
91+
.replace(/([\n\r]\s*)+/gm, ' ')
92+
.replace(/"/g, '\\"');
93+
return `"${shortenedStyle}"`;
94+
})
95+
.join(',\n')
96+
+ ']';
97+
});
98+
}

src/components/button/button.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414

1515

1616
@Component({
17+
moduleId: module.id,
1718
selector: 'button[md-button], button[md-raised-button], button[md-icon-button], ' +
1819
'button[md-fab], button[md-mini-fab]',
1920
inputs: ['color'],
@@ -23,8 +24,8 @@ import {
2324
'(focus)': 'setKeyboardFocus()',
2425
'(blur)': 'removeKeyboardFocus()',
2526
},
26-
templateUrl: './components/button/button.html',
27-
styleUrls: ['./components/button/button.css'],
27+
templateUrl: 'button.html',
28+
styleUrls: ['button.css'],
2829
encapsulation: ViewEncapsulation.None,
2930
changeDetection: ChangeDetectionStrategy.OnPush,
3031
})
@@ -81,6 +82,7 @@ export class MdButton {
8182
}
8283

8384
@Component({
85+
moduleId: module.id,
8486
selector: 'a[md-button], a[md-raised-button], a[md-icon-button], a[md-fab], a[md-mini-fab]',
8587
inputs: ['color'],
8688
host: {
@@ -90,8 +92,8 @@ export class MdButton {
9092
'(blur)': 'removeKeyboardFocus()',
9193
'(click)': 'haltDisabledEvents($event)',
9294
},
93-
templateUrl: './components/button/button.html',
94-
styleUrls: ['./components/button/button.css'],
95+
templateUrl: 'button.html',
96+
styleUrls: ['button.css'],
9597
encapsulation: ViewEncapsulation.None
9698
})
9799
export class MdAnchor extends MdButton {

src/components/card/card.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ it also provides a number of preset styles for common card sections, including:
2121
*/
2222

2323
@Component({
24+
moduleId: module.id,
2425
selector: 'md-card',
25-
templateUrl: './components/card/card.html',
26-
styleUrls: ['./components/card/card.css'],
26+
templateUrl: 'card.html',
27+
styleUrls: ['card.css'],
2728
encapsulation: ViewEncapsulation.None,
2829
changeDetection: ChangeDetectionStrategy.OnPush,
2930
})
@@ -45,8 +46,9 @@ TODO(kara): update link to demo site when it exists
4546
*/
4647

4748
@Component({
49+
moduleId: module.id,
4850
selector: 'md-card-header',
49-
templateUrl: './components/card/card-header.html',
51+
templateUrl: 'card-header.html',
5052
encapsulation: ViewEncapsulation.None,
5153
changeDetection: ChangeDetectionStrategy.OnPush,
5254
})
@@ -64,8 +66,9 @@ TODO(kara): update link to demo site when it exists
6466
*/
6567

6668
@Component({
69+
moduleId: module.id,
6770
selector: 'md-card-title-group',
68-
templateUrl: './components/card/card-title-group.html',
71+
templateUrl: 'card-title-group.html',
6972
encapsulation: ViewEncapsulation.None,
7073
changeDetection: ChangeDetectionStrategy.OnPush,
7174
})

src/components/checkbox/checkbox.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {TestComponentBuilder, ComponentFixture} from '@angular/compiler/testing'
44
import {Component, DebugElement} from '@angular/core';
55
import {By} from '@angular/platform-browser';
66
import {MdCheckbox} from './checkbox';
7-
import {PromiseCompleter} from '../../core/async/promise-completer';
7+
import {PromiseCompleter} from '@angular2-material/core/async/promise-completer';
88

99
// TODO: Implement E2E tests for spacebar/click behavior for checking/unchecking
1010

0 commit comments

Comments
 (0)