revert(format): Revert "chore(format): update to latest formatter"
This reverts commit 03627aa84d90f7f1d8d62f160997b783fdf9eaa4.
This commit is contained in:
parent
03627aa84d
commit
60727c4d2b
410
gulpfile.js
410
gulpfile.js
@ -43,7 +43,9 @@ if (cliArgs.projects) {
|
|||||||
// --projects=angular2 => {angular2: true}
|
// --projects=angular2 => {angular2: true}
|
||||||
var allProjects =
|
var allProjects =
|
||||||
'angular1_router,angular2,benchmarks,benchmarks_external,benchpress,playground,payload_tests,bundle_deps';
|
'angular1_router,angular2,benchmarks,benchmarks_external,benchpress,playground,payload_tests,bundle_deps';
|
||||||
var cliArgsProjects = (cliArgs.projects || allProjects).split(',').reduce((map, projectName) => {
|
var cliArgsProjects = (cliArgs.projects || allProjects)
|
||||||
|
.split(',')
|
||||||
|
.reduce((map, projectName) => {
|
||||||
map[projectName] = true;
|
map[projectName] = true;
|
||||||
return map;
|
return map;
|
||||||
}, {});
|
}, {});
|
||||||
@ -53,9 +55,9 @@ function printModulesWarning() {
|
|||||||
if (!cliArgs.projects && !process.env.CI) {
|
if (!cliArgs.projects && !process.env.CI) {
|
||||||
// if users didn't specify projects to build, tell them why and how they should
|
// if users didn't specify projects to build, tell them why and how they should
|
||||||
console.warn(
|
console.warn(
|
||||||
'Pro Tip: Did you know that you can speed up your build by specifying project name(s)?');
|
"Pro Tip: Did you know that you can speed up your build by specifying project name(s)?");
|
||||||
console.warn(' It\'s like pressing the turbo button in the old days, but better!');
|
console.warn(" It's like pressing the turbo button in the old days, but better!");
|
||||||
console.warn(' Examples: --project=angular2 or --project=angular2');
|
console.warn(" Examples: --project=angular2 or --project=angular2");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,9 +105,8 @@ function runJasmineTests(globs, done) {
|
|||||||
var fork = require('child_process').fork;
|
var fork = require('child_process').fork;
|
||||||
var args = ['--'].concat(globs);
|
var args = ['--'].concat(globs);
|
||||||
|
|
||||||
fork('./tools/cjs-jasmine', args, {
|
fork('./tools/cjs-jasmine', args, {stdio: 'inherit'})
|
||||||
stdio: 'inherit'
|
.on('close', function jasmineCloseHandler(exitCode) {
|
||||||
}).on('close', function jasmineCloseHandler(exitCode) {
|
|
||||||
if (exitCode && treatTestErrorsAsFatal) {
|
if (exitCode && treatTestErrorsAsFatal) {
|
||||||
var err = new Error('Jasmine tests failed');
|
var err = new Error('Jasmine tests failed');
|
||||||
// Mark the error for gulp similar to how gulp-utils.PluginError does it.
|
// Mark the error for gulp similar to how gulp-utils.PluginError does it.
|
||||||
@ -142,8 +143,12 @@ var CONFIG = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var ANGULAR2_BUNDLE_CONFIG = [
|
var ANGULAR2_BUNDLE_CONFIG = [
|
||||||
'angular2/common', 'angular2/core', 'angular2/compiler', 'angular2/instrumentation',
|
'angular2/common',
|
||||||
'angular2/platform/browser', 'angular2/platform/common_dom'
|
'angular2/core',
|
||||||
|
'angular2/compiler',
|
||||||
|
'angular2/instrumentation',
|
||||||
|
'angular2/platform/browser',
|
||||||
|
'angular2/platform/common_dom'
|
||||||
];
|
];
|
||||||
|
|
||||||
var NG2_BUNDLE_CONTENT = ANGULAR2_BUNDLE_CONFIG.join(' + ') + ' - rxjs/*';
|
var NG2_BUNDLE_CONTENT = ANGULAR2_BUNDLE_CONFIG.join(' + ') + ' - rxjs/*';
|
||||||
@ -169,8 +174,8 @@ var PAYLOAD_TESTS_CONFIG = {
|
|||||||
bundleName: 'app-bundle-deps.min.js',
|
bundleName: 'app-bundle-deps.min.js',
|
||||||
cases: ['hello_world'],
|
cases: ['hello_world'],
|
||||||
dist: function(caseName, packaging) {
|
dist: function(caseName, packaging) {
|
||||||
return path.join(
|
return path.join(__dirname, CONFIG.dest.js.prod.es5, 'payload_tests', caseName,
|
||||||
__dirname, CONFIG.dest.js.prod.es5, 'payload_tests', caseName, 'ts/' + packaging);
|
'ts/' + packaging);
|
||||||
},
|
},
|
||||||
systemjs: {sizeLimits: {'uncompressed': 870 * 1024, 'gzip level=9': 165 * 1024}},
|
systemjs: {sizeLimits: {'uncompressed': 870 * 1024, 'gzip level=9': 165 * 1024}},
|
||||||
webpack: {sizeLimits: {'uncompressed': 550 * 1024, 'gzip level=9': 120 * 1024}}
|
webpack: {sizeLimits: {'uncompressed': 550 * 1024, 'gzip level=9': 120 * 1024}}
|
||||||
@ -192,19 +197,18 @@ gulp.task('build/clean.docs_angular_io', (done) => fse.remove(CONFIG.dest.docs_a
|
|||||||
|
|
||||||
gulp.task('build/clean.bundles', (done) => fse.remove(CONFIG.dest.bundles.all, done));
|
gulp.task('build/clean.bundles', (done) => fse.remove(CONFIG.dest.bundles.all, done));
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('build/clean.bundles.benchpress',
|
||||||
'build/clean.bundles.benchpress', (done) => fse.remove(CONFIG.dest.bundles.benchpress, done));
|
(done) => fse.remove(CONFIG.dest.bundles.benchpress, done));
|
||||||
|
|
||||||
// ------------
|
// ------------
|
||||||
// transpile
|
// transpile
|
||||||
|
|
||||||
gulp.task('build/tree.dart', ['build/clean.dart', 'build.tools'], function(done) {
|
gulp.task('build/tree.dart', ['build/clean.dart', 'build.tools'],
|
||||||
runSequence('!build/tree.dart', sequenceComplete(done));
|
function(done) { runSequence('!build/tree.dart', sequenceComplete(done)); });
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('!build/tree.dart',
|
||||||
'!build/tree.dart', function() { return angularBuilder.rebuildDartTree(cliArgsProjects); });
|
function() { return angularBuilder.rebuildDartTree(cliArgsProjects); });
|
||||||
|
|
||||||
|
|
||||||
// ------------
|
// ------------
|
||||||
@ -214,14 +218,12 @@ gulp.task(
|
|||||||
gulp.task('pubget.dart', pubget.dir(gulp, gulpPlugins, {dir: '.', command: DART_SDK.PUB}));
|
gulp.task('pubget.dart', pubget.dir(gulp, gulpPlugins, {dir: '.', command: DART_SDK.PUB}));
|
||||||
|
|
||||||
// Run `pub get` only on the angular2 dir of CONFIG.dest.dart
|
// Run `pub get` only on the angular2 dir of CONFIG.dest.dart
|
||||||
gulp.task(
|
gulp.task('!build/pubget.angular2.dart',
|
||||||
'!build/pubget.angular2.dart',
|
pubget.dir(gulp, gulpPlugins,
|
||||||
pubget.dir(
|
{dir: path.join(CONFIG.dest.dart, 'angular2'), command: DART_SDK.PUB}));
|
||||||
gulp, gulpPlugins, {dir: path.join(CONFIG.dest.dart, 'angular2'), command: DART_SDK.PUB}));
|
|
||||||
|
|
||||||
// Run `pub get` over CONFIG.dest.dart
|
// Run `pub get` over CONFIG.dest.dart
|
||||||
gulp.task(
|
gulp.task('build/pubspec.dart',
|
||||||
'build/pubspec.dart',
|
|
||||||
pubget.subDir(gulp, gulpPlugins, {dir: CONFIG.dest.dart, command: DART_SDK.PUB}));
|
pubget.subDir(gulp, gulpPlugins, {dir: CONFIG.dest.dart, command: DART_SDK.PUB}));
|
||||||
|
|
||||||
|
|
||||||
@ -243,8 +245,7 @@ gulp.task('!build/remove-pub-symlinks', function(done) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
exec(
|
exec('find dist/dart/angular2/test/ -name packages | xargs rm -r',
|
||||||
'find dist/dart/angular2/test/ -name packages | xargs rm -r',
|
|
||||||
function(error, stdout, stderr) {
|
function(error, stdout, stderr) {
|
||||||
if (error) {
|
if (error) {
|
||||||
done(stderr);
|
done(stderr);
|
||||||
@ -268,16 +269,15 @@ gulp.task('build/analyze.dart', () => {
|
|||||||
gulp.task('build/analyze.ddc.dart', () => {
|
gulp.task('build/analyze.ddc.dart', () => {
|
||||||
var dartanalyzer = require('./tools/build/dartanalyzer');
|
var dartanalyzer = require('./tools/build/dartanalyzer');
|
||||||
|
|
||||||
return dartanalyzer(
|
return dartanalyzer(gulp, gulpPlugins,
|
||||||
gulp, gulpPlugins, {dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER, use_ddc: true});
|
{dest: CONFIG.dest.dart, command: DART_SDK.ANALYZER, use_ddc: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
gulp.task('build/check.apidocs.dart', () => {
|
gulp.task('build/check.apidocs.dart', () => {
|
||||||
var dartapidocs = require('./tools/build/dartapidocs');
|
var dartapidocs = require('./tools/build/dartapidocs');
|
||||||
|
|
||||||
return dartapidocs(
|
return dartapidocs(gulp, gulpPlugins,
|
||||||
gulp, gulpPlugins,
|
|
||||||
{dest: CONFIG.dest.dart, output: os.tmpdir(), command: DART_SDK.DARTDOCGEN});
|
{dest: CONFIG.dest.dart, output: os.tmpdir(), command: DART_SDK.DARTDOCGEN});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -288,8 +288,7 @@ gulp.task('build/check.apidocs.dart', () => {
|
|||||||
|
|
||||||
gulp.task(
|
gulp.task(
|
||||||
'build/pubbuild.dart',
|
'build/pubbuild.dart',
|
||||||
pubbuild.subdirs(
|
pubbuild.subdirs(gulp, gulpPlugins,
|
||||||
gulp, gulpPlugins,
|
|
||||||
{src: CONFIG.dest.dart, dest: CONFIG.dest.js.dart2js, command: DART_SDK.PUB}));
|
{src: CONFIG.dest.dart, dest: CONFIG.dest.js.dart2js, command: DART_SDK.PUB}));
|
||||||
|
|
||||||
// ------------
|
// ------------
|
||||||
@ -305,14 +304,14 @@ function doCheckFormat() {
|
|||||||
|
|
||||||
gulp.task('check-format', function() {
|
gulp.task('check-format', function() {
|
||||||
return doCheckFormat().on('warning', function(e) {
|
return doCheckFormat().on('warning', function(e) {
|
||||||
console.log('NOTE: this will be promoted to an ERROR in the continuous build');
|
console.log("NOTE: this will be promoted to an ERROR in the continuous build");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('enforce-format', function() {
|
gulp.task('enforce-format', function() {
|
||||||
return doCheckFormat().on('warning', function(e) {
|
return doCheckFormat().on('warning', function(e) {
|
||||||
console.log('ERROR: You forgot to run clang-format on your change.');
|
console.log("ERROR: You forgot to run clang-format on your change.");
|
||||||
console.log('See https://github.com/angular/angular/blob/master/DEVELOPER.md#clang-format');
|
console.log("See https://github.com/angular/angular/blob/master/DEVELOPER.md#clang-format");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -322,14 +321,14 @@ gulp.task('lint', ['build.tools'], function() {
|
|||||||
// Built-in rules are at
|
// Built-in rules are at
|
||||||
// https://github.com/palantir/tslint#supported-rules
|
// https://github.com/palantir/tslint#supported-rules
|
||||||
var tslintConfig = {
|
var tslintConfig = {
|
||||||
'rules': {
|
"rules": {
|
||||||
'requireInternalWithUnderscore': true,
|
"requireInternalWithUnderscore": true,
|
||||||
'requireParameterType': true,
|
"requireParameterType": true,
|
||||||
'requireReturnType': true,
|
"requireReturnType": true,
|
||||||
'semicolon': true,
|
"semicolon": true,
|
||||||
|
|
||||||
// TODO: find a way to just screen for reserved names
|
// TODO: find a way to just screen for reserved names
|
||||||
'variable-name': false
|
"variable-name": false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return gulp.src(['modules/angular2/src/**/*.ts', '!modules/angular2/src/testing/**'])
|
return gulp.src(['modules/angular2/src/**/*.ts', '!modules/angular2/src/testing/**'])
|
||||||
@ -349,7 +348,7 @@ gulp.task('build/checkCircularDependencies', function(done) {
|
|||||||
var dependencyObject = madge([CONFIG.dest.js.dev.es5], {
|
var dependencyObject = madge([CONFIG.dest.js.dev.es5], {
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
extensions: ['.js'],
|
extensions: ['.js'],
|
||||||
onParseFile: function(data) { data.src = data.src.replace(/\/\* circular \*\//g, '//'); }
|
onParseFile: function(data) { data.src = data.src.replace(/\/\* circular \*\//g, "//"); }
|
||||||
});
|
});
|
||||||
var circularDependencies = dependencyObject.circular().getArray();
|
var circularDependencies = dependencyObject.circular().getArray();
|
||||||
if (circularDependencies.length > 0) {
|
if (circularDependencies.length > 0) {
|
||||||
@ -420,28 +419,25 @@ gulp.task('!proxyServeDart', proxyServeDart);
|
|||||||
gulp.task('serve.dart', function(done) {
|
gulp.task('serve.dart', function(done) {
|
||||||
runSequence(
|
runSequence(
|
||||||
[
|
[
|
||||||
'!proxyServeDart', 'serve/playground.dart', 'serve/benchmarks.dart',
|
'!proxyServeDart',
|
||||||
|
'serve/playground.dart',
|
||||||
|
'serve/benchmarks.dart',
|
||||||
'serve/benchmarks_external.dart'
|
'serve/benchmarks_external.dart'
|
||||||
],
|
],
|
||||||
done);
|
done);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('serve/playground.dart',
|
||||||
'serve/playground.dart',
|
pubserve(gulp, gulpPlugins,
|
||||||
pubserve(
|
|
||||||
gulp, gulpPlugins,
|
|
||||||
{command: DART_SDK.PUB, path: CONFIG.dest.dart + '/playground', port: 8004}));
|
{command: DART_SDK.PUB, path: CONFIG.dest.dart + '/playground', port: 8004}));
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('serve/benchmarks.dart',
|
||||||
'serve/benchmarks.dart',
|
pubserve(gulp, gulpPlugins,
|
||||||
pubserve(
|
|
||||||
gulp, gulpPlugins,
|
|
||||||
{command: DART_SDK.PUB, path: CONFIG.dest.dart + '/benchmarks', port: 8006}));
|
{command: DART_SDK.PUB, path: CONFIG.dest.dart + '/benchmarks', port: 8006}));
|
||||||
|
|
||||||
gulp.task(
|
gulp.task(
|
||||||
'serve/benchmarks_external.dart',
|
'serve/benchmarks_external.dart',
|
||||||
pubserve(
|
pubserve(gulp, gulpPlugins,
|
||||||
gulp, gulpPlugins,
|
|
||||||
{command: DART_SDK.PUB, path: CONFIG.dest.dart + '/benchmarks_external', port: 8008}));
|
{command: DART_SDK.PUB, path: CONFIG.dest.dart + '/benchmarks_external', port: 8008}));
|
||||||
|
|
||||||
gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) {
|
gulp.task('serve.e2e.dart', ['build.js.cjs'], function(neverDone) {
|
||||||
@ -470,14 +466,13 @@ function runKarma(configFile, done) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
gulp.task('test.js', function(done) {
|
gulp.task('test.js', function(done) {
|
||||||
runSequence(
|
runSequence('test.unit.tools/ci', 'test.transpiler.unittest', 'test.unit.js/ci',
|
||||||
'test.unit.tools/ci', 'test.transpiler.unittest', 'test.unit.js/ci', 'test.unit.cjs/ci',
|
'test.unit.cjs/ci', 'test.typings', 'check-public-api', sequenceComplete(done));
|
||||||
'test.typings', 'check-public-api', sequenceComplete(done));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('test.dart', function(done) {
|
gulp.task('test.dart', function(done) {
|
||||||
runSequence(
|
runSequence('versions.dart', 'test.transpiler.unittest', 'test.unit.dart/ci',
|
||||||
'versions.dart', 'test.transpiler.unittest', 'test.unit.dart/ci', sequenceComplete(done));
|
sequenceComplete(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('versions.dart', function() { dartSdk.logVersion(DART_SDK); });
|
gulp.task('versions.dart', function() { dartSdk.logVersion(DART_SDK); });
|
||||||
@ -500,25 +495,23 @@ function getBrowsersFromCLI(provider, isDart) {
|
|||||||
var input = inputList[i];
|
var input = inputList[i];
|
||||||
var karmaChromeLauncher = require('karma-chrome-launcher');
|
var karmaChromeLauncher = require('karma-chrome-launcher');
|
||||||
if (browserProvidersConf.customLaunchers.hasOwnProperty(input) ||
|
if (browserProvidersConf.customLaunchers.hasOwnProperty(input) ||
|
||||||
karmaChromeLauncher.hasOwnProperty('launcher:' + input)) {
|
karmaChromeLauncher.hasOwnProperty("launcher:" + input)) {
|
||||||
// In case of non-sauce browsers, or browsers defined in karma-chrome-launcher (Chrome,
|
// In case of non-sauce browsers, or browsers defined in karma-chrome-launcher (Chrome,
|
||||||
// ChromeCanary and Dartium):
|
// ChromeCanary and Dartium):
|
||||||
// overrides everything, ignoring other options
|
// overrides everything, ignoring other options
|
||||||
outputList = [input];
|
outputList = [input];
|
||||||
isProvider = false;
|
isProvider = false;
|
||||||
break;
|
break;
|
||||||
} else if (
|
} else if (provider &&
|
||||||
provider &&
|
browserProvidersConf.customLaunchers.hasOwnProperty(provider + "_" +
|
||||||
browserProvidersConf.customLaunchers.hasOwnProperty(provider + '_' + input.toUpperCase())) {
|
input.toUpperCase())) {
|
||||||
isProvider = true;
|
isProvider = true;
|
||||||
outputList.push(provider + '_' + input.toUpperCase());
|
outputList.push(provider + "_" + input.toUpperCase());
|
||||||
} else if (
|
} else if (provider && provider == 'SL' &&
|
||||||
provider && provider == 'SL' &&
|
|
||||||
browserProvidersConf.sauceAliases.hasOwnProperty(input.toUpperCase())) {
|
browserProvidersConf.sauceAliases.hasOwnProperty(input.toUpperCase())) {
|
||||||
outputList = outputList.concat(browserProvidersConf.sauceAliases[input.toUpperCase()]);
|
outputList = outputList.concat(browserProvidersConf.sauceAliases[input.toUpperCase()]);
|
||||||
isProvider = true;
|
isProvider = true;
|
||||||
} else if (
|
} else if (provider && provider == 'BS' &&
|
||||||
provider && provider == 'BS' &&
|
|
||||||
browserProvidersConf.browserstackAliases.hasOwnProperty(input.toUpperCase())) {
|
browserProvidersConf.browserstackAliases.hasOwnProperty(input.toUpperCase())) {
|
||||||
outputList = outputList.concat(browserProvidersConf.browserstackAliases[input.toUpperCase()]);
|
outputList = outputList.concat(browserProvidersConf.browserstackAliases[input.toUpperCase()]);
|
||||||
isProvider = true;
|
isProvider = true;
|
||||||
@ -573,8 +566,7 @@ gulp.task('test.unit.js.browserstack', ['build.js.dev'], function(done) {
|
|||||||
function launchKarmaWithExternalBrowsers(reporters, browsers, done) {
|
function launchKarmaWithExternalBrowsers(reporters, browsers, done) {
|
||||||
var karma = require('karma');
|
var karma = require('karma');
|
||||||
|
|
||||||
new karma
|
new karma.Server(
|
||||||
.Server(
|
|
||||||
{
|
{
|
||||||
configFile: __dirname + '/karma-js.conf.js',
|
configFile: __dirname + '/karma-js.conf.js',
|
||||||
singleRun: true,
|
singleRun: true,
|
||||||
@ -630,8 +622,7 @@ gulp.task('!test.unit.router/karma-server', function() {
|
|||||||
gulp.task('!test.unit.router/karma-run', function(done) {
|
gulp.task('!test.unit.router/karma-run', function(done) {
|
||||||
var karma = require('karma');
|
var karma = require('karma');
|
||||||
|
|
||||||
karma.runner.run(
|
karma.runner.run({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'},
|
||||||
{configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'},
|
|
||||||
function(exitCode) {
|
function(exitCode) {
|
||||||
// ignore exitCode, we don't want to fail the build in the interactive (non-ci)
|
// ignore exitCode, we don't want to fail the build in the interactive (non-ci)
|
||||||
// mode
|
// mode
|
||||||
@ -648,8 +639,7 @@ gulp.task('buildRouter.dev', function() {
|
|||||||
|
|
||||||
gulp.task('test.unit.dart', function(done) {
|
gulp.task('test.unit.dart', function(done) {
|
||||||
printModulesWarning();
|
printModulesWarning();
|
||||||
runSequence(
|
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
|
||||||
'build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
|
|
||||||
'!build/change_detect.dart', '!build/remove-pub-symlinks', function(error) {
|
'!build/change_detect.dart', '!build/remove-pub-symlinks', function(error) {
|
||||||
var watch = require('./tools/build/watch');
|
var watch = require('./tools/build/watch');
|
||||||
|
|
||||||
@ -661,7 +651,8 @@ gulp.task('test.unit.dart', function(done) {
|
|||||||
}
|
}
|
||||||
// treatTestErrorsAsFatal = false;
|
// treatTestErrorsAsFatal = false;
|
||||||
|
|
||||||
watch(['modules/angular2/**'], ['!build/tree.dart', '!test.unit.dart/run/angular2']);
|
watch(['modules/angular2/**'],
|
||||||
|
['!build/tree.dart', '!test.unit.dart/run/angular2']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -671,25 +662,21 @@ gulp.task('test.unit.dart', function(done) {
|
|||||||
// Measure in bytes.
|
// Measure in bytes.
|
||||||
var _DART_PAYLOAD_SIZE_LIMITS = {'uncompressed': 320 * 1024, 'gzip level=9': 90 * 1024};
|
var _DART_PAYLOAD_SIZE_LIMITS = {'uncompressed': 320 * 1024, 'gzip level=9': 90 * 1024};
|
||||||
gulp.task('test.payload.dart/ci', function(done) {
|
gulp.task('test.payload.dart/ci', function(done) {
|
||||||
runSequence(
|
runSequence('build/packages.dart', '!pubget.payload.dart', '!pubbuild.payload.dart',
|
||||||
'build/packages.dart', '!pubget.payload.dart', '!pubbuild.payload.dart',
|
|
||||||
'!checkAndReport.payload.dart', done);
|
'!checkAndReport.payload.dart', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('!pubget.payload.dart',
|
||||||
'!pubget.payload.dart',
|
pubget.dir(gulp, gulpPlugins,
|
||||||
pubget.dir(
|
{dir: 'modules_dart/payload/hello_world', command: DART_SDK.PUB}));
|
||||||
gulp, gulpPlugins, {dir: 'modules_dart/payload/hello_world', command: DART_SDK.PUB}));
|
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('!pubbuild.payload.dart',
|
||||||
'!pubbuild.payload.dart',
|
pubbuild.single(gulp, gulpPlugins,
|
||||||
pubbuild.single(
|
{command: DART_SDK.PUB, src: 'modules_dart/payload/hello_world'}));
|
||||||
gulp, gulpPlugins, {command: DART_SDK.PUB, src: 'modules_dart/payload/hello_world'}));
|
|
||||||
|
|
||||||
gulp.task('!checkAndReport.payload.dart', function() {
|
gulp.task('!checkAndReport.payload.dart', function() {
|
||||||
var reportSize = require('./tools/analytics/reportsize');
|
var reportSize = require('./tools/analytics/reportsize');
|
||||||
return reportSize(
|
return reportSize('modules_dart/payload/hello_world/build/web/*.dart.js',
|
||||||
'modules_dart/payload/hello_world/build/web/*.dart.js',
|
|
||||||
{failConditions: _DART_PAYLOAD_SIZE_LIMITS, prefix: 'hello_world'});
|
{failConditions: _DART_PAYLOAD_SIZE_LIMITS, prefix: 'hello_world'});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -714,7 +701,7 @@ gulp.task('!build.payload.js.webpack', function() {
|
|||||||
return webpack({
|
return webpack({
|
||||||
// bundle app + framework
|
// bundle app + framework
|
||||||
entry: CASE_PATH + '/index.js',
|
entry: CASE_PATH + '/index.js',
|
||||||
output: {path: CASE_PATH, filename: 'app-bundle.js'},
|
output: {path: CASE_PATH, filename: "app-bundle.js"},
|
||||||
resolve: {
|
resolve: {
|
||||||
extensions: ['', '.js'],
|
extensions: ['', '.js'],
|
||||||
packageAlias: '', // option added to ignore "broken" package.json in our dist folder
|
packageAlias: '', // option added to ignore "broken" package.json in our dist folder
|
||||||
@ -726,7 +713,8 @@ gulp.task('!build.payload.js.webpack', function() {
|
|||||||
gulp.src([
|
gulp.src([
|
||||||
'node_modules/zone.js/dist/zone.js',
|
'node_modules/zone.js/dist/zone.js',
|
||||||
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
||||||
'node_modules/reflect-metadata/Reflect.js', CASE_PATH + '/app-bundle.js'
|
'node_modules/reflect-metadata/Reflect.js',
|
||||||
|
CASE_PATH + '/app-bundle.js'
|
||||||
])
|
])
|
||||||
.pipe(gulpPlugins.concat(PAYLOAD_TESTS_CONFIG.ts.bundleName))
|
.pipe(gulpPlugins.concat(PAYLOAD_TESTS_CONFIG.ts.bundleName))
|
||||||
.pipe(gulpPlugins.uglify())
|
.pipe(gulpPlugins.uglify())
|
||||||
@ -756,8 +744,10 @@ gulp.task('!build.payload.js.systemjs', function() {
|
|||||||
gulp.src([
|
gulp.src([
|
||||||
'node_modules/systemjs/dist/system.src.js',
|
'node_modules/systemjs/dist/system.src.js',
|
||||||
'dist/js/prod/es5/bundle/angular2-polyfills.js',
|
'dist/js/prod/es5/bundle/angular2-polyfills.js',
|
||||||
'dist/js/prod/es5/bundle/angular2.js', 'dist/js/prod/es5//rxjs/bundles/Rx.js',
|
'dist/js/prod/es5/bundle/angular2.js',
|
||||||
CASE_PATH + '/index.register.js', 'tools/build/systemjs/payload_tests_import.js'
|
'dist/js/prod/es5//rxjs/bundles/Rx.js',
|
||||||
|
CASE_PATH + '/index.register.js',
|
||||||
|
'tools/build/systemjs/payload_tests_import.js'
|
||||||
])
|
])
|
||||||
.pipe(gulpPlugins.concat(PAYLOAD_TESTS_CONFIG.ts.bundleName))
|
.pipe(gulpPlugins.concat(PAYLOAD_TESTS_CONFIG.ts.bundleName))
|
||||||
.pipe(gulpPlugins.uglify())
|
.pipe(gulpPlugins.uglify())
|
||||||
@ -773,13 +763,12 @@ gulp.task('!checkAndReport.payload.js', function() {
|
|||||||
var reportSize = require('./tools/analytics/reportsize');
|
var reportSize = require('./tools/analytics/reportsize');
|
||||||
|
|
||||||
function caseSizeStream(caseName, packaging) {
|
function caseSizeStream(caseName, packaging) {
|
||||||
return reportSize(
|
return reportSize(PAYLOAD_TESTS_CONFIG.ts.dist(caseName, packaging) + '/' +
|
||||||
PAYLOAD_TESTS_CONFIG.ts.dist(caseName, packaging) + '/' +
|
|
||||||
PAYLOAD_TESTS_CONFIG.ts.bundleName,
|
PAYLOAD_TESTS_CONFIG.ts.bundleName,
|
||||||
{
|
{
|
||||||
failConditions: PAYLOAD_TESTS_CONFIG.ts[packaging].sizeLimits,
|
failConditions: PAYLOAD_TESTS_CONFIG.ts[packaging].sizeLimits,
|
||||||
prefix: caseName + '_' + packaging
|
prefix: caseName + '_' + packaging
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return PAYLOAD_TESTS_CONFIG.ts.cases.reduce(function(sizeReportingStreams, caseName) {
|
return PAYLOAD_TESTS_CONFIG.ts.cases.reduce(function(sizeReportingStreams, caseName) {
|
||||||
@ -789,8 +778,7 @@ gulp.task('!checkAndReport.payload.js', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('watch.dart.dev', function(done) {
|
gulp.task('watch.dart.dev', function(done) {
|
||||||
runSequence(
|
runSequence('build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
|
||||||
'build/tree.dart', 'build/pure-packages.dart', '!build/pubget.angular2.dart',
|
|
||||||
'!build/change_detect.dart', '!build/remove-pub-symlinks', function(error) {
|
'!build/change_detect.dart', '!build/remove-pub-symlinks', function(error) {
|
||||||
var watch = require('./tools/build/watch');
|
var watch = require('./tools/build/watch');
|
||||||
|
|
||||||
@ -809,8 +797,7 @@ gulp.task('test.unit.router/ci', function(done) {
|
|||||||
var karma = require('karma');
|
var karma = require('karma');
|
||||||
|
|
||||||
var browserConf = getBrowsersFromCLI();
|
var browserConf = getBrowsersFromCLI();
|
||||||
new karma
|
new karma.Server(
|
||||||
.Server(
|
|
||||||
{
|
{
|
||||||
configFile: __dirname + '/modules/angular1_router/karma-router.conf.js',
|
configFile: __dirname + '/modules/angular1_router/karma-router.conf.js',
|
||||||
singleRun: true,
|
singleRun: true,
|
||||||
@ -825,8 +812,7 @@ gulp.task('test.unit.js/ci', function(done) {
|
|||||||
var karma = require('karma');
|
var karma = require('karma');
|
||||||
|
|
||||||
var browserConf = getBrowsersFromCLI();
|
var browserConf = getBrowsersFromCLI();
|
||||||
new karma
|
new karma.Server(
|
||||||
.Server(
|
|
||||||
{
|
{
|
||||||
configFile: __dirname + '/karma-js.conf.js',
|
configFile: __dirname + '/karma-js.conf.js',
|
||||||
singleRun: true,
|
singleRun: true,
|
||||||
@ -854,8 +840,7 @@ gulp.task('test.unit.js.browserstack/ci', function(done) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('test.unit.dart/ci', function(done) {
|
gulp.task('test.unit.dart/ci', function(done) {
|
||||||
runSequence(
|
runSequence('test.dart.dartium_symlink', '!test.unit.dart/run/angular2',
|
||||||
'test.dart.dartium_symlink', '!test.unit.dart/run/angular2',
|
|
||||||
'!test.unit.dart/run/angular2_testing', '!test.unit.dart/run/benchpress',
|
'!test.unit.dart/run/angular2_testing', '!test.unit.dart/run/benchpress',
|
||||||
sequenceComplete(done));
|
sequenceComplete(done));
|
||||||
});
|
});
|
||||||
@ -910,9 +895,8 @@ gulp.task('test.unit.cjs/ci', function(done) {
|
|||||||
runJasmineTests(['dist/js/cjs/{angular2,benchpress}/test/**/*_spec.js'], done);
|
runJasmineTests(['dist/js/cjs/{angular2,benchpress}/test/**/*_spec.js'], done);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('check-public-api', function(done) {
|
gulp.task('check-public-api',
|
||||||
runJasmineTests(['dist/tools/public_api_guard/**/*_spec.js'], done);
|
function(done) { runJasmineTests(['dist/tools/public_api_guard/**/*_spec.js'], done); });
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone) {
|
gulp.task('test.unit.cjs', ['build/clean.js', 'build.tools'], function(neverDone) {
|
||||||
var watch = require('./tools/build/watch');
|
var watch = require('./tools/build/watch');
|
||||||
@ -933,21 +917,19 @@ gulp.task('test.unit.dartvm', function(neverDone) {
|
|||||||
// Watch for changes made in the TS and Dart code under "modules" and
|
// Watch for changes made in the TS and Dart code under "modules" and
|
||||||
// run ts2dart and test change detector generator prior to rerunning the
|
// run ts2dart and test change detector generator prior to rerunning the
|
||||||
// tests.
|
// tests.
|
||||||
watch(
|
watch('modules/angular2/**', {ignoreInitial: true},
|
||||||
'modules/angular2/**', {ignoreInitial: true},
|
|
||||||
['!build/tree.dart', '!build/change_detect.dart', '!test.unit.dartvm/run']);
|
['!build/tree.dart', '!build/change_detect.dart', '!test.unit.dartvm/run']);
|
||||||
|
|
||||||
// Watch for changes made in Dart code under "modules_dart", then copy it
|
// Watch for changes made in Dart code under "modules_dart", then copy it
|
||||||
// to dist and run test change detector generator prior to retunning the
|
// to dist and run test change detector generator prior to retunning the
|
||||||
// tests.
|
// tests.
|
||||||
watch(
|
watch('modules_dart/**', {ignoreInitial: true},
|
||||||
'modules_dart/**', {ignoreInitial: true},
|
|
||||||
['build/pure-packages.dart', '!build/change_detect.dart', '!test.unit.dartvm/run']);
|
['build/pure-packages.dart', '!build/change_detect.dart', '!test.unit.dartvm/run']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('!test.unit.dartvm/run',
|
||||||
'!test.unit.dartvm/run', runServerDartTests(gulp, gulpPlugins, {dir: 'dist/dart/angular2'}));
|
runServerDartTests(gulp, gulpPlugins, {dir: 'dist/dart/angular2'}));
|
||||||
|
|
||||||
|
|
||||||
gulp.task('test.unit.tools/ci', function(done) {
|
gulp.task('test.unit.tools/ci', function(done) {
|
||||||
@ -971,9 +953,8 @@ gulp.task('test.server.dart', runServerDartTests(gulp, gulpPlugins, {dest: 'dist
|
|||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// test builders
|
// test builders
|
||||||
gulp.task('test.transpiler.unittest', function(done) {
|
gulp.task('test.transpiler.unittest',
|
||||||
runJasmineTests(['tools/transpiler/unittest/**/*.js'], done);
|
function(done) { runJasmineTests(['tools/transpiler/unittest/**/*.js'], done); });
|
||||||
});
|
|
||||||
|
|
||||||
// -----------------
|
// -----------------
|
||||||
// Pre-test checks
|
// Pre-test checks
|
||||||
@ -1008,8 +989,7 @@ gulp.task('!pre.test.typings.layoutNodeModule', ['build.js.cjs'], function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('!pre.test.typings.copyDeps', function() {
|
gulp.task('!pre.test.typings.copyDeps', function() {
|
||||||
return gulp
|
return gulp.src(
|
||||||
.src(
|
|
||||||
[
|
[
|
||||||
'modules/angular2/typings/angular-protractor/*.ts',
|
'modules/angular2/typings/angular-protractor/*.ts',
|
||||||
'modules/angular2/typings/jasmine/*.ts',
|
'modules/angular2/typings/jasmine/*.ts',
|
||||||
@ -1023,16 +1003,17 @@ gulp.task('!pre.test.typings.copyTypingsSpec', function() {
|
|||||||
return gulp.src(['modules/angular2/examples/**/*.ts']).pipe(gulp.dest(tmpdir));
|
return gulp.src(['modules/angular2/examples/**/*.ts']).pipe(gulp.dest(tmpdir));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('test.typings',
|
||||||
'test.typings',
|
|
||||||
[
|
[
|
||||||
'!pre.test.typings.layoutNodeModule', '!pre.test.typings.copyTypingsSpec',
|
'!pre.test.typings.layoutNodeModule',
|
||||||
|
'!pre.test.typings.copyTypingsSpec',
|
||||||
'!pre.test.typings.copyDeps'
|
'!pre.test.typings.copyDeps'
|
||||||
],
|
],
|
||||||
function() {
|
function() {
|
||||||
var tsc = require('gulp-typescript');
|
var tsc = require('gulp-typescript');
|
||||||
|
|
||||||
return gulp.src([tmpdir + '/**/*.ts', '!' + tmpdir + '/node_modules/**/*']).pipe(tsc({
|
return gulp.src([tmpdir + '/**/*.ts', '!' + tmpdir + '/node_modules/**/*'])
|
||||||
|
.pipe(tsc({
|
||||||
target: 'ES6',
|
target: 'ES6',
|
||||||
module: 'commonjs',
|
module: 'commonjs',
|
||||||
experimentalDecorators: true,
|
experimentalDecorators: true,
|
||||||
@ -1051,15 +1032,13 @@ gulp.task(
|
|||||||
//
|
//
|
||||||
// This task is expected to be run after build/tree.dart
|
// This task is expected to be run after build/tree.dart
|
||||||
gulp.task('build/pure-packages.dart', function(done) {
|
gulp.task('build/pure-packages.dart', function(done) {
|
||||||
runSequence(
|
runSequence('build/pure-packages.dart/standalone', 'build/pure-packages.dart/license',
|
||||||
'build/pure-packages.dart/standalone', 'build/pure-packages.dart/license',
|
|
||||||
'build/pure-packages.dart/angular2', sequenceComplete(done));
|
'build/pure-packages.dart/angular2', sequenceComplete(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
gulp.task('build/pure-packages.dart/standalone', function() {
|
gulp.task('build/pure-packages.dart/standalone', function() {
|
||||||
return gulp
|
return gulp.src([
|
||||||
.src([
|
|
||||||
'modules_dart/**/*',
|
'modules_dart/**/*',
|
||||||
'!modules_dart/**/*.proto',
|
'!modules_dart/**/*.proto',
|
||||||
'!modules_dart/**/packages{,/**}',
|
'!modules_dart/**/packages{,/**}',
|
||||||
@ -1076,8 +1055,7 @@ gulp.task('build/pure-packages.dart/license', function() {
|
|||||||
|
|
||||||
|
|
||||||
gulp.task('build/pure-packages.dart/angular2', function() {
|
gulp.task('build/pure-packages.dart/angular2', function() {
|
||||||
return gulp
|
return gulp.src([
|
||||||
.src([
|
|
||||||
'modules_dart/transform/**/*',
|
'modules_dart/transform/**/*',
|
||||||
'!modules_dart/transform/**/*.proto',
|
'!modules_dart/transform/**/*.proto',
|
||||||
'!modules_dart/transform/pubspec.yaml',
|
'!modules_dart/transform/pubspec.yaml',
|
||||||
@ -1088,24 +1066,21 @@ gulp.task('build/pure-packages.dart/angular2', function() {
|
|||||||
|
|
||||||
// Builds all Dart packages, but does not compile them
|
// Builds all Dart packages, but does not compile them
|
||||||
gulp.task('build/packages.dart', function(done) {
|
gulp.task('build/packages.dart', function(done) {
|
||||||
runSequence(
|
runSequence('lint_protos.dart', 'build/tree.dart', 'build/pure-packages.dart',
|
||||||
'lint_protos.dart', 'build/tree.dart', 'build/pure-packages.dart',
|
|
||||||
// Run after 'build/tree.dart' because broccoli clears the dist/dart folder
|
// Run after 'build/tree.dart' because broccoli clears the dist/dart folder
|
||||||
'!build/pubget.angular2.dart', '!build/change_detect.dart', sequenceComplete(done));
|
'!build/pubget.angular2.dart', '!build/change_detect.dart', sequenceComplete(done));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Builds and compiles all Dart packages
|
// Builds and compiles all Dart packages
|
||||||
gulp.task('build.dart', function(done) {
|
gulp.task('build.dart', function(done) {
|
||||||
runSequence(
|
runSequence('build/packages.dart', 'build/pubspec.dart', 'build/analyze.dart',
|
||||||
'build/packages.dart', 'build/pubspec.dart', 'build/analyze.dart', 'build/check.apidocs.dart',
|
'build/check.apidocs.dart', sequenceComplete(done));
|
||||||
sequenceComplete(done));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// public task to build tools
|
// public task to build tools
|
||||||
gulp.task('build.tools', ['build/clean.tools'], function(done) {
|
gulp.task('build.tools', ['build/clean.tools'],
|
||||||
runSequence('!build.tools', sequenceComplete(done));
|
function(done) { runSequence('!build.tools', sequenceComplete(done)); });
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// private task to build tools
|
// private task to build tools
|
||||||
@ -1113,7 +1088,9 @@ gulp.task('!build.tools', function() {
|
|||||||
var sourcemaps = require('gulp-sourcemaps');
|
var sourcemaps = require('gulp-sourcemaps');
|
||||||
var tsc = require('gulp-typescript');
|
var tsc = require('gulp-typescript');
|
||||||
|
|
||||||
var stream = gulp.src(['tools/**/*.ts']).pipe(sourcemaps.init()).pipe(tsc({
|
var stream = gulp.src(['tools/**/*.ts'])
|
||||||
|
.pipe(sourcemaps.init())
|
||||||
|
.pipe(tsc({
|
||||||
target: 'ES5',
|
target: 'ES5',
|
||||||
module: 'commonjs',
|
module: 'commonjs',
|
||||||
declaration: true,
|
declaration: true,
|
||||||
@ -1140,9 +1117,8 @@ gulp.task('!build.tools', function() {
|
|||||||
return stream;
|
return stream;
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('broccoli.js.dev', ['build.tools'], function(done) {
|
gulp.task('broccoli.js.dev', ['build.tools'],
|
||||||
runSequence('!broccoli.js.dev', sequenceComplete(done));
|
function(done) { runSequence('!broccoli.js.dev', sequenceComplete(done)); });
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('!broccoli.js.dev', () => angularBuilder.rebuildBrowserDevTree({
|
gulp.task('!broccoli.js.dev', () => angularBuilder.rebuildBrowserDevTree({
|
||||||
generateEs6: generateEs6,
|
generateEs6: generateEs6,
|
||||||
@ -1158,21 +1134,18 @@ gulp.task('!broccoli.js.prod', () => angularBuilder.rebuildBrowserProdTree({
|
|||||||
useBundles: cliArgs.useBundles
|
useBundles: cliArgs.useBundles
|
||||||
}));
|
}));
|
||||||
|
|
||||||
gulp.task('build.js.dev', ['build/clean.js'], function(done) {
|
gulp.task('build.js.dev', ['build/clean.js'],
|
||||||
runSequence('broccoli.js.dev', sequenceComplete(done));
|
function(done) { runSequence('broccoli.js.dev', sequenceComplete(done)); });
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task('build.js.prod', ['build.tools'], function(done) {
|
gulp.task('build.js.prod', ['build.tools'],
|
||||||
runSequence('!broccoli.js.prod', sequenceComplete(done));
|
function(done) { runSequence('!broccoli.js.prod', sequenceComplete(done)); });
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* public task
|
* public task
|
||||||
*/
|
*/
|
||||||
gulp.task('build.js.cjs', ['build.tools'], function(done) {
|
gulp.task('build.js.cjs', ['build.tools'],
|
||||||
runSequence('!build.js.cjs', sequenceComplete(done));
|
function(done) { runSequence('!build.js.cjs', sequenceComplete(done)); });
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
var firstBuildJsCjs = true;
|
var firstBuildJsCjs = true;
|
||||||
@ -1181,8 +1154,7 @@ var firstBuildJsCjs = true;
|
|||||||
* private task
|
* private task
|
||||||
*/
|
*/
|
||||||
gulp.task('!build.js.cjs', function() {
|
gulp.task('!build.js.cjs', function() {
|
||||||
return angularBuilder
|
return angularBuilder.rebuildNodeTree({
|
||||||
.rebuildNodeTree({
|
|
||||||
generateEs6: generateEs6,
|
generateEs6: generateEs6,
|
||||||
projects: cliArgsProjects,
|
projects: cliArgsProjects,
|
||||||
noTypeChecks: cliArgs.noTypeChecks,
|
noTypeChecks: cliArgs.noTypeChecks,
|
||||||
@ -1200,7 +1172,7 @@ gulp.task('!build.js.cjs', function() {
|
|||||||
|
|
||||||
|
|
||||||
var bundleConfig = {
|
var bundleConfig = {
|
||||||
paths: {'*': 'dist/js/prod/es5/*.js'},
|
paths: {"*": "dist/js/prod/es5/*.js"},
|
||||||
// Files that end up empty after transpilation confuse system-builder
|
// Files that end up empty after transpilation confuse system-builder
|
||||||
// and need to be explitily listed here.
|
// and need to be explitily listed here.
|
||||||
// TODO: upgrade system builder and find a way to declare all input as cjs.
|
// TODO: upgrade system builder and find a way to declare all input as cjs.
|
||||||
@ -1220,10 +1192,10 @@ gulp.task('!bundle.js.prod', ['build.js.prod'], function() {
|
|||||||
.then(function() {
|
.then(function() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
bundler.bundle(bundleConfig, HTTP_BUNDLE_CONTENT, './dist/build/http.js', bundlerConfig),
|
bundler.bundle(bundleConfig, HTTP_BUNDLE_CONTENT, './dist/build/http.js', bundlerConfig),
|
||||||
bundler.bundle(
|
bundler.bundle(bundleConfig, ROUTER_BUNDLE_CONTENT, './dist/build/router.js',
|
||||||
bundleConfig, ROUTER_BUNDLE_CONTENT, './dist/build/router.js', bundlerConfig),
|
bundlerConfig),
|
||||||
bundler.bundle(
|
bundler.bundle(bundleConfig, UPGRADE_BUNDLE_CONTENT, './dist/build/upgrade.js',
|
||||||
bundleConfig, UPGRADE_BUNDLE_CONTENT, './dist/build/upgrade.js', bundlerConfig)
|
bundlerConfig)
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1234,16 +1206,16 @@ gulp.task('!bundle.js.min', ['build.js.prod'], function() {
|
|||||||
var bundlerConfig =
|
var bundlerConfig =
|
||||||
{sourceMaps: true, minify: true, mangle: false, uglify: {compress: {keep_fnames: true}}};
|
{sourceMaps: true, minify: true, mangle: false, uglify: {compress: {keep_fnames: true}}};
|
||||||
|
|
||||||
return bundler
|
return bundler.bundle(bundleConfig, NG2_BUNDLE_CONTENT, './dist/build/angular2.min.js',
|
||||||
.bundle(bundleConfig, NG2_BUNDLE_CONTENT, './dist/build/angular2.min.js', bundlerConfig)
|
bundlerConfig)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
bundler.bundle(
|
bundler.bundle(bundleConfig, HTTP_BUNDLE_CONTENT, './dist/build/http.min.js',
|
||||||
bundleConfig, HTTP_BUNDLE_CONTENT, './dist/build/http.min.js', bundlerConfig),
|
bundlerConfig),
|
||||||
bundler.bundle(
|
bundler.bundle(bundleConfig, ROUTER_BUNDLE_CONTENT, './dist/build/router.min.js',
|
||||||
bundleConfig, ROUTER_BUNDLE_CONTENT, './dist/build/router.min.js', bundlerConfig),
|
bundlerConfig),
|
||||||
bundler.bundle(
|
bundler.bundle(bundleConfig, UPGRADE_BUNDLE_CONTENT, './dist/build/upgrade.min.js',
|
||||||
bundleConfig, UPGRADE_BUNDLE_CONTENT, './dist/build/upgrade.min.js', bundlerConfig)
|
bundlerConfig)
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -1254,37 +1226,34 @@ gulp.task('!bundle.js.dev', ['build.js.dev'], function() {
|
|||||||
var bundlerConfig = {sourceMaps: true};
|
var bundlerConfig = {sourceMaps: true};
|
||||||
|
|
||||||
var devBundleConfig = merge(true, bundleConfig);
|
var devBundleConfig = merge(true, bundleConfig);
|
||||||
devBundleConfig.paths = merge(true, devBundleConfig.paths, {'*': 'dist/js/dev/es5/*.js'});
|
devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"});
|
||||||
|
|
||||||
return bundler
|
return bundler.bundle(devBundleConfig, NG2_BUNDLE_CONTENT, './dist/build/angular2.dev.js',
|
||||||
.bundle(devBundleConfig, NG2_BUNDLE_CONTENT, './dist/build/angular2.dev.js', bundlerConfig)
|
bundlerConfig)
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
bundler.bundle(
|
bundler.bundle(devBundleConfig, HTTP_BUNDLE_CONTENT, './dist/build/http.dev.js',
|
||||||
devBundleConfig, HTTP_BUNDLE_CONTENT, './dist/build/http.dev.js', bundlerConfig),
|
bundlerConfig),
|
||||||
bundler.bundle(
|
bundler.bundle(devBundleConfig, ROUTER_BUNDLE_CONTENT, './dist/build/router.dev.js',
|
||||||
devBundleConfig, ROUTER_BUNDLE_CONTENT, './dist/build/router.dev.js', bundlerConfig),
|
bundlerConfig),
|
||||||
bundler.bundle(
|
bundler.bundle(devBundleConfig, UPGRADE_BUNDLE_CONTENT, './dist/build/upgrade.dev.js',
|
||||||
devBundleConfig, UPGRADE_BUNDLE_CONTENT, './dist/build/upgrade.dev.js', bundlerConfig)
|
bundlerConfig)
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// WebWorker build
|
// WebWorker build
|
||||||
gulp.task('!bundle.web_worker.js.dev', ['build.js.dev'], function() {
|
gulp.task("!bundle.web_worker.js.dev", ["build.js.dev"], function() {
|
||||||
var bundler = require('./tools/build/bundle');
|
var bundler = require('./tools/build/bundle');
|
||||||
var devBundleConfig = merge(true, bundleConfig);
|
var devBundleConfig = merge(true, bundleConfig);
|
||||||
|
|
||||||
devBundleConfig.paths = merge(true, devBundleConfig.paths, {'*': 'dist/js/dev/es5/*.js'});
|
devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"});
|
||||||
|
|
||||||
return bundler
|
return bundler.bundle(devBundleConfig, 'angular2/web_worker/ui',
|
||||||
.bundle(
|
'./dist/build/web_worker/ui.dev.js', {sourceMaps: true})
|
||||||
devBundleConfig, 'angular2/web_worker/ui', './dist/build/web_worker/ui.dev.js',
|
|
||||||
{sourceMaps: true})
|
|
||||||
.then(function() {
|
.then(function() {
|
||||||
return bundler.bundle(
|
return bundler.bundle(devBundleConfig, 'angular2/web_worker/worker',
|
||||||
devBundleConfig, 'angular2/web_worker/worker', './dist/build/web_worker/worker.dev.js',
|
'./dist/build/web_worker/worker.dev.js', {sourceMaps: true});
|
||||||
{sourceMaps: true});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1292,10 +1261,9 @@ gulp.task('!bundle.testing', ['build.js.dev'], function() {
|
|||||||
var bundler = require('./tools/build/bundle');
|
var bundler = require('./tools/build/bundle');
|
||||||
|
|
||||||
var devBundleConfig = merge(true, bundleConfig);
|
var devBundleConfig = merge(true, bundleConfig);
|
||||||
devBundleConfig.paths = merge(true, devBundleConfig.paths, {'*': 'dist/js/dev/es5/*.js'});
|
devBundleConfig.paths = merge(true, devBundleConfig.paths, {"*": "dist/js/dev/es5/*.js"});
|
||||||
|
|
||||||
return bundler.bundle(
|
return bundler.bundle(devBundleConfig, TESTING_BUNDLE_CONTENT, './dist/js/bundle/testing.dev.js',
|
||||||
devBundleConfig, TESTING_BUNDLE_CONTENT, './dist/js/bundle/testing.dev.js',
|
|
||||||
{sourceMaps: true});
|
{sourceMaps: true});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1362,13 +1330,12 @@ gulp.task('!bundles.js.umd', ['build.js.dev'], function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return q.all([
|
return q.all([
|
||||||
webpack(webPackConf(
|
webpack(webPackConf([__dirname + '/tools/build/webpack/angular2-all.umd.js'], 'angular2-all',
|
||||||
[__dirname + '/tools/build/webpack/angular2-all.umd.js'], 'angular2-all', 'dev')),
|
'dev')),
|
||||||
webpack(webPackConf(
|
webpack(webPackConf([__dirname + '/tools/build/webpack/angular2-all.umd.js'], 'angular2-all',
|
||||||
[__dirname + '/tools/build/webpack/angular2-all.umd.js'], 'angular2-all', 'prod')),
|
'prod')),
|
||||||
webpack(webPackConf(
|
webpack(webPackConf([__dirname + '/tools/build/webpack/angular2-all-testing.umd.js'],
|
||||||
[__dirname + '/tools/build/webpack/angular2-all-testing.umd.js'], 'angular2-all-testing',
|
'angular2-all-testing', 'dev'))
|
||||||
'dev'))
|
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1386,8 +1353,7 @@ gulp.task('bundles.js.umd.min', ['!bundles.js.umd', '!bundle.ng.polyfills'], fun
|
|||||||
gulp.task('!bundle.js.prod.deps', ['!bundle.js.prod'], function() {
|
gulp.task('!bundle.js.prod.deps', ['!bundle.js.prod'], function() {
|
||||||
var bundler = require('./tools/build/bundle');
|
var bundler = require('./tools/build/bundle');
|
||||||
|
|
||||||
return merge2(
|
return merge2(bundler.modify(['dist/build/angular2.js'], 'angular2.js'),
|
||||||
bundler.modify(['dist/build/angular2.js'], 'angular2.js'),
|
|
||||||
bundler.modify(['dist/build/http.js'], 'http.js'),
|
bundler.modify(['dist/build/http.js'], 'http.js'),
|
||||||
bundler.modify(['dist/build/router.js'], 'router.js'),
|
bundler.modify(['dist/build/router.js'], 'router.js'),
|
||||||
bundler.modify(['dist/build/upgrade.js'], 'upgrade.js'))
|
bundler.modify(['dist/build/upgrade.js'], 'upgrade.js'))
|
||||||
@ -1398,8 +1364,7 @@ gulp.task('!bundle.js.min.deps', ['!bundle.js.min'], function() {
|
|||||||
var bundler = require('./tools/build/bundle');
|
var bundler = require('./tools/build/bundle');
|
||||||
var uglify = require('gulp-uglify');
|
var uglify = require('gulp-uglify');
|
||||||
|
|
||||||
return merge2(
|
return merge2(bundler.modify(['dist/build/angular2.min.js'], 'angular2.min.js'),
|
||||||
bundler.modify(['dist/build/angular2.min.js'], 'angular2.min.js'),
|
|
||||||
bundler.modify(['dist/build/http.min.js'], 'http.min.js'),
|
bundler.modify(['dist/build/http.min.js'], 'http.min.js'),
|
||||||
bundler.modify(['dist/build/router.min.js'], 'router.min.js'),
|
bundler.modify(['dist/build/router.min.js'], 'router.min.js'),
|
||||||
bundler.modify(['dist/build/upgrade.min.js'], 'upgrade.min.js'))
|
bundler.modify(['dist/build/upgrade.min.js'], 'upgrade.min.js'))
|
||||||
@ -1407,12 +1372,12 @@ gulp.task('!bundle.js.min.deps', ['!bundle.js.min'], function() {
|
|||||||
.pipe(gulp.dest('dist/js/bundle'));
|
.pipe(gulp.dest('dist/js/bundle'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('!bundle.ng.polyfills', ['clean'], function() {
|
gulp.task('!bundle.ng.polyfills', ['clean'],
|
||||||
return addDevDependencies('angular2-polyfills.js');
|
function() { return addDevDependencies('angular2-polyfills.js'); });
|
||||||
});
|
|
||||||
|
|
||||||
var JS_DEV_DEPS = [
|
var JS_DEV_DEPS = [
|
||||||
licenseWrap('node_modules/zone.js/LICENSE', true), 'node_modules/zone.js/dist/zone.js',
|
licenseWrap('node_modules/zone.js/LICENSE', true),
|
||||||
|
'node_modules/zone.js/dist/zone.js',
|
||||||
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
||||||
licenseWrap('node_modules/reflect-metadata/LICENSE', true),
|
licenseWrap('node_modules/reflect-metadata/LICENSE', true),
|
||||||
'node_modules/reflect-metadata/Reflect.js'
|
'node_modules/reflect-metadata/Reflect.js'
|
||||||
@ -1430,8 +1395,7 @@ function addDevDependencies(outputFile) {
|
|||||||
gulp.task('!bundle.js.dev.deps', ['!bundle.js.dev'], function() {
|
gulp.task('!bundle.js.dev.deps', ['!bundle.js.dev'], function() {
|
||||||
var bundler = require('./tools/build/bundle');
|
var bundler = require('./tools/build/bundle');
|
||||||
|
|
||||||
return merge2(
|
return merge2(bundler.modify(['dist/build/angular2.dev.js'], 'angular2.dev.js'),
|
||||||
bundler.modify(['dist/build/angular2.dev.js'], 'angular2.dev.js'),
|
|
||||||
bundler.modify(['dist/build/http.dev.js'], 'http.dev.js'),
|
bundler.modify(['dist/build/http.dev.js'], 'http.dev.js'),
|
||||||
bundler.modify(['dist/build/router.dev.js'], 'router.dev.js'),
|
bundler.modify(['dist/build/router.dev.js'], 'router.dev.js'),
|
||||||
bundler.modify(['dist/build/upgrade.dev.js'], 'upgrade.dev.js'))
|
bundler.modify(['dist/build/upgrade.dev.js'], 'upgrade.dev.js'))
|
||||||
@ -1440,15 +1404,13 @@ gulp.task('!bundle.js.dev.deps', ['!bundle.js.dev'], function() {
|
|||||||
|
|
||||||
gulp.task('!bundle.web_worker.js.dev.deps', ['!bundle.web_worker.js.dev'], function() {
|
gulp.task('!bundle.web_worker.js.dev.deps', ['!bundle.web_worker.js.dev'], function() {
|
||||||
var bundler = require('./tools/build/bundle');
|
var bundler = require('./tools/build/bundle');
|
||||||
return merge2(
|
return merge2(bundler.modify(['dist/build/web_worker/ui.dev.js'], "web_worker/ui.dev.js"),
|
||||||
bundler.modify(['dist/build/web_worker/ui.dev.js'], 'web_worker/ui.dev.js'),
|
bundler.modify(['dist/build/web_worker/worker.dev.js'], "web_worker/worker.dev.js"))
|
||||||
bundler.modify(['dist/build/web_worker/worker.dev.js'], 'web_worker/worker.dev.js'))
|
|
||||||
.pipe(gulp.dest('dist/js/bundle'));
|
.pipe(gulp.dest('dist/js/bundle'));
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('!bundle.copy', function() {
|
gulp.task('!bundle.copy', function() {
|
||||||
return merge2(
|
return merge2(gulp.src('dist/js/bundle/**').pipe(gulp.dest('dist/js/prod/es5/bundle')),
|
||||||
gulp.src('dist/js/bundle/**').pipe(gulp.dest('dist/js/prod/es5/bundle')),
|
|
||||||
gulp.src('dist/js/bundle/**').pipe(gulp.dest('dist/js/dev/es5/bundle')));
|
gulp.src('dist/js/bundle/**').pipe(gulp.dest('dist/js/dev/es5/bundle')));
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1457,21 +1419,27 @@ gulp.task('!bundles.js.checksize', function(done) {
|
|||||||
return reportSize('dist/js/bundle/**/*.js', {printToConsole: ['gzip level=2']});
|
return reportSize('dist/js/bundle/**/*.js', {printToConsole: ['gzip level=2']});
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('bundles.js',
|
||||||
'bundles.js',
|
|
||||||
[
|
[
|
||||||
'!bundle.js.prod.deps', '!bundle.js.dev.deps', '!bundle.js.min.deps',
|
'!bundle.js.prod.deps',
|
||||||
'!bundle.web_worker.js.dev.deps', 'bundles.js.umd.min', '!bundle.testing',
|
'!bundle.js.dev.deps',
|
||||||
'!bundle.ng.polyfills', '!bundles.js.docs'
|
'!bundle.js.min.deps',
|
||||||
|
'!bundle.web_worker.js.dev.deps',
|
||||||
|
'bundles.js.umd.min',
|
||||||
|
'!bundle.testing',
|
||||||
|
'!bundle.ng.polyfills',
|
||||||
|
'!bundles.js.docs'
|
||||||
],
|
],
|
||||||
function(done) { runSequence('!bundle.copy', '!bundles.js.checksize', done); });
|
function(done) { runSequence('!bundle.copy', '!bundles.js.checksize', done); });
|
||||||
|
|
||||||
gulp.task(
|
gulp.task('build.js',
|
||||||
'build.js',
|
|
||||||
['build.js.dev', 'build.js.prod', 'build.js.cjs', 'bundles.js', 'benchpress.bundle']);
|
['build.js.dev', 'build.js.prod', 'build.js.cjs', 'bundles.js', 'benchpress.bundle']);
|
||||||
|
|
||||||
gulp.task('clean', [
|
gulp.task('clean', [
|
||||||
'build/clean.tools', 'build/clean.js', 'build/clean.dart', 'build/clean.docs',
|
'build/clean.tools',
|
||||||
|
'build/clean.js',
|
||||||
|
'build/clean.dart',
|
||||||
|
'build/clean.docs',
|
||||||
'build/clean.bundles'
|
'build/clean.bundles'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -1498,8 +1466,8 @@ gulp.task('gen_protos.dart', function(done) {
|
|||||||
|
|
||||||
// change detection codegen
|
// change detection codegen
|
||||||
gulp.task('build.change_detect.dart', function(done) {
|
gulp.task('build.change_detect.dart', function(done) {
|
||||||
return runSequence(
|
return runSequence('build/packages.dart', '!build/pubget.angular2.dart',
|
||||||
'build/packages.dart', '!build/pubget.angular2.dart', '!build/change_detect.dart', done);
|
'!build/change_detect.dart', done);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('!build/change_detect.dart', function(done) {
|
gulp.task('!build/change_detect.dart', function(done) {
|
||||||
@ -1514,9 +1482,8 @@ gulp.task('!build/change_detect.dart', function(done) {
|
|||||||
var genMain = path.join(srcDir, 'gen_change_detectors.dart');
|
var genMain = path.join(srcDir, 'gen_change_detectors.dart');
|
||||||
var proc = spawn(DART_SDK.VM, [genMain], {stdio: ['ignore', 'pipe', 'inherit']});
|
var proc = spawn(DART_SDK.VM, [genMain], {stdio: ['ignore', 'pipe', 'inherit']});
|
||||||
proc.on('error', function(code) {
|
proc.on('error', function(code) {
|
||||||
done(new Error(
|
done(new Error('Failed while generating change detector classes. Please run manually: ' +
|
||||||
'Failed while generating change detector classes. Please run manually: ' + DART_SDK.VM +
|
DART_SDK.VM + ' ' + dartArgs.join(' ')));
|
||||||
' ' + dartArgs.join(' ')));
|
|
||||||
});
|
});
|
||||||
proc.on('close', function() {
|
proc.on('close', function() {
|
||||||
dartStream.close();
|
dartStream.close();
|
||||||
@ -1532,8 +1499,7 @@ gulp.task('cleanup.builder', function() { return angularBuilder.cleanup(); });
|
|||||||
gulp.task('benchpress.bundle', ['build/clean.bundles.benchpress', 'build.js.cjs'], function(cb) {
|
gulp.task('benchpress.bundle', ['build/clean.bundles.benchpress', 'build.js.cjs'], function(cb) {
|
||||||
var bundler = require('./tools/build/bundle');
|
var bundler = require('./tools/build/bundle');
|
||||||
|
|
||||||
bundler.benchpressBundle(
|
bundler.benchpressBundle(BENCHPRESS_BUNDLE_CONFIG.entries, BENCHPRESS_BUNDLE_CONFIG.packageJson,
|
||||||
BENCHPRESS_BUNDLE_CONFIG.entries, BENCHPRESS_BUNDLE_CONFIG.packageJson,
|
|
||||||
BENCHPRESS_BUNDLE_CONFIG.includes, BENCHPRESS_BUNDLE_CONFIG.excludes,
|
BENCHPRESS_BUNDLE_CONFIG.includes, BENCHPRESS_BUNDLE_CONFIG.excludes,
|
||||||
BENCHPRESS_BUNDLE_CONFIG.ignore, BENCHPRESS_BUNDLE_CONFIG.dest, cb);
|
BENCHPRESS_BUNDLE_CONFIG.ignore, BENCHPRESS_BUNDLE_CONFIG.dest, cb);
|
||||||
});
|
});
|
||||||
@ -1571,7 +1537,7 @@ gulp.on('task_start', (e) => {
|
|||||||
analytics.buildSuccess('gulp <startup>', process.uptime() * 1000);
|
analytics.buildSuccess('gulp <startup>', process.uptime() * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
analytics.buildStart('gulp ' + e.task);
|
analytics.buildStart('gulp ' + e.task)
|
||||||
});
|
});
|
||||||
gulp.on('task_stop', (e) => { analytics.buildSuccess('gulp ' + e.task, e.duration * 1000); });
|
gulp.on('task_stop', (e) => {analytics.buildSuccess('gulp ' + e.task, e.duration * 1000)});
|
||||||
gulp.on('task_err', (e) => { analytics.buildError('gulp ' + e.task, e.duration * 1000); });
|
gulp.on('task_err', (e) => {analytics.buildError('gulp ' + e.task, e.duration * 1000)});
|
||||||
|
@ -165,8 +165,8 @@ function routerTriggerDirective($q) {
|
|||||||
var currentComponent = outlet.currentController =
|
var currentComponent = outlet.currentController =
|
||||||
element.controller(ngOutletCtrl.$$componentName);
|
element.controller(ngOutletCtrl.$$componentName);
|
||||||
if (currentComponent.$routerOnActivate) {
|
if (currentComponent.$routerOnActivate) {
|
||||||
promise = $q.when(currentComponent.$routerOnActivate(
|
promise = $q.when(currentComponent.$routerOnActivate(outlet.currentInstruction,
|
||||||
outlet.currentInstruction, outlet.previousInstruction));
|
outlet.previousInstruction));
|
||||||
}
|
}
|
||||||
promise.then(outlet.deferredActivation.resolve, outlet.deferredActivation.reject);
|
promise.then(outlet.deferredActivation.resolve, outlet.deferredActivation.reject);
|
||||||
}
|
}
|
||||||
@ -213,8 +213,7 @@ function ngLinkDirective($rootRouter, $parse) {
|
|||||||
function getLink(params) {
|
function getLink(params) {
|
||||||
navigationInstruction = router.generate(params);
|
navigationInstruction = router.generate(params);
|
||||||
|
|
||||||
scope.$watch(
|
scope.$watch(function() { return router.isRouteActive(navigationInstruction); },
|
||||||
function() { return router.isRouteActive(navigationInstruction); },
|
|
||||||
function(active) {
|
function(active) {
|
||||||
if (active) {
|
if (active) {
|
||||||
element.addClass('ng-link-active');
|
element.addClass('ng-link-active');
|
||||||
@ -233,8 +232,8 @@ function ngLinkDirective($rootRouter, $parse) {
|
|||||||
let params = routeParamsGetter();
|
let params = routeParamsGetter();
|
||||||
element.attr('href', getLink(params));
|
element.attr('href', getLink(params));
|
||||||
} else {
|
} else {
|
||||||
scope.$watch(
|
scope.$watch(() => routeParamsGetter(scope), params => element.attr('href', getLink(params)),
|
||||||
() => routeParamsGetter(scope), params => element.attr('href', getLink(params)), true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
element.on('click', event => {
|
element.on('click', event => {
|
||||||
|
@ -10,7 +10,13 @@ export * from './src/core/di';
|
|||||||
export * from './src/facade/facade';
|
export * from './src/facade/facade';
|
||||||
export {enableProdMode} from 'angular2/src/facade/lang';
|
export {enableProdMode} from 'angular2/src/facade/lang';
|
||||||
export {platform, createNgZone, PlatformRef, ApplicationRef} from './src/core/application_ref';
|
export {platform, createNgZone, PlatformRef, ApplicationRef} from './src/core/application_ref';
|
||||||
export {APP_ID, APP_COMPONENT, APP_INITIALIZER, PACKAGE_ROOT_URL, PLATFORM_INITIALIZER} from './src/core/application_tokens';
|
export {
|
||||||
|
APP_ID,
|
||||||
|
APP_COMPONENT,
|
||||||
|
APP_INITIALIZER,
|
||||||
|
PACKAGE_ROOT_URL,
|
||||||
|
PLATFORM_INITIALIZER
|
||||||
|
} from './src/core/application_tokens';
|
||||||
export * from './src/core/zone';
|
export * from './src/core/zone';
|
||||||
export * from './src/core/render';
|
export * from './src/core/render';
|
||||||
export * from './src/core/linker';
|
export * from './src/core/linker';
|
||||||
|
@ -20,7 +20,7 @@ expect(door.lock instanceof Lock).toBe(true);
|
|||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
||||||
// #docregion resolve_forward_ref
|
// #docregion resolve_forward_ref
|
||||||
var ref = forwardRef(() => 'refValue');
|
var ref = forwardRef(() => "refValue");
|
||||||
expect(resolveForwardRef(ref)).toEqual('refValue');
|
expect(resolveForwardRef(ref)).toEqual("refValue");
|
||||||
expect(resolveForwardRef('regularValue')).toEqual('regularValue');
|
expect(resolveForwardRef("regularValue")).toEqual("regularValue");
|
||||||
// #enddocregion
|
// #enddocregion
|
@ -27,7 +27,7 @@ export class AsyncPipeExample {
|
|||||||
if (this.arrived) {
|
if (this.arrived) {
|
||||||
this.reset();
|
this.reset();
|
||||||
} else {
|
} else {
|
||||||
this.resolve('hi there!');
|
this.resolve("hi there!");
|
||||||
this.arrived = true;
|
this.arrived = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ export class AsyncPipeExample {
|
|||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
||||||
// #docregion AsyncPipeObservable
|
// #docregion AsyncPipeObservable
|
||||||
@Component({selector: 'task-cmp', template: 'Time: {{ time | async }}'})
|
@Component({selector: "task-cmp", template: "Time: {{ time | async }}"})
|
||||||
class Task {
|
class Task {
|
||||||
time = new Observable<number>((observer: Subscriber<number>) => {
|
time = new Observable<number>((observer: Subscriber<number>) => {
|
||||||
setInterval(() => observer.next(new Date().getTime()), 500);
|
setInterval(() => observer.next(new Date().getTime()), 500);
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
import {provide, Component} from 'angular2/core';
|
import {provide, Component} from 'angular2/core';
|
||||||
import {bootstrap} from 'angular2/platform/browser';
|
import {bootstrap} from 'angular2/platform/browser';
|
||||||
import {CanActivate, RouteConfig, ComponentInstruction, APP_BASE_HREF, ROUTER_DIRECTIVES} from 'angular2/router';
|
import {
|
||||||
|
CanActivate,
|
||||||
|
RouteConfig,
|
||||||
|
ComponentInstruction,
|
||||||
|
APP_BASE_HREF,
|
||||||
|
ROUTER_DIRECTIVES
|
||||||
|
} from 'angular2/router';
|
||||||
|
|
||||||
function checkIfWeHavePermission(instruction: ComponentInstruction) {
|
function checkIfWeHavePermission(instruction: ComponentInstruction) {
|
||||||
return instruction.params['id'] == '1';
|
return instruction.params['id'] == '1';
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
import {provide, Component} from 'angular2/core';
|
import {provide, Component} from 'angular2/core';
|
||||||
import {bootstrap} from 'angular2/platform/browser';
|
import {bootstrap} from 'angular2/platform/browser';
|
||||||
import {CanDeactivate, RouteConfig, RouteParams, ComponentInstruction, ROUTER_DIRECTIVES, APP_BASE_HREF} from 'angular2/router';
|
import {
|
||||||
|
CanDeactivate,
|
||||||
|
RouteConfig,
|
||||||
|
RouteParams,
|
||||||
|
ComponentInstruction,
|
||||||
|
ROUTER_DIRECTIVES,
|
||||||
|
APP_BASE_HREF
|
||||||
|
} from 'angular2/router';
|
||||||
|
|
||||||
// #docregion routerCanDeactivate
|
// #docregion routerCanDeactivate
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
import {Component, provide} from 'angular2/core';
|
import {Component, provide} from 'angular2/core';
|
||||||
import {bootstrap} from 'angular2/platform/browser';
|
import {bootstrap} from 'angular2/platform/browser';
|
||||||
import {OnActivate, ComponentInstruction, RouteConfig, ROUTER_DIRECTIVES, APP_BASE_HREF} from 'angular2/router';
|
import {
|
||||||
|
OnActivate,
|
||||||
|
ComponentInstruction,
|
||||||
|
RouteConfig,
|
||||||
|
ROUTER_DIRECTIVES,
|
||||||
|
APP_BASE_HREF
|
||||||
|
} from 'angular2/router';
|
||||||
|
|
||||||
// #docregion routerOnActivate
|
// #docregion routerOnActivate
|
||||||
@Component({template: `Child`})
|
@Component({template: `Child`})
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
import {Component, Injectable, provide} from 'angular2/core';
|
import {Component, Injectable, provide} from 'angular2/core';
|
||||||
import {bootstrap} from 'angular2/platform/browser';
|
import {bootstrap} from 'angular2/platform/browser';
|
||||||
import {OnDeactivate, ComponentInstruction, RouteConfig, ROUTER_DIRECTIVES, APP_BASE_HREF} from 'angular2/router';
|
import {
|
||||||
|
OnDeactivate,
|
||||||
|
ComponentInstruction,
|
||||||
|
RouteConfig,
|
||||||
|
ROUTER_DIRECTIVES,
|
||||||
|
APP_BASE_HREF
|
||||||
|
} from 'angular2/router';
|
||||||
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@ -51,6 +57,7 @@ class AppCmp {
|
|||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
return bootstrap(AppCmp, [
|
return bootstrap(AppCmp, [
|
||||||
provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/on_deactivate'}), LogService
|
provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/on_deactivate'}),
|
||||||
|
LogService
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,15 @@
|
|||||||
import {Component, provide} from 'angular2/core';
|
import {Component, provide} from 'angular2/core';
|
||||||
import {bootstrap} from 'angular2/platform/browser';
|
import {bootstrap} from 'angular2/platform/browser';
|
||||||
import {CanActivate, RouteConfig, ComponentInstruction, ROUTER_DIRECTIVES, APP_BASE_HREF, CanReuse, RouteParams, OnReuse} from 'angular2/router';
|
import {
|
||||||
|
CanActivate,
|
||||||
|
RouteConfig,
|
||||||
|
ComponentInstruction,
|
||||||
|
ROUTER_DIRECTIVES,
|
||||||
|
APP_BASE_HREF,
|
||||||
|
CanReuse,
|
||||||
|
RouteParams,
|
||||||
|
OnReuse
|
||||||
|
} from 'angular2/router';
|
||||||
|
|
||||||
|
|
||||||
// #docregion reuseCmp
|
// #docregion reuseCmp
|
||||||
@ -44,6 +53,6 @@ class AppCmp {
|
|||||||
|
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
return bootstrap(
|
return bootstrap(AppCmp,
|
||||||
AppCmp, [provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/reuse'})]);
|
[provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/reuse'})]);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,15 @@
|
|||||||
import {describe, fdescribe, xdescribe, it, fit, xit, beforeEach, afterEach, beforeEachProviders, inject} from 'angular2/testing';
|
import {
|
||||||
|
describe,
|
||||||
|
fdescribe,
|
||||||
|
xdescribe,
|
||||||
|
it,
|
||||||
|
fit,
|
||||||
|
xit,
|
||||||
|
beforeEach,
|
||||||
|
afterEach,
|
||||||
|
beforeEachProviders,
|
||||||
|
inject
|
||||||
|
} from 'angular2/testing';
|
||||||
import {provide} from 'angular2/core';
|
import {provide} from 'angular2/core';
|
||||||
|
|
||||||
var db: any;
|
var db: any;
|
||||||
@ -19,9 +30,8 @@ fdescribe('some component', () => {
|
|||||||
// This test will run.
|
// This test will run.
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
describe('another component', () => {
|
describe('another component',
|
||||||
it('also has a test', () => { throw 'This test will not run.'; });
|
() => { it('also has a test', () => { throw 'This test will not run.'; }); });
|
||||||
});
|
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
|
||||||
// #docregion xdescribe
|
// #docregion xdescribe
|
||||||
@ -63,8 +73,7 @@ describe('some component', () => {
|
|||||||
// #docregion beforeEachProviders
|
// #docregion beforeEachProviders
|
||||||
describe('some component', () => {
|
describe('some component', () => {
|
||||||
beforeEachProviders(() => [provide(MyService, {useClass: MyMockService})]);
|
beforeEachProviders(() => [provide(MyService, {useClass: MyMockService})]);
|
||||||
it('uses MyService', inject(
|
it('uses MyService', inject([MyService], (service: MyMockService) => {
|
||||||
[MyService], (service: MyMockService) => {
|
|
||||||
// service is an instance of MyMockService.
|
// service is an instance of MyMockService.
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
@ -16,7 +16,12 @@ import {BaseResponseOptions, ResponseOptions} from './src/http/base_response_opt
|
|||||||
export {Request} from './src/http/static_request';
|
export {Request} from './src/http/static_request';
|
||||||
export {Response} from './src/http/static_response';
|
export {Response} from './src/http/static_response';
|
||||||
|
|
||||||
export {RequestOptionsArgs, ResponseOptionsArgs, Connection, ConnectionBackend} from './src/http/interfaces';
|
export {
|
||||||
|
RequestOptionsArgs,
|
||||||
|
ResponseOptionsArgs,
|
||||||
|
Connection,
|
||||||
|
ConnectionBackend
|
||||||
|
} from './src/http/interfaces';
|
||||||
|
|
||||||
export {BrowserXhr} from './src/http/backends/browser_xhr';
|
export {BrowserXhr} from './src/http/backends/browser_xhr';
|
||||||
export {BaseRequestOptions, RequestOptions} from './src/http/base_request_options';
|
export {BaseRequestOptions, RequestOptions} from './src/http/base_request_options';
|
||||||
@ -150,13 +155,16 @@ export {URLSearchParams} from './src/http/url_search_params';
|
|||||||
export const HTTP_PROVIDERS: any[] = [
|
export const HTTP_PROVIDERS: any[] = [
|
||||||
// TODO(pascal): use factory type annotations once supported in DI
|
// TODO(pascal): use factory type annotations once supported in DI
|
||||||
// issue: https://github.com/angular/angular/issues/3183
|
// issue: https://github.com/angular/angular/issues/3183
|
||||||
provide(Http, {
|
provide(Http,
|
||||||
|
{
|
||||||
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
|
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
|
||||||
new Http(xhrBackend, requestOptions),
|
new Http(xhrBackend, requestOptions),
|
||||||
deps: [XHRBackend, RequestOptions]
|
deps: [XHRBackend, RequestOptions]
|
||||||
}),
|
}),
|
||||||
BrowserXhr, provide(RequestOptions, {useClass: BaseRequestOptions}),
|
BrowserXhr,
|
||||||
provide(ResponseOptions, {useClass: BaseResponseOptions}), XHRBackend
|
provide(RequestOptions, {useClass: BaseRequestOptions}),
|
||||||
|
provide(ResponseOptions, {useClass: BaseResponseOptions}),
|
||||||
|
XHRBackend
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -276,12 +284,14 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS;
|
|||||||
export const JSONP_PROVIDERS: any[] = [
|
export const JSONP_PROVIDERS: any[] = [
|
||||||
// TODO(pascal): use factory type annotations once supported in DI
|
// TODO(pascal): use factory type annotations once supported in DI
|
||||||
// issue: https://github.com/angular/angular/issues/3183
|
// issue: https://github.com/angular/angular/issues/3183
|
||||||
provide(Jsonp, {
|
provide(Jsonp,
|
||||||
|
{
|
||||||
useFactory: (jsonpBackend: JSONPBackend, requestOptions: RequestOptions) =>
|
useFactory: (jsonpBackend: JSONPBackend, requestOptions: RequestOptions) =>
|
||||||
new Jsonp(jsonpBackend, requestOptions),
|
new Jsonp(jsonpBackend, requestOptions),
|
||||||
deps: [JSONPBackend, RequestOptions]
|
deps: [JSONPBackend, RequestOptions]
|
||||||
}),
|
}),
|
||||||
BrowserJsonp, provide(RequestOptions, {useClass: BaseRequestOptions}),
|
BrowserJsonp,
|
||||||
|
provide(RequestOptions, {useClass: BaseRequestOptions}),
|
||||||
provide(ResponseOptions, {useClass: BaseResponseOptions}),
|
provide(ResponseOptions, {useClass: BaseResponseOptions}),
|
||||||
provide(JSONPBackend, {useClass: JSONPBackend_})
|
provide(JSONPBackend, {useClass: JSONPBackend_})
|
||||||
];
|
];
|
||||||
|
@ -1 +1,7 @@
|
|||||||
export {wtfCreateScope, wtfLeave, wtfStartTimeRange, wtfEndTimeRange, WtfScopeFn} from './src/core/profile/profile';
|
export {
|
||||||
|
wtfCreateScope,
|
||||||
|
wtfLeave,
|
||||||
|
wtfStartTimeRange,
|
||||||
|
wtfEndTimeRange,
|
||||||
|
WtfScopeFn
|
||||||
|
} from './src/core/profile/profile';
|
||||||
|
@ -1,12 +1,27 @@
|
|||||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||||
export {BROWSER_PROVIDERS, CACHED_TEMPLATE_PROVIDER, ELEMENT_PROBE_PROVIDERS, ELEMENT_PROBE_PROVIDERS_PROD_MODE, inspectNativeElement, BrowserDomAdapter, By, Title, DOCUMENT, enableDebugTools, disableDebugTools} from 'angular2/src/platform/browser_common';
|
export {
|
||||||
|
BROWSER_PROVIDERS,
|
||||||
|
CACHED_TEMPLATE_PROVIDER,
|
||||||
|
ELEMENT_PROBE_PROVIDERS,
|
||||||
|
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
|
||||||
|
inspectNativeElement,
|
||||||
|
BrowserDomAdapter,
|
||||||
|
By,
|
||||||
|
Title,
|
||||||
|
DOCUMENT,
|
||||||
|
enableDebugTools,
|
||||||
|
disableDebugTools
|
||||||
|
} from 'angular2/src/platform/browser_common';
|
||||||
|
|
||||||
import {Type, isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {Type, isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
import {BROWSER_PROVIDERS, BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
|
import {
|
||||||
|
BROWSER_PROVIDERS,
|
||||||
|
BROWSER_APP_COMMON_PROVIDERS
|
||||||
|
} from 'angular2/src/platform/browser_common';
|
||||||
import {COMPILER_PROVIDERS} from 'angular2/compiler';
|
import {COMPILER_PROVIDERS} from 'angular2/compiler';
|
||||||
import {ComponentRef, platform, reflector} from 'angular2/core';
|
import {ComponentRef, platform, reflector} from 'angular2/core';
|
||||||
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
|
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
|
||||||
import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
|
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl";
|
||||||
import {XHR} from 'angular2/compiler';
|
import {XHR} from 'angular2/compiler';
|
||||||
import {Provider} from 'angular2/src/core/di';
|
import {Provider} from 'angular2/src/core/di';
|
||||||
|
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||||
export {BROWSER_PROVIDERS, ELEMENT_PROBE_PROVIDERS, ELEMENT_PROBE_PROVIDERS_PROD_MODE, inspectNativeElement, BrowserDomAdapter, By, Title, enableDebugTools, disableDebugTools} from 'angular2/src/platform/browser_common';
|
export {
|
||||||
|
BROWSER_PROVIDERS,
|
||||||
|
ELEMENT_PROBE_PROVIDERS,
|
||||||
|
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
|
||||||
|
inspectNativeElement,
|
||||||
|
BrowserDomAdapter,
|
||||||
|
By,
|
||||||
|
Title,
|
||||||
|
enableDebugTools,
|
||||||
|
disableDebugTools
|
||||||
|
} from 'angular2/src/platform/browser_common';
|
||||||
|
|
||||||
import {Type, isPresent} from 'angular2/src/facade/lang';
|
import {Type, isPresent} from 'angular2/src/facade/lang';
|
||||||
import {BROWSER_PROVIDERS, BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
|
import {
|
||||||
|
BROWSER_PROVIDERS,
|
||||||
|
BROWSER_APP_COMMON_PROVIDERS
|
||||||
|
} from 'angular2/src/platform/browser_common';
|
||||||
import {ComponentRef, platform} from 'angular2/core';
|
import {ComponentRef, platform} from 'angular2/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,8 +29,8 @@ export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
|||||||
/**
|
/**
|
||||||
* See {@link bootstrap} for more information.
|
* See {@link bootstrap} for more information.
|
||||||
*/
|
*/
|
||||||
export function bootstrapStatic(
|
export function bootstrapStatic(appComponentType: Type,
|
||||||
appComponentType: Type, customProviders?: Array<any /*Type | Provider | any[]*/>,
|
customProviders?: Array<any /*Type | Provider | any[]*/>,
|
||||||
initReflector?: Function): Promise<ComponentRef> {
|
initReflector?: Function): Promise<ComponentRef> {
|
||||||
if (isPresent(initReflector)) {
|
if (isPresent(initReflector)) {
|
||||||
initReflector();
|
initReflector();
|
||||||
|
@ -6,6 +6,10 @@ export {DomRenderer} from 'angular2/src/platform/dom/dom_renderer';
|
|||||||
export {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
export {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
|
||||||
export {SharedStylesHost, DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
export {SharedStylesHost, DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
||||||
export {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
|
export {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
|
||||||
export {EVENT_MANAGER_PLUGINS, EventManager, EventManagerPlugin} from 'angular2/src/platform/dom/events/event_manager';
|
export {
|
||||||
|
EVENT_MANAGER_PLUGINS,
|
||||||
|
EventManager,
|
||||||
|
EventManagerPlugin
|
||||||
|
} from 'angular2/src/platform/dom/events/event_manager';
|
||||||
export * from 'angular2/src/platform/dom/debug/by';
|
export * from 'angular2/src/platform/dom/debug/by';
|
||||||
export * from 'angular2/src/platform/dom/debug/ng_probe';
|
export * from 'angular2/src/platform/dom/debug/ng_probe';
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import {TEST_BROWSER_STATIC_PLATFORM_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS} from 'angular2/platform/testing/browser_static';
|
import {
|
||||||
|
TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
|
||||||
|
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
||||||
|
} from 'angular2/platform/testing/browser_static';
|
||||||
import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
|
import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
|
||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
|
@ -1,4 +1,12 @@
|
|||||||
import {APP_ID, DirectiveResolver, NgZone, Provider, ViewResolver, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER} from 'angular2/core';
|
import {
|
||||||
|
APP_ID,
|
||||||
|
DirectiveResolver,
|
||||||
|
NgZone,
|
||||||
|
Provider,
|
||||||
|
ViewResolver,
|
||||||
|
PLATFORM_COMMON_PROVIDERS,
|
||||||
|
PLATFORM_INITIALIZER
|
||||||
|
} from 'angular2/core';
|
||||||
import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
|
import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
|
||||||
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
||||||
|
|
||||||
@ -10,7 +18,7 @@ import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
|
|||||||
import {LocationStrategy} from 'angular2/src/router/location/location_strategy';
|
import {LocationStrategy} from 'angular2/src/router/location/location_strategy';
|
||||||
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
|
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
|
||||||
|
|
||||||
import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
|
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl";
|
||||||
import {XHR} from 'angular2/compiler';
|
import {XHR} from 'angular2/compiler';
|
||||||
|
|
||||||
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
|
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
|
||||||
@ -55,6 +63,7 @@ export const ADDITIONAL_TEST_BROWSER_PROVIDERS: Array<any /*Type | Provider | an
|
|||||||
*/
|
*/
|
||||||
export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||||
CONST_EXPR([
|
CONST_EXPR([
|
||||||
BROWSER_APP_COMMON_PROVIDERS, new Provider(XHR, {useClass: XHRImpl}),
|
BROWSER_APP_COMMON_PROVIDERS,
|
||||||
|
new Provider(XHR, {useClass: XHRImpl}),
|
||||||
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
||||||
]);
|
]);
|
||||||
|
@ -1,4 +1,14 @@
|
|||||||
import {APP_ID, DirectiveResolver, NgZone, Provider, ViewResolver, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, APPLICATION_COMMON_PROVIDERS, Renderer} from 'angular2/core';
|
import {
|
||||||
|
APP_ID,
|
||||||
|
DirectiveResolver,
|
||||||
|
NgZone,
|
||||||
|
Provider,
|
||||||
|
ViewResolver,
|
||||||
|
PLATFORM_COMMON_PROVIDERS,
|
||||||
|
PLATFORM_INITIALIZER,
|
||||||
|
APPLICATION_COMMON_PROVIDERS,
|
||||||
|
Renderer
|
||||||
|
} from 'angular2/core';
|
||||||
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
|
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
|
||||||
|
|
||||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||||
@ -20,7 +30,11 @@ import {RootRenderer} from 'angular2/src/core/render/api';
|
|||||||
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
|
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
|
||||||
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
|
||||||
|
|
||||||
import {EventManager, EVENT_MANAGER_PLUGINS, ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/common_dom';
|
import {
|
||||||
|
EventManager,
|
||||||
|
EVENT_MANAGER_PLUGINS,
|
||||||
|
ELEMENT_PROBE_PROVIDERS
|
||||||
|
} from 'angular2/platform/common_dom';
|
||||||
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
|
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
|
||||||
|
|
||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
|
@ -1,7 +1,19 @@
|
|||||||
export {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION_COMMON} from 'angular2/src/platform/worker_app_common';
|
export {
|
||||||
|
WORKER_APP_PLATFORM,
|
||||||
|
WORKER_APP_APPLICATION_COMMON
|
||||||
|
} from 'angular2/src/platform/worker_app_common';
|
||||||
export {WORKER_APP_APPLICATION} from 'angular2/src/platform/worker_app';
|
export {WORKER_APP_APPLICATION} from 'angular2/src/platform/worker_app';
|
||||||
export {ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments} from 'angular2/src/web_workers/shared/client_message_broker';
|
export {
|
||||||
export {ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/service_message_broker';
|
ClientMessageBroker,
|
||||||
|
ClientMessageBrokerFactory,
|
||||||
|
FnArg,
|
||||||
|
UiArguments
|
||||||
|
} from 'angular2/src/web_workers/shared/client_message_broker';
|
||||||
|
export {
|
||||||
|
ReceivedMessage,
|
||||||
|
ServiceMessageBroker,
|
||||||
|
ServiceMessageBrokerFactory
|
||||||
|
} from 'angular2/src/web_workers/shared/service_message_broker';
|
||||||
export {PRIMITIVE} from 'angular2/src/web_workers/shared/serializer';
|
export {PRIMITIVE} from 'angular2/src/web_workers/shared/serializer';
|
||||||
export * from 'angular2/src/web_workers/shared/message_bus';
|
export * from 'angular2/src/web_workers/shared/message_bus';
|
||||||
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
|
||||||
|
@ -1,7 +1,21 @@
|
|||||||
export {WORKER_SCRIPT, WORKER_RENDER_PLATFORM, initializeGenericWorkerRenderer, WORKER_RENDER_APPLICATION_COMMON} from 'angular2/src/platform/worker_render_common';
|
export {
|
||||||
|
WORKER_SCRIPT,
|
||||||
|
WORKER_RENDER_PLATFORM,
|
||||||
|
initializeGenericWorkerRenderer,
|
||||||
|
WORKER_RENDER_APPLICATION_COMMON
|
||||||
|
} from 'angular2/src/platform/worker_render_common';
|
||||||
export {WORKER_RENDER_APPLICATION, WebWorkerInstance} from 'angular2/src/platform/worker_render';
|
export {WORKER_RENDER_APPLICATION, WebWorkerInstance} from 'angular2/src/platform/worker_render';
|
||||||
export {ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments} from '../src/web_workers/shared/client_message_broker';
|
export {
|
||||||
export {ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory} from '../src/web_workers/shared/service_message_broker';
|
ClientMessageBroker,
|
||||||
|
ClientMessageBrokerFactory,
|
||||||
|
FnArg,
|
||||||
|
UiArguments
|
||||||
|
} from '../src/web_workers/shared/client_message_broker';
|
||||||
|
export {
|
||||||
|
ReceivedMessage,
|
||||||
|
ServiceMessageBroker,
|
||||||
|
ServiceMessageBrokerFactory
|
||||||
|
} from '../src/web_workers/shared/service_message_broker';
|
||||||
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
|
export {PRIMITIVE} from '../src/web_workers/shared/serializer';
|
||||||
export * from '../src/web_workers/shared/message_bus';
|
export * from '../src/web_workers/shared/message_bus';
|
||||||
import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render';
|
import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render';
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import {DateWrapper, StringWrapper, RegExpWrapper, NumberWrapper, isPresent} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
DateWrapper,
|
||||||
|
StringWrapper,
|
||||||
|
RegExpWrapper,
|
||||||
|
NumberWrapper,
|
||||||
|
isPresent
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {Math} from 'angular2/src/facade/math';
|
import {Math} from 'angular2/src/facade/math';
|
||||||
import {camelCaseToDashCase} from 'angular2/src/platform/dom/util';
|
import {camelCaseToDashCase} from 'angular2/src/platform/dom/util';
|
||||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
@ -41,8 +47,7 @@ export class Animation {
|
|||||||
* @param data
|
* @param data
|
||||||
* @param browserDetails
|
* @param browserDetails
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(public element: HTMLElement, public data: CssAnimationOptions,
|
||||||
public element: HTMLElement, public data: CssAnimationOptions,
|
|
||||||
public browserDetails: BrowserDetails) {
|
public browserDetails: BrowserDetails) {
|
||||||
this.startTime = DateWrapper.toMillis(DateWrapper.now());
|
this.startTime = DateWrapper.toMillis(DateWrapper.now());
|
||||||
this._stringPrefix = DOM.getAnimationPrefix();
|
this._stringPrefix = DOM.getAnimationPrefix();
|
||||||
@ -75,16 +80,15 @@ export class Animation {
|
|||||||
this.removeClasses(this.data.classesToRemove);
|
this.removeClasses(this.data.classesToRemove);
|
||||||
if (this.data.toStyles != null) this.applyStyles(this.data.toStyles);
|
if (this.data.toStyles != null) this.applyStyles(this.data.toStyles);
|
||||||
var computedStyles = DOM.getComputedStyle(this.element);
|
var computedStyles = DOM.getComputedStyle(this.element);
|
||||||
this.computedDelay = Math.max(
|
this.computedDelay =
|
||||||
this.parseDurationString(
|
Math.max(this.parseDurationString(
|
||||||
computedStyles.getPropertyValue(this._stringPrefix + 'transition-delay')),
|
computedStyles.getPropertyValue(this._stringPrefix + 'transition-delay')),
|
||||||
this.parseDurationString(
|
this.parseDurationString(
|
||||||
this.element.style.getPropertyValue(this._stringPrefix + 'transition-delay')));
|
this.element.style.getPropertyValue(this._stringPrefix + 'transition-delay')));
|
||||||
this.computedDuration = Math.max(
|
this.computedDuration = Math.max(this.parseDurationString(computedStyles.getPropertyValue(
|
||||||
this.parseDurationString(
|
this._stringPrefix + 'transition-duration')),
|
||||||
computedStyles.getPropertyValue(this._stringPrefix + 'transition-duration')),
|
this.parseDurationString(this.element.style.getPropertyValue(
|
||||||
this.parseDurationString(
|
this._stringPrefix + 'transition-duration')));
|
||||||
this.element.style.getPropertyValue(this._stringPrefix + 'transition-duration')));
|
|
||||||
this.addEvents();
|
this.addEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,5 +47,13 @@ import {NgPlural, NgPluralCase} from './ng_plural';
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export const CORE_DIRECTIVES: Type[] = CONST_EXPR([
|
export const CORE_DIRECTIVES: Type[] = CONST_EXPR([
|
||||||
NgClass, NgFor, NgIf, NgStyle, NgSwitch, NgSwitchWhen, NgSwitchDefault, NgPlural, NgPluralCase
|
NgClass,
|
||||||
|
NgFor,
|
||||||
|
NgIf,
|
||||||
|
NgStyle,
|
||||||
|
NgSwitch,
|
||||||
|
NgSwitchWhen,
|
||||||
|
NgSwitchDefault,
|
||||||
|
NgPlural,
|
||||||
|
NgPluralCase
|
||||||
]);
|
]);
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
import {isPresent, isString, isArray} from 'angular2/src/facade/lang';
|
import {isPresent, isString, isArray} from 'angular2/src/facade/lang';
|
||||||
import {DoCheck, OnDestroy, Directive, ElementRef, IterableDiffers, KeyValueDiffers, Renderer, IterableDiffer, KeyValueDiffer, CollectionChangeRecord, KeyValueChangeRecord} from 'angular2/core';
|
import {
|
||||||
|
DoCheck,
|
||||||
|
OnDestroy,
|
||||||
|
Directive,
|
||||||
|
ElementRef,
|
||||||
|
IterableDiffers,
|
||||||
|
KeyValueDiffers,
|
||||||
|
Renderer,
|
||||||
|
IterableDiffer,
|
||||||
|
KeyValueDiffer,
|
||||||
|
CollectionChangeRecord,
|
||||||
|
KeyValueChangeRecord
|
||||||
|
} from 'angular2/core';
|
||||||
import {StringMapWrapper, isListLikeIterable} from 'angular2/src/facade/collection';
|
import {StringMapWrapper, isListLikeIterable} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,8 +80,7 @@ export class NgClass implements DoCheck, OnDestroy {
|
|||||||
private _initialClasses: string[] = [];
|
private _initialClasses: string[] = [];
|
||||||
private _rawClass: string[] | Set<string>;
|
private _rawClass: string[] | Set<string>;
|
||||||
|
|
||||||
constructor(
|
constructor(private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,
|
||||||
private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,
|
|
||||||
private _ngEl: ElementRef, private _renderer: Renderer) {}
|
private _ngEl: ElementRef, private _renderer: Renderer) {}
|
||||||
|
|
||||||
set initialClasses(v: string) {
|
set initialClasses(v: string) {
|
||||||
@ -143,16 +154,16 @@ export class NgClass implements DoCheck, OnDestroy {
|
|||||||
this._initialClasses.forEach(className => this._toggleClass(className, !isCleanup));
|
this._initialClasses.forEach(className => this._toggleClass(className, !isCleanup));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _applyClasses(
|
private _applyClasses(rawClassVal: string[] | Set<string>| {[key: string]: any},
|
||||||
rawClassVal: string[]|Set<string>|{[key: string]: any}, isCleanup: boolean) {
|
isCleanup: boolean) {
|
||||||
if (isPresent(rawClassVal)) {
|
if (isPresent(rawClassVal)) {
|
||||||
if (isArray(rawClassVal)) {
|
if (isArray(rawClassVal)) {
|
||||||
(<string[]>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
|
(<string[]>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
|
||||||
} else if (rawClassVal instanceof Set) {
|
} else if (rawClassVal instanceof Set) {
|
||||||
(<Set<string>>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
|
(<Set<string>>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
|
||||||
} else {
|
} else {
|
||||||
StringMapWrapper.forEach(
|
StringMapWrapper.forEach(<{[k: string]: any}>rawClassVal,
|
||||||
<{[k: string]: any}>rawClassVal, (expVal: any, className: string) => {
|
(expVal: any, className: string) => {
|
||||||
if (isPresent(expVal)) this._toggleClass(className, !isCleanup);
|
if (isPresent(expVal)) this._toggleClass(className, !isCleanup);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,20 @@
|
|||||||
import {DoCheck, Directive, ChangeDetectorRef, IterableDiffer, IterableDiffers, ViewContainerRef, TemplateRef, EmbeddedViewRef, TrackByFn} from 'angular2/core';
|
import {
|
||||||
|
DoCheck,
|
||||||
|
Directive,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
IterableDiffer,
|
||||||
|
IterableDiffers,
|
||||||
|
ViewContainerRef,
|
||||||
|
TemplateRef,
|
||||||
|
EmbeddedViewRef,
|
||||||
|
TrackByFn
|
||||||
|
} from 'angular2/core';
|
||||||
import {isPresent, isBlank, stringify, getTypeNameForDebugging} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, stringify, getTypeNameForDebugging} from 'angular2/src/facade/lang';
|
||||||
import {DefaultIterableDiffer, CollectionChangeRecord} from '../../core/change_detection/differs/default_iterable_differ';
|
import {
|
||||||
import {BaseException} from '../../facade/exceptions';
|
DefaultIterableDiffer,
|
||||||
|
CollectionChangeRecord
|
||||||
|
} from "../../core/change_detection/differs/default_iterable_differ";
|
||||||
|
import {BaseException} from "../../facade/exceptions";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `NgFor` directive instantiates a template once per item from an iterable. The context for
|
* The `NgFor` directive instantiates a template once per item from an iterable. The context for
|
||||||
@ -62,8 +75,7 @@ export class NgFor implements DoCheck {
|
|||||||
_ngForTrackBy: TrackByFn;
|
_ngForTrackBy: TrackByFn;
|
||||||
private _differ: IterableDiffer;
|
private _differ: IterableDiffer;
|
||||||
|
|
||||||
constructor(
|
constructor(private _viewContainer: ViewContainerRef, private _templateRef: TemplateRef,
|
||||||
private _viewContainer: ViewContainerRef, private _templateRef: TemplateRef,
|
|
||||||
private _iterableDiffers: IterableDiffers, private _cdr: ChangeDetectorRef) {}
|
private _iterableDiffers: IterableDiffers, private _cdr: ChangeDetectorRef) {}
|
||||||
|
|
||||||
set ngForOf(value: any) {
|
set ngForOf(value: any) {
|
||||||
@ -97,18 +109,15 @@ export class NgFor implements DoCheck {
|
|||||||
// TODO(rado): check if change detection can produce a change record that is
|
// TODO(rado): check if change detection can produce a change record that is
|
||||||
// easier to consume than current.
|
// easier to consume than current.
|
||||||
var recordViewTuples: RecordViewTuple[] = [];
|
var recordViewTuples: RecordViewTuple[] = [];
|
||||||
changes.forEachRemovedItem(
|
changes.forEachRemovedItem((removedRecord: CollectionChangeRecord) =>
|
||||||
(removedRecord: CollectionChangeRecord) =>
|
|
||||||
recordViewTuples.push(new RecordViewTuple(removedRecord, null)));
|
recordViewTuples.push(new RecordViewTuple(removedRecord, null)));
|
||||||
|
|
||||||
changes.forEachMovedItem(
|
changes.forEachMovedItem((movedRecord: CollectionChangeRecord) =>
|
||||||
(movedRecord: CollectionChangeRecord) =>
|
|
||||||
recordViewTuples.push(new RecordViewTuple(movedRecord, null)));
|
recordViewTuples.push(new RecordViewTuple(movedRecord, null)));
|
||||||
|
|
||||||
var insertTuples = this._bulkRemove(recordViewTuples);
|
var insertTuples = this._bulkRemove(recordViewTuples);
|
||||||
|
|
||||||
changes.forEachAddedItem(
|
changes.forEachAddedItem((addedRecord: CollectionChangeRecord) =>
|
||||||
(addedRecord: CollectionChangeRecord) =>
|
|
||||||
insertTuples.push(new RecordViewTuple(addedRecord, null)));
|
insertTuples.push(new RecordViewTuple(addedRecord, null)));
|
||||||
|
|
||||||
this._bulkInsert(insertTuples);
|
this._bulkInsert(insertTuples);
|
||||||
@ -137,8 +146,7 @@ export class NgFor implements DoCheck {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _bulkRemove(tuples: RecordViewTuple[]): RecordViewTuple[] {
|
private _bulkRemove(tuples: RecordViewTuple[]): RecordViewTuple[] {
|
||||||
tuples.sort(
|
tuples.sort((a: RecordViewTuple, b: RecordViewTuple) =>
|
||||||
(a: RecordViewTuple, b: RecordViewTuple) =>
|
|
||||||
a.record.previousIndex - b.record.previousIndex);
|
a.record.previousIndex - b.record.previousIndex);
|
||||||
var movedTuples: RecordViewTuple[] = [];
|
var movedTuples: RecordViewTuple[] = [];
|
||||||
for (var i = tuples.length - 1; i >= 0; i--) {
|
for (var i = tuples.length - 1; i >= 0; i--) {
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
import {Directive, ViewContainerRef, TemplateRef, ContentChildren, QueryList, Attribute, AfterContentInit, Input} from 'angular2/core';
|
import {
|
||||||
|
Directive,
|
||||||
|
ViewContainerRef,
|
||||||
|
TemplateRef,
|
||||||
|
ContentChildren,
|
||||||
|
QueryList,
|
||||||
|
Attribute,
|
||||||
|
AfterContentInit,
|
||||||
|
Input
|
||||||
|
} from 'angular2/core';
|
||||||
import {isPresent, NumberWrapper} from 'angular2/src/facade/lang';
|
import {isPresent, NumberWrapper} from 'angular2/src/facade/lang';
|
||||||
import {Map} from 'angular2/src/facade/collection';
|
import {Map} from 'angular2/src/facade/collection';
|
||||||
import {SwitchView} from './ng_switch';
|
import {SwitchView} from './ng_switch';
|
||||||
@ -67,8 +76,7 @@ export abstract class NgLocalization { abstract getPluralCategory(value: any): s
|
|||||||
export class NgPluralCase {
|
export class NgPluralCase {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_view: SwitchView;
|
_view: SwitchView;
|
||||||
constructor(
|
constructor(@Attribute('ngPluralCase') public value: string, template: TemplateRef,
|
||||||
@Attribute('ngPluralCase') public value: string, template: TemplateRef,
|
|
||||||
viewContainer: ViewContainerRef) {
|
viewContainer: ViewContainerRef) {
|
||||||
this._view = new SwitchView(viewContainer, template);
|
this._view = new SwitchView(viewContainer, template);
|
||||||
}
|
}
|
||||||
@ -127,7 +135,7 @@ export class NgPlural implements AfterContentInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_isValueView(pluralCase: NgPluralCase): boolean { return pluralCase.value[0] === '='; }
|
_isValueView(pluralCase: NgPluralCase): boolean { return pluralCase.value[0] === "="; }
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_formatValue(pluralCase: NgPluralCase): any {
|
_formatValue(pluralCase: NgPluralCase): any {
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
import {DoCheck, KeyValueDiffer, KeyValueDiffers, ElementRef, Directive, Renderer} from 'angular2/core';
|
import {
|
||||||
|
DoCheck,
|
||||||
|
KeyValueDiffer,
|
||||||
|
KeyValueDiffers,
|
||||||
|
ElementRef,
|
||||||
|
Directive,
|
||||||
|
Renderer
|
||||||
|
} from 'angular2/core';
|
||||||
import {isPresent, isBlank, print} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, print} from 'angular2/src/facade/lang';
|
||||||
import {KeyValueChangeRecord} from '../../core/change_detection/differs/default_keyvalue_differ';
|
import {KeyValueChangeRecord} from "../../core/change_detection/differs/default_keyvalue_differ";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `NgStyle` directive changes styles based on a result of expression evaluation.
|
* The `NgStyle` directive changes styles based on a result of expression evaluation.
|
||||||
@ -60,8 +67,8 @@ export class NgStyle implements DoCheck {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_differ: KeyValueDiffer;
|
_differ: KeyValueDiffer;
|
||||||
|
|
||||||
constructor(
|
constructor(private _differs: KeyValueDiffers, private _ngEl: ElementRef,
|
||||||
private _differs: KeyValueDiffers, private _ngEl: ElementRef, private _renderer: Renderer) {}
|
private _renderer: Renderer) {}
|
||||||
|
|
||||||
set rawStyle(v: {[key: string]: string}) {
|
set rawStyle(v: {[key: string]: string}) {
|
||||||
this._rawStyle = v;
|
this._rawStyle = v;
|
||||||
|
@ -175,8 +175,8 @@ export class NgSwitchWhen {
|
|||||||
_view: SwitchView;
|
_view: SwitchView;
|
||||||
private _switch: NgSwitch;
|
private _switch: NgSwitch;
|
||||||
|
|
||||||
constructor(
|
constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef,
|
||||||
viewContainer: ViewContainerRef, templateRef: TemplateRef, @Host() ngSwitch: NgSwitch) {
|
@Host() ngSwitch: NgSwitch) {
|
||||||
this._switch = ngSwitch;
|
this._switch = ngSwitch;
|
||||||
this._view = new SwitchView(viewContainer, templateRef);
|
this._view = new SwitchView(viewContainer, templateRef);
|
||||||
}
|
}
|
||||||
@ -195,8 +195,8 @@ export class NgSwitchWhen {
|
|||||||
*/
|
*/
|
||||||
@Directive({selector: '[ngSwitchDefault]'})
|
@Directive({selector: '[ngSwitchDefault]'})
|
||||||
export class NgSwitchDefault {
|
export class NgSwitchDefault {
|
||||||
constructor(
|
constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef,
|
||||||
viewContainer: ViewContainerRef, templateRef: TemplateRef, @Host() sswitch: NgSwitch) {
|
@Host() sswitch: NgSwitch) {
|
||||||
sswitch._registerView(_WHEN_DEFAULT, new SwitchView(viewContainer, templateRef));
|
sswitch._registerView(_WHEN_DEFAULT, new SwitchView(viewContainer, templateRef));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,19 @@ export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './forms/directives/contro
|
|||||||
export {DefaultValueAccessor} from './forms/directives/default_value_accessor';
|
export {DefaultValueAccessor} from './forms/directives/default_value_accessor';
|
||||||
export {NgControlStatus} from './forms/directives/ng_control_status';
|
export {NgControlStatus} from './forms/directives/ng_control_status';
|
||||||
export {CheckboxControlValueAccessor} from './forms/directives/checkbox_value_accessor';
|
export {CheckboxControlValueAccessor} from './forms/directives/checkbox_value_accessor';
|
||||||
export {NgSelectOption, SelectControlValueAccessor} from './forms/directives/select_control_value_accessor';
|
export {
|
||||||
|
NgSelectOption,
|
||||||
|
SelectControlValueAccessor
|
||||||
|
} from './forms/directives/select_control_value_accessor';
|
||||||
export {FORM_DIRECTIVES, RadioButtonState} from './forms/directives';
|
export {FORM_DIRECTIVES, RadioButtonState} from './forms/directives';
|
||||||
export {NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validators} from './forms/validators';
|
export {NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validators} from './forms/validators';
|
||||||
export {RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, Validator} from './forms/directives/validators';
|
export {
|
||||||
|
RequiredValidator,
|
||||||
|
MinLengthValidator,
|
||||||
|
MaxLengthValidator,
|
||||||
|
PatternValidator,
|
||||||
|
Validator
|
||||||
|
} from './forms/directives/validators';
|
||||||
export {FormBuilder} from './forms/form_builder';
|
export {FormBuilder} from './forms/form_builder';
|
||||||
import {FormBuilder} from './forms/form_builder';
|
import {FormBuilder} from './forms/form_builder';
|
||||||
import {RadioControlRegistry} from './forms/directives/radio_control_value_accessor';
|
import {RadioControlRegistry} from './forms/directives/radio_control_value_accessor';
|
||||||
|
@ -10,8 +10,16 @@ import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor
|
|||||||
import {NumberValueAccessor} from './directives/number_value_accessor';
|
import {NumberValueAccessor} from './directives/number_value_accessor';
|
||||||
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
|
||||||
import {NgControlStatus} from './directives/ng_control_status';
|
import {NgControlStatus} from './directives/ng_control_status';
|
||||||
import {SelectControlValueAccessor, NgSelectOption} from './directives/select_control_value_accessor';
|
import {
|
||||||
import {RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator} from './directives/validators';
|
SelectControlValueAccessor,
|
||||||
|
NgSelectOption
|
||||||
|
} from './directives/select_control_value_accessor';
|
||||||
|
import {
|
||||||
|
RequiredValidator,
|
||||||
|
MinLengthValidator,
|
||||||
|
MaxLengthValidator,
|
||||||
|
PatternValidator
|
||||||
|
} from './directives/validators';
|
||||||
|
|
||||||
export {NgControlName} from './directives/ng_control_name';
|
export {NgControlName} from './directives/ng_control_name';
|
||||||
export {NgFormControl} from './directives/ng_form_control';
|
export {NgFormControl} from './directives/ng_form_control';
|
||||||
@ -21,11 +29,22 @@ export {NgFormModel} from './directives/ng_form_model';
|
|||||||
export {NgForm} from './directives/ng_form';
|
export {NgForm} from './directives/ng_form';
|
||||||
export {DefaultValueAccessor} from './directives/default_value_accessor';
|
export {DefaultValueAccessor} from './directives/default_value_accessor';
|
||||||
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
|
||||||
export {RadioControlValueAccessor, RadioButtonState} from './directives/radio_control_value_accessor';
|
export {
|
||||||
|
RadioControlValueAccessor,
|
||||||
|
RadioButtonState
|
||||||
|
} from './directives/radio_control_value_accessor';
|
||||||
export {NumberValueAccessor} from './directives/number_value_accessor';
|
export {NumberValueAccessor} from './directives/number_value_accessor';
|
||||||
export {NgControlStatus} from './directives/ng_control_status';
|
export {NgControlStatus} from './directives/ng_control_status';
|
||||||
export {SelectControlValueAccessor, NgSelectOption} from './directives/select_control_value_accessor';
|
export {
|
||||||
export {RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator} from './directives/validators';
|
SelectControlValueAccessor,
|
||||||
|
NgSelectOption
|
||||||
|
} from './directives/select_control_value_accessor';
|
||||||
|
export {
|
||||||
|
RequiredValidator,
|
||||||
|
MinLengthValidator,
|
||||||
|
MaxLengthValidator,
|
||||||
|
PatternValidator
|
||||||
|
} from './directives/validators';
|
||||||
export {NgControl} from './directives/ng_control';
|
export {NgControl} from './directives/ng_control';
|
||||||
export {ControlValueAccessor} from './directives/control_value_accessor';
|
export {ControlValueAccessor} from './directives/control_value_accessor';
|
||||||
|
|
||||||
@ -46,12 +65,24 @@ export {ControlValueAccessor} from './directives/control_value_accessor';
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export const FORM_DIRECTIVES: Type[] = CONST_EXPR([
|
export const FORM_DIRECTIVES: Type[] = CONST_EXPR([
|
||||||
NgControlName, NgControlGroup,
|
NgControlName,
|
||||||
|
NgControlGroup,
|
||||||
|
|
||||||
NgFormControl, NgModel, NgFormModel, NgForm,
|
NgFormControl,
|
||||||
|
NgModel,
|
||||||
|
NgFormModel,
|
||||||
|
NgForm,
|
||||||
|
|
||||||
NgSelectOption, DefaultValueAccessor, NumberValueAccessor, CheckboxControlValueAccessor,
|
NgSelectOption,
|
||||||
SelectControlValueAccessor, RadioControlValueAccessor, NgControlStatus,
|
DefaultValueAccessor,
|
||||||
|
NumberValueAccessor,
|
||||||
|
CheckboxControlValueAccessor,
|
||||||
|
SelectControlValueAccessor,
|
||||||
|
RadioControlValueAccessor,
|
||||||
|
NgControlStatus,
|
||||||
|
|
||||||
RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator
|
RequiredValidator,
|
||||||
|
MinLengthValidator,
|
||||||
|
MaxLengthValidator,
|
||||||
|
PatternValidator
|
||||||
]);
|
]);
|
||||||
|
@ -31,4 +31,4 @@ export interface ControlValueAccessor {
|
|||||||
*
|
*
|
||||||
* See {@link DefaultValueAccessor} for how to implement one.
|
* See {@link DefaultValueAccessor} for how to implement one.
|
||||||
*/
|
*/
|
||||||
export const NG_VALUE_ACCESSOR: OpaqueToken = CONST_EXPR(new OpaqueToken('NgValueAccessor'));
|
export const NG_VALUE_ACCESSOR: OpaqueToken = CONST_EXPR(new OpaqueToken("NgValueAccessor"));
|
@ -1,4 +1,15 @@
|
|||||||
import {OnInit, OnDestroy, Directive, Optional, Inject, Host, SkipSelf, forwardRef, Provider, Self} from 'angular2/core';
|
import {
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
Directive,
|
||||||
|
Optional,
|
||||||
|
Inject,
|
||||||
|
Host,
|
||||||
|
SkipSelf,
|
||||||
|
forwardRef,
|
||||||
|
Provider,
|
||||||
|
Self
|
||||||
|
} from 'angular2/core';
|
||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
@ -67,8 +78,7 @@ export class NgControlGroup extends ControlContainer implements OnInit,
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_parent: ControlContainer;
|
_parent: ControlContainer;
|
||||||
|
|
||||||
constructor(
|
constructor(@Host() @SkipSelf() parent: ControlContainer,
|
||||||
@Host() @SkipSelf() parent: ControlContainer,
|
|
||||||
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
|
@ -1,12 +1,31 @@
|
|||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||||
|
|
||||||
import {OnChanges, OnDestroy, SimpleChange, Query, Directive, forwardRef, Host, SkipSelf, Provider, Inject, Optional, Self} from 'angular2/core';
|
import {
|
||||||
|
OnChanges,
|
||||||
|
OnDestroy,
|
||||||
|
SimpleChange,
|
||||||
|
Query,
|
||||||
|
Directive,
|
||||||
|
forwardRef,
|
||||||
|
Host,
|
||||||
|
SkipSelf,
|
||||||
|
Provider,
|
||||||
|
Inject,
|
||||||
|
Optional,
|
||||||
|
Self
|
||||||
|
} from 'angular2/core';
|
||||||
|
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {controlPath, composeValidators, composeAsyncValidators, isPropertyUpdated, selectValueAccessor} from './shared';
|
import {
|
||||||
|
controlPath,
|
||||||
|
composeValidators,
|
||||||
|
composeAsyncValidators,
|
||||||
|
isPropertyUpdated,
|
||||||
|
selectValueAccessor
|
||||||
|
} from './shared';
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
||||||
@ -120,9 +139,7 @@ export class NgControlName extends NgControl implements OnChanges,
|
|||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn {
|
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||||
return composeAsyncValidators(this._asyncValidators);
|
|
||||||
}
|
|
||||||
|
|
||||||
get control(): Control { return this.formDirective.getControl(this); }
|
get control(): Control { return this.formDirective.getControl(this); }
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
import {PromiseWrapper, ObservableWrapper, EventEmitter, PromiseCompleter} from 'angular2/src/facade/async';
|
import {
|
||||||
|
PromiseWrapper,
|
||||||
|
ObservableWrapper,
|
||||||
|
EventEmitter,
|
||||||
|
PromiseCompleter
|
||||||
|
} from 'angular2/src/facade/async';
|
||||||
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
import {Directive, forwardRef, Provider, Optional, Inject, Self} from 'angular2/core';
|
import {Directive, forwardRef, Provider, Optional, Inject, Self} from 'angular2/core';
|
||||||
@ -85,12 +90,11 @@ export class NgForm extends ControlContainer implements Form {
|
|||||||
form: ControlGroup;
|
form: ControlGroup;
|
||||||
ngSubmit = new EventEmitter();
|
ngSubmit = new EventEmitter();
|
||||||
|
|
||||||
constructor(
|
constructor(@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
||||||
@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
|
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
this.form = new ControlGroup(
|
this.form = new ControlGroup({}, null, composeValidators(validators),
|
||||||
{}, null, composeValidators(validators), composeAsyncValidators(asyncValidators));
|
composeAsyncValidators(asyncValidators));
|
||||||
}
|
}
|
||||||
|
|
||||||
get formDirective(): Form { return this; }
|
get formDirective(): Form { return this; }
|
||||||
|
@ -1,12 +1,28 @@
|
|||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||||
import {OnChanges, SimpleChange, Query, Directive, forwardRef, Provider, Inject, Optional, Self} from 'angular2/core';
|
import {
|
||||||
|
OnChanges,
|
||||||
|
SimpleChange,
|
||||||
|
Query,
|
||||||
|
Directive,
|
||||||
|
forwardRef,
|
||||||
|
Provider,
|
||||||
|
Inject,
|
||||||
|
Optional,
|
||||||
|
Self
|
||||||
|
} from 'angular2/core';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {setUpControl, composeValidators, composeAsyncValidators, isPropertyUpdated, selectValueAccessor} from './shared';
|
import {
|
||||||
|
setUpControl,
|
||||||
|
composeValidators,
|
||||||
|
composeAsyncValidators,
|
||||||
|
isPropertyUpdated,
|
||||||
|
selectValueAccessor
|
||||||
|
} from './shared';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
||||||
|
|
||||||
const formControlBinding =
|
const formControlBinding =
|
||||||
@ -97,9 +113,7 @@ export class NgFormControl extends NgControl implements OnChanges {
|
|||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn {
|
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||||
return composeAsyncValidators(this._asyncValidators);
|
|
||||||
}
|
|
||||||
|
|
||||||
get control(): Control { return this.form; }
|
get control(): Control { return this.form; }
|
||||||
|
|
||||||
@ -109,6 +123,6 @@ export class NgFormControl extends NgControl implements OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _isControlChanged(changes: {[key: string]: any}): boolean {
|
private _isControlChanged(changes: {[key: string]: any}): boolean {
|
||||||
return StringMapWrapper.contains(changes, 'form');
|
return StringMapWrapper.contains(changes, "form");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
|
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
|
||||||
import {SimpleChange, OnChanges, Directive, forwardRef, Provider, Inject, Optional, Self} from 'angular2/core';
|
import {
|
||||||
|
SimpleChange,
|
||||||
|
OnChanges,
|
||||||
|
Directive,
|
||||||
|
forwardRef,
|
||||||
|
Provider,
|
||||||
|
Inject,
|
||||||
|
Optional,
|
||||||
|
Self
|
||||||
|
} from 'angular2/core';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {NgControlGroup} from './ng_control_group';
|
import {NgControlGroup} from './ng_control_group';
|
||||||
import {ControlContainer} from './control_container';
|
import {ControlContainer} from './control_container';
|
||||||
@ -99,14 +108,13 @@ export class NgFormModel extends ControlContainer implements Form,
|
|||||||
directives: NgControl[] = [];
|
directives: NgControl[] = [];
|
||||||
ngSubmit = new EventEmitter();
|
ngSubmit = new EventEmitter();
|
||||||
|
|
||||||
constructor(
|
constructor(@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
||||||
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
|
|
||||||
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges(changes: {[key: string]: SimpleChange}): void {
|
ngOnChanges(changes: {[key: string]: SimpleChange}): void {
|
||||||
if (StringMapWrapper.contains(changes, 'form')) {
|
if (StringMapWrapper.contains(changes, "form")) {
|
||||||
var sync = composeValidators(this._validators);
|
var sync = composeValidators(this._validators);
|
||||||
this.form.validator = Validators.compose([this.form.validator, sync]);
|
this.form.validator = Validators.compose([this.form.validator, sync]);
|
||||||
|
|
||||||
|
@ -1,11 +1,26 @@
|
|||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||||
import {OnChanges, SimpleChange, Directive, forwardRef, Provider, Inject, Optional, Self} from 'angular2/core';
|
import {
|
||||||
|
OnChanges,
|
||||||
|
SimpleChange,
|
||||||
|
Directive,
|
||||||
|
forwardRef,
|
||||||
|
Provider,
|
||||||
|
Inject,
|
||||||
|
Optional,
|
||||||
|
Self
|
||||||
|
} from 'angular2/core';
|
||||||
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
|
||||||
import {NgControl} from './ng_control';
|
import {NgControl} from './ng_control';
|
||||||
import {Control} from '../model';
|
import {Control} from '../model';
|
||||||
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
|
||||||
import {setUpControl, isPropertyUpdated, selectValueAccessor, composeValidators, composeAsyncValidators} from './shared';
|
import {
|
||||||
|
setUpControl,
|
||||||
|
isPropertyUpdated,
|
||||||
|
selectValueAccessor,
|
||||||
|
composeValidators,
|
||||||
|
composeAsyncValidators
|
||||||
|
} from './shared';
|
||||||
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
import {ValidatorFn, AsyncValidatorFn} from './validators';
|
||||||
|
|
||||||
const formControlBinding =
|
const formControlBinding =
|
||||||
@ -75,9 +90,7 @@ export class NgModel extends NgControl implements OnChanges {
|
|||||||
|
|
||||||
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
get validator(): ValidatorFn { return composeValidators(this._validators); }
|
||||||
|
|
||||||
get asyncValidator(): AsyncValidatorFn {
|
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); }
|
||||||
return composeAsyncValidators(this._asyncValidators);
|
|
||||||
}
|
|
||||||
|
|
||||||
viewToModelUpdate(newValue: any): void {
|
viewToModelUpdate(newValue: any): void {
|
||||||
this.viewModel = newValue;
|
this.viewModel = newValue;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {AbstractControl} from '../model';
|
import {AbstractControl} from "../model";
|
||||||
import {Validator, ValidatorFn, AsyncValidatorFn} from './validators';
|
import {Validator, ValidatorFn, AsyncValidatorFn} from './validators';
|
||||||
|
|
||||||
export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn {
|
export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn {
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
import {Directive, ElementRef, Renderer, Self, forwardRef, Provider, Attribute, Input, OnInit, OnDestroy, Injector, Injectable} from 'angular2/core';
|
import {
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from 'angular2/src/common/forms/directives/control_value_accessor';
|
Directive,
|
||||||
|
ElementRef,
|
||||||
|
Renderer,
|
||||||
|
Self,
|
||||||
|
forwardRef,
|
||||||
|
Provider,
|
||||||
|
Attribute,
|
||||||
|
Input,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy,
|
||||||
|
Injector,
|
||||||
|
Injectable
|
||||||
|
} from 'angular2/core';
|
||||||
|
import {
|
||||||
|
NG_VALUE_ACCESSOR,
|
||||||
|
ControlValueAccessor
|
||||||
|
} from 'angular2/src/common/forms/directives/control_value_accessor';
|
||||||
import {NgControl} from 'angular2/src/common/forms/directives/ng_control';
|
import {NgControl} from 'angular2/src/common/forms/directives/ng_control';
|
||||||
import {CONST_EXPR, looseIdentical, isPresent} from 'angular2/src/facade/lang';
|
import {CONST_EXPR, looseIdentical, isPresent} from 'angular2/src/facade/lang';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
@ -82,8 +98,7 @@ export class RadioControlValueAccessor implements ControlValueAccessor,
|
|||||||
onChange = () => {};
|
onChange = () => {};
|
||||||
onTouched = () => {};
|
onTouched = () => {};
|
||||||
|
|
||||||
constructor(
|
constructor(private _renderer: Renderer, private _elementRef: ElementRef,
|
||||||
private _renderer: Renderer, private _elementRef: ElementRef,
|
|
||||||
private _registry: RadioControlRegistry, private _injector: Injector) {}
|
private _registry: RadioControlRegistry, private _injector: Injector) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
@ -1,6 +1,23 @@
|
|||||||
import {Directive, Renderer, forwardRef, Provider, ElementRef, Input, Host, OnDestroy, Optional} from 'angular2/core';
|
import {
|
||||||
|
Directive,
|
||||||
|
Renderer,
|
||||||
|
forwardRef,
|
||||||
|
Provider,
|
||||||
|
ElementRef,
|
||||||
|
Input,
|
||||||
|
Host,
|
||||||
|
OnDestroy,
|
||||||
|
Optional
|
||||||
|
} from 'angular2/core';
|
||||||
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
|
||||||
import {CONST_EXPR, StringWrapper, isPrimitive, isPresent, isBlank, looseIdentical} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
CONST_EXPR,
|
||||||
|
StringWrapper,
|
||||||
|
isPrimitive,
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
looseIdentical
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {MapWrapper} from 'angular2/src/facade/collection';
|
import {MapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
@ -9,12 +26,12 @@ const SELECT_VALUE_ACCESSOR = CONST_EXPR(new Provider(
|
|||||||
|
|
||||||
function _buildValueString(id: string, value: any): string {
|
function _buildValueString(id: string, value: any): string {
|
||||||
if (isBlank(id)) return `${value}`;
|
if (isBlank(id)) return `${value}`;
|
||||||
if (!isPrimitive(value)) value = 'Object';
|
if (!isPrimitive(value)) value = "Object";
|
||||||
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
return StringWrapper.slice(`${id}: ${value}`, 0, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _extractId(valueString: string): string {
|
function _extractId(valueString: string): string {
|
||||||
return valueString.split(':')[0];
|
return valueString.split(":")[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,8 +98,7 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
|
|||||||
export class NgSelectOption implements OnDestroy {
|
export class NgSelectOption implements OnDestroy {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
constructor(
|
constructor(private _element: ElementRef, private _renderer: Renderer,
|
||||||
private _element: ElementRef, private _renderer: Renderer,
|
|
||||||
@Optional() @Host() private _select: SelectControlValueAccessor) {
|
@Optional() @Host() private _select: SelectControlValueAccessor) {
|
||||||
if (isPresent(this._select)) this.id = this._select._registerOption();
|
if (isPresent(this._select)) this.id = this._select._registerOption();
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ export function controlPath(name: string, parent: ControlContainer): string[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function setUpControl(control: Control, dir: NgControl): void {
|
export function setUpControl(control: Control, dir: NgControl): void {
|
||||||
if (isBlank(control)) _throwError(dir, 'Cannot find control');
|
if (isBlank(control)) _throwError(dir, "Cannot find control");
|
||||||
if (isBlank(dir.valueAccessor)) _throwError(dir, 'No value accessor for');
|
if (isBlank(dir.valueAccessor)) _throwError(dir, "No value accessor for");
|
||||||
|
|
||||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||||
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||||
@ -47,13 +47,13 @@ export function setUpControl(control: Control, dir: NgControl): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
|
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
|
||||||
if (isBlank(control)) _throwError(dir, 'Cannot find control');
|
if (isBlank(control)) _throwError(dir, "Cannot find control");
|
||||||
control.validator = Validators.compose([control.validator, dir.validator]);
|
control.validator = Validators.compose([control.validator, dir.validator]);
|
||||||
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _throwError(dir: AbstractControlDirective, message: string): void {
|
function _throwError(dir: AbstractControlDirective, message: string): void {
|
||||||
var path = dir.path.join(' -> ');
|
var path = dir.path.join(" -> ");
|
||||||
throw new BaseException(`${message} '${path}'`);
|
throw new BaseException(`${message} '${path}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,23 +61,23 @@ export function composeValidators(validators: /* Array<Validator|Function> */ an
|
|||||||
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
|
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function composeAsyncValidators(validators: /* Array<Validator|Function> */ any[]):
|
export function composeAsyncValidators(
|
||||||
AsyncValidatorFn {
|
validators: /* Array<Validator|Function> */ any[]): AsyncValidatorFn {
|
||||||
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
|
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
|
||||||
if (!StringMapWrapper.contains(changes, 'model')) return false;
|
if (!StringMapWrapper.contains(changes, "model")) return false;
|
||||||
var change = changes['model'];
|
var change = changes["model"];
|
||||||
|
|
||||||
if (change.isFirstChange()) return true;
|
if (change.isFirstChange()) return true;
|
||||||
return !looseIdentical(viewModel, change.currentValue);
|
return !looseIdentical(viewModel, change.currentValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
|
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
|
||||||
export function selectValueAccessor(
|
export function selectValueAccessor(dir: NgControl,
|
||||||
dir: NgControl, valueAccessors: ControlValueAccessor[]): ControlValueAccessor {
|
valueAccessors: ControlValueAccessor[]): ControlValueAccessor {
|
||||||
if (isBlank(valueAccessors)) return null;
|
if (isBlank(valueAccessors)) return null;
|
||||||
|
|
||||||
var defaultAccessor: ControlValueAccessor;
|
var defaultAccessor: ControlValueAccessor;
|
||||||
@ -87,17 +87,17 @@ export function selectValueAccessor(
|
|||||||
if (hasConstructor(v, DefaultValueAccessor)) {
|
if (hasConstructor(v, DefaultValueAccessor)) {
|
||||||
defaultAccessor = v;
|
defaultAccessor = v;
|
||||||
|
|
||||||
} else if (
|
} else if (hasConstructor(v, CheckboxControlValueAccessor) ||
|
||||||
hasConstructor(v, CheckboxControlValueAccessor) || hasConstructor(v, NumberValueAccessor) ||
|
hasConstructor(v, NumberValueAccessor) ||
|
||||||
hasConstructor(v, SelectControlValueAccessor) ||
|
hasConstructor(v, SelectControlValueAccessor) ||
|
||||||
hasConstructor(v, RadioControlValueAccessor)) {
|
hasConstructor(v, RadioControlValueAccessor)) {
|
||||||
if (isPresent(builtinAccessor))
|
if (isPresent(builtinAccessor))
|
||||||
_throwError(dir, 'More than one built-in value accessor matches');
|
_throwError(dir, "More than one built-in value accessor matches");
|
||||||
builtinAccessor = v;
|
builtinAccessor = v;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (isPresent(customAccessor))
|
if (isPresent(customAccessor))
|
||||||
_throwError(dir, 'More than one custom value accessor matches');
|
_throwError(dir, "More than one custom value accessor matches");
|
||||||
customAccessor = v;
|
customAccessor = v;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -106,6 +106,6 @@ export function selectValueAccessor(
|
|||||||
if (isPresent(builtinAccessor)) return builtinAccessor;
|
if (isPresent(builtinAccessor)) return builtinAccessor;
|
||||||
if (isPresent(defaultAccessor)) return defaultAccessor;
|
if (isPresent(defaultAccessor)) return defaultAccessor;
|
||||||
|
|
||||||
_throwError(dir, 'No valid value accessor for');
|
_throwError(dir, "No valid value accessor for");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import {CONST_EXPR} from 'angular2/src/facade/lang';
|
|||||||
import {Validators, NG_VALIDATORS} from '../validators';
|
import {Validators, NG_VALIDATORS} from '../validators';
|
||||||
import {AbstractControl} from '../model';
|
import {AbstractControl} from '../model';
|
||||||
import * as modelModule from '../model';
|
import * as modelModule from '../model';
|
||||||
import {NumberWrapper} from 'angular2/src/facade/lang';
|
import {NumberWrapper} from "angular2/src/facade/lang";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ const MIN_LENGTH_VALIDATOR = CONST_EXPR(
|
|||||||
export class MinLengthValidator implements Validator {
|
export class MinLengthValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute('minlength') minLength: string) {
|
constructor(@Attribute("minlength") minLength: string) {
|
||||||
this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10));
|
this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ const MAX_LENGTH_VALIDATOR = CONST_EXPR(
|
|||||||
export class MaxLengthValidator implements Validator {
|
export class MaxLengthValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute('maxlength') maxLength: string) {
|
constructor(@Attribute("maxlength") maxLength: string) {
|
||||||
this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10));
|
this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ const PATTERN_VALIDATOR = CONST_EXPR(
|
|||||||
export class PatternValidator implements Validator {
|
export class PatternValidator implements Validator {
|
||||||
private _validator: ValidatorFn;
|
private _validator: ValidatorFn;
|
||||||
|
|
||||||
constructor(@Attribute('pattern') pattern: string) {
|
constructor(@Attribute("pattern") pattern: string) {
|
||||||
this._validator = Validators.pattern(pattern);
|
this._validator = Validators.pattern(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,21 +54,21 @@ export class FormBuilder {
|
|||||||
*
|
*
|
||||||
* See the {@link ControlGroup} constructor for more details.
|
* See the {@link ControlGroup} constructor for more details.
|
||||||
*/
|
*/
|
||||||
group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any} = null):
|
group(controlsConfig: {[key: string]: any},
|
||||||
modelModule.ControlGroup {
|
extra: {[key: string]: any} = null): modelModule.ControlGroup {
|
||||||
var controls = this._reduceControls(controlsConfig);
|
var controls = this._reduceControls(controlsConfig);
|
||||||
var optionals = <{[key: string]: boolean}>(
|
var optionals = <{[key: string]: boolean}>(
|
||||||
isPresent(extra) ? StringMapWrapper.get(extra, 'optionals') : null);
|
isPresent(extra) ? StringMapWrapper.get(extra, "optionals") : null);
|
||||||
var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, 'validator') : null;
|
var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, "validator") : null;
|
||||||
var asyncValidator: AsyncValidatorFn =
|
var asyncValidator: AsyncValidatorFn =
|
||||||
isPresent(extra) ? StringMapWrapper.get(extra, 'asyncValidator') : null;
|
isPresent(extra) ? StringMapWrapper.get(extra, "asyncValidator") : null;
|
||||||
return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator);
|
return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`.
|
* Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`.
|
||||||
*/
|
*/
|
||||||
control(value: Object, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null):
|
control(value: Object, validator: ValidatorFn = null,
|
||||||
modelModule.Control {
|
asyncValidator: AsyncValidatorFn = null): modelModule.Control {
|
||||||
return new modelModule.Control(value, validator, asyncValidator);
|
return new modelModule.Control(value, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,16 +76,15 @@ export class FormBuilder {
|
|||||||
* Construct an array of {@link Control}s from the given `controlsConfig` array of
|
* Construct an array of {@link Control}s from the given `controlsConfig` array of
|
||||||
* configuration, with the given optional `validator` and `asyncValidator`.
|
* configuration, with the given optional `validator` and `asyncValidator`.
|
||||||
*/
|
*/
|
||||||
array(
|
array(controlsConfig: any[], validator: ValidatorFn = null,
|
||||||
controlsConfig: any[], validator: ValidatorFn = null,
|
|
||||||
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray {
|
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray {
|
||||||
var controls = controlsConfig.map(c => this._createControl(c));
|
var controls = controlsConfig.map(c => this._createControl(c));
|
||||||
return new modelModule.ControlArray(controls, validator, asyncValidator);
|
return new modelModule.ControlArray(controls, validator, asyncValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_reduceControls(controlsConfig: {[k: string]: any}):
|
_reduceControls(controlsConfig: {[k: string]:
|
||||||
{[key: string]: modelModule.AbstractControl} {
|
any}): {[key: string]: modelModule.AbstractControl} {
|
||||||
var controls: {[key: string]: modelModule.AbstractControl} = {};
|
var controls: {[key: string]: modelModule.AbstractControl} = {};
|
||||||
StringMapWrapper.forEach(controlsConfig, (controlConfig: any, controlName: string) => {
|
StringMapWrapper.forEach(controlsConfig, (controlConfig: any, controlName: string) => {
|
||||||
controls[controlName] = this._createControl(controlConfig);
|
controls[controlName] = this._createControl(controlConfig);
|
||||||
|
@ -7,18 +7,18 @@ import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
|||||||
/**
|
/**
|
||||||
* Indicates that a Control is valid, i.e. that no errors exist in the input value.
|
* Indicates that a Control is valid, i.e. that no errors exist in the input value.
|
||||||
*/
|
*/
|
||||||
export const VALID = 'VALID';
|
export const VALID = "VALID";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that a Control is invalid, i.e. that an error exists in the input value.
|
* Indicates that a Control is invalid, i.e. that an error exists in the input value.
|
||||||
*/
|
*/
|
||||||
export const INVALID = 'INVALID';
|
export const INVALID = "INVALID";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that a Control is pending, i.e. that async validation is occurring and
|
* Indicates that a Control is pending, i.e. that async validation is occurring and
|
||||||
* errors are not yet available for the input value.
|
* errors are not yet available for the input value.
|
||||||
*/
|
*/
|
||||||
export const PENDING = 'PENDING';
|
export const PENDING = "PENDING";
|
||||||
|
|
||||||
export function isControl(control: Object): boolean {
|
export function isControl(control: Object): boolean {
|
||||||
return control instanceof AbstractControl;
|
return control instanceof AbstractControl;
|
||||||
@ -28,11 +28,12 @@ function _find(control: AbstractControl, path: Array<string|number>| string) {
|
|||||||
if (isBlank(path)) return null;
|
if (isBlank(path)) return null;
|
||||||
|
|
||||||
if (!(path instanceof Array)) {
|
if (!(path instanceof Array)) {
|
||||||
path = (<string>path).split('/');
|
path = (<string>path).split("/");
|
||||||
}
|
}
|
||||||
if (path instanceof Array && ListWrapper.isEmpty(path)) return null;
|
if (path instanceof Array && ListWrapper.isEmpty(path)) return null;
|
||||||
|
|
||||||
return (<Array<string|number>>path).reduce((v, name) => {
|
return (<Array<string | number>>path)
|
||||||
|
.reduce((v, name) => {
|
||||||
if (v instanceof ControlGroup) {
|
if (v instanceof ControlGroup) {
|
||||||
return isPresent(v.controls[name]) ? v.controls[name] : null;
|
return isPresent(v.controls[name]) ? v.controls[name] : null;
|
||||||
} else if (v instanceof ControlArray) {
|
} else if (v instanceof ControlArray) {
|
||||||
@ -113,8 +114,8 @@ export abstract class AbstractControl {
|
|||||||
|
|
||||||
setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; }
|
setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; }
|
||||||
|
|
||||||
updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
|
updateValueAndValidity(
|
||||||
void {
|
{onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
|
||||||
onlySelf = normalizeBool(onlySelf);
|
onlySelf = normalizeBool(onlySelf);
|
||||||
emitEvent = isPresent(emitEvent) ? emitEvent : true;
|
emitEvent = isPresent(emitEvent) ? emitEvent : true;
|
||||||
|
|
||||||
@ -270,8 +271,8 @@ export class Control extends AbstractControl {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_onChange: Function;
|
_onChange: Function;
|
||||||
|
|
||||||
constructor(
|
constructor(value: any = null, validator: ValidatorFn = null,
|
||||||
value: any = null, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) {
|
asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._value = value;
|
this._value = value;
|
||||||
this.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
this.updateValueAndValidity({onlySelf: true, emitEvent: false});
|
||||||
@ -334,9 +335,9 @@ export class Control extends AbstractControl {
|
|||||||
export class ControlGroup extends AbstractControl {
|
export class ControlGroup extends AbstractControl {
|
||||||
private _optionals: {[key: string]: boolean};
|
private _optionals: {[key: string]: boolean};
|
||||||
|
|
||||||
constructor(
|
constructor(public controls: {[key: string]: AbstractControl},
|
||||||
public controls: {[key: string]: AbstractControl}, optionals: {[key: string]: boolean} = null,
|
optionals: {[key: string]: boolean} = null, validator: ValidatorFn = null,
|
||||||
validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) {
|
asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._optionals = isPresent(optionals) ? optionals : {};
|
this._optionals = isPresent(optionals) ? optionals : {};
|
||||||
this._initObservables();
|
this._initObservables();
|
||||||
@ -449,8 +450,7 @@ export class ControlGroup extends AbstractControl {
|
|||||||
* ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
|
* ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
|
||||||
*/
|
*/
|
||||||
export class ControlArray extends AbstractControl {
|
export class ControlArray extends AbstractControl {
|
||||||
constructor(
|
constructor(public controls: AbstractControl[], validator: ValidatorFn = null,
|
||||||
public controls: AbstractControl[], validator: ValidatorFn = null,
|
|
||||||
asyncValidator: AsyncValidatorFn = null) {
|
asyncValidator: AsyncValidatorFn = null) {
|
||||||
super(validator, asyncValidator);
|
super(validator, asyncValidator);
|
||||||
this._initObservables();
|
this._initObservables();
|
||||||
|
@ -16,7 +16,7 @@ import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
|
|||||||
*
|
*
|
||||||
* {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'}
|
* {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'}
|
||||||
*/
|
*/
|
||||||
export const NG_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken('NgValidators'));
|
export const NG_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken("NgValidators"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Providers for asynchronous validators to be used for {@link Control}s
|
* Providers for asynchronous validators to be used for {@link Control}s
|
||||||
@ -26,7 +26,7 @@ export const NG_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken('NgValidato
|
|||||||
*
|
*
|
||||||
* See {@link NG_VALIDATORS} for more details.
|
* See {@link NG_VALIDATORS} for more details.
|
||||||
*/
|
*/
|
||||||
export const NG_ASYNC_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken('NgAsyncValidators'));
|
export const NG_ASYNC_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken("NgAsyncValidators"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a set of validators used by form controls.
|
* Provides a set of validators used by form controls.
|
||||||
@ -45,8 +45,8 @@ export class Validators {
|
|||||||
* Validator that requires controls to have a non-empty value.
|
* Validator that requires controls to have a non-empty value.
|
||||||
*/
|
*/
|
||||||
static required(control: modelModule.AbstractControl): {[key: string]: boolean} {
|
static required(control: modelModule.AbstractControl): {[key: string]: boolean} {
|
||||||
return isBlank(control.value) || (isString(control.value) && control.value == '') ?
|
return isBlank(control.value) || (isString(control.value) && control.value == "") ?
|
||||||
{'required': true} :
|
{"required": true} :
|
||||||
null;
|
null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ export class Validators {
|
|||||||
if (isPresent(Validators.required(control))) return null;
|
if (isPresent(Validators.required(control))) return null;
|
||||||
var v: string = control.value;
|
var v: string = control.value;
|
||||||
return v.length < minLength ?
|
return v.length < minLength ?
|
||||||
{'minlength': {'requiredLength': minLength, 'actualLength': v.length}} :
|
{"minlength": {"requiredLength": minLength, "actualLength": v.length}} :
|
||||||
null;
|
null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -71,7 +71,7 @@ export class Validators {
|
|||||||
if (isPresent(Validators.required(control))) return null;
|
if (isPresent(Validators.required(control))) return null;
|
||||||
var v: string = control.value;
|
var v: string = control.value;
|
||||||
return v.length > maxLength ?
|
return v.length > maxLength ?
|
||||||
{'maxlength': {'requiredLength': maxLength, 'actualLength': v.length}} :
|
{"maxlength": {"requiredLength": maxLength, "actualLength": v.length}} :
|
||||||
null;
|
null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ export class Validators {
|
|||||||
let regex = new RegExp(`^${pattern}$`);
|
let regex = new RegExp(`^${pattern}$`);
|
||||||
let v: string = control.value;
|
let v: string = control.value;
|
||||||
return regex.test(v) ? null :
|
return regex.test(v) ? null :
|
||||||
{'pattern': {'requiredPattern': `^${pattern}$`, 'actualValue': v}};
|
{"pattern": {"requiredPattern": `^${pattern}$`, "actualValue": v}};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,13 +124,13 @@ function _convertToPromise(obj: any): any {
|
|||||||
return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj);
|
return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _executeValidators(
|
function _executeValidators(control: modelModule.AbstractControl,
|
||||||
control: modelModule.AbstractControl, validators: ValidatorFn[]): any[] {
|
validators: ValidatorFn[]): any[] {
|
||||||
return validators.map(v => v(control));
|
return validators.map(v => v(control));
|
||||||
}
|
}
|
||||||
|
|
||||||
function _executeAsyncValidators(
|
function _executeAsyncValidators(control: modelModule.AbstractControl,
|
||||||
control: modelModule.AbstractControl, validators: AsyncValidatorFn[]): any[] {
|
validators: AsyncValidatorFn[]): any[] {
|
||||||
return validators.map(v => v(control));
|
return validators.map(v => v(control));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
import {isBlank, isPresent, isPromise, CONST} from 'angular2/src/facade/lang';
|
import {isBlank, isPresent, isPromise, CONST} from 'angular2/src/facade/lang';
|
||||||
import {ObservableWrapper, Observable, EventEmitter} from 'angular2/src/facade/async';
|
import {ObservableWrapper, Observable, EventEmitter} from 'angular2/src/facade/async';
|
||||||
import {Pipe, Injectable, ChangeDetectorRef, OnDestroy, PipeTransform, WrappedValue} from 'angular2/core';
|
import {
|
||||||
|
Pipe,
|
||||||
|
Injectable,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
OnDestroy,
|
||||||
|
PipeTransform,
|
||||||
|
WrappedValue
|
||||||
|
} from 'angular2/core';
|
||||||
|
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
@ -23,6 +23,16 @@ import {CONST_EXPR} from 'angular2/src/facade/lang';
|
|||||||
* property of the `@Component` decorator.
|
* property of the `@Component` decorator.
|
||||||
*/
|
*/
|
||||||
export const COMMON_PIPES = CONST_EXPR([
|
export const COMMON_PIPES = CONST_EXPR([
|
||||||
AsyncPipe, UpperCasePipe, LowerCasePipe, JsonPipe, SlicePipe, DecimalPipe, PercentPipe,
|
AsyncPipe,
|
||||||
CurrencyPipe, DatePipe, ReplacePipe, I18nPluralPipe, I18nSelectPipe
|
UpperCasePipe,
|
||||||
|
LowerCasePipe,
|
||||||
|
JsonPipe,
|
||||||
|
SlicePipe,
|
||||||
|
DecimalPipe,
|
||||||
|
PercentPipe,
|
||||||
|
CurrencyPipe,
|
||||||
|
DatePipe,
|
||||||
|
ReplacePipe,
|
||||||
|
I18nPluralPipe,
|
||||||
|
I18nSelectPipe
|
||||||
]);
|
]);
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
import {isDate, isNumber, isPresent, Date, DateWrapper, CONST, isBlank, FunctionWrapper} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isDate,
|
||||||
|
isNumber,
|
||||||
|
isPresent,
|
||||||
|
Date,
|
||||||
|
DateWrapper,
|
||||||
|
CONST,
|
||||||
|
isBlank,
|
||||||
|
FunctionWrapper
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {DateFormatter} from 'angular2/src/facade/intl';
|
import {DateFormatter} from 'angular2/src/facade/intl';
|
||||||
import {PipeTransform, WrappedValue, Pipe, Injectable} from 'angular2/core';
|
import {PipeTransform, WrappedValue, Pipe, Injectable} from 'angular2/core';
|
||||||
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import {CONST, isStringMap, StringWrapper, isPresent, RegExpWrapper} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
CONST,
|
||||||
|
isStringMap,
|
||||||
|
StringWrapper,
|
||||||
|
isPresent,
|
||||||
|
RegExpWrapper
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {Injectable, PipeTransform, Pipe} from 'angular2/core';
|
import {Injectable, PipeTransform, Pipe} from 'angular2/core';
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
import {isNumber, isPresent, isBlank, StringWrapper, NumberWrapper, RegExpWrapper, CONST, FunctionWrapper} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isNumber,
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
StringWrapper,
|
||||||
|
NumberWrapper,
|
||||||
|
RegExpWrapper,
|
||||||
|
CONST,
|
||||||
|
FunctionWrapper
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||||
import {NumberFormatter, NumberFormatStyle} from 'angular2/src/facade/intl';
|
import {NumberFormatter, NumberFormatStyle} from 'angular2/src/facade/intl';
|
||||||
import {Injectable, PipeTransform, WrappedValue, Pipe} from 'angular2/core';
|
import {Injectable, PipeTransform, WrappedValue, Pipe} from 'angular2/core';
|
||||||
@ -16,8 +25,7 @@ var _re = RegExpWrapper.create('^(\\d+)?\\.((\\d+)(\\-(\\d+))?)?$');
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class NumberPipe {
|
export class NumberPipe {
|
||||||
/** @internal */
|
/** @internal */
|
||||||
static _format(
|
static _format(value: number, style: NumberFormatStyle, digits: string, currency: string = null,
|
||||||
value: number, style: NumberFormatStyle, digits: string, currency: string = null,
|
|
||||||
currencyAsSymbol: boolean = false): string {
|
currencyAsSymbol: boolean = false): string {
|
||||||
if (isBlank(value)) return null;
|
if (isBlank(value)) return null;
|
||||||
if (!isNumber(value)) {
|
if (!isNumber(value)) {
|
||||||
@ -139,7 +147,7 @@ export class CurrencyPipe extends NumberPipe implements PipeTransform {
|
|||||||
var currencyCode: string = isPresent(args) && args.length > 0 ? args[0] : 'USD';
|
var currencyCode: string = isPresent(args) && args.length > 0 ? args[0] : 'USD';
|
||||||
var symbolDisplay: boolean = isPresent(args) && args.length > 1 ? args[1] : false;
|
var symbolDisplay: boolean = isPresent(args) && args.length > 1 ? args[1] : false;
|
||||||
var digits: string = isPresent(args) && args.length > 2 ? args[2] : null;
|
var digits: string = isPresent(args) && args.length > 2 ? args[2] : null;
|
||||||
return NumberPipe._format(
|
return NumberPipe._format(value, NumberFormatStyle.Currency, digits, currencyCode,
|
||||||
value, NumberFormatStyle.Currency, digits, currencyCode, symbolDisplay);
|
symbolDisplay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import {isBlank, isString, isNumber, isFunction, RegExpWrapper, StringWrapper} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isBlank,
|
||||||
|
isString,
|
||||||
|
isNumber,
|
||||||
|
isFunction,
|
||||||
|
RegExpWrapper,
|
||||||
|
StringWrapper
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import {Injectable, PipeTransform, Pipe} from 'angular2/core';
|
import {Injectable, PipeTransform, Pipe} from 'angular2/core';
|
||||||
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
|
||||||
|
@ -2,10 +2,34 @@ import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
|||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
import {reflector} from 'angular2/src/core/reflection/reflection';
|
import {reflector} from 'angular2/src/core/reflection/reflection';
|
||||||
|
|
||||||
import {DirectiveIndex, BindingRecord, DirectiveRecord, ChangeDetectionStrategy, ChangeDetectorDefinition, ChangeDetectorGenConfig, ASTWithSource} from 'angular2/src/core/change_detection/change_detection';
|
import {
|
||||||
|
DirectiveIndex,
|
||||||
|
BindingRecord,
|
||||||
|
DirectiveRecord,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDetectorDefinition,
|
||||||
|
ChangeDetectorGenConfig,
|
||||||
|
ASTWithSource
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
import {CompileDirectiveMetadata, CompileTypeMetadata} from './directive_metadata';
|
import {CompileDirectiveMetadata, CompileTypeMetadata} from './directive_metadata';
|
||||||
import {TemplateAst, ElementAst, BoundTextAst, PropertyBindingType, DirectiveAst, TemplateAstVisitor, templateVisitAll, NgContentAst, EmbeddedTemplateAst, VariableAst, BoundElementPropertyAst, BoundEventAst, BoundDirectivePropertyAst, AttrAst, TextAst} from './template_ast';
|
import {
|
||||||
|
TemplateAst,
|
||||||
|
ElementAst,
|
||||||
|
BoundTextAst,
|
||||||
|
PropertyBindingType,
|
||||||
|
DirectiveAst,
|
||||||
|
TemplateAstVisitor,
|
||||||
|
templateVisitAll,
|
||||||
|
NgContentAst,
|
||||||
|
EmbeddedTemplateAst,
|
||||||
|
VariableAst,
|
||||||
|
BoundElementPropertyAst,
|
||||||
|
BoundEventAst,
|
||||||
|
BoundDirectivePropertyAst,
|
||||||
|
AttrAst,
|
||||||
|
TextAst
|
||||||
|
} from './template_ast';
|
||||||
import {LifecycleHooks} from 'angular2/src/core/linker/interfaces';
|
import {LifecycleHooks} from 'angular2/src/core/linker/interfaces';
|
||||||
|
|
||||||
export function createChangeDetectorDefinitions(
|
export function createChangeDetectorDefinitions(
|
||||||
@ -26,8 +50,7 @@ class ProtoViewVisitor implements TemplateAstVisitor {
|
|||||||
eventRecords: BindingRecord[] = [];
|
eventRecords: BindingRecord[] = [];
|
||||||
directiveRecords: DirectiveRecord[] = [];
|
directiveRecords: DirectiveRecord[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(public parent: ProtoViewVisitor, public allVisitors: ProtoViewVisitor[],
|
||||||
public parent: ProtoViewVisitor, public allVisitors: ProtoViewVisitor[],
|
|
||||||
public strategy: ChangeDetectionStrategy) {
|
public strategy: ChangeDetectionStrategy) {
|
||||||
this.viewIndex = allVisitors.length;
|
this.viewIndex = allVisitors.length;
|
||||||
allVisitors.push(this);
|
allVisitors.push(this);
|
||||||
@ -73,7 +96,8 @@ class ProtoViewVisitor implements TemplateAstVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
visitEvent(ast: BoundEventAst, directiveRecord: DirectiveRecord): any {
|
visitEvent(ast: BoundEventAst, directiveRecord: DirectiveRecord): any {
|
||||||
var bindingRecord = isPresent(directiveRecord) ?
|
var bindingRecord =
|
||||||
|
isPresent(directiveRecord) ?
|
||||||
BindingRecord.createForHostEvent(ast.handler, ast.fullName, directiveRecord) :
|
BindingRecord.createForHostEvent(ast.handler, ast.fullName, directiveRecord) :
|
||||||
BindingRecord.createForEvent(ast.handler, ast.fullName, this.boundElementCount - 1);
|
BindingRecord.createForEvent(ast.handler, ast.fullName, this.boundElementCount - 1);
|
||||||
this.eventRecords.push(bindingRecord);
|
this.eventRecords.push(bindingRecord);
|
||||||
@ -85,19 +109,23 @@ class ProtoViewVisitor implements TemplateAstVisitor {
|
|||||||
var dirIndex = isPresent(directiveRecord) ? directiveRecord.directiveIndex : null;
|
var dirIndex = isPresent(directiveRecord) ? directiveRecord.directiveIndex : null;
|
||||||
var bindingRecord;
|
var bindingRecord;
|
||||||
if (ast.type === PropertyBindingType.Property) {
|
if (ast.type === PropertyBindingType.Property) {
|
||||||
bindingRecord = isPresent(dirIndex) ?
|
bindingRecord =
|
||||||
|
isPresent(dirIndex) ?
|
||||||
BindingRecord.createForHostProperty(dirIndex, ast.value, ast.name) :
|
BindingRecord.createForHostProperty(dirIndex, ast.value, ast.name) :
|
||||||
BindingRecord.createForElementProperty(ast.value, boundElementIndex, ast.name);
|
BindingRecord.createForElementProperty(ast.value, boundElementIndex, ast.name);
|
||||||
} else if (ast.type === PropertyBindingType.Attribute) {
|
} else if (ast.type === PropertyBindingType.Attribute) {
|
||||||
bindingRecord = isPresent(dirIndex) ?
|
bindingRecord =
|
||||||
|
isPresent(dirIndex) ?
|
||||||
BindingRecord.createForHostAttribute(dirIndex, ast.value, ast.name) :
|
BindingRecord.createForHostAttribute(dirIndex, ast.value, ast.name) :
|
||||||
BindingRecord.createForElementAttribute(ast.value, boundElementIndex, ast.name);
|
BindingRecord.createForElementAttribute(ast.value, boundElementIndex, ast.name);
|
||||||
} else if (ast.type === PropertyBindingType.Class) {
|
} else if (ast.type === PropertyBindingType.Class) {
|
||||||
bindingRecord = isPresent(dirIndex) ?
|
bindingRecord =
|
||||||
|
isPresent(dirIndex) ?
|
||||||
BindingRecord.createForHostClass(dirIndex, ast.value, ast.name) :
|
BindingRecord.createForHostClass(dirIndex, ast.value, ast.name) :
|
||||||
BindingRecord.createForElementClass(ast.value, boundElementIndex, ast.name);
|
BindingRecord.createForElementClass(ast.value, boundElementIndex, ast.name);
|
||||||
} else if (ast.type === PropertyBindingType.Style) {
|
} else if (ast.type === PropertyBindingType.Style) {
|
||||||
bindingRecord = isPresent(dirIndex) ?
|
bindingRecord =
|
||||||
|
isPresent(dirIndex) ?
|
||||||
BindingRecord.createForHostStyle(dirIndex, ast.value, ast.name, ast.unit) :
|
BindingRecord.createForHostStyle(dirIndex, ast.value, ast.name, ast.unit) :
|
||||||
BindingRecord.createForElementStyle(ast.value, boundElementIndex, ast.name, ast.unit);
|
BindingRecord.createForElementStyle(ast.value, boundElementIndex, ast.name, ast.unit);
|
||||||
}
|
}
|
||||||
@ -167,8 +195,7 @@ class ProtoViewVisitor implements TemplateAstVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function createChangeDefinitions(
|
function createChangeDefinitions(pvVisitors: ProtoViewVisitor[], componentType: CompileTypeMetadata,
|
||||||
pvVisitors: ProtoViewVisitor[], componentType: CompileTypeMetadata,
|
|
||||||
genConfig: ChangeDetectorGenConfig): ChangeDetectorDefinition[] {
|
genConfig: ChangeDetectorGenConfig): ChangeDetectorDefinition[] {
|
||||||
var pvVariableNames = _collectNestedProtoViewsVariableNames(pvVisitors);
|
var pvVariableNames = _collectNestedProtoViewsVariableNames(pvVisitors);
|
||||||
return pvVisitors.map(pvVisitor => {
|
return pvVisitors.map(pvVisitor => {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import {CompileTypeMetadata} from './directive_metadata';
|
import {CompileTypeMetadata} from './directive_metadata';
|
||||||
import {SourceExpressions, moduleRef} from './source_module';
|
import {SourceExpressions, moduleRef} from './source_module';
|
||||||
import {ChangeDetectorJITGenerator} from 'angular2/src/core/change_detection/change_detection_jit_generator';
|
import {
|
||||||
|
ChangeDetectorJITGenerator
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection_jit_generator';
|
||||||
import {AbstractChangeDetector} from 'angular2/src/core/change_detection/abstract_change_detector';
|
import {AbstractChangeDetector} from 'angular2/src/core/change_detection/abstract_change_detector';
|
||||||
import {ChangeDetectionUtil} from 'angular2/src/core/change_detection/change_detection_util';
|
import {ChangeDetectionUtil} from 'angular2/src/core/change_detection/change_detection_util';
|
||||||
import {ChangeDetectorState} from 'angular2/src/core/change_detection/constants';
|
import {ChangeDetectorState} from 'angular2/src/core/change_detection/constants';
|
||||||
@ -8,16 +10,21 @@ import {ChangeDetectorState} from 'angular2/src/core/change_detection/constants'
|
|||||||
import {createChangeDetectorDefinitions} from './change_definition_factory';
|
import {createChangeDetectorDefinitions} from './change_definition_factory';
|
||||||
import {IS_DART, isJsObject, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {IS_DART, isJsObject, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {ChangeDetectorGenConfig, ChangeDetectorDefinition, DynamicProtoChangeDetector, ChangeDetectionStrategy} from 'angular2/src/core/change_detection/change_detection';
|
import {
|
||||||
|
ChangeDetectorGenConfig,
|
||||||
|
ChangeDetectorDefinition,
|
||||||
|
DynamicProtoChangeDetector,
|
||||||
|
ChangeDetectionStrategy
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
import {TemplateAst} from './template_ast';
|
import {TemplateAst} from './template_ast';
|
||||||
import {Codegen} from 'angular2/src/transform/template_compiler/change_detector_codegen';
|
import {Codegen} from 'angular2/src/transform/template_compiler/change_detector_codegen';
|
||||||
import {MODULE_SUFFIX} from './util';
|
import {MODULE_SUFFIX} from './util';
|
||||||
import {Injectable} from 'angular2/src/core/di';
|
import {Injectable} from 'angular2/src/core/di';
|
||||||
|
|
||||||
const ABSTRACT_CHANGE_DETECTOR = 'AbstractChangeDetector';
|
const ABSTRACT_CHANGE_DETECTOR = "AbstractChangeDetector";
|
||||||
const UTIL = 'ChangeDetectionUtil';
|
const UTIL = "ChangeDetectionUtil";
|
||||||
const CHANGE_DETECTOR_STATE = 'ChangeDetectorState';
|
const CHANGE_DETECTOR_STATE = "ChangeDetectorState";
|
||||||
|
|
||||||
export const CHANGE_DETECTION_JIT_IMPORTS = CONST_EXPR({
|
export const CHANGE_DETECTION_JIT_IMPORTS = CONST_EXPR({
|
||||||
'AbstractChangeDetector': AbstractChangeDetector,
|
'AbstractChangeDetector': AbstractChangeDetector,
|
||||||
@ -38,13 +45,12 @@ var CONSTANTS_MODULE =
|
|||||||
export class ChangeDetectionCompiler {
|
export class ChangeDetectionCompiler {
|
||||||
constructor(private _genConfig: ChangeDetectorGenConfig) {}
|
constructor(private _genConfig: ChangeDetectorGenConfig) {}
|
||||||
|
|
||||||
compileComponentRuntime(
|
compileComponentRuntime(componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
|
||||||
componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
|
|
||||||
parsedTemplate: TemplateAst[]): Function[] {
|
parsedTemplate: TemplateAst[]): Function[] {
|
||||||
var changeDetectorDefinitions =
|
var changeDetectorDefinitions =
|
||||||
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
||||||
return changeDetectorDefinitions.map(
|
return changeDetectorDefinitions.map(definition =>
|
||||||
definition => this._createChangeDetectorFactory(definition));
|
this._createChangeDetectorFactory(definition));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createChangeDetectorFactory(definition: ChangeDetectorDefinition): Function {
|
private _createChangeDetectorFactory(definition: ChangeDetectorDefinition): Function {
|
||||||
@ -52,8 +58,7 @@ export class ChangeDetectionCompiler {
|
|||||||
return () => proto.instantiate();
|
return () => proto.instantiate();
|
||||||
}
|
}
|
||||||
|
|
||||||
compileComponentCodeGen(
|
compileComponentCodeGen(componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
|
||||||
componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
|
|
||||||
parsedTemplate: TemplateAst[]): SourceExpressions {
|
parsedTemplate: TemplateAst[]): SourceExpressions {
|
||||||
var changeDetectorDefinitions =
|
var changeDetectorDefinitions =
|
||||||
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import {RuntimeCompiler_} from './runtime_compiler';
|
import {RuntimeCompiler_} from "./runtime_compiler";
|
||||||
export {TemplateCompiler} from './template_compiler';
|
export {TemplateCompiler} from './template_compiler';
|
||||||
export {CompileDirectiveMetadata, CompileTypeMetadata, CompileTemplateMetadata} from './directive_metadata';
|
export {
|
||||||
|
CompileDirectiveMetadata,
|
||||||
|
CompileTypeMetadata,
|
||||||
|
CompileTemplateMetadata
|
||||||
|
} from './directive_metadata';
|
||||||
export {SourceModule, SourceWithImports} from './source_module';
|
export {SourceModule, SourceWithImports} from './source_module';
|
||||||
export {PLATFORM_DIRECTIVES, PLATFORM_PIPES} from 'angular2/src/core/platform_directives_and_pipes';
|
export {PLATFORM_DIRECTIVES, PLATFORM_PIPES} from 'angular2/src/core/platform_directives_and_pipes';
|
||||||
export * from 'angular2/src/compiler/template_ast';
|
export * from 'angular2/src/compiler/template_ast';
|
||||||
@ -33,11 +37,22 @@ function _createChangeDetectorGenConfig() {
|
|||||||
* template compilation.
|
* template compilation.
|
||||||
*/
|
*/
|
||||||
export const COMPILER_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([
|
export const COMPILER_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([
|
||||||
Lexer, Parser, HtmlParser, TemplateParser, TemplateNormalizer, RuntimeMetadataResolver,
|
Lexer,
|
||||||
DEFAULT_PACKAGE_URL_PROVIDER, StyleCompiler, ProtoViewCompiler, ViewCompiler,
|
Parser,
|
||||||
|
HtmlParser,
|
||||||
|
TemplateParser,
|
||||||
|
TemplateNormalizer,
|
||||||
|
RuntimeMetadataResolver,
|
||||||
|
DEFAULT_PACKAGE_URL_PROVIDER,
|
||||||
|
StyleCompiler,
|
||||||
|
ProtoViewCompiler,
|
||||||
|
ViewCompiler,
|
||||||
ChangeDetectionCompiler,
|
ChangeDetectionCompiler,
|
||||||
new Provider(ChangeDetectorGenConfig, {useFactory: _createChangeDetectorGenConfig, deps: []}),
|
new Provider(ChangeDetectorGenConfig, {useFactory: _createChangeDetectorGenConfig, deps: []}),
|
||||||
TemplateCompiler, new Provider(RuntimeCompiler, {useClass: RuntimeCompiler_}),
|
TemplateCompiler,
|
||||||
new Provider(Compiler, {useExisting: RuntimeCompiler}), DomElementSchemaRegistry,
|
new Provider(RuntimeCompiler, {useClass: RuntimeCompiler_}),
|
||||||
new Provider(ElementSchemaRegistry, {useExisting: DomElementSchemaRegistry}), UrlResolver
|
new Provider(Compiler, {useExisting: RuntimeCompiler}),
|
||||||
|
DomElementSchemaRegistry,
|
||||||
|
new Provider(ElementSchemaRegistry, {useExisting: DomElementSchemaRegistry}),
|
||||||
|
UrlResolver
|
||||||
]);
|
]);
|
||||||
|
@ -1,9 +1,65 @@
|
|||||||
import {NumberWrapper, StringWrapper, isPresent, resolveEnumToken} from 'angular2/src/facade/lang';
|
import {NumberWrapper, StringWrapper, isPresent, resolveEnumToken} from "angular2/src/facade/lang";
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
|
|
||||||
import {isWhitespace, $EOF, $HASH, $TILDA, $CARET, $PERCENT, $$, $_, $COLON, $SQ, $DQ, $EQ, $SLASH, $BACKSLASH, $PERIOD, $STAR, $PLUS, $LPAREN, $RPAREN, $LBRACE, $RBRACE, $LBRACKET, $RBRACKET, $PIPE, $COMMA, $SEMICOLON, $MINUS, $BANG, $QUESTION, $AT, $AMPERSAND, $GT, $a, $A, $z, $Z, $0, $9, $FF, $CR, $LF, $VTAB} from 'angular2/src/compiler/chars';
|
import {
|
||||||
|
isWhitespace,
|
||||||
|
$EOF,
|
||||||
|
$HASH,
|
||||||
|
$TILDA,
|
||||||
|
$CARET,
|
||||||
|
$PERCENT,
|
||||||
|
$$,
|
||||||
|
$_,
|
||||||
|
$COLON,
|
||||||
|
$SQ,
|
||||||
|
$DQ,
|
||||||
|
$EQ,
|
||||||
|
$SLASH,
|
||||||
|
$BACKSLASH,
|
||||||
|
$PERIOD,
|
||||||
|
$STAR,
|
||||||
|
$PLUS,
|
||||||
|
$LPAREN,
|
||||||
|
$RPAREN,
|
||||||
|
$LBRACE,
|
||||||
|
$RBRACE,
|
||||||
|
$LBRACKET,
|
||||||
|
$RBRACKET,
|
||||||
|
$PIPE,
|
||||||
|
$COMMA,
|
||||||
|
$SEMICOLON,
|
||||||
|
$MINUS,
|
||||||
|
$BANG,
|
||||||
|
$QUESTION,
|
||||||
|
$AT,
|
||||||
|
$AMPERSAND,
|
||||||
|
$GT,
|
||||||
|
$a,
|
||||||
|
$A,
|
||||||
|
$z,
|
||||||
|
$Z,
|
||||||
|
$0,
|
||||||
|
$9,
|
||||||
|
$FF,
|
||||||
|
$CR,
|
||||||
|
$LF,
|
||||||
|
$VTAB
|
||||||
|
} from "angular2/src/compiler/chars";
|
||||||
|
|
||||||
export {$EOF, $AT, $RBRACE, $LBRACE, $LBRACKET, $RBRACKET, $LPAREN, $RPAREN, $COMMA, $COLON, $SEMICOLON, isWhitespace} from 'angular2/src/compiler/chars';
|
export {
|
||||||
|
$EOF,
|
||||||
|
$AT,
|
||||||
|
$RBRACE,
|
||||||
|
$LBRACE,
|
||||||
|
$LBRACKET,
|
||||||
|
$RBRACKET,
|
||||||
|
$LPAREN,
|
||||||
|
$RPAREN,
|
||||||
|
$COMMA,
|
||||||
|
$COLON,
|
||||||
|
$SEMICOLON,
|
||||||
|
isWhitespace
|
||||||
|
} from "angular2/src/compiler/chars";
|
||||||
|
|
||||||
export enum CssTokenType {
|
export enum CssTokenType {
|
||||||
EOF,
|
EOF,
|
||||||
@ -38,37 +94,35 @@ export class LexedCssResult {
|
|||||||
constructor(public error: CssScannerError, public token: CssToken) {}
|
constructor(public error: CssScannerError, public token: CssToken) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateErrorMessage(
|
export function generateErrorMessage(input: string, message: string, errorValue: string,
|
||||||
input: string, message: string, errorValue: string, index: number, row: number,
|
index: number, row: number, column: number): string {
|
||||||
column: number): string {
|
|
||||||
return `${message} at column ${row}:${column} in expression [` +
|
return `${message} at column ${row}:${column} in expression [` +
|
||||||
findProblemCode(input, errorValue, index, column) + ']';
|
findProblemCode(input, errorValue, index, column) + ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findProblemCode(
|
export function findProblemCode(input: string, errorValue: string, index: number,
|
||||||
input: string, errorValue: string, index: number, column: number): string {
|
column: number): string {
|
||||||
var endOfProblemLine = index;
|
var endOfProblemLine = index;
|
||||||
var current = charCode(input, index);
|
var current = charCode(input, index);
|
||||||
while (current > 0 && !isNewline(current)) {
|
while (current > 0 && !isNewline(current)) {
|
||||||
current = charCode(input, ++endOfProblemLine);
|
current = charCode(input, ++endOfProblemLine);
|
||||||
}
|
}
|
||||||
var choppedString = input.substring(0, endOfProblemLine);
|
var choppedString = input.substring(0, endOfProblemLine);
|
||||||
var pointerPadding = '';
|
var pointerPadding = "";
|
||||||
for (var i = 0; i < column; i++) {
|
for (var i = 0; i < column; i++) {
|
||||||
pointerPadding += ' ';
|
pointerPadding += " ";
|
||||||
}
|
}
|
||||||
var pointerString = '';
|
var pointerString = "";
|
||||||
for (var i = 0; i < errorValue.length; i++) {
|
for (var i = 0; i < errorValue.length; i++) {
|
||||||
pointerString += '^';
|
pointerString += "^";
|
||||||
}
|
}
|
||||||
return choppedString + '\n' + pointerPadding + pointerString + '\n';
|
return choppedString + "\n" + pointerPadding + pointerString + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CssToken {
|
export class CssToken {
|
||||||
numValue: number;
|
numValue: number;
|
||||||
constructor(
|
constructor(public index: number, public column: number, public line: number,
|
||||||
public index: number, public column: number, public line: number, public type: CssTokenType,
|
public type: CssTokenType, public strValue: string) {
|
||||||
public strValue: string) {
|
|
||||||
this.numValue = charCode(strValue, 0);
|
this.numValue = charCode(strValue, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +248,7 @@ export class CssScanner {
|
|||||||
|
|
||||||
var next = output.token;
|
var next = output.token;
|
||||||
if (!isPresent(next)) {
|
if (!isPresent(next)) {
|
||||||
next = new CssToken(0, 0, 0, CssTokenType.EOF, 'end of file');
|
next = new CssToken(0, 0, 0, CssTokenType.EOF, "end of file");
|
||||||
}
|
}
|
||||||
|
|
||||||
var isMatchingType;
|
var isMatchingType;
|
||||||
@ -211,17 +265,16 @@ export class CssScanner {
|
|||||||
|
|
||||||
var error = null;
|
var error = null;
|
||||||
if (!isMatchingType || (isPresent(value) && value != next.strValue)) {
|
if (!isMatchingType || (isPresent(value) && value != next.strValue)) {
|
||||||
var errorMessage = resolveEnumToken(CssTokenType, next.type) + ' does not match expected ' +
|
var errorMessage = resolveEnumToken(CssTokenType, next.type) + " does not match expected " +
|
||||||
resolveEnumToken(CssTokenType, type) + ' value';
|
resolveEnumToken(CssTokenType, type) + " value";
|
||||||
|
|
||||||
if (isPresent(value)) {
|
if (isPresent(value)) {
|
||||||
errorMessage += ' ("' + next.strValue + '" should match "' + value + '")';
|
errorMessage += ' ("' + next.strValue + '" should match "' + value + '")';
|
||||||
}
|
}
|
||||||
|
|
||||||
error = new CssScannerError(
|
error = new CssScannerError(
|
||||||
next, generateErrorMessage(
|
next, generateErrorMessage(this.input, errorMessage, next.strValue, previousIndex,
|
||||||
this.input, errorMessage, next.strValue, previousIndex, previousLine,
|
previousLine, previousColumn));
|
||||||
previousColumn));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LexedCssResult(error, next);
|
return new LexedCssResult(error, next);
|
||||||
@ -301,8 +354,8 @@ export class CssScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scanComment(): CssToken {
|
scanComment(): CssToken {
|
||||||
if (this.assertCondition(
|
if (this.assertCondition(isCommentStart(this.peek, this.peekPeek),
|
||||||
isCommentStart(this.peek, this.peekPeek), 'Expected comment start value')) {
|
"Expected comment start value")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,8 +392,8 @@ export class CssScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scanString(): CssToken {
|
scanString(): CssToken {
|
||||||
if (this.assertCondition(
|
if (this.assertCondition(isStringStart(this.peek, this.peekPeek),
|
||||||
isStringStart(this.peek, this.peekPeek), 'Unexpected non-string starting value')) {
|
"Unexpected non-string starting value")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +412,7 @@ export class CssScanner {
|
|||||||
this.advance();
|
this.advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.assertCondition(this.peek == target, 'Unterminated quote')) {
|
if (this.assertCondition(this.peek == target, "Unterminated quote")) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
this.advance();
|
this.advance();
|
||||||
@ -389,8 +442,8 @@ export class CssScanner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scanIdentifier(): CssToken {
|
scanIdentifier(): CssToken {
|
||||||
if (this.assertCondition(
|
if (this.assertCondition(isIdentifierStart(this.peek, this.peekPeek),
|
||||||
isIdentifierStart(this.peek, this.peekPeek), 'Expected identifier starting value')) {
|
'Expected identifier starting value')) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,8 +469,7 @@ export class CssScanner {
|
|||||||
scanCharacter(): CssToken {
|
scanCharacter(): CssToken {
|
||||||
var start = this.index;
|
var start = this.index;
|
||||||
var startingColumn = this.column;
|
var startingColumn = this.column;
|
||||||
if (this.assertCondition(
|
if (this.assertCondition(isValidCssCharacter(this.peek, this._currentMode),
|
||||||
isValidCssCharacter(this.peek, this._currentMode),
|
|
||||||
charStr(this.peek) + ' is not a valid CSS character')) {
|
charStr(this.peek) + ' is not a valid CSS character')) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,40 @@
|
|||||||
import {ParseSourceSpan, ParseSourceFile, ParseLocation, ParseError} from 'angular2/src/compiler/parse_util';
|
import {
|
||||||
|
ParseSourceSpan,
|
||||||
|
ParseSourceFile,
|
||||||
|
ParseLocation,
|
||||||
|
ParseError
|
||||||
|
} from "angular2/src/compiler/parse_util";
|
||||||
|
|
||||||
import {bitWiseOr, bitWiseAnd, NumberWrapper, StringWrapper, isPresent} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
bitWiseOr,
|
||||||
|
bitWiseAnd,
|
||||||
|
NumberWrapper,
|
||||||
|
StringWrapper,
|
||||||
|
isPresent
|
||||||
|
} from "angular2/src/facade/lang";
|
||||||
|
|
||||||
import {CssLexerMode, CssToken, CssTokenType, CssScanner, CssScannerError, generateErrorMessage, $AT, $EOF, $RBRACE, $LBRACE, $LBRACKET, $RBRACKET, $LPAREN, $RPAREN, $COMMA, $COLON, $SEMICOLON, isNewline} from 'angular2/src/compiler/css/lexer';
|
import {
|
||||||
|
CssLexerMode,
|
||||||
|
CssToken,
|
||||||
|
CssTokenType,
|
||||||
|
CssScanner,
|
||||||
|
CssScannerError,
|
||||||
|
generateErrorMessage,
|
||||||
|
$AT,
|
||||||
|
$EOF,
|
||||||
|
$RBRACE,
|
||||||
|
$LBRACE,
|
||||||
|
$LBRACKET,
|
||||||
|
$RBRACKET,
|
||||||
|
$LPAREN,
|
||||||
|
$RPAREN,
|
||||||
|
$COMMA,
|
||||||
|
$COLON,
|
||||||
|
$SEMICOLON,
|
||||||
|
isNewline
|
||||||
|
} from "angular2/src/compiler/css/lexer";
|
||||||
|
|
||||||
export {CssToken} from 'angular2/src/compiler/css/lexer';
|
export {CssToken} from "angular2/src/compiler/css/lexer";
|
||||||
|
|
||||||
export enum BlockType {
|
export enum BlockType {
|
||||||
Import,
|
Import,
|
||||||
@ -30,7 +60,7 @@ const SEMICOLON_DELIM = 32;
|
|||||||
const NEWLINE_DELIM = 64;
|
const NEWLINE_DELIM = 64;
|
||||||
const RPAREN_DELIM = 128;
|
const RPAREN_DELIM = 128;
|
||||||
|
|
||||||
function mergeTokens(tokens: CssToken[], separator: string = ''): CssToken {
|
function mergeTokens(tokens: CssToken[], separator: string = ""): CssToken {
|
||||||
var mainToken = tokens[0];
|
var mainToken = tokens[0];
|
||||||
var str = mainToken.strValue;
|
var str = mainToken.strValue;
|
||||||
for (var i = 1; i < tokens.length; i++) {
|
for (var i = 1; i < tokens.length; i++) {
|
||||||
@ -175,8 +205,7 @@ export class CssParser {
|
|||||||
|
|
||||||
var token = this._scan();
|
var token = this._scan();
|
||||||
|
|
||||||
this._assertCondition(
|
this._assertCondition(token.type == CssTokenType.AtKeyword,
|
||||||
token.type == CssTokenType.AtKeyword,
|
|
||||||
`The CSS Rule ${token.strValue} is not a valid [@] rule.`, token);
|
`The CSS Rule ${token.strValue} is not a valid [@] rule.`, token);
|
||||||
|
|
||||||
var block, type = this._resolveBlockType(token);
|
var block, type = this._resolveBlockType(token);
|
||||||
@ -216,11 +245,10 @@ export class CssParser {
|
|||||||
default:
|
default:
|
||||||
var listOfTokens = [];
|
var listOfTokens = [];
|
||||||
this._scanner.setMode(CssLexerMode.ALL);
|
this._scanner.setMode(CssLexerMode.ALL);
|
||||||
this._error(
|
this._error(generateErrorMessage(
|
||||||
generateErrorMessage(
|
|
||||||
this._scanner.input,
|
this._scanner.input,
|
||||||
`The CSS "at" rule "${token.strValue}" is not allowed to used here`, token.strValue,
|
`The CSS "at" rule "${token.strValue}" is not allowed to used here`,
|
||||||
token.index, token.line, token.column),
|
token.strValue, token.index, token.line, token.column),
|
||||||
token);
|
token);
|
||||||
|
|
||||||
this._collectUntilDelim(bitWiseOr([delimiters, LBRACE_DELIM, SEMICOLON_DELIM]))
|
this._collectUntilDelim(bitWiseOr([delimiters, LBRACE_DELIM, SEMICOLON_DELIM]))
|
||||||
@ -375,7 +403,7 @@ export class CssParser {
|
|||||||
// contains an inner selector that needs to be parsed
|
// contains an inner selector that needs to be parsed
|
||||||
// in isolation
|
// in isolation
|
||||||
if (this._scanner.getMode() == CssLexerMode.PSEUDO_SELECTOR && isPresent(previousToken) &&
|
if (this._scanner.getMode() == CssLexerMode.PSEUDO_SELECTOR && isPresent(previousToken) &&
|
||||||
previousToken.numValue == $COLON && token.strValue == 'not' &&
|
previousToken.numValue == $COLON && token.strValue == "not" &&
|
||||||
this._scanner.peek == $LPAREN) {
|
this._scanner.peek == $LPAREN) {
|
||||||
selectorCssTokens.push(token);
|
selectorCssTokens.push(token);
|
||||||
selectorCssTokens.push(this._consume(CssTokenType.Character, '('));
|
selectorCssTokens.push(this._consume(CssTokenType.Character, '('));
|
||||||
@ -425,7 +453,7 @@ export class CssParser {
|
|||||||
|
|
||||||
this._scanner.setMode(CssLexerMode.STYLE_VALUE);
|
this._scanner.setMode(CssLexerMode.STYLE_VALUE);
|
||||||
|
|
||||||
var strValue = '';
|
var strValue = "";
|
||||||
var tokens = [];
|
var tokens = [];
|
||||||
var previous: CssToken;
|
var previous: CssToken;
|
||||||
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
|
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
|
||||||
@ -465,8 +493,8 @@ export class CssParser {
|
|||||||
this._consume(CssTokenType.Character, ';');
|
this._consume(CssTokenType.Character, ';');
|
||||||
} else if (code != $RBRACE) {
|
} else if (code != $RBRACE) {
|
||||||
this._error(
|
this._error(
|
||||||
generateErrorMessage(
|
generateErrorMessage(this._scanner.input,
|
||||||
this._scanner.input, `The CSS key/value definition did not end with a semicolon`,
|
`The CSS key/value definition did not end with a semicolon`,
|
||||||
previous.strValue, previous.index, previous.line, previous.column),
|
previous.strValue, previous.index, previous.line, previous.column),
|
||||||
previous);
|
previous);
|
||||||
}
|
}
|
||||||
@ -564,7 +592,7 @@ export class CssParser {
|
|||||||
remainingTokens.forEach((token) => { propStr.push(token.strValue); });
|
remainingTokens.forEach((token) => { propStr.push(token.strValue); });
|
||||||
}
|
}
|
||||||
|
|
||||||
prop = new CssToken(prop.index, prop.column, prop.line, prop.type, propStr.join(' '));
|
prop = new CssToken(prop.index, prop.column, prop.line, prop.type, propStr.join(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
// this means we've reached the end of the definition and/or block
|
// this means we've reached the end of the definition and/or block
|
||||||
@ -580,9 +608,8 @@ export class CssParser {
|
|||||||
if (parseValue) {
|
if (parseValue) {
|
||||||
value = this._parseValue(delimiters);
|
value = this._parseValue(delimiters);
|
||||||
} else {
|
} else {
|
||||||
this._error(
|
this._error(generateErrorMessage(this._scanner.input,
|
||||||
generateErrorMessage(
|
`The CSS property was not paired with a style value`,
|
||||||
this._scanner.input, `The CSS property was not paired with a style value`,
|
|
||||||
prop.strValue, prop.index, prop.line, prop.column),
|
prop.strValue, prop.index, prop.line, prop.column),
|
||||||
prop);
|
prop);
|
||||||
}
|
}
|
||||||
@ -602,8 +629,8 @@ export class CssParser {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_error(message: string, problemToken: CssToken) {
|
_error(message: string, problemToken: CssToken) {
|
||||||
var length = problemToken.strValue.length;
|
var length = problemToken.strValue.length;
|
||||||
var error = CssParseError.create(
|
var error = CssParseError.create(this._file, 0, problemToken.line, problemToken.column, length,
|
||||||
this._file, 0, problemToken.line, problemToken.column, length, message);
|
message);
|
||||||
this._errors.push(error);
|
this._errors.push(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,7 +657,7 @@ export class CssKeyframeRuleAST extends CssBlockRuleAST {
|
|||||||
export class CssKeyframeDefinitionAST extends CssBlockRuleAST {
|
export class CssKeyframeDefinitionAST extends CssBlockRuleAST {
|
||||||
public steps;
|
public steps;
|
||||||
constructor(_steps: CssToken[], block: CssBlockAST) {
|
constructor(_steps: CssToken[], block: CssBlockAST) {
|
||||||
super(BlockType.Keyframes, block, mergeTokens(_steps, ','));
|
super(BlockType.Keyframes, block, mergeTokens(_steps, ","));
|
||||||
this.steps = _steps;
|
this.steps = _steps;
|
||||||
}
|
}
|
||||||
visit(visitor: CssASTVisitor, context?: any) {
|
visit(visitor: CssASTVisitor, context?: any) {
|
||||||
@ -642,11 +669,10 @@ export class CssBlockDefinitionRuleAST extends CssBlockRuleAST {
|
|||||||
public strValue: string;
|
public strValue: string;
|
||||||
constructor(type: BlockType, public query: CssToken[], block: CssBlockAST) {
|
constructor(type: BlockType, public query: CssToken[], block: CssBlockAST) {
|
||||||
super(type, block);
|
super(type, block);
|
||||||
this.strValue = query.map(token => token.strValue).join('');
|
this.strValue = query.map(token => token.strValue).join("");
|
||||||
var firstCssToken: CssToken = query[0];
|
var firstCssToken: CssToken = query[0];
|
||||||
this.name = new CssToken(
|
this.name = new CssToken(firstCssToken.index, firstCssToken.column, firstCssToken.line,
|
||||||
firstCssToken.index, firstCssToken.column, firstCssToken.line, CssTokenType.Identifier,
|
CssTokenType.Identifier, this.strValue);
|
||||||
this.strValue);
|
|
||||||
}
|
}
|
||||||
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssBlock(this.block, context); }
|
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssBlock(this.block, context); }
|
||||||
}
|
}
|
||||||
@ -666,7 +692,7 @@ export class CssSelectorRuleAST extends CssBlockRuleAST {
|
|||||||
|
|
||||||
constructor(public selectors: CssSelectorAST[], block: CssBlockAST) {
|
constructor(public selectors: CssSelectorAST[], block: CssBlockAST) {
|
||||||
super(BlockType.Selector, block);
|
super(BlockType.Selector, block);
|
||||||
this.strValue = selectors.map(selector => selector.strValue).join(',');
|
this.strValue = selectors.map(selector => selector.strValue).join(",");
|
||||||
}
|
}
|
||||||
|
|
||||||
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelectorRule(this, context); }
|
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelectorRule(this, context); }
|
||||||
@ -681,7 +707,7 @@ export class CssSelectorAST extends CssAST {
|
|||||||
public strValue;
|
public strValue;
|
||||||
constructor(public tokens: CssToken[], public isComplex: boolean = false) {
|
constructor(public tokens: CssToken[], public isComplex: boolean = false) {
|
||||||
super();
|
super();
|
||||||
this.strValue = tokens.map(token => token.strValue).join('');
|
this.strValue = tokens.map(token => token.strValue).join("");
|
||||||
}
|
}
|
||||||
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelector(this, context); }
|
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelector(this, context); }
|
||||||
}
|
}
|
||||||
@ -697,13 +723,12 @@ export class CssStyleSheetAST extends CssAST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CssParseError extends ParseError {
|
export class CssParseError extends ParseError {
|
||||||
static create(
|
static create(file: ParseSourceFile, offset: number, line: number, col: number, length: number,
|
||||||
file: ParseSourceFile, offset: number, line: number, col: number, length: number,
|
|
||||||
errMsg: string): CssParseError {
|
errMsg: string): CssParseError {
|
||||||
var start = new ParseLocation(file, offset, line, col);
|
var start = new ParseLocation(file, offset, line, col);
|
||||||
var end = new ParseLocation(file, offset, line, col + length);
|
var end = new ParseLocation(file, offset, line, col + length);
|
||||||
var span = new ParseSourceSpan(start, end);
|
var span = new ParseSourceSpan(start, end);
|
||||||
return new CssParseError(span, 'CSS Parse Error: ' + errMsg);
|
return new CssParseError(span, "CSS Parse Error: " + errMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(span: ParseSourceSpan, message: string) { super(span, message); }
|
constructor(span: ParseSourceSpan, message: string) { super(span, message); }
|
||||||
|
@ -1,7 +1,23 @@
|
|||||||
import {isPresent, isBlank, isNumber, isBoolean, normalizeBool, normalizeBlank, serializeEnum, Type, isString, RegExpWrapper, StringWrapper, isArray} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
isNumber,
|
||||||
|
isBoolean,
|
||||||
|
normalizeBool,
|
||||||
|
normalizeBlank,
|
||||||
|
serializeEnum,
|
||||||
|
Type,
|
||||||
|
isString,
|
||||||
|
RegExpWrapper,
|
||||||
|
StringWrapper,
|
||||||
|
isArray
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {unimplemented} from 'angular2/src/facade/exceptions';
|
import {unimplemented} from 'angular2/src/facade/exceptions';
|
||||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {ChangeDetectionStrategy, CHANGE_DETECTION_STRATEGY_VALUES} from 'angular2/src/core/change_detection/change_detection';
|
import {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
CHANGE_DETECTION_STRATEGY_VALUES
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
import {ViewEncapsulation, VIEW_ENCAPSULATION_VALUES} from 'angular2/src/core/metadata/view';
|
import {ViewEncapsulation, VIEW_ENCAPSULATION_VALUES} from 'angular2/src/core/metadata/view';
|
||||||
import {CssSelector} from 'angular2/src/compiler/selector';
|
import {CssSelector} from 'angular2/src/compiler/selector';
|
||||||
import {splitAtColon} from './util';
|
import {splitAtColon} from './util';
|
||||||
@ -385,8 +401,8 @@ export class CompileTemplateMetadata {
|
|||||||
|
|
||||||
toJson(): {[key: string]: any} {
|
toJson(): {[key: string]: any} {
|
||||||
return {
|
return {
|
||||||
'encapsulation': isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) :
|
'encapsulation':
|
||||||
this.encapsulation,
|
isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) : this.encapsulation,
|
||||||
'template': this.template,
|
'template': this.template,
|
||||||
'templateUrl': this.templateUrl,
|
'templateUrl': this.templateUrl,
|
||||||
'styles': this.styles,
|
'styles': this.styles,
|
||||||
@ -400,9 +416,9 @@ export class CompileTemplateMetadata {
|
|||||||
* Metadata regarding compilation of a directive.
|
* Metadata regarding compilation of a directive.
|
||||||
*/
|
*/
|
||||||
export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
||||||
static create(
|
static create({type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs,
|
||||||
{type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs, outputs,
|
outputs, host, lifecycleHooks, providers, viewProviders, queries, viewQueries,
|
||||||
host, lifecycleHooks, providers, viewProviders, queries, viewQueries, template}: {
|
template}: {
|
||||||
type?: CompileTypeMetadata,
|
type?: CompileTypeMetadata,
|
||||||
isComponent?: boolean,
|
isComponent?: boolean,
|
||||||
dynamicLoadable?: boolean,
|
dynamicLoadable?: boolean,
|
||||||
@ -492,10 +508,9 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
|||||||
queries: CompileQueryMetadata[];
|
queries: CompileQueryMetadata[];
|
||||||
viewQueries: CompileQueryMetadata[];
|
viewQueries: CompileQueryMetadata[];
|
||||||
template: CompileTemplateMetadata;
|
template: CompileTemplateMetadata;
|
||||||
constructor(
|
constructor({type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs,
|
||||||
{type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs, outputs,
|
outputs, hostListeners, hostProperties, hostAttributes, lifecycleHooks, providers,
|
||||||
hostListeners, hostProperties, hostAttributes, lifecycleHooks, providers, viewProviders,
|
viewProviders, queries, viewQueries, template}: {
|
||||||
queries, viewQueries, template}: {
|
|
||||||
type?: CompileTypeMetadata,
|
type?: CompileTypeMetadata,
|
||||||
isComponent?: boolean,
|
isComponent?: boolean,
|
||||||
dynamicLoadable?: boolean,
|
dynamicLoadable?: boolean,
|
||||||
@ -591,8 +606,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
|
|||||||
/**
|
/**
|
||||||
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
|
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
|
||||||
*/
|
*/
|
||||||
export function createHostComponentMeta(
|
export function createHostComponentMeta(componentType: CompileTypeMetadata,
|
||||||
componentType: CompileTypeMetadata, componentSelector: string): CompileDirectiveMetadata {
|
componentSelector: string): CompileDirectiveMetadata {
|
||||||
var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate();
|
var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate();
|
||||||
return CompileDirectiveMetadata.create({
|
return CompileDirectiveMetadata.create({
|
||||||
type: new CompileTypeMetadata({
|
type: new CompileTypeMetadata({
|
||||||
@ -623,9 +638,8 @@ export class CompilePipeMetadata implements CompileMetadataWithType {
|
|||||||
type: CompileTypeMetadata;
|
type: CompileTypeMetadata;
|
||||||
name: string;
|
name: string;
|
||||||
pure: boolean;
|
pure: boolean;
|
||||||
constructor({type, name, pure}: {type?: CompileTypeMetadata,
|
constructor({type, name,
|
||||||
name?: string,
|
pure}: {type?: CompileTypeMetadata, name?: string, pure?: boolean} = {}) {
|
||||||
pure?: boolean} = {}) {
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.pure = normalizeBool(pure);
|
this.pure = normalizeBool(pure);
|
||||||
|
@ -18,8 +18,7 @@ export class HtmlAttrAst implements HtmlAst {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class HtmlElementAst implements HtmlAst {
|
export class HtmlElementAst implements HtmlAst {
|
||||||
constructor(
|
constructor(public name: string, public attrs: HtmlAttrAst[], public children: HtmlAst[],
|
||||||
public name: string, public attrs: HtmlAttrAst[], public children: HtmlAst[],
|
|
||||||
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
|
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
|
||||||
public endSourceSpan: ParseSourceSpan) {}
|
public endSourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: HtmlAstVisitor, context: any): any { return visitor.visitElement(this, context); }
|
visit(visitor: HtmlAstVisitor, context: any): any { return visitor.visitElement(this, context); }
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import {StringWrapper, NumberWrapper, isPresent, isBlank, CONST_EXPR, serializeEnum} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
StringWrapper,
|
||||||
|
NumberWrapper,
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
CONST_EXPR,
|
||||||
|
serializeEnum
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {ParseLocation, ParseError, ParseSourceFile, ParseSourceSpan} from './parse_util';
|
import {ParseLocation, ParseError, ParseSourceFile, ParseSourceSpan} from './parse_util';
|
||||||
import {getHtmlTagDefinition, HtmlTagContentType, NAMED_ENTITIES} from './html_tags';
|
import {getHtmlTagDefinition, HtmlTagContentType, NAMED_ENTITIES} from './html_tags';
|
||||||
@ -22,8 +29,8 @@ export enum HtmlTokenType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class HtmlToken {
|
export class HtmlToken {
|
||||||
constructor(
|
constructor(public type: HtmlTokenType, public parts: string[],
|
||||||
public type: HtmlTokenType, public parts: string[], public sourceSpan: ParseSourceSpan) {}
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HtmlTokenError extends ParseError {
|
export class HtmlTokenError extends ParseError {
|
||||||
@ -184,8 +191,8 @@ class _HtmlTokenizer {
|
|||||||
if (isBlank(end)) {
|
if (isBlank(end)) {
|
||||||
end = this._getLocation();
|
end = this._getLocation();
|
||||||
}
|
}
|
||||||
var token = new HtmlToken(
|
var token = new HtmlToken(this.currentTokenType, parts,
|
||||||
this.currentTokenType, parts, new ParseSourceSpan(this.currentTokenStart, end));
|
new ParseSourceSpan(this.currentTokenStart, end));
|
||||||
this.tokens.push(token);
|
this.tokens.push(token);
|
||||||
this.currentTokenStart = null;
|
this.currentTokenStart = null;
|
||||||
this.currentTokenType = null;
|
this.currentTokenType = null;
|
||||||
@ -232,8 +239,8 @@ class _HtmlTokenizer {
|
|||||||
private _requireCharCode(charCode: number) {
|
private _requireCharCode(charCode: number) {
|
||||||
var location = this._getLocation();
|
var location = this._getLocation();
|
||||||
if (!this._attemptCharCode(charCode)) {
|
if (!this._attemptCharCode(charCode)) {
|
||||||
throw this._createError(
|
throw this._createError(unexpectedCharacterErrorMsg(this.peek),
|
||||||
unexpectedCharacterErrorMsg(this.peek), this._getSpan(location, location));
|
this._getSpan(location, location));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,12 +335,12 @@ class _HtmlTokenizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _consumeRawText(
|
private _consumeRawText(decodeEntities: boolean, firstCharOfEnd: number,
|
||||||
decodeEntities: boolean, firstCharOfEnd: number, attemptEndRest: Function): HtmlToken {
|
attemptEndRest: Function): HtmlToken {
|
||||||
var tagCloseStart;
|
var tagCloseStart;
|
||||||
var textStart = this._getLocation();
|
var textStart = this._getLocation();
|
||||||
this._beginToken(
|
this._beginToken(decodeEntities ? HtmlTokenType.ESCAPABLE_RAW_TEXT : HtmlTokenType.RAW_TEXT,
|
||||||
decodeEntities ? HtmlTokenType.ESCAPABLE_RAW_TEXT : HtmlTokenType.RAW_TEXT, textStart);
|
textStart);
|
||||||
var parts = [];
|
var parts = [];
|
||||||
while (true) {
|
while (true) {
|
||||||
tagCloseStart = this._getLocation();
|
tagCloseStart = this._getLocation();
|
||||||
|
@ -1,4 +1,13 @@
|
|||||||
import {isPresent, isBlank, StringWrapper, stringify, assertionsEnabled, StringJoiner, serializeEnum, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
StringWrapper,
|
||||||
|
stringify,
|
||||||
|
assertionsEnabled,
|
||||||
|
StringJoiner,
|
||||||
|
serializeEnum,
|
||||||
|
CONST_EXPR
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
@ -26,9 +35,8 @@ export class HtmlParser {
|
|||||||
parse(sourceContent: string, sourceUrl: string): HtmlParseTreeResult {
|
parse(sourceContent: string, sourceUrl: string): HtmlParseTreeResult {
|
||||||
var tokensAndErrors = tokenizeHtml(sourceContent, sourceUrl);
|
var tokensAndErrors = tokenizeHtml(sourceContent, sourceUrl);
|
||||||
var treeAndErrors = new TreeBuilder(tokensAndErrors.tokens).build();
|
var treeAndErrors = new TreeBuilder(tokensAndErrors.tokens).build();
|
||||||
return new HtmlParseTreeResult(
|
return new HtmlParseTreeResult(treeAndErrors.rootNodes, (<ParseError[]>tokensAndErrors.errors)
|
||||||
treeAndErrors.rootNodes,
|
.concat(treeAndErrors.errors));
|
||||||
(<ParseError[]>tokensAndErrors.errors).concat(treeAndErrors.errors));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +63,8 @@ class TreeBuilder {
|
|||||||
} else if (this.peek.type === HtmlTokenType.COMMENT_START) {
|
} else if (this.peek.type === HtmlTokenType.COMMENT_START) {
|
||||||
this._closeVoidElement();
|
this._closeVoidElement();
|
||||||
this._consumeComment(this._advance());
|
this._consumeComment(this._advance());
|
||||||
} else if (
|
} else if (this.peek.type === HtmlTokenType.TEXT ||
|
||||||
this.peek.type === HtmlTokenType.TEXT || this.peek.type === HtmlTokenType.RAW_TEXT ||
|
this.peek.type === HtmlTokenType.RAW_TEXT ||
|
||||||
this.peek.type === HtmlTokenType.ESCAPABLE_RAW_TEXT) {
|
this.peek.type === HtmlTokenType.ESCAPABLE_RAW_TEXT) {
|
||||||
this._closeVoidElement();
|
this._closeVoidElement();
|
||||||
this._consumeText(this._advance());
|
this._consumeText(this._advance());
|
||||||
@ -166,8 +174,8 @@ class TreeBuilder {
|
|||||||
var tagDef = getHtmlTagDefinition(el.name);
|
var tagDef = getHtmlTagDefinition(el.name);
|
||||||
var parentEl = this._getParentElement();
|
var parentEl = this._getParentElement();
|
||||||
if (tagDef.requireExtraParent(isPresent(parentEl) ? parentEl.name : null)) {
|
if (tagDef.requireExtraParent(isPresent(parentEl) ? parentEl.name : null)) {
|
||||||
var newParent = new HtmlElementAst(
|
var newParent = new HtmlElementAst(tagDef.parentToAdd, [], [el], el.sourceSpan,
|
||||||
tagDef.parentToAdd, [], [el], el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
|
el.startSourceSpan, el.endSourceSpan);
|
||||||
this._addToParent(newParent);
|
this._addToParent(newParent);
|
||||||
this.elementStack.push(newParent);
|
this.elementStack.push(newParent);
|
||||||
this.elementStack.push(el);
|
this.elementStack.push(el);
|
||||||
@ -184,12 +192,12 @@ class TreeBuilder {
|
|||||||
this._getParentElement().endSourceSpan = endTagToken.sourceSpan;
|
this._getParentElement().endSourceSpan = endTagToken.sourceSpan;
|
||||||
|
|
||||||
if (getHtmlTagDefinition(fullName).isVoid) {
|
if (getHtmlTagDefinition(fullName).isVoid) {
|
||||||
this.errors.push(HtmlTreeError.create(
|
this.errors.push(
|
||||||
fullName, endTagToken.sourceSpan,
|
HtmlTreeError.create(fullName, endTagToken.sourceSpan,
|
||||||
`Void elements do not have end tags "${endTagToken.parts[1]}"`));
|
`Void elements do not have end tags "${endTagToken.parts[1]}"`));
|
||||||
} else if (!this._popElement(fullName)) {
|
} else if (!this._popElement(fullName)) {
|
||||||
this.errors.push(HtmlTreeError.create(
|
this.errors.push(HtmlTreeError.create(fullName, endTagToken.sourceSpan,
|
||||||
fullName, endTagToken.sourceSpan, `Unexpected closing tag "${endTagToken.parts[1]}"`));
|
`Unexpected closing tag "${endTagToken.parts[1]}"`));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +242,8 @@ class TreeBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getElementFullName(
|
function getElementFullName(prefix: string, localName: string,
|
||||||
prefix: string, localName: string, parentElement: HtmlElementAst): string {
|
parentElement: HtmlElementAst): string {
|
||||||
if (isBlank(prefix)) {
|
if (isBlank(prefix)) {
|
||||||
prefix = getHtmlTagDefinition(localName).implicitNamespacePrefix;
|
prefix = getHtmlTagDefinition(localName).implicitNamespacePrefix;
|
||||||
if (isBlank(prefix) && isPresent(parentElement)) {
|
if (isBlank(prefix) && isPresent(parentElement)) {
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import {isPresent, isBlank, normalizeBool, RegExpWrapper, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
normalizeBool,
|
||||||
|
RegExpWrapper,
|
||||||
|
CONST_EXPR
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
// see http://www.w3.org/TR/html51/syntax.html#named-character-references
|
// see http://www.w3.org/TR/html51/syntax.html#named-character-references
|
||||||
// see https://html.spec.whatwg.org/multipage/entities.json
|
// see https://html.spec.whatwg.org/multipage/entities.json
|
||||||
@ -275,9 +281,8 @@ export class HtmlTagDefinition {
|
|||||||
public isVoid: boolean;
|
public isVoid: boolean;
|
||||||
public ignoreFirstLf: boolean;
|
public ignoreFirstLf: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor({closedByChildren, requiredParents, implicitNamespacePrefix, contentType,
|
||||||
{closedByChildren, requiredParents, implicitNamespacePrefix, contentType, closedByParent,
|
closedByParent, isVoid, ignoreFirstLf}: {
|
||||||
isVoid, ignoreFirstLf}: {
|
|
||||||
closedByChildren?: string[],
|
closedByChildren?: string[],
|
||||||
closedByParent?: boolean,
|
closedByParent?: boolean,
|
||||||
requiredParents?: string[],
|
requiredParents?: string[],
|
||||||
@ -337,9 +342,32 @@ var TAG_DEFINITIONS: {[key: string]: HtmlTagDefinition} = {
|
|||||||
'wbr': new HtmlTagDefinition({isVoid: true}),
|
'wbr': new HtmlTagDefinition({isVoid: true}),
|
||||||
'p': new HtmlTagDefinition({
|
'p': new HtmlTagDefinition({
|
||||||
closedByChildren: [
|
closedByChildren: [
|
||||||
'address', 'article', 'aside', 'blockquote', 'div', 'dl', 'fieldset', 'footer', 'form',
|
'address',
|
||||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr',
|
'article',
|
||||||
'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'
|
'aside',
|
||||||
|
'blockquote',
|
||||||
|
'div',
|
||||||
|
'dl',
|
||||||
|
'fieldset',
|
||||||
|
'footer',
|
||||||
|
'form',
|
||||||
|
'h1',
|
||||||
|
'h2',
|
||||||
|
'h3',
|
||||||
|
'h4',
|
||||||
|
'h5',
|
||||||
|
'h6',
|
||||||
|
'header',
|
||||||
|
'hgroup',
|
||||||
|
'hr',
|
||||||
|
'main',
|
||||||
|
'nav',
|
||||||
|
'ol',
|
||||||
|
'p',
|
||||||
|
'pre',
|
||||||
|
'section',
|
||||||
|
'table',
|
||||||
|
'ul'
|
||||||
],
|
],
|
||||||
closedByParent: true
|
closedByParent: true
|
||||||
}),
|
}),
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
import {Injectable, Provider, provide} from 'angular2/src/core/di';
|
import {Injectable, Provider, provide} from 'angular2/src/core/di';
|
||||||
|
|
||||||
import {StringWrapper, RegExpWrapper, CONST_EXPR, isBlank, isPresent} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
StringWrapper,
|
||||||
|
RegExpWrapper,
|
||||||
|
CONST_EXPR,
|
||||||
|
isBlank,
|
||||||
|
isPresent
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {HtmlAstVisitor, HtmlAttrAst, HtmlElementAst, HtmlTextAst, HtmlCommentAst, HtmlAst} from './html_ast';
|
import {
|
||||||
|
HtmlAstVisitor,
|
||||||
|
HtmlAttrAst,
|
||||||
|
HtmlElementAst,
|
||||||
|
HtmlTextAst,
|
||||||
|
HtmlCommentAst,
|
||||||
|
HtmlAst
|
||||||
|
} from './html_ast';
|
||||||
import {HtmlParser, HtmlParseTreeResult} from './html_parser';
|
import {HtmlParser, HtmlParseTreeResult} from './html_parser';
|
||||||
|
|
||||||
import {dashCaseToCamelCase, camelCaseToDashCase} from './util';
|
import {dashCaseToCamelCase, camelCaseToDashCase} from './util';
|
||||||
@ -37,8 +50,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
|||||||
this.visitingTemplateEl = ast.name.toLowerCase() == 'template';
|
this.visitingTemplateEl = ast.name.toLowerCase() == 'template';
|
||||||
let attrs = ast.attrs.map(attr => attr.visit(this, null));
|
let attrs = ast.attrs.map(attr => attr.visit(this, null));
|
||||||
let children = ast.children.map(child => child.visit(this, null));
|
let children = ast.children.map(child => child.visit(this, null));
|
||||||
return new HtmlElementAst(
|
return new HtmlElementAst(ast.name, attrs, children, ast.sourceSpan, ast.startSourceSpan,
|
||||||
ast.name, attrs, children, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
|
ast.endSourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
visitAttr(originalAst: HtmlAttrAst, context: any): HtmlAttrAst {
|
visitAttr(originalAst: HtmlAttrAst, context: any): HtmlAttrAst {
|
||||||
@ -102,8 +115,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
|||||||
name = 'template';
|
name = 'template';
|
||||||
|
|
||||||
// rewrite the directive selector
|
// rewrite the directive selector
|
||||||
value = StringWrapper.replaceAllMapped(
|
value = StringWrapper.replaceAllMapped(value, TEMPLATE_SELECTOR_REGEXP,
|
||||||
value, TEMPLATE_SELECTOR_REGEXP, (m) => { return dashCaseToCamelCase(m[1]); });
|
(m) => { return dashCaseToCamelCase(m[1]); });
|
||||||
|
|
||||||
// rewrite the var declarations
|
// rewrite the var declarations
|
||||||
value = StringWrapper.replaceAllMapped(value, VARIABLE_TPL_BINDING_REGEXP, m => {
|
value = StringWrapper.replaceAllMapped(value, VARIABLE_TPL_BINDING_REGEXP, m => {
|
||||||
@ -129,8 +142,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
|
|||||||
} else if (isPresent(m[2])) {
|
} else if (isPresent(m[2])) {
|
||||||
attrName = `[(${dashCaseToCamelCase(m[2])})]`;
|
attrName = `[(${dashCaseToCamelCase(m[2])})]`;
|
||||||
} else if (isPresent(m[3])) {
|
} else if (isPresent(m[3])) {
|
||||||
let prop = StringWrapper.replaceAllMapped(
|
let prop = StringWrapper.replaceAllMapped(m[3], SPECIAL_PREFIXES_REGEXP,
|
||||||
m[3], SPECIAL_PREFIXES_REGEXP, (m) => { return m[1].toLowerCase() + '.'; });
|
(m) => { return m[1].toLowerCase() + '.'; });
|
||||||
|
|
||||||
if (prop.startsWith('class.') || prop.startsWith('attr.') || prop.startsWith('style.')) {
|
if (prop.startsWith('class.') || prop.startsWith('attr.') || prop.startsWith('style.')) {
|
||||||
attrName = `[${prop}]`;
|
attrName = `[${prop}]`;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
export class ParseLocation {
|
export class ParseLocation {
|
||||||
constructor(
|
constructor(public file: ParseSourceFile, public offset: number, public line: number,
|
||||||
public file: ParseSourceFile, public offset: number, public line: number,
|
|
||||||
public col: number) {}
|
public col: number) {}
|
||||||
|
|
||||||
toString(): string { return `${this.file.url}@${this.line}:${this.col}`; }
|
toString(): string { return `${this.file.url}@${this.line}:${this.col}`; }
|
||||||
@ -34,7 +33,7 @@ export abstract class ParseError {
|
|||||||
while (ctxLen < 100 && ctxStart > 0) {
|
while (ctxLen < 100 && ctxStart > 0) {
|
||||||
ctxStart--;
|
ctxStart--;
|
||||||
ctxLen++;
|
ctxLen++;
|
||||||
if (source[ctxStart] == '\n') {
|
if (source[ctxStart] == "\n") {
|
||||||
if (++ctxLines == 3) {
|
if (++ctxLines == 3) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -46,7 +45,7 @@ export abstract class ParseError {
|
|||||||
while (ctxLen < 100 && ctxEnd < source.length - 1) {
|
while (ctxLen < 100 && ctxEnd < source.length - 1) {
|
||||||
ctxEnd++;
|
ctxEnd++;
|
||||||
ctxLen++;
|
ctxLen++;
|
||||||
if (source[ctxEnd] == '\n') {
|
if (source[ctxEnd] == "\n") {
|
||||||
if (++ctxLines == 3) {
|
if (++ctxLines == 3) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,54 @@
|
|||||||
import {isPresent, isBlank, Type, isString, StringWrapper, IS_DART, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {
|
||||||
import {SetWrapper, StringMapWrapper, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
isPresent,
|
||||||
import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
|
isBlank,
|
||||||
import {CompileTypeMetadata, CompileDirectiveMetadata, CompilePipeMetadata} from './directive_metadata';
|
Type,
|
||||||
|
isString,
|
||||||
|
StringWrapper,
|
||||||
|
IS_DART,
|
||||||
|
CONST_EXPR
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
import {
|
||||||
|
SetWrapper,
|
||||||
|
StringMapWrapper,
|
||||||
|
ListWrapper,
|
||||||
|
MapWrapper
|
||||||
|
} from 'angular2/src/facade/collection';
|
||||||
|
import {
|
||||||
|
TemplateAst,
|
||||||
|
TemplateAstVisitor,
|
||||||
|
NgContentAst,
|
||||||
|
EmbeddedTemplateAst,
|
||||||
|
ElementAst,
|
||||||
|
VariableAst,
|
||||||
|
BoundEventAst,
|
||||||
|
BoundElementPropertyAst,
|
||||||
|
AttrAst,
|
||||||
|
BoundTextAst,
|
||||||
|
TextAst,
|
||||||
|
DirectiveAst,
|
||||||
|
BoundDirectivePropertyAst,
|
||||||
|
templateVisitAll
|
||||||
|
} from './template_ast';
|
||||||
|
import {
|
||||||
|
CompileTypeMetadata,
|
||||||
|
CompileDirectiveMetadata,
|
||||||
|
CompilePipeMetadata
|
||||||
|
} from './directive_metadata';
|
||||||
import {SourceExpressions, SourceExpression, moduleRef} from './source_module';
|
import {SourceExpressions, SourceExpression, moduleRef} from './source_module';
|
||||||
import {AppProtoView, AppView} from 'angular2/src/core/linker/view';
|
import {AppProtoView, AppView} from 'angular2/src/core/linker/view';
|
||||||
import {ViewType} from 'angular2/src/core/linker/view_type';
|
import {ViewType} from 'angular2/src/core/linker/view_type';
|
||||||
import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element';
|
import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element';
|
||||||
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
||||||
import {escapeSingleQuoteString, codeGenConstConstructorCall, codeGenValueFn, codeGenFnHeader, MODULE_SUFFIX, codeGenStringMap, Expression, Statement} from './util';
|
import {
|
||||||
|
escapeSingleQuoteString,
|
||||||
|
codeGenConstConstructorCall,
|
||||||
|
codeGenValueFn,
|
||||||
|
codeGenFnHeader,
|
||||||
|
MODULE_SUFFIX,
|
||||||
|
codeGenStringMap,
|
||||||
|
Expression,
|
||||||
|
Statement
|
||||||
|
} from './util';
|
||||||
import {Injectable} from 'angular2/src/core/di';
|
import {Injectable} from 'angular2/src/core/di';
|
||||||
|
|
||||||
export const PROTO_VIEW_JIT_IMPORTS = CONST_EXPR(
|
export const PROTO_VIEW_JIT_IMPORTS = CONST_EXPR(
|
||||||
@ -33,20 +74,19 @@ const STYLE_ATTR = 'style';
|
|||||||
export class ProtoViewCompiler {
|
export class ProtoViewCompiler {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
compileProtoViewRuntime(
|
compileProtoViewRuntime(metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
|
||||||
metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
|
template: TemplateAst[], pipes: CompilePipeMetadata[]):
|
||||||
template: TemplateAst[],
|
CompileProtoViews<AppProtoView, AppProtoElement, any> {
|
||||||
pipes: CompilePipeMetadata[]): CompileProtoViews<AppProtoView, AppProtoElement, any> {
|
|
||||||
var protoViewFactory = new RuntimeProtoViewFactory(metadataCache, component, pipes);
|
var protoViewFactory = new RuntimeProtoViewFactory(metadataCache, component, pipes);
|
||||||
var allProtoViews = [];
|
var allProtoViews = [];
|
||||||
protoViewFactory.createCompileProtoView(template, [], [], allProtoViews);
|
protoViewFactory.createCompileProtoView(template, [], [], allProtoViews);
|
||||||
return new CompileProtoViews<AppProtoView, AppProtoElement, any>([], allProtoViews);
|
return new CompileProtoViews<AppProtoView, AppProtoElement, any>([], allProtoViews);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileProtoViewCodeGen(
|
compileProtoViewCodeGen(resolvedMetadataCacheExpr: Expression,
|
||||||
resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata,
|
component: CompileDirectiveMetadata, template: TemplateAst[],
|
||||||
template: TemplateAst[],
|
pipes: CompilePipeMetadata[]):
|
||||||
pipes: CompilePipeMetadata[]): CompileProtoViews<Expression, Expression, string> {
|
CompileProtoViews<Expression, Expression, string> {
|
||||||
var protoViewFactory = new CodeGenProtoViewFactory(resolvedMetadataCacheExpr, component, pipes);
|
var protoViewFactory = new CodeGenProtoViewFactory(resolvedMetadataCacheExpr, component, pipes);
|
||||||
var allProtoViews = [];
|
var allProtoViews = [];
|
||||||
var allStatements = [];
|
var allStatements = [];
|
||||||
@ -57,29 +97,26 @@ export class ProtoViewCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class CompileProtoViews<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
export class CompileProtoViews<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
||||||
constructor(
|
constructor(public declarations: STATEMENT[],
|
||||||
public declarations: STATEMENT[],
|
|
||||||
public protoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
|
public protoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> {
|
export class CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> {
|
||||||
constructor(
|
constructor(public embeddedTemplateIndex: number,
|
||||||
public embeddedTemplateIndex: number,
|
public protoElements: CompileProtoElement<APP_PROTO_EL>[],
|
||||||
public protoElements: CompileProtoElement<APP_PROTO_EL>[], public protoView: APP_PROTO_VIEW) {
|
public protoView: APP_PROTO_VIEW) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class CompileProtoElement<APP_PROTO_EL> {
|
export class CompileProtoElement<APP_PROTO_EL> {
|
||||||
constructor(
|
constructor(public boundElementIndex, public attrNameAndValues: string[][],
|
||||||
public boundElementIndex, public attrNameAndValues: string[][],
|
|
||||||
public variableNameAndValues: string[][], public renderEvents: BoundEventAst[],
|
public variableNameAndValues: string[][], public renderEvents: BoundEventAst[],
|
||||||
public directives: CompileDirectiveMetadata[], public embeddedTemplateIndex: number,
|
public directives: CompileDirectiveMetadata[], public embeddedTemplateIndex: number,
|
||||||
public appProtoEl: APP_PROTO_EL) {}
|
public appProtoEl: APP_PROTO_EL) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function visitAndReturnContext(
|
function visitAndReturnContext(visitor: TemplateAstVisitor, asts: TemplateAst[],
|
||||||
visitor: TemplateAstVisitor, asts: TemplateAst[], context: any): any {
|
context: any): any {
|
||||||
templateVisitAll(visitor, asts, context);
|
templateVisitAll(visitor, asts, context);
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
@ -87,16 +124,17 @@ function visitAndReturnContext(
|
|||||||
abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
||||||
constructor(public component: CompileDirectiveMetadata) {}
|
constructor(public component: CompileDirectiveMetadata) {}
|
||||||
|
|
||||||
abstract createAppProtoView(
|
abstract createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType,
|
||||||
embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
|
templateVariableBindings: string[][],
|
||||||
targetStatements: STATEMENT[]): APP_PROTO_VIEW;
|
targetStatements: STATEMENT[]): APP_PROTO_VIEW;
|
||||||
|
|
||||||
abstract createAppProtoElement(
|
abstract createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][],
|
||||||
boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
|
variableNameAndValues: string[][],
|
||||||
directives: CompileDirectiveMetadata[], targetStatements: STATEMENT[]): APP_PROTO_EL;
|
directives: CompileDirectiveMetadata[],
|
||||||
|
targetStatements: STATEMENT[]): APP_PROTO_EL;
|
||||||
|
|
||||||
createCompileProtoView(
|
createCompileProtoView(template: TemplateAst[], templateVariableBindings: string[][],
|
||||||
template: TemplateAst[], templateVariableBindings: string[][], targetStatements: STATEMENT[],
|
targetStatements: STATEMENT[],
|
||||||
targetProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]):
|
targetProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]):
|
||||||
CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> {
|
CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> {
|
||||||
var embeddedTemplateIndex = targetProtoViews.length;
|
var embeddedTemplateIndex = targetProtoViews.length;
|
||||||
@ -107,8 +145,8 @@ abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
|||||||
this, targetStatements, targetProtoViews);
|
this, targetStatements, targetProtoViews);
|
||||||
templateVisitAll(builder, template);
|
templateVisitAll(builder, template);
|
||||||
var viewType = getViewType(this.component, embeddedTemplateIndex);
|
var viewType = getViewType(this.component, embeddedTemplateIndex);
|
||||||
var appProtoView = this.createAppProtoView(
|
var appProtoView = this.createAppProtoView(embeddedTemplateIndex, viewType,
|
||||||
embeddedTemplateIndex, viewType, templateVariableBindings, targetStatements);
|
templateVariableBindings, targetStatements);
|
||||||
var cpv = new CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>(
|
var cpv = new CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>(
|
||||||
embeddedTemplateIndex, builder.protoElements, appProtoView);
|
embeddedTemplateIndex, builder.protoElements, appProtoView);
|
||||||
targetProtoViews[embeddedTemplateIndex] = cpv;
|
targetProtoViews[embeddedTemplateIndex] = cpv;
|
||||||
@ -119,8 +157,7 @@ abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
|
|||||||
class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, Statement> {
|
class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, Statement> {
|
||||||
private _nextVarId: number = 0;
|
private _nextVarId: number = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(public resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata,
|
||||||
public resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata,
|
|
||||||
public pipes: CompilePipeMetadata[]) {
|
public pipes: CompilePipeMetadata[]) {
|
||||||
super(component);
|
super(component);
|
||||||
}
|
}
|
||||||
@ -129,8 +166,8 @@ class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, S
|
|||||||
return `appProtoView${this._nextVarId++}_${this.component.type.name}${embeddedTemplateIndex}`;
|
return `appProtoView${this._nextVarId++}_${this.component.type.name}${embeddedTemplateIndex}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppProtoView(
|
createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType,
|
||||||
embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
|
templateVariableBindings: string[][],
|
||||||
targetStatements: Statement[]): Expression {
|
targetStatements: Statement[]): Expression {
|
||||||
var protoViewVarName = this._nextProtoViewVar(embeddedTemplateIndex);
|
var protoViewVarName = this._nextProtoViewVar(embeddedTemplateIndex);
|
||||||
var viewTypeExpr = codeGenViewType(viewType);
|
var viewTypeExpr = codeGenViewType(viewType);
|
||||||
@ -143,9 +180,9 @@ class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, S
|
|||||||
return new Expression(protoViewVarName);
|
return new Expression(protoViewVarName);
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppProtoElement(
|
createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][],
|
||||||
boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
|
variableNameAndValues: string[][], directives: CompileDirectiveMetadata[],
|
||||||
directives: CompileDirectiveMetadata[], targetStatements: Statement[]): Expression {
|
targetStatements: Statement[]): Expression {
|
||||||
var varName = `appProtoEl${this._nextVarId++}_${this.component.type.name}`;
|
var varName = `appProtoEl${this._nextVarId++}_${this.component.type.name}`;
|
||||||
var value = `${APP_EL_MODULE_REF}AppProtoElement.create(
|
var value = `${APP_EL_MODULE_REF}AppProtoElement.create(
|
||||||
${this.resolvedMetadataCacheExpr.expression},
|
${this.resolvedMetadataCacheExpr.expression},
|
||||||
@ -161,27 +198,24 @@ class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RuntimeProtoViewFactory extends ProtoViewFactory<AppProtoView, AppProtoElement, any> {
|
class RuntimeProtoViewFactory extends ProtoViewFactory<AppProtoView, AppProtoElement, any> {
|
||||||
constructor(
|
constructor(public metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
|
||||||
public metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
|
|
||||||
public pipes: CompilePipeMetadata[]) {
|
public pipes: CompilePipeMetadata[]) {
|
||||||
super(component);
|
super(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppProtoView(
|
createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType,
|
||||||
embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
|
templateVariableBindings: string[][], targetStatements: any[]): AppProtoView {
|
||||||
targetStatements: any[]): AppProtoView {
|
|
||||||
var pipes =
|
var pipes =
|
||||||
embeddedTemplateIndex === 0 ? this.pipes.map(pipeMeta => pipeMeta.type.runtime) : [];
|
embeddedTemplateIndex === 0 ? this.pipes.map(pipeMeta => pipeMeta.type.runtime) : [];
|
||||||
var templateVars = keyValueArrayToStringMap(templateVariableBindings);
|
var templateVars = keyValueArrayToStringMap(templateVariableBindings);
|
||||||
return AppProtoView.create(this.metadataCache, viewType, pipes, templateVars);
|
return AppProtoView.create(this.metadataCache, viewType, pipes, templateVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppProtoElement(
|
createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][],
|
||||||
boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
|
variableNameAndValues: string[][], directives: CompileDirectiveMetadata[],
|
||||||
directives: CompileDirectiveMetadata[], targetStatements: any[]): AppProtoElement {
|
targetStatements: any[]): AppProtoElement {
|
||||||
var attrs = keyValueArrayToStringMap(attrNameAndValues);
|
var attrs = keyValueArrayToStringMap(attrNameAndValues);
|
||||||
return AppProtoElement.create(
|
return AppProtoElement.create(this.metadataCache, boundElementIndex, attrs,
|
||||||
this.metadataCache, boundElementIndex, attrs,
|
|
||||||
directives.map(dirMeta => dirMeta.type.runtime),
|
directives.map(dirMeta => dirMeta.type.runtime),
|
||||||
keyValueArrayToStringMap(variableNameAndValues));
|
keyValueArrayToStringMap(variableNameAndValues));
|
||||||
}
|
}
|
||||||
@ -192,13 +226,12 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
|||||||
protoElements: CompileProtoElement<APP_PROTO_EL>[] = [];
|
protoElements: CompileProtoElement<APP_PROTO_EL>[] = [];
|
||||||
boundElementCount: number = 0;
|
boundElementCount: number = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(public factory: ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT>,
|
||||||
public factory: ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT>,
|
|
||||||
public allStatements: STATEMENT[],
|
public allStatements: STATEMENT[],
|
||||||
public allProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
|
public allProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
|
||||||
|
|
||||||
private _readAttrNameAndValues(directives: CompileDirectiveMetadata[], attrAsts: TemplateAst[]):
|
private _readAttrNameAndValues(directives: CompileDirectiveMetadata[],
|
||||||
string[][] {
|
attrAsts: TemplateAst[]): string[][] {
|
||||||
var attrs = visitAndReturnContext(this, attrAsts, {});
|
var attrs = visitAndReturnContext(this, attrAsts, {});
|
||||||
directives.forEach(directiveMeta => {
|
directives.forEach(directiveMeta => {
|
||||||
StringMapWrapper.forEach(directiveMeta.hostAttributes, (value: string, name: string) => {
|
StringMapWrapper.forEach(directiveMeta.hostAttributes, (value: string, name: string) => {
|
||||||
@ -229,17 +262,15 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
|||||||
var renderEvents: Map<string, BoundEventAst> =
|
var renderEvents: Map<string, BoundEventAst> =
|
||||||
visitAndReturnContext(this, ast.outputs, new Map<string, BoundEventAst>());
|
visitAndReturnContext(this, ast.outputs, new Map<string, BoundEventAst>());
|
||||||
ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => {
|
ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => {
|
||||||
directiveAst.visit(
|
directiveAst.visit(this, new DirectiveContext(index, boundElementIndex, renderEvents,
|
||||||
this, new DirectiveContext(
|
variableNameAndValues, directives));
|
||||||
index, boundElementIndex, renderEvents, variableNameAndValues, directives));
|
|
||||||
});
|
});
|
||||||
var renderEventArray = [];
|
var renderEventArray = [];
|
||||||
renderEvents.forEach((eventAst, _) => renderEventArray.push(eventAst));
|
renderEvents.forEach((eventAst, _) => renderEventArray.push(eventAst));
|
||||||
|
|
||||||
var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs);
|
var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs);
|
||||||
this._addProtoElement(
|
this._addProtoElement(ast.isBound(), boundElementIndex, attrNameAndValues,
|
||||||
ast.isBound(), boundElementIndex, attrNameAndValues, variableNameAndValues,
|
variableNameAndValues, renderEventArray, directives, null);
|
||||||
renderEventArray, directives, null);
|
|
||||||
templateVisitAll(this, ast.children);
|
templateVisitAll(this, ast.children);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -249,8 +280,8 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
|||||||
var directives: CompileDirectiveMetadata[] = [];
|
var directives: CompileDirectiveMetadata[] = [];
|
||||||
ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => {
|
ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => {
|
||||||
directiveAst.visit(
|
directiveAst.visit(
|
||||||
this, new DirectiveContext(
|
this, new DirectiveContext(index, boundElementIndex, new Map<string, BoundEventAst>(), [],
|
||||||
index, boundElementIndex, new Map<string, BoundEventAst>(), [], directives));
|
directives));
|
||||||
});
|
});
|
||||||
|
|
||||||
var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs);
|
var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs);
|
||||||
@ -258,21 +289,19 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
|||||||
varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]);
|
varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]);
|
||||||
var nestedProtoView = this.factory.createCompileProtoView(
|
var nestedProtoView = this.factory.createCompileProtoView(
|
||||||
ast.children, templateVariableBindings, this.allStatements, this.allProtoViews);
|
ast.children, templateVariableBindings, this.allStatements, this.allProtoViews);
|
||||||
this._addProtoElement(
|
this._addProtoElement(true, boundElementIndex, attrNameAndValues, [], [], directives,
|
||||||
true, boundElementIndex, attrNameAndValues, [], [], directives,
|
|
||||||
nestedProtoView.embeddedTemplateIndex);
|
nestedProtoView.embeddedTemplateIndex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addProtoElement(
|
private _addProtoElement(isBound: boolean, boundElementIndex, attrNameAndValues: string[][],
|
||||||
isBound: boolean, boundElementIndex, attrNameAndValues: string[][],
|
|
||||||
variableNameAndValues: string[][], renderEvents: BoundEventAst[],
|
variableNameAndValues: string[][], renderEvents: BoundEventAst[],
|
||||||
directives: CompileDirectiveMetadata[], embeddedTemplateIndex: number) {
|
directives: CompileDirectiveMetadata[], embeddedTemplateIndex: number) {
|
||||||
var appProtoEl = null;
|
var appProtoEl = null;
|
||||||
if (isBound) {
|
if (isBound) {
|
||||||
appProtoEl = this.factory.createAppProtoElement(
|
appProtoEl =
|
||||||
boundElementIndex, attrNameAndValues, variableNameAndValues, directives,
|
this.factory.createAppProtoElement(boundElementIndex, attrNameAndValues,
|
||||||
this.allStatements);
|
variableNameAndValues, directives, this.allStatements);
|
||||||
}
|
}
|
||||||
var compileProtoEl = new CompileProtoElement<APP_PROTO_EL>(
|
var compileProtoEl = new CompileProtoElement<APP_PROTO_EL>(
|
||||||
boundElementIndex, attrNameAndValues, variableNameAndValues, renderEvents, directives,
|
boundElementIndex, attrNameAndValues, variableNameAndValues, renderEvents, directives,
|
||||||
@ -288,9 +317,8 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
|||||||
visitDirective(ast: DirectiveAst, ctx: DirectiveContext): any {
|
visitDirective(ast: DirectiveAst, ctx: DirectiveContext): any {
|
||||||
ctx.targetDirectives.push(ast.directive);
|
ctx.targetDirectives.push(ast.directive);
|
||||||
templateVisitAll(this, ast.hostEvents, ctx.hostEventTargetAndNames);
|
templateVisitAll(this, ast.hostEvents, ctx.hostEventTargetAndNames);
|
||||||
ast.exportAsVars.forEach(varAst => {
|
ast.exportAsVars.forEach(
|
||||||
ctx.targetVariableNameAndValues.push([varAst.name, ctx.index]);
|
varAst => { ctx.targetVariableNameAndValues.push([varAst.name, ctx.index]); });
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
visitEvent(ast: BoundEventAst, eventTargetAndNames: Map<string, BoundEventAst>): any {
|
visitEvent(ast: BoundEventAst, eventTargetAndNames: Map<string, BoundEventAst>): any {
|
||||||
@ -303,14 +331,12 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
|
|||||||
|
|
||||||
function mapToKeyValueArray(data: {[key: string]: string}): string[][] {
|
function mapToKeyValueArray(data: {[key: string]: string}): string[][] {
|
||||||
var entryArray: string[][] = [];
|
var entryArray: string[][] = [];
|
||||||
StringMapWrapper.forEach(data, (value: string, name: string) => {
|
StringMapWrapper.forEach(data,
|
||||||
entryArray.push([name, value]);
|
(value: string, name: string) => { entryArray.push([name, value]); });
|
||||||
});
|
|
||||||
// We need to sort to get a defined output order
|
// We need to sort to get a defined output order
|
||||||
// for tests and for caching generated artifacts...
|
// for tests and for caching generated artifacts...
|
||||||
ListWrapper.sort<string[]>(
|
ListWrapper.sort<string[]>(entryArray, (entry1: string[], entry2: string[]) =>
|
||||||
entryArray,
|
StringWrapper.compare(entry1[0], entry2[0]));
|
||||||
(entry1: string[], entry2: string[]) => StringWrapper.compare(entry1[0], entry2[0]));
|
|
||||||
var keyValueArray: string[][] = [];
|
var keyValueArray: string[][] = [];
|
||||||
entryArray.forEach((entry) => { keyValueArray.push([entry[0], entry[1]]); });
|
entryArray.forEach((entry) => { keyValueArray.push([entry[0], entry[1]]); });
|
||||||
return keyValueArray;
|
return keyValueArray;
|
||||||
@ -325,8 +351,7 @@ function mergeAttributeValue(attrName: string, attrValue1: string, attrValue2: s
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DirectiveContext {
|
class DirectiveContext {
|
||||||
constructor(
|
constructor(public index: number, public boundElementIndex: number,
|
||||||
public index: number, public boundElementIndex: number,
|
|
||||||
public hostEventTargetAndNames: Map<string, BoundEventAst>,
|
public hostEventTargetAndNames: Map<string, BoundEventAst>,
|
||||||
public targetVariableNameAndValues: any[][],
|
public targetVariableNameAndValues: any[][],
|
||||||
public targetDirectives: CompileDirectiveMetadata[]) {}
|
public targetDirectives: CompileDirectiveMetadata[]) {}
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
import {resolveForwardRef} from 'angular2/src/core/di';
|
import {resolveForwardRef} from 'angular2/src/core/di';
|
||||||
import {Type, isBlank, isPresent, isArray, stringify, RegExpWrapper} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
Type,
|
||||||
|
isBlank,
|
||||||
|
isPresent,
|
||||||
|
isArray,
|
||||||
|
stringify,
|
||||||
|
RegExpWrapper
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import * as cpl from './directive_metadata';
|
import * as cpl from './directive_metadata';
|
||||||
import * as md from 'angular2/src/core/metadata/directives';
|
import * as md from 'angular2/src/core/metadata/directives';
|
||||||
@ -23,8 +30,7 @@ export class RuntimeMetadataResolver {
|
|||||||
private _anonymousTypes = new Map<Object, number>();
|
private _anonymousTypes = new Map<Object, number>();
|
||||||
private _anonymousTypeIndex = 0;
|
private _anonymousTypeIndex = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
|
||||||
private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
|
|
||||||
private _viewResolver: ViewResolver,
|
private _viewResolver: ViewResolver,
|
||||||
@Optional() @Inject(PLATFORM_DIRECTIVES) private _platformDirectives: Type[],
|
@Optional() @Inject(PLATFORM_DIRECTIVES) private _platformDirectives: Type[],
|
||||||
@Optional() @Inject(PLATFORM_PIPES) private _platformPipes: Type[]) {}
|
@Optional() @Inject(PLATFORM_PIPES) private _platformPipes: Type[]) {}
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import {Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {isPresent, isBlank, RegExpWrapper, RegExpMatcherWrapper, StringWrapper} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
RegExpWrapper,
|
||||||
|
RegExpMatcherWrapper,
|
||||||
|
StringWrapper
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||||
|
|
||||||
const _EMPTY_ATTR_VALUE = '';
|
const _EMPTY_ATTR_VALUE = '';
|
||||||
@ -30,7 +36,7 @@ export class CssSelector {
|
|||||||
var _addResult = (res: CssSelector[], cssSel) => {
|
var _addResult = (res: CssSelector[], cssSel) => {
|
||||||
if (cssSel.notSelectors.length > 0 && isBlank(cssSel.element) &&
|
if (cssSel.notSelectors.length > 0 && isBlank(cssSel.element) &&
|
||||||
ListWrapper.isEmpty(cssSel.classNames) && ListWrapper.isEmpty(cssSel.attrs)) {
|
ListWrapper.isEmpty(cssSel.classNames) && ListWrapper.isEmpty(cssSel.attrs)) {
|
||||||
cssSel.element = '*';
|
cssSel.element = "*";
|
||||||
}
|
}
|
||||||
res.push(cssSel);
|
res.push(cssSel);
|
||||||
};
|
};
|
||||||
@ -168,8 +174,8 @@ export class SelectorMatcher {
|
|||||||
* @param cssSelector A css selector
|
* @param cssSelector A css selector
|
||||||
* @param callbackCtxt An opaque object that will be given to the callback of the `match` function
|
* @param callbackCtxt An opaque object that will be given to the callback of the `match` function
|
||||||
*/
|
*/
|
||||||
private _addSelectable(
|
private _addSelectable(cssSelector: CssSelector, callbackCtxt: any,
|
||||||
cssSelector: CssSelector, callbackCtxt: any, listContext: SelectorListContext) {
|
listContext: SelectorListContext) {
|
||||||
var matcher: SelectorMatcher = this;
|
var matcher: SelectorMatcher = this;
|
||||||
var element = cssSelector.element;
|
var element = cssSelector.element;
|
||||||
var classNames = cssSelector.classNames;
|
var classNames = cssSelector.classNames;
|
||||||
@ -223,8 +229,8 @@ export class SelectorMatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addTerminal(
|
private _addTerminal(map: Map<string, SelectorContext[]>, name: string,
|
||||||
map: Map<string, SelectorContext[]>, name: string, selectable: SelectorContext) {
|
selectable: SelectorContext) {
|
||||||
var terminalList = map.get(name);
|
var terminalList = map.get(name);
|
||||||
if (isBlank(terminalList)) {
|
if (isBlank(terminalList)) {
|
||||||
terminalList = [];
|
terminalList = [];
|
||||||
@ -281,8 +287,8 @@ export class SelectorMatcher {
|
|||||||
|
|
||||||
var terminalValuesMap = this._attrValueMap.get(attrName);
|
var terminalValuesMap = this._attrValueMap.get(attrName);
|
||||||
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
|
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
|
||||||
result = this._matchTerminal(
|
result = this._matchTerminal(terminalValuesMap, _EMPTY_ATTR_VALUE, cssSelector,
|
||||||
terminalValuesMap, _EMPTY_ATTR_VALUE, cssSelector, matchedCallback) ||
|
matchedCallback) ||
|
||||||
result;
|
result;
|
||||||
}
|
}
|
||||||
result = this._matchTerminal(terminalValuesMap, attrValue, cssSelector, matchedCallback) ||
|
result = this._matchTerminal(terminalValuesMap, attrValue, cssSelector, matchedCallback) ||
|
||||||
@ -290,8 +296,8 @@ export class SelectorMatcher {
|
|||||||
|
|
||||||
var partialValuesMap = this._attrValuePartialMap.get(attrName);
|
var partialValuesMap = this._attrValuePartialMap.get(attrName);
|
||||||
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
|
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
|
||||||
result = this._matchPartial(
|
result = this._matchPartial(partialValuesMap, _EMPTY_ATTR_VALUE, cssSelector,
|
||||||
partialValuesMap, _EMPTY_ATTR_VALUE, cssSelector, matchedCallback) ||
|
matchedCallback) ||
|
||||||
result;
|
result;
|
||||||
}
|
}
|
||||||
result =
|
result =
|
||||||
@ -302,15 +308,14 @@ export class SelectorMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_matchTerminal(
|
_matchTerminal(map: Map<string, SelectorContext[]>, name, cssSelector: CssSelector,
|
||||||
map: Map<string, SelectorContext[]>, name, cssSelector: CssSelector,
|
|
||||||
matchedCallback: (c: CssSelector, a: any) => void): boolean {
|
matchedCallback: (c: CssSelector, a: any) => void): boolean {
|
||||||
if (isBlank(map) || isBlank(name)) {
|
if (isBlank(map) || isBlank(name)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var selectables = map.get(name);
|
var selectables = map.get(name);
|
||||||
var starSelectables = map.get('*');
|
var starSelectables = map.get("*");
|
||||||
if (isPresent(starSelectables)) {
|
if (isPresent(starSelectables)) {
|
||||||
selectables = selectables.concat(starSelectables);
|
selectables = selectables.concat(starSelectables);
|
||||||
}
|
}
|
||||||
@ -327,8 +332,7 @@ export class SelectorMatcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_matchPartial(
|
_matchPartial(map: Map<string, SelectorMatcher>, name, cssSelector: CssSelector,
|
||||||
map: Map<string, SelectorMatcher>, name, cssSelector: CssSelector,
|
|
||||||
matchedCallback /*: (c: CssSelector, a: any) => void*/): boolean {
|
matchedCallback /*: (c: CssSelector, a: any) => void*/): boolean {
|
||||||
if (isBlank(map) || isBlank(name)) {
|
if (isBlank(map) || isBlank(name)) {
|
||||||
return false;
|
return false;
|
||||||
@ -355,8 +359,7 @@ export class SelectorListContext {
|
|||||||
export class SelectorContext {
|
export class SelectorContext {
|
||||||
notSelectors: CssSelector[];
|
notSelectors: CssSelector[];
|
||||||
|
|
||||||
constructor(
|
constructor(public selector: CssSelector, public cbContext: any,
|
||||||
public selector: CssSelector, public cbContext: any,
|
|
||||||
public listContext: SelectorListContext) {
|
public listContext: SelectorListContext) {
|
||||||
this.notSelectors = selector.notSelectors;
|
this.notSelectors = selector.notSelectors;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {StringWrapper, RegExp, RegExpWrapper, RegExpMatcherWrapper, isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
StringWrapper,
|
||||||
|
RegExp,
|
||||||
|
RegExpWrapper,
|
||||||
|
RegExpMatcherWrapper,
|
||||||
|
isPresent,
|
||||||
|
isBlank
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This file is a port of shadowCSS from webcomponents.js to TypeScript.
|
* This file is a port of shadowCSS from webcomponents.js to TypeScript.
|
||||||
@ -167,8 +174,8 @@ export class ShadowCss {
|
|||||||
**/
|
**/
|
||||||
private _insertPolyfillDirectivesInCssText(cssText: string): string {
|
private _insertPolyfillDirectivesInCssText(cssText: string): string {
|
||||||
// Difference with webcomponents.js: does not handle comments
|
// Difference with webcomponents.js: does not handle comments
|
||||||
return StringWrapper.replaceAllMapped(
|
return StringWrapper.replaceAllMapped(cssText, _cssContentNextSelectorRe,
|
||||||
cssText, _cssContentNextSelectorRe, function(m) { return m[1] + '{'; });
|
function(m) { return m[1] + '{'; });
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -272,8 +279,8 @@ export class ShadowCss {
|
|||||||
* scopeName.foo .bar { ... }
|
* scopeName.foo .bar { ... }
|
||||||
*/
|
*/
|
||||||
private _convertColonHostContext(cssText: string): string {
|
private _convertColonHostContext(cssText: string): string {
|
||||||
return this._convertColonRule(
|
return this._convertColonRule(cssText, _cssColonHostContextRe,
|
||||||
cssText, _cssColonHostContextRe, this._colonHostContextPartReplacer);
|
this._colonHostContextPartReplacer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _convertColonRule(cssText: string, regExp: RegExp, partReplacer: Function): string {
|
private _convertColonRule(cssText: string, regExp: RegExp, partReplacer: Function): string {
|
||||||
@ -332,8 +339,8 @@ export class ShadowCss {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _scopeSelector(
|
private _scopeSelector(selector: string, scopeSelector: string, hostSelector: string,
|
||||||
selector: string, scopeSelector: string, hostSelector: string, strict: boolean): string {
|
strict: boolean): string {
|
||||||
var r = [], parts = selector.split(',');
|
var r = [], parts = selector.split(',');
|
||||||
for (var i = 0; i < parts.length; i++) {
|
for (var i = 0; i < parts.length; i++) {
|
||||||
var p = parts[i].trim();
|
var p = parts[i].trim();
|
||||||
@ -363,15 +370,15 @@ export class ShadowCss {
|
|||||||
return RegExpWrapper.create('^(' + scopeSelector + ')' + _selectorReSuffix, 'm');
|
return RegExpWrapper.create('^(' + scopeSelector + ')' + _selectorReSuffix, 'm');
|
||||||
}
|
}
|
||||||
|
|
||||||
private _applySelectorScope(selector: string, scopeSelector: string, hostSelector: string):
|
private _applySelectorScope(selector: string, scopeSelector: string,
|
||||||
string {
|
hostSelector: string): string {
|
||||||
// Difference from webcomponentsjs: scopeSelector could not be an array
|
// Difference from webcomponentsjs: scopeSelector could not be an array
|
||||||
return this._applySimpleSelectorScope(selector, scopeSelector, hostSelector);
|
return this._applySimpleSelectorScope(selector, scopeSelector, hostSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
// scope via name and [is=name]
|
// scope via name and [is=name]
|
||||||
private _applySimpleSelectorScope(selector: string, scopeSelector: string, hostSelector: string):
|
private _applySimpleSelectorScope(selector: string, scopeSelector: string,
|
||||||
string {
|
hostSelector: string): string {
|
||||||
if (isPresent(RegExpWrapper.firstMatch(_polyfillHostRe, selector))) {
|
if (isPresent(RegExpWrapper.firstMatch(_polyfillHostRe, selector))) {
|
||||||
var replaceBy = this.strictStyling ? `[${hostSelector}]` : scopeSelector;
|
var replaceBy = this.strictStyling ? `[${hostSelector}]` : scopeSelector;
|
||||||
selector = StringWrapper.replace(selector, _polyfillHostNoCombinator, replaceBy);
|
selector = StringWrapper.replace(selector, _polyfillHostNoCombinator, replaceBy);
|
||||||
@ -390,8 +397,7 @@ export class ShadowCss {
|
|||||||
for (var i = 0; i < splits.length; i++) {
|
for (var i = 0; i < splits.length; i++) {
|
||||||
var sep = splits[i];
|
var sep = splits[i];
|
||||||
var parts = scoped.split(sep);
|
var parts = scoped.split(sep);
|
||||||
scoped = parts
|
scoped = parts.map(p => {
|
||||||
.map(p => {
|
|
||||||
// remove :host since it should be unnecessary
|
// remove :host since it should be unnecessary
|
||||||
var t = StringWrapper.replaceAll(p.trim(), _polyfillHostRe, '');
|
var t = StringWrapper.replaceAll(p.trim(), _polyfillHostRe, '');
|
||||||
if (t.length > 0 && !ListWrapper.contains(splits, t) &&
|
if (t.length > 0 && !ListWrapper.contains(splits, t) &&
|
||||||
@ -430,7 +436,8 @@ var _cssColonHostRe = RegExpWrapper.create('(' + _polyfillHost + _parenSuffix, '
|
|||||||
var _cssColonHostContextRe = RegExpWrapper.create('(' + _polyfillHostContext + _parenSuffix, 'im');
|
var _cssColonHostContextRe = RegExpWrapper.create('(' + _polyfillHostContext + _parenSuffix, 'im');
|
||||||
var _polyfillHostNoCombinator = _polyfillHost + '-no-combinator';
|
var _polyfillHostNoCombinator = _polyfillHost + '-no-combinator';
|
||||||
var _shadowDOMSelectorsRe = [
|
var _shadowDOMSelectorsRe = [
|
||||||
/::shadow/g, /::content/g,
|
/::shadow/g,
|
||||||
|
/::content/g,
|
||||||
// Deprecated selectors
|
// Deprecated selectors
|
||||||
// TODO(vicb): see https://github.com/angular/clang-format/issues/16
|
// TODO(vicb): see https://github.com/angular/clang-format/issues/16
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
@ -1,6 +1,30 @@
|
|||||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {isArray, isBlank, isNumber, isPresent, isPrimitive, isString, Type} from 'angular2/src/facade/lang';
|
import {
|
||||||
import {AttributeMetadata, DirectiveMetadata, ComponentMetadata, ContentChildrenMetadata, ContentChildMetadata, InputMetadata, HostBindingMetadata, HostListenerMetadata, OutputMetadata, PipeMetadata, ViewMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata, QueryMetadata,} from 'angular2/src/core/metadata';
|
isArray,
|
||||||
|
isBlank,
|
||||||
|
isNumber,
|
||||||
|
isPresent,
|
||||||
|
isPrimitive,
|
||||||
|
isString,
|
||||||
|
Type
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
import {
|
||||||
|
AttributeMetadata,
|
||||||
|
DirectiveMetadata,
|
||||||
|
ComponentMetadata,
|
||||||
|
ContentChildrenMetadata,
|
||||||
|
ContentChildMetadata,
|
||||||
|
InputMetadata,
|
||||||
|
HostBindingMetadata,
|
||||||
|
HostListenerMetadata,
|
||||||
|
OutputMetadata,
|
||||||
|
PipeMetadata,
|
||||||
|
ViewMetadata,
|
||||||
|
ViewChildMetadata,
|
||||||
|
ViewChildrenMetadata,
|
||||||
|
ViewQueryMetadata,
|
||||||
|
QueryMetadata,
|
||||||
|
} from 'angular2/src/core/metadata';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The host of the static resolver is expected to be able to provide module metadata in the form of
|
* The host of the static resolver is expected to be able to provide module metadata in the form of
|
||||||
@ -100,8 +124,8 @@ export class StaticReflector {
|
|||||||
private initializeConversionMap(): any {
|
private initializeConversionMap(): any {
|
||||||
let core_metadata = 'angular2/src/core/metadata';
|
let core_metadata = 'angular2/src/core/metadata';
|
||||||
let conversionMap = this.conversionMap;
|
let conversionMap = this.conversionMap;
|
||||||
conversionMap.set(
|
conversionMap.set(this.getStaticType(core_metadata, 'Directive'),
|
||||||
this.getStaticType(core_metadata, 'Directive'), (moduleContext, expression) => {
|
(moduleContext, expression) => {
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||||
if (!isPresent(p0)) {
|
if (!isPresent(p0)) {
|
||||||
p0 = {};
|
p0 = {};
|
||||||
@ -118,8 +142,8 @@ export class StaticReflector {
|
|||||||
queries: p0['queries'],
|
queries: p0['queries'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
conversionMap.set(
|
conversionMap.set(this.getStaticType(core_metadata, 'Component'),
|
||||||
this.getStaticType(core_metadata, 'Component'), (moduleContext, expression) => {
|
(moduleContext, expression) => {
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||||
if (!isPresent(p0)) {
|
if (!isPresent(p0)) {
|
||||||
p0 = {};
|
p0 = {};
|
||||||
@ -148,14 +172,12 @@ export class StaticReflector {
|
|||||||
encapsulation: p0['encapsulation']
|
encapsulation: p0['encapsulation']
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
conversionMap.set(
|
conversionMap.set(this.getStaticType(core_metadata, 'Input'),
|
||||||
this.getStaticType(core_metadata, 'Input'),
|
(moduleContext, expression) => new InputMetadata(
|
||||||
(moduleContext, expression) =>
|
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||||
new InputMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
conversionMap.set(this.getStaticType(core_metadata, 'Output'),
|
||||||
conversionMap.set(
|
(moduleContext, expression) => new OutputMetadata(
|
||||||
this.getStaticType(core_metadata, 'Output'),
|
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||||
(moduleContext, expression) =>
|
|
||||||
new OutputMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'View'), (moduleContext, expression) => {
|
conversionMap.set(this.getStaticType(core_metadata, 'View'), (moduleContext, expression) => {
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||||
if (!isPresent(p0)) {
|
if (!isPresent(p0)) {
|
||||||
@ -170,10 +192,9 @@ export class StaticReflector {
|
|||||||
styles: p0['styles'],
|
styles: p0['styles'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
conversionMap.set(
|
conversionMap.set(this.getStaticType(core_metadata, 'Attribute'),
|
||||||
this.getStaticType(core_metadata, 'Attribute'),
|
(moduleContext, expression) => new AttributeMetadata(
|
||||||
(moduleContext, expression) =>
|
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||||
new AttributeMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(this.getStaticType(core_metadata, 'Query'), (moduleContext, expression) => {
|
conversionMap.set(this.getStaticType(core_metadata, 'Query'), (moduleContext, expression) => {
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||||
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
||||||
@ -182,24 +203,20 @@ export class StaticReflector {
|
|||||||
}
|
}
|
||||||
return new QueryMetadata(p0, {descendants: p1.descendants, first: p1.first});
|
return new QueryMetadata(p0, {descendants: p1.descendants, first: p1.first});
|
||||||
});
|
});
|
||||||
conversionMap.set(
|
conversionMap.set(this.getStaticType(core_metadata, 'ContentChildren'),
|
||||||
this.getStaticType(core_metadata, 'ContentChildren'),
|
(moduleContext, expression) => new ContentChildrenMetadata(
|
||||||
(moduleContext, expression) =>
|
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||||
new ContentChildrenMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
conversionMap.set(this.getStaticType(core_metadata, 'ContentChild'),
|
||||||
conversionMap.set(
|
(moduleContext, expression) => new ContentChildMetadata(
|
||||||
this.getStaticType(core_metadata, 'ContentChild'),
|
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||||
(moduleContext, expression) =>
|
conversionMap.set(this.getStaticType(core_metadata, 'ViewChildren'),
|
||||||
new ContentChildMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
(moduleContext, expression) => new ViewChildrenMetadata(
|
||||||
conversionMap.set(
|
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||||
this.getStaticType(core_metadata, 'ViewChildren'),
|
conversionMap.set(this.getStaticType(core_metadata, 'ViewChild'),
|
||||||
(moduleContext, expression) =>
|
(moduleContext, expression) => new ViewChildMetadata(
|
||||||
new ViewChildrenMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||||
conversionMap.set(
|
conversionMap.set(this.getStaticType(core_metadata, 'ViewQuery'),
|
||||||
this.getStaticType(core_metadata, 'ViewChild'),
|
(moduleContext, expression) => {
|
||||||
(moduleContext, expression) =>
|
|
||||||
new ViewChildMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
|
||||||
conversionMap.set(
|
|
||||||
this.getStaticType(core_metadata, 'ViewQuery'), (moduleContext, expression) => {
|
|
||||||
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
|
||||||
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
|
||||||
if (!isPresent(p1)) {
|
if (!isPresent(p1)) {
|
||||||
@ -220,12 +237,10 @@ export class StaticReflector {
|
|||||||
pure: p0['pure'],
|
pure: p0['pure'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
conversionMap.set(
|
conversionMap.set(this.getStaticType(core_metadata, 'HostBinding'),
|
||||||
this.getStaticType(core_metadata, 'HostBinding'),
|
(moduleContext, expression) => new HostBindingMetadata(
|
||||||
(moduleContext, expression) =>
|
this.getDecoratorParameter(moduleContext, expression, 0)));
|
||||||
new HostBindingMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
|
conversionMap.set(this.getStaticType(core_metadata, 'HostListener'),
|
||||||
conversionMap.set(
|
|
||||||
this.getStaticType(core_metadata, 'HostListener'),
|
|
||||||
(moduleContext, expression) => new HostListenerMetadata(
|
(moduleContext, expression) => new HostListenerMetadata(
|
||||||
this.getDecoratorParameter(moduleContext, expression, 0),
|
this.getDecoratorParameter(moduleContext, expression, 0),
|
||||||
this.getDecoratorParameter(moduleContext, expression, 1)));
|
this.getDecoratorParameter(moduleContext, expression, 1)));
|
||||||
@ -249,8 +264,8 @@ export class StaticReflector {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getDecoratorParameter(
|
private getDecoratorParameter(moduleContext: string, expression: {[key: string]: any},
|
||||||
moduleContext: string, expression: {[key: string]: any}, index: number): any {
|
index: number): any {
|
||||||
if (isMetadataSymbolicCallExpression(expression) && isPresent(expression['arguments']) &&
|
if (isMetadataSymbolicCallExpression(expression) && isPresent(expression['arguments']) &&
|
||||||
(<any[]>expression['arguments']).length <= index + 1) {
|
(<any[]>expression['arguments']).length <= index + 1) {
|
||||||
return this.simplify(moduleContext, (<any[]>expression['arguments'])[index]);
|
return this.simplify(moduleContext, (<any[]>expression['arguments'])[index]);
|
||||||
@ -258,14 +273,14 @@ export class StaticReflector {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getPropertyMetadata(moduleContext: string, value: {[key: string]: any}):
|
private getPropertyMetadata(moduleContext: string,
|
||||||
{[key: string]: any} {
|
value: {[key: string]: any}): {[key: string]: any} {
|
||||||
if (isPresent(value)) {
|
if (isPresent(value)) {
|
||||||
let result = {};
|
let result = {};
|
||||||
StringMapWrapper.forEach(value, (value, name) => {
|
StringMapWrapper.forEach(value, (value, name) => {
|
||||||
let data = this.getMemberData(moduleContext, value);
|
let data = this.getMemberData(moduleContext, value);
|
||||||
if (isPresent(data)) {
|
if (isPresent(data)) {
|
||||||
let propertyData = data.filter(d => d['kind'] == 'property')
|
let propertyData = data.filter(d => d['kind'] == "property")
|
||||||
.map(d => d['directives'])
|
.map(d => d['directives'])
|
||||||
.reduce((p, c) => (<any[]>p).concat(<any[]>c), []);
|
.reduce((p, c) => (<any[]>p).concat(<any[]>c), []);
|
||||||
if (propertyData.length != 0) {
|
if (propertyData.length != 0) {
|
||||||
@ -286,7 +301,8 @@ export class StaticReflector {
|
|||||||
for (let item of member) {
|
for (let item of member) {
|
||||||
result.push({
|
result.push({
|
||||||
kind: item['__symbolic'],
|
kind: item['__symbolic'],
|
||||||
directives: isPresent(item['decorators']) ?
|
directives:
|
||||||
|
isPresent(item['decorators']) ?
|
||||||
(<any[]>item['decorators'])
|
(<any[]>item['decorators'])
|
||||||
.map(decorator => this.convertKnownDecorator(moduleContext, decorator))
|
.map(decorator => this.convertKnownDecorator(moduleContext, decorator))
|
||||||
.filter(d => isPresent(d)) :
|
.filter(d => isPresent(d)) :
|
||||||
@ -315,7 +331,7 @@ export class StaticReflector {
|
|||||||
if (isPresent(expression)) {
|
if (isPresent(expression)) {
|
||||||
if (isPresent(expression['__symbolic'])) {
|
if (isPresent(expression['__symbolic'])) {
|
||||||
switch (expression['__symbolic']) {
|
switch (expression['__symbolic']) {
|
||||||
case 'binop':
|
case "binop":
|
||||||
let left = simplify(expression['left']);
|
let left = simplify(expression['left']);
|
||||||
let right = simplify(expression['right']);
|
let right = simplify(expression['right']);
|
||||||
switch (expression['operator']) {
|
switch (expression['operator']) {
|
||||||
@ -361,7 +377,7 @@ export class StaticReflector {
|
|||||||
return left % right;
|
return left % right;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
case 'pre':
|
case "pre":
|
||||||
let operand = simplify(expression['operand']);
|
let operand = simplify(expression['operand']);
|
||||||
switch (expression['operator']) {
|
switch (expression['operator']) {
|
||||||
case '+':
|
case '+':
|
||||||
@ -374,17 +390,17 @@ export class StaticReflector {
|
|||||||
return ~operand;
|
return ~operand;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
case 'index':
|
case "index":
|
||||||
let indexTarget = simplify(expression['expression']);
|
let indexTarget = simplify(expression['expression']);
|
||||||
let index = simplify(expression['index']);
|
let index = simplify(expression['index']);
|
||||||
if (isPresent(indexTarget) && isPrimitive(index)) return indexTarget[index];
|
if (isPresent(indexTarget) && isPrimitive(index)) return indexTarget[index];
|
||||||
return null;
|
return null;
|
||||||
case 'select':
|
case "select":
|
||||||
let selectTarget = simplify(expression['expression']);
|
let selectTarget = simplify(expression['expression']);
|
||||||
let member = simplify(expression['member']);
|
let member = simplify(expression['member']);
|
||||||
if (isPresent(selectTarget) && isPrimitive(member)) return selectTarget[member];
|
if (isPresent(selectTarget) && isPrimitive(member)) return selectTarget[member];
|
||||||
return null;
|
return null;
|
||||||
case 'reference':
|
case "reference":
|
||||||
let referenceModuleName =
|
let referenceModuleName =
|
||||||
_this.normalizeModuleName(moduleContext, expression['module']);
|
_this.normalizeModuleName(moduleContext, expression['module']);
|
||||||
let referenceModule = _this.getModuleMetadata(referenceModuleName);
|
let referenceModule = _this.getModuleMetadata(referenceModuleName);
|
||||||
@ -394,7 +410,7 @@ export class StaticReflector {
|
|||||||
return _this.getStaticType(referenceModuleName, expression['name']);
|
return _this.getStaticType(referenceModuleName, expression['name']);
|
||||||
}
|
}
|
||||||
return _this.simplify(referenceModuleName, referenceValue);
|
return _this.simplify(referenceModuleName, referenceValue);
|
||||||
case 'call':
|
case "call":
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -414,7 +430,7 @@ export class StaticReflector {
|
|||||||
if (!isPresent(moduleMetadata)) {
|
if (!isPresent(moduleMetadata)) {
|
||||||
moduleMetadata = this.host.getMetadataFor(module);
|
moduleMetadata = this.host.getMetadataFor(module);
|
||||||
if (!isPresent(moduleMetadata)) {
|
if (!isPresent(moduleMetadata)) {
|
||||||
moduleMetadata = {__symbolic: 'module', module: module, metadata: {}};
|
moduleMetadata = {__symbolic: "module", module: module, metadata: {}};
|
||||||
}
|
}
|
||||||
this.metadataCache.set(module, moduleMetadata);
|
this.metadataCache.set(module, moduleMetadata);
|
||||||
}
|
}
|
||||||
@ -425,7 +441,7 @@ export class StaticReflector {
|
|||||||
let moduleMetadata = this.getModuleMetadata(type.moduleId);
|
let moduleMetadata = this.getModuleMetadata(type.moduleId);
|
||||||
let result = moduleMetadata['metadata'][type.name];
|
let result = moduleMetadata['metadata'][type.name];
|
||||||
if (!isPresent(result)) {
|
if (!isPresent(result)) {
|
||||||
result = {__symbolic: 'class'};
|
result = {__symbolic: "class"};
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,12 @@ import {PromiseWrapper} from 'angular2/src/facade/async';
|
|||||||
import {ShadowCss} from 'angular2/src/compiler/shadow_css';
|
import {ShadowCss} from 'angular2/src/compiler/shadow_css';
|
||||||
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/compiler/url_resolver';
|
||||||
import {extractStyleUrls} from './style_url_resolver';
|
import {extractStyleUrls} from './style_url_resolver';
|
||||||
import {escapeSingleQuoteString, codeGenExportVariable, codeGenToString, MODULE_SUFFIX} from './util';
|
import {
|
||||||
|
escapeSingleQuoteString,
|
||||||
|
codeGenExportVariable,
|
||||||
|
codeGenToString,
|
||||||
|
MODULE_SUFFIX
|
||||||
|
} from './util';
|
||||||
import {Injectable} from 'angular2/src/core/di';
|
import {Injectable} from 'angular2/src/core/di';
|
||||||
|
|
||||||
const COMPONENT_VARIABLE = '%COMP%';
|
const COMPONENT_VARIABLE = '%COMP%';
|
||||||
@ -24,8 +29,8 @@ export class StyleCompiler {
|
|||||||
compileComponentRuntime(template: CompileTemplateMetadata): Promise<Array<string | any[]>> {
|
compileComponentRuntime(template: CompileTemplateMetadata): Promise<Array<string | any[]>> {
|
||||||
var styles = template.styles;
|
var styles = template.styles;
|
||||||
var styleAbsUrls = template.styleUrls;
|
var styleAbsUrls = template.styleUrls;
|
||||||
return this._loadStyles(
|
return this._loadStyles(styles, styleAbsUrls,
|
||||||
styles, styleAbsUrls, template.encapsulation === ViewEncapsulation.Emulated);
|
template.encapsulation === ViewEncapsulation.Emulated);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileComponentCodeGen(template: CompileTemplateMetadata): SourceExpression {
|
compileComponentCodeGen(template: CompileTemplateMetadata): SourceExpression {
|
||||||
@ -39,24 +44,23 @@ export class StyleCompiler {
|
|||||||
this._styleModule(
|
this._styleModule(
|
||||||
stylesheetUrl, false,
|
stylesheetUrl, false,
|
||||||
this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, false)),
|
this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, false)),
|
||||||
this._styleModule(
|
this._styleModule(stylesheetUrl, true, this._styleCodeGen([styleWithImports.style],
|
||||||
stylesheetUrl, true,
|
styleWithImports.styleUrls, true))
|
||||||
this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, true))
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCache() { this._styleCache.clear(); }
|
clearCache() { this._styleCache.clear(); }
|
||||||
|
|
||||||
private _loadStyles(plainStyles: string[], absUrls: string[], encapsulate: boolean):
|
private _loadStyles(plainStyles: string[], absUrls: string[],
|
||||||
Promise<Array<string|any[]>> {
|
encapsulate: boolean): Promise<Array<string | any[]>> {
|
||||||
var promises: Promise<string[]>[] = absUrls.map((absUrl: string): Promise<string[]> => {
|
var promises: Promise<string[]>[] = absUrls.map((absUrl: string): Promise<string[]> => {
|
||||||
var cacheKey = `${absUrl}${encapsulate ? '.shim' : ''}`;
|
var cacheKey = `${absUrl}${encapsulate ? '.shim' : ''}`;
|
||||||
var result: Promise<string[]> = this._styleCache.get(cacheKey);
|
var result: Promise<string[]> = this._styleCache.get(cacheKey);
|
||||||
if (isBlank(result)) {
|
if (isBlank(result)) {
|
||||||
result = this._xhr.get(absUrl).then((style) => {
|
result = this._xhr.get(absUrl).then((style) => {
|
||||||
var styleWithImports = extractStyleUrls(this._urlResolver, absUrl, style);
|
var styleWithImports = extractStyleUrls(this._urlResolver, absUrl, style);
|
||||||
return this._loadStyles(
|
return this._loadStyles([styleWithImports.style], styleWithImports.styleUrls,
|
||||||
[styleWithImports.style], styleWithImports.styleUrls, encapsulate);
|
encapsulate);
|
||||||
});
|
});
|
||||||
this._styleCache.set(cacheKey, result);
|
this._styleCache.set(cacheKey, result);
|
||||||
}
|
}
|
||||||
@ -83,8 +87,8 @@ export class StyleCompiler {
|
|||||||
return new SourceExpression([], expressionSource);
|
return new SourceExpression([], expressionSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _styleModule(stylesheetUrl: string, shim: boolean, expression: SourceExpression):
|
private _styleModule(stylesheetUrl: string, shim: boolean,
|
||||||
SourceModule {
|
expression: SourceExpression): SourceModule {
|
||||||
var moduleSource = `
|
var moduleSource = `
|
||||||
${expression.declarations.join('\n')}
|
${expression.declarations.join('\n')}
|
||||||
${codeGenExportVariable('STYLES')}${expression.expression};
|
${codeGenExportVariable('STYLES')}${expression.expression};
|
||||||
|
@ -18,8 +18,8 @@ export function isStyleUrlResolvable(url: string): boolean {
|
|||||||
* Rewrites stylesheets by resolving and removing the @import urls that
|
* Rewrites stylesheets by resolving and removing the @import urls that
|
||||||
* are either relative or don't have a `package:` scheme
|
* are either relative or don't have a `package:` scheme
|
||||||
*/
|
*/
|
||||||
export function extractStyleUrls(
|
export function extractStyleUrls(resolver: UrlResolver, baseUrl: string,
|
||||||
resolver: UrlResolver, baseUrl: string, cssText: string): StyleWithImports {
|
cssText: string): StyleWithImports {
|
||||||
var foundUrls = [];
|
var foundUrls = [];
|
||||||
var modifiedCssText = StringWrapper.replaceAllMapped(cssText, _cssImportRe, (m) => {
|
var modifiedCssText = StringWrapper.replaceAllMapped(cssText, _cssImportRe, (m) => {
|
||||||
var url = isPresent(m[1]) ? m[1] : m[2];
|
var url = isPresent(m[1]) ? m[1] : m[2];
|
||||||
|
@ -22,8 +22,8 @@ export interface TemplateAst {
|
|||||||
* A segment of text within the template.
|
* A segment of text within the template.
|
||||||
*/
|
*/
|
||||||
export class TextAst implements TemplateAst {
|
export class TextAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public value: string, public ngContentIndex: number,
|
||||||
public value: string, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitText(this, context); }
|
visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitText(this, context); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,8 +31,8 @@ export class TextAst implements TemplateAst {
|
|||||||
* A bound expression within the text of a template.
|
* A bound expression within the text of a template.
|
||||||
*/
|
*/
|
||||||
export class BoundTextAst implements TemplateAst {
|
export class BoundTextAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public value: AST, public ngContentIndex: number,
|
||||||
public value: AST, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitBoundText(this, context);
|
return visitor.visitBoundText(this, context);
|
||||||
}
|
}
|
||||||
@ -50,9 +50,8 @@ export class AttrAst implements TemplateAst {
|
|||||||
* A binding for an element property (e.g. `[property]="expression"`).
|
* A binding for an element property (e.g. `[property]="expression"`).
|
||||||
*/
|
*/
|
||||||
export class BoundElementPropertyAst implements TemplateAst {
|
export class BoundElementPropertyAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public name: string, public type: PropertyBindingType, public value: AST,
|
||||||
public name: string, public type: PropertyBindingType, public value: AST, public unit: string,
|
public unit: string, public sourceSpan: ParseSourceSpan) {}
|
||||||
public sourceSpan: ParseSourceSpan) {}
|
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitElementProperty(this, context);
|
return visitor.visitElementProperty(this, context);
|
||||||
}
|
}
|
||||||
@ -62,8 +61,7 @@ export class BoundElementPropertyAst implements TemplateAst {
|
|||||||
* A binding for an element event (e.g. `(event)="handler()"`).
|
* A binding for an element event (e.g. `(event)="handler()"`).
|
||||||
*/
|
*/
|
||||||
export class BoundEventAst implements TemplateAst {
|
export class BoundEventAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public name: string, public target: string, public handler: AST,
|
||||||
public name: string, public target: string, public handler: AST,
|
|
||||||
public sourceSpan: ParseSourceSpan) {}
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitEvent(this, context);
|
return visitor.visitEvent(this, context);
|
||||||
@ -91,11 +89,11 @@ export class VariableAst implements TemplateAst {
|
|||||||
* An element declaration in a template.
|
* An element declaration in a template.
|
||||||
*/
|
*/
|
||||||
export class ElementAst implements TemplateAst {
|
export class ElementAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public name: string, public attrs: AttrAst[],
|
||||||
public name: string, public attrs: AttrAst[], public inputs: BoundElementPropertyAst[],
|
public inputs: BoundElementPropertyAst[], public outputs: BoundEventAst[],
|
||||||
public outputs: BoundEventAst[], public exportAsVars: VariableAst[],
|
public exportAsVars: VariableAst[], public directives: DirectiveAst[],
|
||||||
public directives: DirectiveAst[], public children: TemplateAst[],
|
public children: TemplateAst[], public ngContentIndex: number,
|
||||||
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitElement(this, context);
|
return visitor.visitElement(this, context);
|
||||||
}
|
}
|
||||||
@ -104,8 +102,7 @@ export class ElementAst implements TemplateAst {
|
|||||||
* Whether the element has any active bindings (inputs, outputs, vars, or directives).
|
* Whether the element has any active bindings (inputs, outputs, vars, or directives).
|
||||||
*/
|
*/
|
||||||
isBound(): boolean {
|
isBound(): boolean {
|
||||||
return (
|
return (this.inputs.length > 0 || this.outputs.length > 0 || this.exportAsVars.length > 0 ||
|
||||||
this.inputs.length > 0 || this.outputs.length > 0 || this.exportAsVars.length > 0 ||
|
|
||||||
this.directives.length > 0);
|
this.directives.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +120,7 @@ export class ElementAst implements TemplateAst {
|
|||||||
* A `<template>` element included in an Angular template.
|
* A `<template>` element included in an Angular template.
|
||||||
*/
|
*/
|
||||||
export class EmbeddedTemplateAst implements TemplateAst {
|
export class EmbeddedTemplateAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
|
||||||
public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
|
|
||||||
public directives: DirectiveAst[], public children: TemplateAst[],
|
public directives: DirectiveAst[], public children: TemplateAst[],
|
||||||
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
@ -136,8 +132,7 @@ export class EmbeddedTemplateAst implements TemplateAst {
|
|||||||
* A directive property with a bound value (e.g. `*ngIf="condition").
|
* A directive property with a bound value (e.g. `*ngIf="condition").
|
||||||
*/
|
*/
|
||||||
export class BoundDirectivePropertyAst implements TemplateAst {
|
export class BoundDirectivePropertyAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public directiveName: string, public templateName: string, public value: AST,
|
||||||
public directiveName: string, public templateName: string, public value: AST,
|
|
||||||
public sourceSpan: ParseSourceSpan) {}
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitDirectiveProperty(this, context);
|
return visitor.visitDirectiveProperty(this, context);
|
||||||
@ -148,8 +143,8 @@ export class BoundDirectivePropertyAst implements TemplateAst {
|
|||||||
* A directive declared on an element.
|
* A directive declared on an element.
|
||||||
*/
|
*/
|
||||||
export class DirectiveAst implements TemplateAst {
|
export class DirectiveAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public directive: CompileDirectiveMetadata,
|
||||||
public directive: CompileDirectiveMetadata, public inputs: BoundDirectivePropertyAst[],
|
public inputs: BoundDirectivePropertyAst[],
|
||||||
public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[],
|
public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[],
|
||||||
public exportAsVars: VariableAst[], public sourceSpan: ParseSourceSpan) {}
|
public exportAsVars: VariableAst[], public sourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
@ -161,8 +156,8 @@ export class DirectiveAst implements TemplateAst {
|
|||||||
* Position where content is to be projected (instance of `<ng-content>` in a template).
|
* Position where content is to be projected (instance of `<ng-content>` in a template).
|
||||||
*/
|
*/
|
||||||
export class NgContentAst implements TemplateAst {
|
export class NgContentAst implements TemplateAst {
|
||||||
constructor(
|
constructor(public index: number, public ngContentIndex: number,
|
||||||
public index: number, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||||
return visitor.visitNgContent(this, context);
|
return visitor.visitNgContent(this, context);
|
||||||
}
|
}
|
||||||
@ -214,8 +209,8 @@ export interface TemplateAstVisitor {
|
|||||||
/**
|
/**
|
||||||
* Visit every node in a list of {@link TemplateAst}s with the given {@link TemplateAstVisitor}.
|
* Visit every node in a list of {@link TemplateAst}s with the given {@link TemplateAstVisitor}.
|
||||||
*/
|
*/
|
||||||
export function templateVisitAll(
|
export function templateVisitAll(visitor: TemplateAstVisitor, asts: TemplateAst[],
|
||||||
visitor: TemplateAstVisitor, asts: TemplateAst[], context: any = null): any[] {
|
context: any = null): any[] {
|
||||||
var result = [];
|
var result = [];
|
||||||
asts.forEach(ast => {
|
asts.forEach(ast => {
|
||||||
var astResult = ast.visit(visitor, context);
|
var astResult = ast.visit(visitor, context);
|
||||||
|
@ -1,15 +1,55 @@
|
|||||||
import {IS_DART, Type, Json, isBlank, isPresent, stringify, evalExpression} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
IS_DART,
|
||||||
|
Type,
|
||||||
|
Json,
|
||||||
|
isBlank,
|
||||||
|
isPresent,
|
||||||
|
stringify,
|
||||||
|
evalExpression
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import {ListWrapper, SetWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
import {
|
||||||
|
ListWrapper,
|
||||||
|
SetWrapper,
|
||||||
|
MapWrapper,
|
||||||
|
StringMapWrapper
|
||||||
|
} from 'angular2/src/facade/collection';
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {createHostComponentMeta, CompileDirectiveMetadata, CompileTypeMetadata, CompileTemplateMetadata, CompilePipeMetadata, CompileMetadataWithType} from './directive_metadata';
|
import {
|
||||||
import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
|
createHostComponentMeta,
|
||||||
|
CompileDirectiveMetadata,
|
||||||
|
CompileTypeMetadata,
|
||||||
|
CompileTemplateMetadata,
|
||||||
|
CompilePipeMetadata,
|
||||||
|
CompileMetadataWithType
|
||||||
|
} from './directive_metadata';
|
||||||
|
import {
|
||||||
|
TemplateAst,
|
||||||
|
TemplateAstVisitor,
|
||||||
|
NgContentAst,
|
||||||
|
EmbeddedTemplateAst,
|
||||||
|
ElementAst,
|
||||||
|
VariableAst,
|
||||||
|
BoundEventAst,
|
||||||
|
BoundElementPropertyAst,
|
||||||
|
AttrAst,
|
||||||
|
BoundTextAst,
|
||||||
|
TextAst,
|
||||||
|
DirectiveAst,
|
||||||
|
BoundDirectivePropertyAst,
|
||||||
|
templateVisitAll
|
||||||
|
} from './template_ast';
|
||||||
import {Injectable} from 'angular2/src/core/di';
|
import {Injectable} from 'angular2/src/core/di';
|
||||||
import {SourceModule, moduleRef, SourceExpression} from './source_module';
|
import {SourceModule, moduleRef, SourceExpression} from './source_module';
|
||||||
import {ChangeDetectionCompiler, CHANGE_DETECTION_JIT_IMPORTS} from './change_detector_compiler';
|
import {ChangeDetectionCompiler, CHANGE_DETECTION_JIT_IMPORTS} from './change_detector_compiler';
|
||||||
import {StyleCompiler} from './style_compiler';
|
import {StyleCompiler} from './style_compiler';
|
||||||
import {ViewCompiler, VIEW_JIT_IMPORTS} from './view_compiler';
|
import {ViewCompiler, VIEW_JIT_IMPORTS} from './view_compiler';
|
||||||
import {ProtoViewCompiler, APP_VIEW_MODULE_REF, CompileProtoView, PROTO_VIEW_JIT_IMPORTS} from './proto_view_compiler';
|
import {
|
||||||
|
ProtoViewCompiler,
|
||||||
|
APP_VIEW_MODULE_REF,
|
||||||
|
CompileProtoView,
|
||||||
|
PROTO_VIEW_JIT_IMPORTS
|
||||||
|
} from './proto_view_compiler';
|
||||||
import {TemplateParser, PipeCollector} from './template_parser';
|
import {TemplateParser, PipeCollector} from './template_parser';
|
||||||
import {TemplateNormalizer} from './template_normalizer';
|
import {TemplateNormalizer} from './template_normalizer';
|
||||||
import {RuntimeMetadataResolver} from './runtime_metadata';
|
import {RuntimeMetadataResolver} from './runtime_metadata';
|
||||||
@ -17,7 +57,14 @@ import {HostViewFactory} from 'angular2/src/core/linker/view';
|
|||||||
import {ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection';
|
import {ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection';
|
||||||
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
||||||
|
|
||||||
import {codeGenExportVariable, escapeSingleQuoteString, codeGenValueFn, MODULE_SUFFIX, addAll, Expression} from './util';
|
import {
|
||||||
|
codeGenExportVariable,
|
||||||
|
escapeSingleQuoteString,
|
||||||
|
codeGenValueFn,
|
||||||
|
MODULE_SUFFIX,
|
||||||
|
addAll,
|
||||||
|
Expression
|
||||||
|
} from './util';
|
||||||
|
|
||||||
export var METADATA_CACHE_MODULE_REF =
|
export var METADATA_CACHE_MODULE_REF =
|
||||||
moduleRef('package:angular2/src/core/linker/resolved_metadata_cache' + MODULE_SUFFIX);
|
moduleRef('package:angular2/src/core/linker/resolved_metadata_cache' + MODULE_SUFFIX);
|
||||||
@ -33,10 +80,10 @@ export class TemplateCompiler {
|
|||||||
private _compiledTemplateCache = new Map<any, CompiledTemplate>();
|
private _compiledTemplateCache = new Map<any, CompiledTemplate>();
|
||||||
private _compiledTemplateDone = new Map<any, Promise<CompiledTemplate>>();
|
private _compiledTemplateDone = new Map<any, Promise<CompiledTemplate>>();
|
||||||
|
|
||||||
constructor(
|
constructor(private _runtimeMetadataResolver: RuntimeMetadataResolver,
|
||||||
private _runtimeMetadataResolver: RuntimeMetadataResolver,
|
private _templateNormalizer: TemplateNormalizer,
|
||||||
private _templateNormalizer: TemplateNormalizer, private _templateParser: TemplateParser,
|
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
|
||||||
private _styleCompiler: StyleCompiler, private _cdCompiler: ChangeDetectionCompiler,
|
private _cdCompiler: ChangeDetectionCompiler,
|
||||||
private _protoViewCompiler: ProtoViewCompiler, private _viewCompiler: ViewCompiler,
|
private _protoViewCompiler: ProtoViewCompiler, private _viewCompiler: ViewCompiler,
|
||||||
private _resolvedMetadataCache: ResolvedMetadataCache,
|
private _resolvedMetadataCache: ResolvedMetadataCache,
|
||||||
private _genConfig: ChangeDetectorGenConfig) {}
|
private _genConfig: ChangeDetectorGenConfig) {}
|
||||||
@ -84,8 +131,7 @@ export class TemplateCompiler {
|
|||||||
this._compileComponentRuntime(hostCacheKey, hostMeta, [compMeta], [], []);
|
this._compileComponentRuntime(hostCacheKey, hostMeta, [compMeta], [], []);
|
||||||
}
|
}
|
||||||
return this._compiledTemplateDone.get(hostCacheKey)
|
return this._compiledTemplateDone.get(hostCacheKey)
|
||||||
.then(
|
.then((compiledTemplate: CompiledTemplate) =>
|
||||||
(compiledTemplate: CompiledTemplate) =>
|
|
||||||
new HostViewFactory(compMeta.selector, compiledTemplate.viewFactory));
|
new HostViewFactory(compMeta.selector, compiledTemplate.viewFactory));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,8 +150,8 @@ export class TemplateCompiler {
|
|||||||
components.forEach(componentWithDirs => {
|
components.forEach(componentWithDirs => {
|
||||||
var compMeta = <CompileDirectiveMetadata>componentWithDirs.component;
|
var compMeta = <CompileDirectiveMetadata>componentWithDirs.component;
|
||||||
assertComponent(compMeta);
|
assertComponent(compMeta);
|
||||||
this._compileComponentCodeGen(
|
this._compileComponentCodeGen(compMeta, componentWithDirs.directives, componentWithDirs.pipes,
|
||||||
compMeta, componentWithDirs.directives, componentWithDirs.pipes, declarations);
|
declarations);
|
||||||
if (compMeta.dynamicLoadable) {
|
if (compMeta.dynamicLoadable) {
|
||||||
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
|
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
|
||||||
var viewFactoryExpression =
|
var viewFactoryExpression =
|
||||||
@ -127,9 +173,10 @@ export class TemplateCompiler {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private _compileComponentRuntime(
|
private _compileComponentRuntime(cacheKey: any, compMeta: CompileDirectiveMetadata,
|
||||||
cacheKey: any, compMeta: CompileDirectiveMetadata, viewDirectives: CompileDirectiveMetadata[],
|
viewDirectives: CompileDirectiveMetadata[],
|
||||||
pipes: CompilePipeMetadata[], compilingComponentsPath: any[]): CompiledTemplate {
|
pipes: CompilePipeMetadata[],
|
||||||
|
compilingComponentsPath: any[]): CompiledTemplate {
|
||||||
let uniqViewDirectives = <CompileDirectiveMetadata[]>removeDuplicates(viewDirectives);
|
let uniqViewDirectives = <CompileDirectiveMetadata[]>removeDuplicates(viewDirectives);
|
||||||
let uniqViewPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
let uniqViewPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
||||||
var compiledTemplate = this._compiledTemplateCache.get(cacheKey);
|
var compiledTemplate = this._compiledTemplateCache.get(cacheKey);
|
||||||
@ -137,8 +184,7 @@ export class TemplateCompiler {
|
|||||||
if (isBlank(compiledTemplate)) {
|
if (isBlank(compiledTemplate)) {
|
||||||
compiledTemplate = new CompiledTemplate();
|
compiledTemplate = new CompiledTemplate();
|
||||||
this._compiledTemplateCache.set(cacheKey, compiledTemplate);
|
this._compiledTemplateCache.set(cacheKey, compiledTemplate);
|
||||||
done =
|
done = PromiseWrapper
|
||||||
PromiseWrapper
|
|
||||||
.all([<any>this._styleCompiler.compileComponentRuntime(compMeta.template)].concat(
|
.all([<any>this._styleCompiler.compileComponentRuntime(compMeta.template)].concat(
|
||||||
uniqViewDirectives.map(dirMeta => this.normalizeDirectiveMetadata(dirMeta))))
|
uniqViewDirectives.map(dirMeta => this.normalizeDirectiveMetadata(dirMeta))))
|
||||||
.then((stylesAndNormalizedViewDirMetas: any[]) => {
|
.then((stylesAndNormalizedViewDirMetas: any[]) => {
|
||||||
@ -153,10 +199,12 @@ export class TemplateCompiler {
|
|||||||
usedDirectives.components.forEach(
|
usedDirectives.components.forEach(
|
||||||
component => this._compileNestedComponentRuntime(
|
component => this._compileNestedComponentRuntime(
|
||||||
component, compilingComponentsPath, childPromises));
|
component, compilingComponentsPath, childPromises));
|
||||||
return PromiseWrapper.all(childPromises).then((_) => {
|
return PromiseWrapper.all(childPromises)
|
||||||
|
.then((_) => {
|
||||||
var filteredPipes = filterPipes(parsedTemplate, uniqViewPipes);
|
var filteredPipes = filterPipes(parsedTemplate, uniqViewPipes);
|
||||||
compiledTemplate.init(this._createViewFactoryRuntime(
|
compiledTemplate.init(this._createViewFactoryRuntime(
|
||||||
compMeta, parsedTemplate, usedDirectives.directives, styles, filteredPipes));
|
compMeta, parsedTemplate, usedDirectives.directives, styles,
|
||||||
|
filteredPipes));
|
||||||
return compiledTemplate;
|
return compiledTemplate;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -165,8 +213,8 @@ export class TemplateCompiler {
|
|||||||
return compiledTemplate;
|
return compiledTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _compileNestedComponentRuntime(
|
private _compileNestedComponentRuntime(childComponentDir: CompileDirectiveMetadata,
|
||||||
childComponentDir: CompileDirectiveMetadata, parentCompilingComponentsPath: any[],
|
parentCompilingComponentsPath: any[],
|
||||||
childPromises: Promise<any>[]) {
|
childPromises: Promise<any>[]) {
|
||||||
var compilingComponentsPath = ListWrapper.clone(parentCompilingComponentsPath);
|
var compilingComponentsPath = ListWrapper.clone(parentCompilingComponentsPath);
|
||||||
|
|
||||||
@ -177,17 +225,16 @@ export class TemplateCompiler {
|
|||||||
this._runtimeMetadataResolver.getViewPipesMetadata(childComponentDir.type.runtime);
|
this._runtimeMetadataResolver.getViewPipesMetadata(childComponentDir.type.runtime);
|
||||||
var childIsRecursive = ListWrapper.contains(compilingComponentsPath, childCacheKey);
|
var childIsRecursive = ListWrapper.contains(compilingComponentsPath, childCacheKey);
|
||||||
compilingComponentsPath.push(childCacheKey);
|
compilingComponentsPath.push(childCacheKey);
|
||||||
this._compileComponentRuntime(
|
this._compileComponentRuntime(childCacheKey, childComponentDir, childViewDirectives,
|
||||||
childCacheKey, childComponentDir, childViewDirectives, childViewPipes,
|
childViewPipes, compilingComponentsPath);
|
||||||
compilingComponentsPath);
|
|
||||||
if (!childIsRecursive) {
|
if (!childIsRecursive) {
|
||||||
// Only wait for a child if it is not a cycle
|
// Only wait for a child if it is not a cycle
|
||||||
childPromises.push(this._compiledTemplateDone.get(childCacheKey));
|
childPromises.push(this._compiledTemplateDone.get(childCacheKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createViewFactoryRuntime(
|
private _createViewFactoryRuntime(compMeta: CompileDirectiveMetadata,
|
||||||
compMeta: CompileDirectiveMetadata, parsedTemplate: TemplateAst[],
|
parsedTemplate: TemplateAst[],
|
||||||
directives: CompileDirectiveMetadata[], styles: string[],
|
directives: CompileDirectiveMetadata[], styles: string[],
|
||||||
pipes: CompilePipeMetadata[]): Function {
|
pipes: CompilePipeMetadata[]): Function {
|
||||||
if (IS_DART || !this._genConfig.useJit) {
|
if (IS_DART || !this._genConfig.useJit) {
|
||||||
@ -200,14 +247,11 @@ export class TemplateCompiler {
|
|||||||
(compMeta) => this._getNestedComponentViewFactory(compMeta));
|
(compMeta) => this._getNestedComponentViewFactory(compMeta));
|
||||||
} else {
|
} else {
|
||||||
var declarations = [];
|
var declarations = [];
|
||||||
var viewFactoryExpr = this._createViewFactoryCodeGen(
|
var viewFactoryExpr = this._createViewFactoryCodeGen('resolvedMetadataCache', compMeta,
|
||||||
'resolvedMetadataCache', compMeta, new SourceExpression([], 'styles'), parsedTemplate,
|
new SourceExpression([], 'styles'),
|
||||||
pipes, declarations);
|
parsedTemplate, pipes, declarations);
|
||||||
var vars: {[key: string]: any} = {
|
var vars: {[key: string]: any} =
|
||||||
'exports': {},
|
{'exports': {}, 'styles': styles, 'resolvedMetadataCache': this._resolvedMetadataCache};
|
||||||
'styles': styles,
|
|
||||||
'resolvedMetadataCache': this._resolvedMetadataCache
|
|
||||||
};
|
|
||||||
directives.forEach(dirMeta => {
|
directives.forEach(dirMeta => {
|
||||||
vars[dirMeta.type.name] = dirMeta.type.runtime;
|
vars[dirMeta.type.name] = dirMeta.type.runtime;
|
||||||
if (dirMeta.isComponent && dirMeta.type.runtime !== compMeta.type.runtime) {
|
if (dirMeta.isComponent && dirMeta.type.runtime !== compMeta.type.runtime) {
|
||||||
@ -228,23 +272,24 @@ export class TemplateCompiler {
|
|||||||
return this._compiledTemplateCache.get(compMeta.type.runtime).viewFactory;
|
return this._compiledTemplateCache.get(compMeta.type.runtime).viewFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _compileComponentCodeGen(
|
private _compileComponentCodeGen(compMeta: CompileDirectiveMetadata,
|
||||||
compMeta: CompileDirectiveMetadata, directives: CompileDirectiveMetadata[],
|
directives: CompileDirectiveMetadata[],
|
||||||
pipes: CompilePipeMetadata[], targetDeclarations: string[]): string {
|
pipes: CompilePipeMetadata[],
|
||||||
|
targetDeclarations: string[]): string {
|
||||||
let uniqueDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives);
|
let uniqueDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives);
|
||||||
let uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
let uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
|
||||||
var styleExpr = this._styleCompiler.compileComponentCodeGen(compMeta.template);
|
var styleExpr = this._styleCompiler.compileComponentCodeGen(compMeta.template);
|
||||||
var parsedTemplate = this._templateParser.parse(
|
var parsedTemplate = this._templateParser.parse(compMeta.template.template, uniqueDirectives,
|
||||||
compMeta.template.template, uniqueDirectives, uniqPipes, compMeta.type.name);
|
uniqPipes, compMeta.type.name);
|
||||||
var filteredPipes = filterPipes(parsedTemplate, uniqPipes);
|
var filteredPipes = filterPipes(parsedTemplate, uniqPipes);
|
||||||
return this._createViewFactoryCodeGen(
|
return this._createViewFactoryCodeGen(
|
||||||
`${METADATA_CACHE_MODULE_REF}CODEGEN_RESOLVED_METADATA_CACHE`, compMeta, styleExpr,
|
`${METADATA_CACHE_MODULE_REF}CODEGEN_RESOLVED_METADATA_CACHE`, compMeta, styleExpr,
|
||||||
parsedTemplate, filteredPipes, targetDeclarations);
|
parsedTemplate, filteredPipes, targetDeclarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createViewFactoryCodeGen(
|
private _createViewFactoryCodeGen(resolvedMetadataCacheExpr: string,
|
||||||
resolvedMetadataCacheExpr: string, compMeta: CompileDirectiveMetadata,
|
compMeta: CompileDirectiveMetadata, styleExpr: SourceExpression,
|
||||||
styleExpr: SourceExpression, parsedTemplate: TemplateAst[], pipes: CompilePipeMetadata[],
|
parsedTemplate: TemplateAst[], pipes: CompilePipeMetadata[],
|
||||||
targetDeclarations: string[]): string {
|
targetDeclarations: string[]): string {
|
||||||
var changeDetectorsExprs = this._cdCompiler.compileComponentCodeGen(
|
var changeDetectorsExprs = this._cdCompiler.compileComponentCodeGen(
|
||||||
compMeta.type, compMeta.changeDetection, parsedTemplate);
|
compMeta.type, compMeta.changeDetection, parsedTemplate);
|
||||||
@ -263,9 +308,8 @@ export class TemplateCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class NormalizedComponentWithViewDirectives {
|
export class NormalizedComponentWithViewDirectives {
|
||||||
constructor(
|
constructor(public component: CompileDirectiveMetadata,
|
||||||
public component: CompileDirectiveMetadata, public directives: CompileDirectiveMetadata[],
|
public directives: CompileDirectiveMetadata[], public pipes: CompilePipeMetadata[]) {}
|
||||||
public pipes: CompilePipeMetadata[]) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CompiledTemplate {
|
class CompiledTemplate {
|
||||||
@ -304,8 +348,7 @@ function removeDuplicates(items: CompileMetadataWithType[]): CompileMetadataWith
|
|||||||
let res = [];
|
let res = [];
|
||||||
items.forEach(item => {
|
items.forEach(item => {
|
||||||
let hasMatch =
|
let hasMatch =
|
||||||
res.filter(
|
res.filter(r => r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl &&
|
||||||
r => r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl &&
|
|
||||||
r.type.runtime == item.type.runtime)
|
r.type.runtime == item.type.runtime)
|
||||||
.length > 0;
|
.length > 0;
|
||||||
if (!hasMatch) {
|
if (!hasMatch) {
|
||||||
@ -358,8 +401,8 @@ class DirectiveCollector implements TemplateAstVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function filterPipes(
|
function filterPipes(template: TemplateAst[],
|
||||||
template: TemplateAst[], allPipes: CompilePipeMetadata[]): CompilePipeMetadata[] {
|
allPipes: CompilePipeMetadata[]): CompilePipeMetadata[] {
|
||||||
var visitor = new PipeVisitor();
|
var visitor = new PipeVisitor();
|
||||||
templateVisitAll(visitor, template);
|
templateVisitAll(visitor, template);
|
||||||
return allPipes.filter((pipeMeta) => SetWrapper.has(visitor.collector.pipes, pipeMeta.name));
|
return allPipes.filter((pipeMeta) => SetWrapper.has(visitor.collector.pipes, pipeMeta.name));
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
import {CompileTypeMetadata, CompileDirectiveMetadata, CompileTemplateMetadata} from './directive_metadata';
|
import {
|
||||||
|
CompileTypeMetadata,
|
||||||
|
CompileDirectiveMetadata,
|
||||||
|
CompileTemplateMetadata
|
||||||
|
} from './directive_metadata';
|
||||||
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank} from 'angular2/src/facade/lang';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import {PromiseWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
@ -10,35 +14,41 @@ import {Injectable} from 'angular2/src/core/di';
|
|||||||
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
||||||
|
|
||||||
|
|
||||||
import {HtmlAstVisitor, HtmlElementAst, HtmlTextAst, HtmlAttrAst, HtmlAst, HtmlCommentAst, htmlVisitAll} from './html_ast';
|
import {
|
||||||
|
HtmlAstVisitor,
|
||||||
|
HtmlElementAst,
|
||||||
|
HtmlTextAst,
|
||||||
|
HtmlAttrAst,
|
||||||
|
HtmlAst,
|
||||||
|
HtmlCommentAst,
|
||||||
|
htmlVisitAll
|
||||||
|
} from './html_ast';
|
||||||
import {HtmlParser} from './html_parser';
|
import {HtmlParser} from './html_parser';
|
||||||
|
|
||||||
import {preparseElement, PreparsedElement, PreparsedElementType} from './template_preparser';
|
import {preparseElement, PreparsedElement, PreparsedElementType} from './template_preparser';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TemplateNormalizer {
|
export class TemplateNormalizer {
|
||||||
constructor(
|
constructor(private _xhr: XHR, private _urlResolver: UrlResolver,
|
||||||
private _xhr: XHR, private _urlResolver: UrlResolver, private _htmlParser: HtmlParser) {}
|
private _htmlParser: HtmlParser) {}
|
||||||
|
|
||||||
normalizeTemplate(directiveType: CompileTypeMetadata, template: CompileTemplateMetadata):
|
normalizeTemplate(directiveType: CompileTypeMetadata,
|
||||||
Promise<CompileTemplateMetadata> {
|
template: CompileTemplateMetadata): Promise<CompileTemplateMetadata> {
|
||||||
if (isPresent(template.template)) {
|
if (isPresent(template.template)) {
|
||||||
return PromiseWrapper.resolve(this.normalizeLoadedTemplate(
|
return PromiseWrapper.resolve(this.normalizeLoadedTemplate(
|
||||||
directiveType, template, template.template, directiveType.moduleUrl));
|
directiveType, template, template.template, directiveType.moduleUrl));
|
||||||
} else if (isPresent(template.templateUrl)) {
|
} else if (isPresent(template.templateUrl)) {
|
||||||
var sourceAbsUrl = this._urlResolver.resolve(directiveType.moduleUrl, template.templateUrl);
|
var sourceAbsUrl = this._urlResolver.resolve(directiveType.moduleUrl, template.templateUrl);
|
||||||
return this._xhr.get(sourceAbsUrl)
|
return this._xhr.get(sourceAbsUrl)
|
||||||
.then(
|
.then(templateContent => this.normalizeLoadedTemplate(directiveType, template,
|
||||||
templateContent => this.normalizeLoadedTemplate(
|
templateContent, sourceAbsUrl));
|
||||||
directiveType, template, templateContent, sourceAbsUrl));
|
|
||||||
} else {
|
} else {
|
||||||
throw new BaseException(`No template specified for component ${directiveType.name}`);
|
throw new BaseException(`No template specified for component ${directiveType.name}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
normalizeLoadedTemplate(
|
normalizeLoadedTemplate(directiveType: CompileTypeMetadata, templateMeta: CompileTemplateMetadata,
|
||||||
directiveType: CompileTypeMetadata, templateMeta: CompileTemplateMetadata, template: string,
|
template: string, templateAbsUrl: string): CompileTemplateMetadata {
|
||||||
templateAbsUrl: string): CompileTemplateMetadata {
|
|
||||||
var rootNodesAndErrors = this._htmlParser.parse(template, directiveType.name);
|
var rootNodesAndErrors = this._htmlParser.parse(template, directiveType.name);
|
||||||
if (rootNodesAndErrors.errors.length > 0) {
|
if (rootNodesAndErrors.errors.length > 0) {
|
||||||
var errorString = rootNodesAndErrors.errors.join('\n');
|
var errorString = rootNodesAndErrors.errors.join('\n');
|
||||||
|
@ -11,7 +11,23 @@ import {splitNsName, mergeNsAndName} from './html_tags';
|
|||||||
import {ParseSourceSpan, ParseError, ParseLocation} from './parse_util';
|
import {ParseSourceSpan, ParseError, ParseLocation} from './parse_util';
|
||||||
import {RecursiveAstVisitor, BindingPipe} from 'angular2/src/core/change_detection/parser/ast';
|
import {RecursiveAstVisitor, BindingPipe} from 'angular2/src/core/change_detection/parser/ast';
|
||||||
|
|
||||||
import {ElementAst, BoundElementPropertyAst, BoundEventAst, VariableAst, TemplateAst, TemplateAstVisitor, templateVisitAll, TextAst, BoundTextAst, EmbeddedTemplateAst, AttrAst, NgContentAst, PropertyBindingType, DirectiveAst, BoundDirectivePropertyAst} from './template_ast';
|
import {
|
||||||
|
ElementAst,
|
||||||
|
BoundElementPropertyAst,
|
||||||
|
BoundEventAst,
|
||||||
|
VariableAst,
|
||||||
|
TemplateAst,
|
||||||
|
TemplateAstVisitor,
|
||||||
|
templateVisitAll,
|
||||||
|
TextAst,
|
||||||
|
BoundTextAst,
|
||||||
|
EmbeddedTemplateAst,
|
||||||
|
AttrAst,
|
||||||
|
NgContentAst,
|
||||||
|
PropertyBindingType,
|
||||||
|
DirectiveAst,
|
||||||
|
BoundDirectivePropertyAst
|
||||||
|
} from './template_ast';
|
||||||
import {CssSelector, SelectorMatcher} from 'angular2/src/compiler/selector';
|
import {CssSelector, SelectorMatcher} from 'angular2/src/compiler/selector';
|
||||||
|
|
||||||
import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema_registry';
|
import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema_registry';
|
||||||
@ -19,7 +35,15 @@ import {preparseElement, PreparsedElement, PreparsedElementType} from './templat
|
|||||||
|
|
||||||
import {isStyleUrlResolvable} from './style_url_resolver';
|
import {isStyleUrlResolvable} from './style_url_resolver';
|
||||||
|
|
||||||
import {HtmlAstVisitor, HtmlAst, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, htmlVisitAll} from './html_ast';
|
import {
|
||||||
|
HtmlAstVisitor,
|
||||||
|
HtmlAst,
|
||||||
|
HtmlElementAst,
|
||||||
|
HtmlAttrAst,
|
||||||
|
HtmlTextAst,
|
||||||
|
HtmlCommentAst,
|
||||||
|
htmlVisitAll
|
||||||
|
} from './html_ast';
|
||||||
|
|
||||||
import {splitAtColon} from './util';
|
import {splitAtColon} from './util';
|
||||||
|
|
||||||
@ -65,13 +89,11 @@ export class TemplateParseResult {
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TemplateParser {
|
export class TemplateParser {
|
||||||
constructor(
|
constructor(private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry,
|
||||||
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry,
|
|
||||||
private _htmlParser: HtmlParser,
|
private _htmlParser: HtmlParser,
|
||||||
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {}
|
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {}
|
||||||
|
|
||||||
parse(
|
parse(template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||||
template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
|
||||||
templateUrl: string): TemplateAst[] {
|
templateUrl: string): TemplateAst[] {
|
||||||
var result = this.tryParse(template, directives, pipes, templateUrl);
|
var result = this.tryParse(template, directives, pipes, templateUrl);
|
||||||
if (isPresent(result.errors)) {
|
if (isPresent(result.errors)) {
|
||||||
@ -81,8 +103,7 @@ export class TemplateParser {
|
|||||||
return result.templateAst;
|
return result.templateAst;
|
||||||
}
|
}
|
||||||
|
|
||||||
tryParse(
|
tryParse(template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||||
template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
|
||||||
templateUrl: string): TemplateParseResult {
|
templateUrl: string): TemplateParseResult {
|
||||||
var parseVisitor =
|
var parseVisitor =
|
||||||
new TemplateParseVisitor(directives, pipes, this._exprParser, this._schemaRegistry);
|
new TemplateParseVisitor(directives, pipes, this._exprParser, this._schemaRegistry);
|
||||||
@ -107,12 +128,11 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
ngContentCount: number = 0;
|
ngContentCount: number = 0;
|
||||||
pipesByName: Map<string, CompilePipeMetadata>;
|
pipesByName: Map<string, CompilePipeMetadata>;
|
||||||
|
|
||||||
constructor(
|
constructor(directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
||||||
directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
|
|
||||||
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry) {
|
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry) {
|
||||||
this.selectorMatcher = new SelectorMatcher();
|
this.selectorMatcher = new SelectorMatcher();
|
||||||
ListWrapper.forEachWithIndex(
|
ListWrapper.forEachWithIndex(directives,
|
||||||
directives, (directive: CompileDirectiveMetadata, index: number) => {
|
(directive: CompileDirectiveMetadata, index: number) => {
|
||||||
var selector = CssSelector.parse(directive.selector);
|
var selector = CssSelector.parse(directive.selector);
|
||||||
this.selectorMatcher.addSelectables(selector, directive);
|
this.selectorMatcher.addSelectables(selector, directive);
|
||||||
this.directivesIndex.set(directive, index);
|
this.directivesIndex.set(directive, index);
|
||||||
@ -255,9 +275,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
elementOrDirectiveProps, isTemplateElement ? [] : vars, element.sourceSpan);
|
elementOrDirectiveProps, isTemplateElement ? [] : vars, element.sourceSpan);
|
||||||
var elementProps: BoundElementPropertyAst[] =
|
var elementProps: BoundElementPropertyAst[] =
|
||||||
this._createElementPropertyAsts(element.name, elementOrDirectiveProps, directives);
|
this._createElementPropertyAsts(element.name, elementOrDirectiveProps, directives);
|
||||||
var children = htmlVisitAll(
|
var children = htmlVisitAll(preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this,
|
||||||
preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
|
element.children, Component.create(directives));
|
||||||
Component.create(directives));
|
|
||||||
|
|
||||||
// Override the actual selector when the `ngProjectAs` attribute is provided
|
// Override the actual selector when the `ngProjectAs` attribute is provided
|
||||||
var projectionSelector = isPresent(preparsedElement.projectAs) ?
|
var projectionSelector = isPresent(preparsedElement.projectAs) ?
|
||||||
@ -277,21 +296,21 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||||
} else if (isTemplateElement) {
|
} else if (isTemplateElement) {
|
||||||
this._assertAllEventsPublishedByDirectives(directives, events);
|
this._assertAllEventsPublishedByDirectives(directives, events);
|
||||||
this._assertNoComponentsNorElementBindingsOnTemplate(
|
this._assertNoComponentsNorElementBindingsOnTemplate(directives, elementProps,
|
||||||
directives, elementProps, element.sourceSpan);
|
|
||||||
|
|
||||||
parsedElement = new EmbeddedTemplateAst(
|
|
||||||
attrs, events, vars, directives, children, hasInlineTemplates ? null : ngContentIndex,
|
|
||||||
element.sourceSpan);
|
element.sourceSpan);
|
||||||
|
|
||||||
|
parsedElement =
|
||||||
|
new EmbeddedTemplateAst(attrs, events, vars, directives, children,
|
||||||
|
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||||
} else {
|
} else {
|
||||||
this._assertOnlyOneComponent(directives, element.sourceSpan);
|
this._assertOnlyOneComponent(directives, element.sourceSpan);
|
||||||
var elementExportAsVars = vars.filter(varAst => varAst.value.length === 0);
|
var elementExportAsVars = vars.filter(varAst => varAst.value.length === 0);
|
||||||
let ngContentIndex =
|
let ngContentIndex =
|
||||||
hasInlineTemplates ? null : component.findNgContentIndex(projectionSelector);
|
hasInlineTemplates ? null : component.findNgContentIndex(projectionSelector);
|
||||||
|
|
||||||
parsedElement = new ElementAst(
|
parsedElement =
|
||||||
nodeName, attrs, elementProps, events, elementExportAsVars, directives, children,
|
new ElementAst(nodeName, attrs, elementProps, events, elementExportAsVars, directives,
|
||||||
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
children, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
|
||||||
}
|
}
|
||||||
if (hasInlineTemplates) {
|
if (hasInlineTemplates) {
|
||||||
var templateCssSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs);
|
var templateCssSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs);
|
||||||
@ -300,19 +319,18 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
templateElementOrDirectiveProps, [], element.sourceSpan);
|
templateElementOrDirectiveProps, [], element.sourceSpan);
|
||||||
var templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
|
var templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
|
||||||
element.name, templateElementOrDirectiveProps, templateDirectives);
|
element.name, templateElementOrDirectiveProps, templateDirectives);
|
||||||
this._assertNoComponentsNorElementBindingsOnTemplate(
|
this._assertNoComponentsNorElementBindingsOnTemplate(templateDirectives, templateElementProps,
|
||||||
templateDirectives, templateElementProps, element.sourceSpan);
|
|
||||||
|
|
||||||
parsedElement = new EmbeddedTemplateAst(
|
|
||||||
[], [], templateVars, templateDirectives, [parsedElement], ngContentIndex,
|
|
||||||
element.sourceSpan);
|
element.sourceSpan);
|
||||||
|
|
||||||
|
parsedElement = new EmbeddedTemplateAst([], [], templateVars, templateDirectives,
|
||||||
|
[parsedElement], ngContentIndex, element.sourceSpan);
|
||||||
}
|
}
|
||||||
return parsedElement;
|
return parsedElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseInlineTemplateBinding(
|
private _parseInlineTemplateBinding(attr: HtmlAttrAst, targetMatchableAttrs: string[][],
|
||||||
attr: HtmlAttrAst, targetMatchableAttrs: string[][],
|
targetProps: BoundElementOrDirectiveProperty[],
|
||||||
targetProps: BoundElementOrDirectiveProperty[], targetVars: VariableAst[]): boolean {
|
targetVars: VariableAst[]): boolean {
|
||||||
var templateBindingsSource = null;
|
var templateBindingsSource = null;
|
||||||
if (attr.name == TEMPLATE_ATTR) {
|
if (attr.name == TEMPLATE_ATTR) {
|
||||||
templateBindingsSource = attr.value;
|
templateBindingsSource = attr.value;
|
||||||
@ -328,8 +346,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
targetVars.push(new VariableAst(binding.key, binding.name, attr.sourceSpan));
|
targetVars.push(new VariableAst(binding.key, binding.name, attr.sourceSpan));
|
||||||
targetMatchableAttrs.push([binding.key, binding.name]);
|
targetMatchableAttrs.push([binding.key, binding.name]);
|
||||||
} else if (isPresent(binding.expression)) {
|
} else if (isPresent(binding.expression)) {
|
||||||
this._parsePropertyAst(
|
this._parsePropertyAst(binding.key, binding.expression, attr.sourceSpan,
|
||||||
binding.key, binding.expression, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
targetMatchableAttrs, targetProps);
|
||||||
} else {
|
} else {
|
||||||
targetMatchableAttrs.push([binding.key, '']);
|
targetMatchableAttrs.push([binding.key, '']);
|
||||||
this._parseLiteralAttr(binding.key, null, attr.sourceSpan, targetProps);
|
this._parseLiteralAttr(binding.key, null, attr.sourceSpan, targetProps);
|
||||||
@ -340,8 +358,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseAttr(
|
private _parseAttr(attr: HtmlAttrAst, targetMatchableAttrs: string[][],
|
||||||
attr: HtmlAttrAst, targetMatchableAttrs: string[][],
|
|
||||||
targetProps: BoundElementOrDirectiveProperty[], targetEvents: BoundEventAst[],
|
targetProps: BoundElementOrDirectiveProperty[], targetEvents: BoundEventAst[],
|
||||||
targetVars: VariableAst[]): boolean {
|
targetVars: VariableAst[]): boolean {
|
||||||
var attrName = this._normalizeAttributeName(attr.name);
|
var attrName = this._normalizeAttributeName(attr.name);
|
||||||
@ -351,8 +368,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
if (isPresent(bindParts)) {
|
if (isPresent(bindParts)) {
|
||||||
hasBinding = true;
|
hasBinding = true;
|
||||||
if (isPresent(bindParts[1])) { // match: bind-prop
|
if (isPresent(bindParts[1])) { // match: bind-prop
|
||||||
this._parseProperty(
|
this._parseProperty(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||||
bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
targetProps);
|
||||||
|
|
||||||
} else if (isPresent(
|
} else if (isPresent(
|
||||||
bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden"
|
bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden"
|
||||||
@ -360,32 +377,32 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
this._parseVariable(identifier, attrValue, attr.sourceSpan, targetVars);
|
this._parseVariable(identifier, attrValue, attr.sourceSpan, targetVars);
|
||||||
|
|
||||||
} else if (isPresent(bindParts[3])) { // match: on-event
|
} else if (isPresent(bindParts[3])) { // match: on-event
|
||||||
this._parseEvent(
|
this._parseEvent(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||||
bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
|
targetEvents);
|
||||||
|
|
||||||
} else if (isPresent(bindParts[4])) { // match: bindon-prop
|
} else if (isPresent(bindParts[4])) { // match: bindon-prop
|
||||||
this._parseProperty(
|
this._parseProperty(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||||
bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
targetProps);
|
||||||
this._parseAssignmentEvent(
|
this._parseAssignmentEvent(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||||
bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
|
targetEvents);
|
||||||
|
|
||||||
} else if (isPresent(bindParts[6])) { // match: [(expr)]
|
} else if (isPresent(bindParts[6])) { // match: [(expr)]
|
||||||
this._parseProperty(
|
this._parseProperty(bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||||
bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
targetProps);
|
||||||
this._parseAssignmentEvent(
|
this._parseAssignmentEvent(bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||||
bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
|
targetEvents);
|
||||||
|
|
||||||
} else if (isPresent(bindParts[7])) { // match: [expr]
|
} else if (isPresent(bindParts[7])) { // match: [expr]
|
||||||
this._parseProperty(
|
this._parseProperty(bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||||
bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
targetProps);
|
||||||
|
|
||||||
} else if (isPresent(bindParts[8])) { // match: (event)
|
} else if (isPresent(bindParts[8])) { // match: (event)
|
||||||
this._parseEvent(
|
this._parseEvent(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs,
|
||||||
bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
|
targetEvents);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hasBinding = this._parsePropertyInterpolation(
|
hasBinding = this._parsePropertyInterpolation(attrName, attrValue, attr.sourceSpan,
|
||||||
attrName, attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
|
targetMatchableAttrs, targetProps);
|
||||||
}
|
}
|
||||||
if (!hasBinding) {
|
if (!hasBinding) {
|
||||||
this._parseLiteralAttr(attrName, attrValue, attr.sourceSpan, targetProps);
|
this._parseLiteralAttr(attrName, attrValue, attr.sourceSpan, targetProps);
|
||||||
@ -397,24 +414,23 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
return attrName.toLowerCase().startsWith('data-') ? attrName.substring(5) : attrName;
|
return attrName.toLowerCase().startsWith('data-') ? attrName.substring(5) : attrName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseVariable(
|
private _parseVariable(identifier: string, value: string, sourceSpan: ParseSourceSpan,
|
||||||
identifier: string, value: string, sourceSpan: ParseSourceSpan, targetVars: VariableAst[]) {
|
targetVars: VariableAst[]) {
|
||||||
if (identifier.indexOf('-') > -1) {
|
if (identifier.indexOf('-') > -1) {
|
||||||
this._reportError(`"-" is not allowed in variable names`, sourceSpan);
|
this._reportError(`"-" is not allowed in variable names`, sourceSpan);
|
||||||
}
|
}
|
||||||
targetVars.push(new VariableAst(identifier, value, sourceSpan));
|
targetVars.push(new VariableAst(identifier, value, sourceSpan));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseProperty(
|
private _parseProperty(name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||||
name: string, expression: string, sourceSpan: ParseSourceSpan,
|
targetMatchableAttrs: string[][],
|
||||||
targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[]) {
|
targetProps: BoundElementOrDirectiveProperty[]) {
|
||||||
this._parsePropertyAst(
|
this._parsePropertyAst(name, this._parseBinding(expression, sourceSpan), sourceSpan,
|
||||||
name, this._parseBinding(expression, sourceSpan), sourceSpan, targetMatchableAttrs,
|
targetMatchableAttrs, targetProps);
|
||||||
targetProps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parsePropertyInterpolation(
|
private _parsePropertyInterpolation(name: string, value: string, sourceSpan: ParseSourceSpan,
|
||||||
name: string, value: string, sourceSpan: ParseSourceSpan, targetMatchableAttrs: string[][],
|
targetMatchableAttrs: string[][],
|
||||||
targetProps: BoundElementOrDirectiveProperty[]): boolean {
|
targetProps: BoundElementOrDirectiveProperty[]): boolean {
|
||||||
var expr = this._parseInterpolation(value, sourceSpan);
|
var expr = this._parseInterpolation(value, sourceSpan);
|
||||||
if (isPresent(expr)) {
|
if (isPresent(expr)) {
|
||||||
@ -424,22 +440,20 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parsePropertyAst(
|
private _parsePropertyAst(name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan,
|
||||||
name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan,
|
targetMatchableAttrs: string[][],
|
||||||
targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[]) {
|
targetProps: BoundElementOrDirectiveProperty[]) {
|
||||||
targetMatchableAttrs.push([name, ast.source]);
|
targetMatchableAttrs.push([name, ast.source]);
|
||||||
targetProps.push(new BoundElementOrDirectiveProperty(name, ast, false, sourceSpan));
|
targetProps.push(new BoundElementOrDirectiveProperty(name, ast, false, sourceSpan));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseAssignmentEvent(
|
private _parseAssignmentEvent(name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||||
name: string, expression: string, sourceSpan: ParseSourceSpan,
|
|
||||||
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
|
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
|
||||||
this._parseEvent(
|
this._parseEvent(`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs,
|
||||||
`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs, targetEvents);
|
targetEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseEvent(
|
private _parseEvent(name: string, expression: string, sourceSpan: ParseSourceSpan,
|
||||||
name: string, expression: string, sourceSpan: ParseSourceSpan,
|
|
||||||
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
|
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
|
||||||
// long format: 'target: eventName'
|
// long format: 'target: eventName'
|
||||||
var parts = splitAtColon(name, [null, name]);
|
var parts = splitAtColon(name, [null, name]);
|
||||||
@ -452,23 +466,22 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
// so don't add the event name to the matchableAttrs
|
// so don't add the event name to the matchableAttrs
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseLiteralAttr(
|
private _parseLiteralAttr(name: string, value: string, sourceSpan: ParseSourceSpan,
|
||||||
name: string, value: string, sourceSpan: ParseSourceSpan,
|
|
||||||
targetProps: BoundElementOrDirectiveProperty[]) {
|
targetProps: BoundElementOrDirectiveProperty[]) {
|
||||||
targetProps.push(new BoundElementOrDirectiveProperty(
|
targetProps.push(new BoundElementOrDirectiveProperty(
|
||||||
name, this._exprParser.wrapLiteralPrimitive(value, ''), true, sourceSpan));
|
name, this._exprParser.wrapLiteralPrimitive(value, ''), true, sourceSpan));
|
||||||
}
|
}
|
||||||
|
|
||||||
private _parseDirectives(selectorMatcher: SelectorMatcher, elementCssSelector: CssSelector):
|
private _parseDirectives(selectorMatcher: SelectorMatcher,
|
||||||
CompileDirectiveMetadata[] {
|
elementCssSelector: CssSelector): CompileDirectiveMetadata[] {
|
||||||
var directives = [];
|
var directives = [];
|
||||||
selectorMatcher.match(
|
selectorMatcher.match(elementCssSelector,
|
||||||
elementCssSelector, (selector, directive) => { directives.push(directive); });
|
(selector, directive) => { directives.push(directive); });
|
||||||
// Need to sort the directives so that we get consistent results throughout,
|
// Need to sort the directives so that we get consistent results throughout,
|
||||||
// as selectorMatcher uses Maps inside.
|
// as selectorMatcher uses Maps inside.
|
||||||
// Also need to make components the first directive in the array
|
// Also need to make components the first directive in the array
|
||||||
ListWrapper.sort(
|
ListWrapper.sort(directives,
|
||||||
directives, (dir1: CompileDirectiveMetadata, dir2: CompileDirectiveMetadata) => {
|
(dir1: CompileDirectiveMetadata, dir2: CompileDirectiveMetadata) => {
|
||||||
var dir1Comp = dir1.isComponent;
|
var dir1Comp = dir1.isComponent;
|
||||||
var dir2Comp = dir2.isComponent;
|
var dir2Comp = dir2.isComponent;
|
||||||
if (dir1Comp && !dir2Comp) {
|
if (dir1Comp && !dir2Comp) {
|
||||||
@ -482,17 +495,17 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
return directives;
|
return directives;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createDirectiveAsts(
|
private _createDirectiveAsts(elementName: string, directives: CompileDirectiveMetadata[],
|
||||||
elementName: string, directives: CompileDirectiveMetadata[],
|
props: BoundElementOrDirectiveProperty[],
|
||||||
props: BoundElementOrDirectiveProperty[], possibleExportAsVars: VariableAst[],
|
possibleExportAsVars: VariableAst[],
|
||||||
sourceSpan: ParseSourceSpan): DirectiveAst[] {
|
sourceSpan: ParseSourceSpan): DirectiveAst[] {
|
||||||
var matchedVariables = new Set<string>();
|
var matchedVariables = new Set<string>();
|
||||||
var directiveAsts = directives.map((directive: CompileDirectiveMetadata) => {
|
var directiveAsts = directives.map((directive: CompileDirectiveMetadata) => {
|
||||||
var hostProperties: BoundElementPropertyAst[] = [];
|
var hostProperties: BoundElementPropertyAst[] = [];
|
||||||
var hostEvents: BoundEventAst[] = [];
|
var hostEvents: BoundEventAst[] = [];
|
||||||
var directiveProperties: BoundDirectivePropertyAst[] = [];
|
var directiveProperties: BoundDirectivePropertyAst[] = [];
|
||||||
this._createDirectiveHostPropertyAsts(
|
this._createDirectiveHostPropertyAsts(elementName, directive.hostProperties, sourceSpan,
|
||||||
elementName, directive.hostProperties, sourceSpan, hostProperties);
|
hostProperties);
|
||||||
this._createDirectiveHostEventAsts(directive.hostListeners, sourceSpan, hostEvents);
|
this._createDirectiveHostEventAsts(directive.hostListeners, sourceSpan, hostEvents);
|
||||||
this._createDirectivePropertyAsts(directive.inputs, props, directiveProperties);
|
this._createDirectivePropertyAsts(directive.inputs, props, directiveProperties);
|
||||||
var exportAsVars = [];
|
var exportAsVars = [];
|
||||||
@ -503,20 +516,20 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
matchedVariables.add(varAst.name);
|
matchedVariables.add(varAst.name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return new DirectiveAst(
|
return new DirectiveAst(directive, directiveProperties, hostProperties, hostEvents,
|
||||||
directive, directiveProperties, hostProperties, hostEvents, exportAsVars, sourceSpan);
|
exportAsVars, sourceSpan);
|
||||||
});
|
});
|
||||||
possibleExportAsVars.forEach((varAst) => {
|
possibleExportAsVars.forEach((varAst) => {
|
||||||
if (varAst.value.length > 0 && !SetWrapper.has(matchedVariables, varAst.name)) {
|
if (varAst.value.length > 0 && !SetWrapper.has(matchedVariables, varAst.name)) {
|
||||||
this._reportError(
|
this._reportError(`There is no directive with "exportAs" set to "${varAst.value}"`,
|
||||||
`There is no directive with "exportAs" set to "${varAst.value}"`, varAst.sourceSpan);
|
varAst.sourceSpan);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return directiveAsts;
|
return directiveAsts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createDirectiveHostPropertyAsts(
|
private _createDirectiveHostPropertyAsts(elementName: string, hostProps: {[key: string]: string},
|
||||||
elementName: string, hostProps: {[key: string]: string}, sourceSpan: ParseSourceSpan,
|
sourceSpan: ParseSourceSpan,
|
||||||
targetPropertyAsts: BoundElementPropertyAst[]) {
|
targetPropertyAsts: BoundElementPropertyAst[]) {
|
||||||
if (isPresent(hostProps)) {
|
if (isPresent(hostProps)) {
|
||||||
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
|
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
|
||||||
@ -527,8 +540,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createDirectiveHostEventAsts(
|
private _createDirectiveHostEventAsts(hostListeners: {[key: string]: string},
|
||||||
hostListeners: {[key: string]: string}, sourceSpan: ParseSourceSpan,
|
sourceSpan: ParseSourceSpan,
|
||||||
targetEventAsts: BoundEventAst[]) {
|
targetEventAsts: BoundEventAst[]) {
|
||||||
if (isPresent(hostListeners)) {
|
if (isPresent(hostListeners)) {
|
||||||
StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => {
|
StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => {
|
||||||
@ -537,8 +550,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createDirectivePropertyAsts(
|
private _createDirectivePropertyAsts(directiveProperties: {[key: string]: string},
|
||||||
directiveProperties: {[key: string]: string}, boundProps: BoundElementOrDirectiveProperty[],
|
boundProps: BoundElementOrDirectiveProperty[],
|
||||||
targetBoundDirectiveProps: BoundDirectivePropertyAst[]) {
|
targetBoundDirectiveProps: BoundDirectivePropertyAst[]) {
|
||||||
if (isPresent(directiveProperties)) {
|
if (isPresent(directiveProperties)) {
|
||||||
var boundPropsByName = new Map<string, BoundElementOrDirectiveProperty>();
|
var boundPropsByName = new Map<string, BoundElementOrDirectiveProperty>();
|
||||||
@ -562,8 +575,7 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createElementPropertyAsts(
|
private _createElementPropertyAsts(elementName: string, props: BoundElementOrDirectiveProperty[],
|
||||||
elementName: string, props: BoundElementOrDirectiveProperty[],
|
|
||||||
directives: DirectiveAst[]): BoundElementPropertyAst[] {
|
directives: DirectiveAst[]): BoundElementPropertyAst[] {
|
||||||
var boundElementProps: BoundElementPropertyAst[] = [];
|
var boundElementProps: BoundElementPropertyAst[] = [];
|
||||||
var boundDirectivePropsIndex = new Map<string, BoundDirectivePropertyAst>();
|
var boundDirectivePropsIndex = new Map<string, BoundDirectivePropertyAst>();
|
||||||
@ -574,15 +586,14 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
});
|
});
|
||||||
props.forEach((prop: BoundElementOrDirectiveProperty) => {
|
props.forEach((prop: BoundElementOrDirectiveProperty) => {
|
||||||
if (!prop.isLiteral && isBlank(boundDirectivePropsIndex.get(prop.name))) {
|
if (!prop.isLiteral && isBlank(boundDirectivePropsIndex.get(prop.name))) {
|
||||||
boundElementProps.push(this._createElementPropertyAst(
|
boundElementProps.push(this._createElementPropertyAst(elementName, prop.name,
|
||||||
elementName, prop.name, prop.expression, prop.sourceSpan));
|
prop.expression, prop.sourceSpan));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return boundElementProps;
|
return boundElementProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createElementPropertyAst(
|
private _createElementPropertyAst(elementName: string, name: string, ast: AST,
|
||||||
elementName: string, name: string, ast: AST,
|
|
||||||
sourceSpan: ParseSourceSpan): BoundElementPropertyAst {
|
sourceSpan: ParseSourceSpan): BoundElementPropertyAst {
|
||||||
var unit = null;
|
var unit = null;
|
||||||
var bindingType;
|
var bindingType;
|
||||||
@ -641,13 +652,13 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _assertNoComponentsNorElementBindingsOnTemplate(
|
private _assertNoComponentsNorElementBindingsOnTemplate(directives: DirectiveAst[],
|
||||||
directives: DirectiveAst[], elementProps: BoundElementPropertyAst[],
|
elementProps: BoundElementPropertyAst[],
|
||||||
sourceSpan: ParseSourceSpan) {
|
sourceSpan: ParseSourceSpan) {
|
||||||
var componentTypeNames: string[] = this._findComponentDirectiveNames(directives);
|
var componentTypeNames: string[] = this._findComponentDirectiveNames(directives);
|
||||||
if (componentTypeNames.length > 0) {
|
if (componentTypeNames.length > 0) {
|
||||||
this._reportError(
|
this._reportError(`Components on an embedded template: ${componentTypeNames.join(',')}`,
|
||||||
`Components on an embedded template: ${componentTypeNames.join(',')}`, sourceSpan);
|
sourceSpan);
|
||||||
}
|
}
|
||||||
elementProps.forEach(prop => {
|
elementProps.forEach(prop => {
|
||||||
this._reportError(
|
this._reportError(
|
||||||
@ -656,13 +667,12 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _assertAllEventsPublishedByDirectives(
|
private _assertAllEventsPublishedByDirectives(directives: DirectiveAst[],
|
||||||
directives: DirectiveAst[], events: BoundEventAst[]) {
|
events: BoundEventAst[]) {
|
||||||
var allDirectiveEvents = new Set<string>();
|
var allDirectiveEvents = new Set<string>();
|
||||||
directives.forEach(directive => {
|
directives.forEach(directive => {
|
||||||
StringMapWrapper.forEach(directive.directive.outputs, (eventName: string, _) => {
|
StringMapWrapper.forEach(directive.directive.outputs,
|
||||||
allDirectiveEvents.add(eventName);
|
(eventName: string, _) => { allDirectiveEvents.add(eventName); });
|
||||||
});
|
|
||||||
});
|
});
|
||||||
events.forEach(event => {
|
events.forEach(event => {
|
||||||
if (isPresent(event.target) || !SetWrapper.has(allDirectiveEvents, event.name)) {
|
if (isPresent(event.target) || !SetWrapper.has(allDirectiveEvents, event.name)) {
|
||||||
@ -690,9 +700,8 @@ class NonBindableVisitor implements HtmlAstVisitor {
|
|||||||
var selector = createElementCssSelector(ast.name, attrNameAndValues);
|
var selector = createElementCssSelector(ast.name, attrNameAndValues);
|
||||||
var ngContentIndex = component.findNgContentIndex(selector);
|
var ngContentIndex = component.findNgContentIndex(selector);
|
||||||
var children = htmlVisitAll(this, ast.children, EMPTY_COMPONENT);
|
var children = htmlVisitAll(this, ast.children, EMPTY_COMPONENT);
|
||||||
return new ElementAst(
|
return new ElementAst(ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], children,
|
||||||
ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], children, ngContentIndex,
|
ngContentIndex, ast.sourceSpan);
|
||||||
ast.sourceSpan);
|
|
||||||
}
|
}
|
||||||
visitComment(ast: HtmlCommentAst, context: any): any { return null; }
|
visitComment(ast: HtmlCommentAst, context: any): any { return null; }
|
||||||
visitAttr(ast: HtmlAttrAst, context: any): AttrAst {
|
visitAttr(ast: HtmlAttrAst, context: any): AttrAst {
|
||||||
@ -705,8 +714,7 @@ class NonBindableVisitor implements HtmlAstVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class BoundElementOrDirectiveProperty {
|
class BoundElementOrDirectiveProperty {
|
||||||
constructor(
|
constructor(public name: string, public expression: AST, public isLiteral: boolean,
|
||||||
public name: string, public expression: AST, public isLiteral: boolean,
|
|
||||||
public sourceSpan: ParseSourceSpan) {}
|
public sourceSpan: ParseSourceSpan) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,8 +740,8 @@ class Component {
|
|||||||
}
|
}
|
||||||
return new Component(matcher, wildcardNgContentIndex);
|
return new Component(matcher, wildcardNgContentIndex);
|
||||||
}
|
}
|
||||||
constructor(
|
constructor(public ngContentIndexMatcher: SelectorMatcher,
|
||||||
public ngContentIndexMatcher: SelectorMatcher, public wildcardNgContentIndex: number) {}
|
public wildcardNgContentIndex: number) {}
|
||||||
|
|
||||||
findNgContentIndex(selector: CssSelector): number {
|
findNgContentIndex(selector: CssSelector): number {
|
||||||
var ngContentIndices = [];
|
var ngContentIndices = [];
|
||||||
|
@ -59,8 +59,7 @@ export enum PreparsedElementType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PreparsedElement {
|
export class PreparsedElement {
|
||||||
constructor(
|
constructor(public type: PreparsedElementType, public selectAttr: string, public hrefAttr: string,
|
||||||
public type: PreparsedElementType, public selectAttr: string, public hrefAttr: string,
|
|
||||||
public nonBindable: boolean, public projectAs: string) {}
|
public nonBindable: boolean, public projectAs: string) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import {Injectable, Inject} from 'angular2/src/core/di';
|
import {Injectable, Inject} from 'angular2/src/core/di';
|
||||||
import {StringWrapper, isPresent, isBlank, RegExpWrapper, normalizeBlank} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
StringWrapper,
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
RegExpWrapper,
|
||||||
|
normalizeBlank
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {PACKAGE_ROOT_URL} from 'angular2/src/core/application_tokens';
|
import {PACKAGE_ROOT_URL} from 'angular2/src/core/application_tokens';
|
||||||
@ -15,7 +21,7 @@ export function createWithoutPackagePrefix(): UrlResolver {
|
|||||||
/**
|
/**
|
||||||
* A default provider for {@link PACKAGE_ROOT_URL} that maps to '/'.
|
* A default provider for {@link PACKAGE_ROOT_URL} that maps to '/'.
|
||||||
*/
|
*/
|
||||||
export var DEFAULT_PACKAGE_URL_PROVIDER = new Provider(PACKAGE_ROOT_URL, {useValue: '/'});
|
export var DEFAULT_PACKAGE_URL_PROVIDER = new Provider(PACKAGE_ROOT_URL, {useValue: "/"});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by the {@link Compiler} when resolving HTML and CSS template URLs.
|
* Used by the {@link Compiler} when resolving HTML and CSS template URLs.
|
||||||
@ -34,7 +40,7 @@ export class UrlResolver {
|
|||||||
|
|
||||||
constructor(@Inject(PACKAGE_ROOT_URL) packagePrefix: string = null) {
|
constructor(@Inject(PACKAGE_ROOT_URL) packagePrefix: string = null) {
|
||||||
if (isPresent(packagePrefix)) {
|
if (isPresent(packagePrefix)) {
|
||||||
this._packagePrefix = StringWrapper.stripRight(packagePrefix, '/') + '/';
|
this._packagePrefix = StringWrapper.stripRight(packagePrefix, "/") + "/";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,8 +61,8 @@ export class UrlResolver {
|
|||||||
if (isPresent(baseUrl) && baseUrl.length > 0) {
|
if (isPresent(baseUrl) && baseUrl.length > 0) {
|
||||||
resolvedUrl = _resolveUrl(baseUrl, resolvedUrl);
|
resolvedUrl = _resolveUrl(baseUrl, resolvedUrl);
|
||||||
}
|
}
|
||||||
if (isPresent(this._packagePrefix) && getUrlScheme(resolvedUrl) == 'package') {
|
if (isPresent(this._packagePrefix) && getUrlScheme(resolvedUrl) == "package") {
|
||||||
resolvedUrl = resolvedUrl.replace('package:', this._packagePrefix);
|
resolvedUrl = resolvedUrl.replace("package:", this._packagePrefix);
|
||||||
}
|
}
|
||||||
return resolvedUrl;
|
return resolvedUrl;
|
||||||
}
|
}
|
||||||
@ -67,7 +73,7 @@ export class UrlResolver {
|
|||||||
*/
|
*/
|
||||||
export function getUrlScheme(url: string): string {
|
export function getUrlScheme(url: string): string {
|
||||||
var match = _split(url);
|
var match = _split(url);
|
||||||
return (match && match[_ComponentIndex.Scheme]) || '';
|
return (match && match[_ComponentIndex.Scheme]) || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// The code below is adapted from Traceur:
|
// The code below is adapted from Traceur:
|
||||||
@ -90,9 +96,9 @@ export function getUrlScheme(url: string): string {
|
|||||||
* @param {?string=} opt_fragment The URI-encoded fragment identifier.
|
* @param {?string=} opt_fragment The URI-encoded fragment identifier.
|
||||||
* @return {string} The fully combined URI.
|
* @return {string} The fully combined URI.
|
||||||
*/
|
*/
|
||||||
function _buildFromEncodedParts(
|
function _buildFromEncodedParts(opt_scheme?: string, opt_userInfo?: string, opt_domain?: string,
|
||||||
opt_scheme?: string, opt_userInfo?: string, opt_domain?: string, opt_port?: string,
|
opt_port?: string, opt_path?: string, opt_queryData?: string,
|
||||||
opt_path?: string, opt_queryData?: string, opt_fragment?: string): string {
|
opt_fragment?: string): string {
|
||||||
var out = [];
|
var out = [];
|
||||||
|
|
||||||
if (isPresent(opt_scheme)) {
|
if (isPresent(opt_scheme)) {
|
||||||
@ -190,8 +196,8 @@ function _buildFromEncodedParts(
|
|||||||
* @type {!RegExp}
|
* @type {!RegExp}
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
var _splitRe = RegExpWrapper.create(
|
var _splitRe =
|
||||||
'^' +
|
RegExpWrapper.create('^' +
|
||||||
'(?:' +
|
'(?:' +
|
||||||
'([^:/?#.]+)' + // scheme - ignore special characters
|
'([^:/?#.]+)' + // scheme - ignore special characters
|
||||||
// used by other URL parts such as :,
|
// used by other URL parts such as :,
|
||||||
@ -298,10 +304,9 @@ function _joinAndCanonicalizePath(parts: any[]): string {
|
|||||||
path = isBlank(path) ? '' : _removeDotSegments(path);
|
path = isBlank(path) ? '' : _removeDotSegments(path);
|
||||||
parts[_ComponentIndex.Path] = path;
|
parts[_ComponentIndex.Path] = path;
|
||||||
|
|
||||||
return _buildFromEncodedParts(
|
return _buildFromEncodedParts(parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo],
|
||||||
parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo], parts[_ComponentIndex.Domain],
|
parts[_ComponentIndex.Domain], parts[_ComponentIndex.Port], path,
|
||||||
parts[_ComponentIndex.Port], path, parts[_ComponentIndex.QueryData],
|
parts[_ComponentIndex.QueryData], parts[_ComponentIndex.Fragment]);
|
||||||
parts[_ComponentIndex.Fragment]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
import {IS_DART, StringWrapper, isBlank, isPresent, isString, isArray} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
IS_DART,
|
||||||
|
StringWrapper,
|
||||||
|
isBlank,
|
||||||
|
isPresent,
|
||||||
|
isString,
|
||||||
|
isArray
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
var CAMEL_CASE_REGEXP = /([A-Z])/g;
|
var CAMEL_CASE_REGEXP = /([A-Z])/g;
|
||||||
var DASH_CASE_REGEXP = /-([a-z])/g;
|
var DASH_CASE_REGEXP = /-([a-z])/g;
|
||||||
@ -10,13 +17,13 @@ export var MODULE_SUFFIX = IS_DART ? '.dart' : '.js';
|
|||||||
export var CONST_VAR = IS_DART ? 'const' : 'var';
|
export var CONST_VAR = IS_DART ? 'const' : 'var';
|
||||||
|
|
||||||
export function camelCaseToDashCase(input: string): string {
|
export function camelCaseToDashCase(input: string): string {
|
||||||
return StringWrapper.replaceAllMapped(
|
return StringWrapper.replaceAllMapped(input, CAMEL_CASE_REGEXP,
|
||||||
input, CAMEL_CASE_REGEXP, (m) => { return '-' + m[1].toLowerCase(); });
|
(m) => { return '-' + m[1].toLowerCase(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dashCaseToCamelCase(input: string): string {
|
export function dashCaseToCamelCase(input: string): string {
|
||||||
return StringWrapper.replaceAllMapped(
|
return StringWrapper.replaceAllMapped(input, DASH_CASE_REGEXP,
|
||||||
input, DASH_CASE_REGEXP, (m) => { return m[1].toUpperCase(); });
|
(m) => { return m[1].toUpperCase(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function escapeSingleQuoteString(input: string): string {
|
export function escapeSingleQuoteString(input: string): string {
|
||||||
|
@ -1,18 +1,65 @@
|
|||||||
import {isPresent, isBlank, Type, isString, StringWrapper, IS_DART, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
Type,
|
||||||
|
isString,
|
||||||
|
StringWrapper,
|
||||||
|
IS_DART,
|
||||||
|
CONST_EXPR
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {SetWrapper, StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
import {SetWrapper, StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
|
import {
|
||||||
|
TemplateAst,
|
||||||
|
TemplateAstVisitor,
|
||||||
|
NgContentAst,
|
||||||
|
EmbeddedTemplateAst,
|
||||||
|
ElementAst,
|
||||||
|
VariableAst,
|
||||||
|
BoundEventAst,
|
||||||
|
BoundElementPropertyAst,
|
||||||
|
AttrAst,
|
||||||
|
BoundTextAst,
|
||||||
|
TextAst,
|
||||||
|
DirectiveAst,
|
||||||
|
BoundDirectivePropertyAst,
|
||||||
|
templateVisitAll
|
||||||
|
} from './template_ast';
|
||||||
import {CompileTypeMetadata, CompileDirectiveMetadata} from './directive_metadata';
|
import {CompileTypeMetadata, CompileDirectiveMetadata} from './directive_metadata';
|
||||||
import {SourceExpressions, SourceExpression, moduleRef} from './source_module';
|
import {SourceExpressions, SourceExpression, moduleRef} from './source_module';
|
||||||
import {AppProtoView, AppView, flattenNestedViewRenderNodes, checkSlotCount} from 'angular2/src/core/linker/view';
|
import {
|
||||||
|
AppProtoView,
|
||||||
|
AppView,
|
||||||
|
flattenNestedViewRenderNodes,
|
||||||
|
checkSlotCount
|
||||||
|
} from 'angular2/src/core/linker/view';
|
||||||
import {ViewType} from 'angular2/src/core/linker/view_type';
|
import {ViewType} from 'angular2/src/core/linker/view_type';
|
||||||
import {AppViewManager_} from 'angular2/src/core/linker/view_manager';
|
import {AppViewManager_} from 'angular2/src/core/linker/view_manager';
|
||||||
import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element';
|
import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element';
|
||||||
import {Renderer, ParentRenderer} from 'angular2/src/core/render/api';
|
import {Renderer, ParentRenderer} from 'angular2/src/core/render/api';
|
||||||
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
|
||||||
import {escapeSingleQuoteString, codeGenConstConstructorCall, codeGenValueFn, codeGenFnHeader, MODULE_SUFFIX, Statement, escapeValue, codeGenArray, codeGenFlatArray, Expression, flattenArray, CONST_VAR} from './util';
|
import {
|
||||||
|
escapeSingleQuoteString,
|
||||||
|
codeGenConstConstructorCall,
|
||||||
|
codeGenValueFn,
|
||||||
|
codeGenFnHeader,
|
||||||
|
MODULE_SUFFIX,
|
||||||
|
Statement,
|
||||||
|
escapeValue,
|
||||||
|
codeGenArray,
|
||||||
|
codeGenFlatArray,
|
||||||
|
Expression,
|
||||||
|
flattenArray,
|
||||||
|
CONST_VAR
|
||||||
|
} from './util';
|
||||||
import {ResolvedProvider, Injectable, Injector} from 'angular2/src/core/di';
|
import {ResolvedProvider, Injectable, Injector} from 'angular2/src/core/di';
|
||||||
|
|
||||||
import {APP_VIEW_MODULE_REF, APP_EL_MODULE_REF, METADATA_MODULE_REF, CompileProtoView, CompileProtoElement} from './proto_view_compiler';
|
import {
|
||||||
|
APP_VIEW_MODULE_REF,
|
||||||
|
APP_EL_MODULE_REF,
|
||||||
|
METADATA_MODULE_REF,
|
||||||
|
CompileProtoView,
|
||||||
|
CompileProtoElement
|
||||||
|
} from './proto_view_compiler';
|
||||||
|
|
||||||
export const VIEW_JIT_IMPORTS = CONST_EXPR({
|
export const VIEW_JIT_IMPORTS = CONST_EXPR({
|
||||||
'AppView': AppView,
|
'AppView': AppView,
|
||||||
@ -26,17 +73,18 @@ export const VIEW_JIT_IMPORTS = CONST_EXPR({
|
|||||||
export class ViewCompiler {
|
export class ViewCompiler {
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
compileComponentRuntime(
|
compileComponentRuntime(component: CompileDirectiveMetadata, template: TemplateAst[],
|
||||||
component: CompileDirectiveMetadata, template: TemplateAst[], styles: Array<string|any[]>,
|
styles: Array<string | any[]>,
|
||||||
protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
|
protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
|
||||||
changeDetectorFactories: Function[], componentViewFactory: Function): Function {
|
changeDetectorFactories: Function[],
|
||||||
var viewFactory = new RuntimeViewFactory(
|
componentViewFactory: Function): Function {
|
||||||
component, styles, protoViews, changeDetectorFactories, componentViewFactory);
|
var viewFactory = new RuntimeViewFactory(component, styles, protoViews, changeDetectorFactories,
|
||||||
|
componentViewFactory);
|
||||||
return viewFactory.createViewFactory(template, 0, []);
|
return viewFactory.createViewFactory(template, 0, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileComponentCodeGen(
|
compileComponentCodeGen(component: CompileDirectiveMetadata, template: TemplateAst[],
|
||||||
component: CompileDirectiveMetadata, template: TemplateAst[], styles: SourceExpression,
|
styles: SourceExpression,
|
||||||
protoViews: CompileProtoView<Expression, Expression>[],
|
protoViews: CompileProtoView<Expression, Expression>[],
|
||||||
changeDetectorFactoryExpressions: SourceExpressions,
|
changeDetectorFactoryExpressions: SourceExpressions,
|
||||||
componentViewFactory: Function): SourceExpression {
|
componentViewFactory: Function): SourceExpression {
|
||||||
@ -44,59 +92,55 @@ export class ViewCompiler {
|
|||||||
component, styles, protoViews, changeDetectorFactoryExpressions, componentViewFactory);
|
component, styles, protoViews, changeDetectorFactoryExpressions, componentViewFactory);
|
||||||
var targetStatements: Statement[] = [];
|
var targetStatements: Statement[] = [];
|
||||||
var viewFactoryExpression = viewFactory.createViewFactory(template, 0, targetStatements);
|
var viewFactoryExpression = viewFactory.createViewFactory(template, 0, targetStatements);
|
||||||
return new SourceExpression(
|
return new SourceExpression(targetStatements.map(stmt => stmt.statement),
|
||||||
targetStatements.map(stmt => stmt.statement), viewFactoryExpression.expression);
|
viewFactoryExpression.expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ViewFactory<EXPRESSION, STATEMENT> {
|
interface ViewFactory<EXPRESSION, STATEMENT> {
|
||||||
createText(renderer: EXPRESSION, parent: EXPRESSION, text: string, targetStatements: STATEMENT[]):
|
createText(renderer: EXPRESSION, parent: EXPRESSION, text: string,
|
||||||
EXPRESSION;
|
|
||||||
|
|
||||||
createElement(
|
|
||||||
renderer: EXPRESSION, parent: EXPRESSION, name: string, rootSelector: EXPRESSION,
|
|
||||||
targetStatements: STATEMENT[]): EXPRESSION;
|
targetStatements: STATEMENT[]): EXPRESSION;
|
||||||
|
|
||||||
createTemplateAnchor(renderer: EXPRESSION, parent: EXPRESSION, targetStatements: STATEMENT[]):
|
createElement(renderer: EXPRESSION, parent: EXPRESSION, name: string, rootSelector: EXPRESSION,
|
||||||
EXPRESSION;
|
|
||||||
|
|
||||||
createGlobalEventListener(
|
|
||||||
renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number, eventAst: BoundEventAst,
|
|
||||||
targetStatements: STATEMENT[]): EXPRESSION;
|
targetStatements: STATEMENT[]): EXPRESSION;
|
||||||
|
|
||||||
createElementEventListener(
|
createTemplateAnchor(renderer: EXPRESSION, parent: EXPRESSION,
|
||||||
renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number, renderNode: EXPRESSION,
|
targetStatements: STATEMENT[]): EXPRESSION;
|
||||||
|
|
||||||
|
createGlobalEventListener(renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number,
|
||||||
eventAst: BoundEventAst, targetStatements: STATEMENT[]): EXPRESSION;
|
eventAst: BoundEventAst, targetStatements: STATEMENT[]): EXPRESSION;
|
||||||
|
|
||||||
setElementAttribute(
|
createElementEventListener(renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number,
|
||||||
renderer: EXPRESSION, renderNode: EXPRESSION, attrName: string, attrValue: string,
|
renderNode: EXPRESSION, eventAst: BoundEventAst,
|
||||||
targetStatements: STATEMENT[]);
|
targetStatements: STATEMENT[]): EXPRESSION;
|
||||||
|
|
||||||
createAppElement(
|
setElementAttribute(renderer: EXPRESSION, renderNode: EXPRESSION, attrName: string,
|
||||||
appProtoEl: EXPRESSION, view: EXPRESSION, renderNode: EXPRESSION, parentAppEl: EXPRESSION,
|
attrValue: string, targetStatements: STATEMENT[]);
|
||||||
embeddedViewFactory: EXPRESSION, targetStatements: STATEMENT[]): EXPRESSION;
|
|
||||||
|
|
||||||
createAndSetComponentView(
|
createAppElement(appProtoEl: EXPRESSION, view: EXPRESSION, renderNode: EXPRESSION,
|
||||||
renderer: EXPRESSION, viewManager: EXPRESSION, view: EXPRESSION, appEl: EXPRESSION,
|
parentAppEl: EXPRESSION, embeddedViewFactory: EXPRESSION,
|
||||||
component: CompileDirectiveMetadata, contentNodesByNgContentIndex: EXPRESSION[][],
|
targetStatements: STATEMENT[]): EXPRESSION;
|
||||||
|
|
||||||
|
createAndSetComponentView(renderer: EXPRESSION, viewManager: EXPRESSION, view: EXPRESSION,
|
||||||
|
appEl: EXPRESSION, component: CompileDirectiveMetadata,
|
||||||
|
contentNodesByNgContentIndex: EXPRESSION[][],
|
||||||
targetStatements: STATEMENT[]);
|
targetStatements: STATEMENT[]);
|
||||||
|
|
||||||
getProjectedNodes(projectableNodes: EXPRESSION, ngContentIndex: number): EXPRESSION;
|
getProjectedNodes(projectableNodes: EXPRESSION, ngContentIndex: number): EXPRESSION;
|
||||||
|
|
||||||
appendProjectedNodes(
|
appendProjectedNodes(renderer: EXPRESSION, parent: EXPRESSION, nodes: EXPRESSION,
|
||||||
renderer: EXPRESSION, parent: EXPRESSION, nodes: EXPRESSION, targetStatements: STATEMENT[]);
|
targetStatements: STATEMENT[]);
|
||||||
|
|
||||||
createViewFactory(
|
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number,
|
||||||
asts: TemplateAst[], embeddedTemplateIndex: number,
|
|
||||||
targetStatements: STATEMENT[]): EXPRESSION;
|
targetStatements: STATEMENT[]): EXPRESSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
||||||
private _nextVarId: number = 0;
|
private _nextVarId: number = 0;
|
||||||
constructor(
|
constructor(public component: CompileDirectiveMetadata, public styles: SourceExpression,
|
||||||
public component: CompileDirectiveMetadata, public styles: SourceExpression,
|
|
||||||
public protoViews: CompileProtoView<Expression, Expression>[],
|
public protoViews: CompileProtoView<Expression, Expression>[],
|
||||||
public changeDetectorExpressions: SourceExpressions, public componentViewFactory: Function) {}
|
public changeDetectorExpressions: SourceExpressions,
|
||||||
|
public componentViewFactory: Function) {}
|
||||||
|
|
||||||
private _nextVar(prefix: string): string {
|
private _nextVar(prefix: string): string {
|
||||||
return `${prefix}${this._nextVarId++}_${this.component.type.name}`;
|
return `${prefix}${this._nextVarId++}_${this.component.type.name}`;
|
||||||
@ -110,8 +154,8 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
return `disposable${this._nextVarId++}_${this.component.type.name}`;
|
return `disposable${this._nextVarId++}_${this.component.type.name}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
createText(renderer: Expression, parent: Expression, text: string, targetStatements: Statement[]):
|
createText(renderer: Expression, parent: Expression, text: string,
|
||||||
Expression {
|
targetStatements: Statement[]): Expression {
|
||||||
var varName = this._nextRenderVar();
|
var varName = this._nextRenderVar();
|
||||||
var statement =
|
var statement =
|
||||||
`var ${varName} = ${renderer.expression}.createText(${isPresent(parent) ? parent.expression : null}, ${escapeSingleQuoteString(text)});`;
|
`var ${varName} = ${renderer.expression}.createText(${isPresent(parent) ? parent.expression : null}, ${escapeSingleQuoteString(text)});`;
|
||||||
@ -119,9 +163,8 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
return new Expression(varName);
|
return new Expression(varName);
|
||||||
}
|
}
|
||||||
|
|
||||||
createElement(
|
createElement(renderer: Expression, parentRenderNode: Expression, name: string,
|
||||||
renderer: Expression, parentRenderNode: Expression, name: string, rootSelector: Expression,
|
rootSelector: Expression, targetStatements: Statement[]): Expression {
|
||||||
targetStatements: Statement[]): Expression {
|
|
||||||
var varName = this._nextRenderVar();
|
var varName = this._nextRenderVar();
|
||||||
var valueExpr;
|
var valueExpr;
|
||||||
if (isPresent(rootSelector)) {
|
if (isPresent(rootSelector)) {
|
||||||
@ -137,8 +180,7 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
return new Expression(varName);
|
return new Expression(varName);
|
||||||
}
|
}
|
||||||
|
|
||||||
createTemplateAnchor(
|
createTemplateAnchor(renderer: Expression, parentRenderNode: Expression,
|
||||||
renderer: Expression, parentRenderNode: Expression,
|
|
||||||
targetStatements: Statement[]): Expression {
|
targetStatements: Statement[]): Expression {
|
||||||
var varName = this._nextRenderVar();
|
var varName = this._nextRenderVar();
|
||||||
var valueExpr =
|
var valueExpr =
|
||||||
@ -147,9 +189,8 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
return new Expression(varName);
|
return new Expression(varName);
|
||||||
}
|
}
|
||||||
|
|
||||||
createGlobalEventListener(
|
createGlobalEventListener(renderer: Expression, appView: Expression, boundElementIndex: number,
|
||||||
renderer: Expression, appView: Expression, boundElementIndex: number, eventAst: BoundEventAst,
|
eventAst: BoundEventAst, targetStatements: Statement[]): Expression {
|
||||||
targetStatements: Statement[]): Expression {
|
|
||||||
var disposableVar = this._nextDisposableVar();
|
var disposableVar = this._nextDisposableVar();
|
||||||
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
|
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
|
||||||
targetStatements.push(new Statement(
|
targetStatements.push(new Statement(
|
||||||
@ -157,9 +198,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
return new Expression(disposableVar);
|
return new Expression(disposableVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
createElementEventListener(
|
createElementEventListener(renderer: Expression, appView: Expression, boundElementIndex: number,
|
||||||
renderer: Expression, appView: Expression, boundElementIndex: number, renderNode: Expression,
|
renderNode: Expression, eventAst: BoundEventAst,
|
||||||
eventAst: BoundEventAst, targetStatements: Statement[]): Expression {
|
targetStatements: Statement[]): Expression {
|
||||||
var disposableVar = this._nextDisposableVar();
|
var disposableVar = this._nextDisposableVar();
|
||||||
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
|
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
|
||||||
targetStatements.push(new Statement(
|
targetStatements.push(new Statement(
|
||||||
@ -167,16 +208,15 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
return new Expression(disposableVar);
|
return new Expression(disposableVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
setElementAttribute(
|
setElementAttribute(renderer: Expression, renderNode: Expression, attrName: string,
|
||||||
renderer: Expression, renderNode: Expression, attrName: string, attrValue: string,
|
attrValue: string, targetStatements: Statement[]) {
|
||||||
targetStatements: Statement[]) {
|
|
||||||
targetStatements.push(new Statement(
|
targetStatements.push(new Statement(
|
||||||
`${renderer.expression}.setElementAttribute(${renderNode.expression}, ${escapeSingleQuoteString(attrName)}, ${escapeSingleQuoteString(attrValue)});`));
|
`${renderer.expression}.setElementAttribute(${renderNode.expression}, ${escapeSingleQuoteString(attrName)}, ${escapeSingleQuoteString(attrValue)});`));
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppElement(
|
createAppElement(appProtoEl: Expression, appView: Expression, renderNode: Expression,
|
||||||
appProtoEl: Expression, appView: Expression, renderNode: Expression, parentAppEl: Expression,
|
parentAppEl: Expression, embeddedViewFactory: Expression,
|
||||||
embeddedViewFactory: Expression, targetStatements: Statement[]): Expression {
|
targetStatements: Statement[]): Expression {
|
||||||
var appVar = this._nextAppVar();
|
var appVar = this._nextAppVar();
|
||||||
var varValue =
|
var varValue =
|
||||||
`new ${APP_EL_MODULE_REF}AppElement(${appProtoEl.expression}, ${appView.expression},
|
`new ${APP_EL_MODULE_REF}AppElement(${appProtoEl.expression}, ${appView.expression},
|
||||||
@ -185,9 +225,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
return new Expression(appVar);
|
return new Expression(appVar);
|
||||||
}
|
}
|
||||||
|
|
||||||
createAndSetComponentView(
|
createAndSetComponentView(renderer: Expression, viewManager: Expression, view: Expression,
|
||||||
renderer: Expression, viewManager: Expression, view: Expression, appEl: Expression,
|
appEl: Expression, component: CompileDirectiveMetadata,
|
||||||
component: CompileDirectiveMetadata, contentNodesByNgContentIndex: Expression[][],
|
contentNodesByNgContentIndex: Expression[][],
|
||||||
targetStatements: Statement[]) {
|
targetStatements: Statement[]) {
|
||||||
var codeGenContentNodes;
|
var codeGenContentNodes;
|
||||||
if (this.component.type.isHost) {
|
if (this.component.type.isHost) {
|
||||||
@ -204,14 +244,13 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
return new Expression(`${projectableNodes.expression}[${ngContentIndex}]`, true);
|
return new Expression(`${projectableNodes.expression}[${ngContentIndex}]`, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendProjectedNodes(
|
appendProjectedNodes(renderer: Expression, parent: Expression, nodes: Expression,
|
||||||
renderer: Expression, parent: Expression, nodes: Expression, targetStatements: Statement[]) {
|
targetStatements: Statement[]) {
|
||||||
targetStatements.push(new Statement(
|
targetStatements.push(new Statement(
|
||||||
`${renderer.expression}.projectNodes(${parent.expression}, ${APP_VIEW_MODULE_REF}flattenNestedViewRenderNodes(${nodes.expression}));`));
|
`${renderer.expression}.projectNodes(${parent.expression}, ${APP_VIEW_MODULE_REF}flattenNestedViewRenderNodes(${nodes.expression}));`));
|
||||||
}
|
}
|
||||||
|
|
||||||
createViewFactory(
|
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number,
|
||||||
asts: TemplateAst[], embeddedTemplateIndex: number,
|
|
||||||
targetStatements: Statement[]): Expression {
|
targetStatements: Statement[]): Expression {
|
||||||
var compileProtoView = this.protoViews[embeddedTemplateIndex];
|
var compileProtoView = this.protoViews[embeddedTemplateIndex];
|
||||||
var isHostView = this.component.type.isHost;
|
var isHostView = this.component.type.isHost;
|
||||||
@ -229,8 +268,13 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
|
|||||||
var viewFactoryName = codeGenViewFactoryName(this.component, embeddedTemplateIndex);
|
var viewFactoryName = codeGenViewFactoryName(this.component, embeddedTemplateIndex);
|
||||||
var changeDetectorFactory = this.changeDetectorExpressions.expressions[embeddedTemplateIndex];
|
var changeDetectorFactory = this.changeDetectorExpressions.expressions[embeddedTemplateIndex];
|
||||||
var factoryArgs = [
|
var factoryArgs = [
|
||||||
'parentRenderer', 'viewManager', 'containerEl', 'projectableNodes', 'rootSelector',
|
'parentRenderer',
|
||||||
'dynamicallyCreatedProviders', 'rootInjector'
|
'viewManager',
|
||||||
|
'containerEl',
|
||||||
|
'projectableNodes',
|
||||||
|
'rootSelector',
|
||||||
|
'dynamicallyCreatedProviders',
|
||||||
|
'rootInjector'
|
||||||
];
|
];
|
||||||
var initRendererStmts = [];
|
var initRendererStmts = [];
|
||||||
var rendererExpr = `parentRenderer`;
|
var rendererExpr = `parentRenderer`;
|
||||||
@ -272,8 +316,7 @@ ${codeGenFnHeader(factoryArgs, viewFactoryName)}{
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RuntimeViewFactory implements ViewFactory<any, any> {
|
class RuntimeViewFactory implements ViewFactory<any, any> {
|
||||||
constructor(
|
constructor(public component: CompileDirectiveMetadata, public styles: Array<string | any[]>,
|
||||||
public component: CompileDirectiveMetadata, public styles: Array<string|any[]>,
|
|
||||||
public protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
|
public protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
|
||||||
public changeDetectorFactories: Function[], public componentViewFactory: Function) {}
|
public changeDetectorFactories: Function[], public componentViewFactory: Function) {}
|
||||||
|
|
||||||
@ -281,8 +324,7 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
|||||||
return renderer.createText(parent, text);
|
return renderer.createText(parent, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
createElement(
|
createElement(renderer: Renderer, parent: any, name: string, rootSelector: string,
|
||||||
renderer: Renderer, parent: any, name: string, rootSelector: string,
|
|
||||||
targetStatements: any[]): any {
|
targetStatements: any[]): any {
|
||||||
var el;
|
var el;
|
||||||
if (isPresent(rootSelector)) {
|
if (isPresent(rootSelector)) {
|
||||||
@ -297,37 +339,35 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
|||||||
return renderer.createTemplateAnchor(parent);
|
return renderer.createTemplateAnchor(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
createGlobalEventListener(
|
createGlobalEventListener(renderer: Renderer, appView: AppView, boundElementIndex: number,
|
||||||
renderer: Renderer, appView: AppView, boundElementIndex: number, eventAst: BoundEventAst,
|
eventAst: BoundEventAst, targetStatements: any[]): any {
|
||||||
targetStatements: any[]): any {
|
|
||||||
return renderer.listenGlobal(
|
return renderer.listenGlobal(
|
||||||
eventAst.target, eventAst.name,
|
eventAst.target, eventAst.name,
|
||||||
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
|
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
createElementEventListener(
|
createElementEventListener(renderer: Renderer, appView: AppView, boundElementIndex: number,
|
||||||
renderer: Renderer, appView: AppView, boundElementIndex: number, renderNode: any,
|
renderNode: any, eventAst: BoundEventAst,
|
||||||
eventAst: BoundEventAst, targetStatements: any[]): any {
|
targetStatements: any[]): any {
|
||||||
return renderer.listen(
|
return renderer.listen(
|
||||||
renderNode, eventAst.name,
|
renderNode, eventAst.name,
|
||||||
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
|
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
setElementAttribute(
|
setElementAttribute(renderer: Renderer, renderNode: any, attrName: string, attrValue: string,
|
||||||
renderer: Renderer, renderNode: any, attrName: string, attrValue: string,
|
|
||||||
targetStatements: any[]) {
|
targetStatements: any[]) {
|
||||||
renderer.setElementAttribute(renderNode, attrName, attrValue);
|
renderer.setElementAttribute(renderNode, attrName, attrValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
createAppElement(
|
createAppElement(appProtoEl: AppProtoElement, appView: AppView, renderNode: any,
|
||||||
appProtoEl: AppProtoElement, appView: AppView, renderNode: any, parentAppEl: AppElement,
|
parentAppEl: AppElement, embeddedViewFactory: Function,
|
||||||
embeddedViewFactory: Function, targetStatements: any[]): any {
|
targetStatements: any[]): any {
|
||||||
return new AppElement(appProtoEl, appView, parentAppEl, renderNode, embeddedViewFactory);
|
return new AppElement(appProtoEl, appView, parentAppEl, renderNode, embeddedViewFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
createAndSetComponentView(
|
createAndSetComponentView(renderer: Renderer, viewManager: AppViewManager_, appView: AppView,
|
||||||
renderer: Renderer, viewManager: AppViewManager_, appView: AppView, appEl: AppElement,
|
appEl: AppElement, component: CompileDirectiveMetadata,
|
||||||
component: CompileDirectiveMetadata, contentNodesByNgContentIndex: Array<Array<any|any[]>>,
|
contentNodesByNgContentIndex: Array<Array<any | any[]>>,
|
||||||
targetStatements: any[]) {
|
targetStatements: any[]) {
|
||||||
var flattenedContentNodes;
|
var flattenedContentNodes;
|
||||||
if (this.component.type.isHost) {
|
if (this.component.type.isHost) {
|
||||||
@ -349,8 +389,8 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
|||||||
renderer.projectNodes(parent, flattenNestedViewRenderNodes(nodes));
|
renderer.projectNodes(parent, flattenNestedViewRenderNodes(nodes));
|
||||||
}
|
}
|
||||||
|
|
||||||
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number, targetStatements: any[]):
|
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number,
|
||||||
Function {
|
targetStatements: any[]): Function {
|
||||||
var compileProtoView = this.protoViews[embeddedTemplateIndex];
|
var compileProtoView = this.protoViews[embeddedTemplateIndex];
|
||||||
var isComponentView = compileProtoView.protoView.type === ViewType.COMPONENT;
|
var isComponentView = compileProtoView.protoView.type === ViewType.COMPONENT;
|
||||||
var renderComponentType = null;
|
var renderComponentType = null;
|
||||||
@ -358,8 +398,7 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
|||||||
projectableNodes: any[][], rootSelector: string = null,
|
projectableNodes: any[][], rootSelector: string = null,
|
||||||
dynamicallyCreatedProviders: ResolvedProvider[] = null,
|
dynamicallyCreatedProviders: ResolvedProvider[] = null,
|
||||||
rootInjector: Injector = null) => {
|
rootInjector: Injector = null) => {
|
||||||
checkSlotCount(
|
checkSlotCount(this.component.type.name, this.component.template.ngContentSelectors.length,
|
||||||
this.component.type.name, this.component.template.ngContentSelectors.length,
|
|
||||||
projectableNodes);
|
projectableNodes);
|
||||||
var renderer;
|
var renderer;
|
||||||
if (embeddedTemplateIndex === 0) {
|
if (embeddedTemplateIndex === 0) {
|
||||||
@ -372,16 +411,15 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
|||||||
renderer = <Renderer>parentRenderer;
|
renderer = <Renderer>parentRenderer;
|
||||||
}
|
}
|
||||||
var changeDetector = this.changeDetectorFactories[embeddedTemplateIndex]();
|
var changeDetector = this.changeDetectorFactories[embeddedTemplateIndex]();
|
||||||
var view = new AppView(
|
var view =
|
||||||
compileProtoView.protoView, renderer, viewManager, projectableNodes, containerEl,
|
new AppView(compileProtoView.protoView, renderer, viewManager, projectableNodes,
|
||||||
dynamicallyCreatedProviders, rootInjector, changeDetector);
|
containerEl, dynamicallyCreatedProviders, rootInjector, changeDetector);
|
||||||
var visitor = new ViewBuilderVisitor<any, any>(
|
var visitor = new ViewBuilderVisitor<any, any>(
|
||||||
renderer, viewManager, projectableNodes, rootSelector, view, compileProtoView, [], this);
|
renderer, viewManager, projectableNodes, rootSelector, view, compileProtoView, [], this);
|
||||||
var parentRenderNode =
|
var parentRenderNode =
|
||||||
isComponentView ? renderer.createViewRoot(containerEl.nativeElement) : null;
|
isComponentView ? renderer.createViewRoot(containerEl.nativeElement) : null;
|
||||||
templateVisitAll(visitor, asts, new ParentElement(parentRenderNode, null, null));
|
templateVisitAll(visitor, asts, new ParentElement(parentRenderNode, null, null));
|
||||||
view.init(
|
view.init(flattenArray(visitor.rootNodesOrAppElements, []), visitor.renderNodes,
|
||||||
flattenArray(visitor.rootNodesOrAppElements, []), visitor.renderNodes,
|
|
||||||
visitor.appDisposables, visitor.appElements);
|
visitor.appDisposables, visitor.appElements);
|
||||||
return view;
|
return view;
|
||||||
};
|
};
|
||||||
@ -391,8 +429,7 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
|
|||||||
class ParentElement<EXPRESSION> {
|
class ParentElement<EXPRESSION> {
|
||||||
public contentNodesByNgContentIndex: Array<EXPRESSION>[];
|
public contentNodesByNgContentIndex: Array<EXPRESSION>[];
|
||||||
|
|
||||||
constructor(
|
constructor(public renderNode: EXPRESSION, public appEl: EXPRESSION,
|
||||||
public renderNode: EXPRESSION, public appEl: EXPRESSION,
|
|
||||||
public component: CompileDirectiveMetadata) {
|
public component: CompileDirectiveMetadata) {
|
||||||
if (isPresent(component)) {
|
if (isPresent(component)) {
|
||||||
this.contentNodesByNgContentIndex =
|
this.contentNodesByNgContentIndex =
|
||||||
@ -421,14 +458,13 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
|||||||
|
|
||||||
elementCount: number = 0;
|
elementCount: number = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(public renderer: EXPRESSION, public viewManager: EXPRESSION,
|
||||||
public renderer: EXPRESSION, public viewManager: EXPRESSION,
|
public projectableNodes: EXPRESSION, public rootSelector: EXPRESSION,
|
||||||
public projectableNodes: EXPRESSION, public rootSelector: EXPRESSION, public view: EXPRESSION,
|
public view: EXPRESSION, public protoView: CompileProtoView<EXPRESSION, EXPRESSION>,
|
||||||
public protoView: CompileProtoView<EXPRESSION, EXPRESSION>,
|
public targetStatements: STATEMENT[],
|
||||||
public targetStatements: STATEMENT[], public factory: ViewFactory<EXPRESSION, STATEMENT>) {}
|
public factory: ViewFactory<EXPRESSION, STATEMENT>) {}
|
||||||
|
|
||||||
private _addRenderNode(
|
private _addRenderNode(renderNode: EXPRESSION, appEl: EXPRESSION, ngContentIndex: number,
|
||||||
renderNode: EXPRESSION, appEl: EXPRESSION, ngContentIndex: number,
|
|
||||||
parent: ParentElement<EXPRESSION>) {
|
parent: ParentElement<EXPRESSION>) {
|
||||||
this.renderNodes.push(renderNode);
|
this.renderNodes.push(renderNode);
|
||||||
if (isPresent(parent.component)) {
|
if (isPresent(parent.component)) {
|
||||||
@ -440,8 +476,8 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getParentRenderNode(ngContentIndex: number, parent: ParentElement<EXPRESSION>):
|
private _getParentRenderNode(ngContentIndex: number,
|
||||||
EXPRESSION {
|
parent: ParentElement<EXPRESSION>): EXPRESSION {
|
||||||
return isPresent(parent.component) &&
|
return isPresent(parent.component) &&
|
||||||
parent.component.template.encapsulation !== ViewEncapsulation.Native ?
|
parent.component.template.encapsulation !== ViewEncapsulation.Native ?
|
||||||
null :
|
null :
|
||||||
@ -469,8 +505,8 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isPresent(parent.renderNode)) {
|
if (isPresent(parent.renderNode)) {
|
||||||
this.factory.appendProjectedNodes(
|
this.factory.appendProjectedNodes(this.renderer, parent.renderNode, nodesExpression,
|
||||||
this.renderer, parent.renderNode, nodesExpression, this.renderStmts);
|
this.renderStmts);
|
||||||
} else {
|
} else {
|
||||||
this.rootNodesOrAppElements.push(nodesExpression);
|
this.rootNodesOrAppElements.push(nodesExpression);
|
||||||
}
|
}
|
||||||
@ -493,22 +529,22 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
|||||||
disposable = this.factory.createGlobalEventListener(
|
disposable = this.factory.createGlobalEventListener(
|
||||||
this.renderer, this.view, protoEl.boundElementIndex, eventAst, this.renderStmts);
|
this.renderer, this.view, protoEl.boundElementIndex, eventAst, this.renderStmts);
|
||||||
} else {
|
} else {
|
||||||
disposable = this.factory.createElementEventListener(
|
disposable = this.factory.createElementEventListener(this.renderer, this.view,
|
||||||
this.renderer, this.view, protoEl.boundElementIndex, renderNode, eventAst,
|
protoEl.boundElementIndex, renderNode,
|
||||||
this.renderStmts);
|
eventAst, this.renderStmts);
|
||||||
}
|
}
|
||||||
this.appDisposables.push(disposable);
|
this.appDisposables.push(disposable);
|
||||||
});
|
});
|
||||||
for (var i = 0; i < protoEl.attrNameAndValues.length; i++) {
|
for (var i = 0; i < protoEl.attrNameAndValues.length; i++) {
|
||||||
var attrName = protoEl.attrNameAndValues[i][0];
|
var attrName = protoEl.attrNameAndValues[i][0];
|
||||||
var attrValue = protoEl.attrNameAndValues[i][1];
|
var attrValue = protoEl.attrNameAndValues[i][1];
|
||||||
this.factory.setElementAttribute(
|
this.factory.setElementAttribute(this.renderer, renderNode, attrName, attrValue,
|
||||||
this.renderer, renderNode, attrName, attrValue, this.renderStmts);
|
this.renderStmts);
|
||||||
}
|
}
|
||||||
var appEl = null;
|
var appEl = null;
|
||||||
if (isPresent(protoEl.appProtoEl)) {
|
if (isPresent(protoEl.appProtoEl)) {
|
||||||
appEl = this.factory.createAppElement(
|
appEl = this.factory.createAppElement(protoEl.appProtoEl, this.view, renderNode, parent.appEl,
|
||||||
protoEl.appProtoEl, this.view, renderNode, parent.appEl, null, this.appStmts);
|
null, this.appStmts);
|
||||||
this.appElements.push(appEl);
|
this.appElements.push(appEl);
|
||||||
}
|
}
|
||||||
this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent);
|
this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent);
|
||||||
@ -517,9 +553,9 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
|||||||
renderNode, isPresent(appEl) ? appEl : parent.appEl, component);
|
renderNode, isPresent(appEl) ? appEl : parent.appEl, component);
|
||||||
templateVisitAll(this, ast.children, newParent);
|
templateVisitAll(this, ast.children, newParent);
|
||||||
if (isPresent(appEl) && isPresent(component)) {
|
if (isPresent(appEl) && isPresent(component)) {
|
||||||
this.factory.createAndSetComponentView(
|
this.factory.createAndSetComponentView(this.renderer, this.viewManager, this.view, appEl,
|
||||||
this.renderer, this.viewManager, this.view, appEl, component,
|
component, newParent.contentNodesByNgContentIndex,
|
||||||
newParent.contentNodesByNgContentIndex, this.appStmts);
|
this.appStmts);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -533,9 +569,8 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
|||||||
var embeddedViewFactory = this.factory.createViewFactory(
|
var embeddedViewFactory = this.factory.createViewFactory(
|
||||||
ast.children, protoEl.embeddedTemplateIndex, this.targetStatements);
|
ast.children, protoEl.embeddedTemplateIndex, this.targetStatements);
|
||||||
|
|
||||||
var appEl = this.factory.createAppElement(
|
var appEl = this.factory.createAppElement(protoEl.appProtoEl, this.view, renderNode,
|
||||||
protoEl.appProtoEl, this.view, renderNode, parent.appEl, embeddedViewFactory,
|
parent.appEl, embeddedViewFactory, this.appStmts);
|
||||||
this.appStmts);
|
|
||||||
this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent);
|
this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent);
|
||||||
this.appElements.push(appEl);
|
this.appElements.push(appEl);
|
||||||
return null;
|
return null;
|
||||||
@ -550,15 +585,15 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function codeGenEventHandler(
|
function codeGenEventHandler(view: Expression, boundElementIndex: number,
|
||||||
view: Expression, boundElementIndex: number, eventName: string): string {
|
eventName: string): string {
|
||||||
return codeGenValueFn(
|
return codeGenValueFn(
|
||||||
['event'],
|
['event'],
|
||||||
`${view.expression}.triggerEventHandlers(${escapeValue(eventName)}, event, ${boundElementIndex})`);
|
`${view.expression}.triggerEventHandlers(${escapeValue(eventName)}, event, ${boundElementIndex})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function codeGenViewFactoryName(
|
function codeGenViewFactoryName(component: CompileDirectiveMetadata,
|
||||||
component: CompileDirectiveMetadata, embeddedTemplateIndex: number): string {
|
embeddedTemplateIndex: number): string {
|
||||||
return `viewFactory_${component.type.name}${embeddedTemplateIndex}`;
|
return `viewFactory_${component.type.name}${embeddedTemplateIndex}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,26 +1,40 @@
|
|||||||
import {Type, CONST_EXPR} from 'angular2/src/facade/lang';
|
import {Type, CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
|
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
|
||||||
import {APP_COMPONENT_REF_PROMISE, APP_COMPONENT, APP_ID_RANDOM_PROVIDER} from './application_tokens';
|
import {
|
||||||
import {IterableDiffers, defaultIterableDiffers, KeyValueDiffers, defaultKeyValueDiffers} from './change_detection/change_detection';
|
APP_COMPONENT_REF_PROMISE,
|
||||||
|
APP_COMPONENT,
|
||||||
|
APP_ID_RANDOM_PROVIDER
|
||||||
|
} from './application_tokens';
|
||||||
|
import {
|
||||||
|
IterableDiffers,
|
||||||
|
defaultIterableDiffers,
|
||||||
|
KeyValueDiffers,
|
||||||
|
defaultKeyValueDiffers
|
||||||
|
} from './change_detection/change_detection';
|
||||||
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
|
||||||
import {AppViewManager} from './linker/view_manager';
|
import {AppViewManager} from './linker/view_manager';
|
||||||
import {AppViewManager_} from './linker/view_manager';
|
import {AppViewManager_} from "./linker/view_manager";
|
||||||
import {ViewResolver} from './linker/view_resolver';
|
import {ViewResolver} from './linker/view_resolver';
|
||||||
import {DirectiveResolver} from './linker/directive_resolver';
|
import {DirectiveResolver} from './linker/directive_resolver';
|
||||||
import {PipeResolver} from './linker/pipe_resolver';
|
import {PipeResolver} from './linker/pipe_resolver';
|
||||||
import {Compiler} from './linker/compiler';
|
import {Compiler} from './linker/compiler';
|
||||||
import {Compiler_} from './linker/compiler';
|
import {Compiler_} from "./linker/compiler";
|
||||||
import {DynamicComponentLoader} from './linker/dynamic_component_loader';
|
import {DynamicComponentLoader} from './linker/dynamic_component_loader';
|
||||||
import {DynamicComponentLoader_} from './linker/dynamic_component_loader';
|
import {DynamicComponentLoader_} from "./linker/dynamic_component_loader";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default set of providers which should be included in any Angular
|
* A default set of providers which should be included in any Angular
|
||||||
* application, regardless of the platform it runs onto.
|
* application, regardless of the platform it runs onto.
|
||||||
*/
|
*/
|
||||||
export const APPLICATION_COMMON_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([
|
export const APPLICATION_COMMON_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([
|
||||||
new Provider(Compiler, {useClass: Compiler_}), APP_ID_RANDOM_PROVIDER, ResolvedMetadataCache,
|
new Provider(Compiler, {useClass: Compiler_}),
|
||||||
new Provider(AppViewManager, {useClass: AppViewManager_}), ViewResolver,
|
APP_ID_RANDOM_PROVIDER,
|
||||||
|
ResolvedMetadataCache,
|
||||||
|
new Provider(AppViewManager, {useClass: AppViewManager_}),
|
||||||
|
ViewResolver,
|
||||||
new Provider(IterableDiffers, {useValue: defaultIterableDiffers}),
|
new Provider(IterableDiffers, {useValue: defaultIterableDiffers}),
|
||||||
new Provider(KeyValueDiffers, {useValue: defaultKeyValueDiffers}), DirectiveResolver,
|
new Provider(KeyValueDiffers, {useValue: defaultKeyValueDiffers}),
|
||||||
PipeResolver, new Provider(DynamicComponentLoader, {useClass: DynamicComponentLoader_})
|
DirectiveResolver,
|
||||||
|
PipeResolver,
|
||||||
|
new Provider(DynamicComponentLoader, {useClass: DynamicComponentLoader_})
|
||||||
]);
|
]);
|
@ -1,12 +1,33 @@
|
|||||||
import {NgZone, NgZoneError} from 'angular2/src/core/zone/ng_zone';
|
import {NgZone, NgZoneError} from 'angular2/src/core/zone/ng_zone';
|
||||||
import {Type, isBlank, isPresent, assertionsEnabled, print, IS_DART} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
Type,
|
||||||
|
isBlank,
|
||||||
|
isPresent,
|
||||||
|
assertionsEnabled,
|
||||||
|
print,
|
||||||
|
IS_DART
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
|
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
|
||||||
import {APP_COMPONENT_REF_PROMISE, APP_COMPONENT, APP_ID_RANDOM_PROVIDER, PLATFORM_INITIALIZER, APP_INITIALIZER} from './application_tokens';
|
import {
|
||||||
|
APP_COMPONENT_REF_PROMISE,
|
||||||
|
APP_COMPONENT,
|
||||||
|
APP_ID_RANDOM_PROVIDER,
|
||||||
|
PLATFORM_INITIALIZER,
|
||||||
|
APP_INITIALIZER
|
||||||
|
} from './application_tokens';
|
||||||
import {PromiseWrapper, PromiseCompleter, ObservableWrapper} from 'angular2/src/facade/async';
|
import {PromiseWrapper, PromiseCompleter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
|
||||||
import {ComponentRef, DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
|
import {
|
||||||
import {BaseException, WrappedException, ExceptionHandler, unimplemented} from 'angular2/src/facade/exceptions';
|
ComponentRef,
|
||||||
|
DynamicComponentLoader
|
||||||
|
} from 'angular2/src/core/linker/dynamic_component_loader';
|
||||||
|
import {
|
||||||
|
BaseException,
|
||||||
|
WrappedException,
|
||||||
|
ExceptionHandler,
|
||||||
|
unimplemented
|
||||||
|
} from 'angular2/src/facade/exceptions';
|
||||||
import {Console} from 'angular2/src/core/console';
|
import {Console} from 'angular2/src/core/console';
|
||||||
import {wtfLeave, wtfCreateScope, WtfScopeFn} from './profile/profile';
|
import {wtfLeave, wtfCreateScope, WtfScopeFn} from './profile/profile';
|
||||||
import {ChangeDetectorRef} from 'angular2/src/core/change_detection/change_detector_ref';
|
import {ChangeDetectorRef} from 'angular2/src/core/change_detection/change_detector_ref';
|
||||||
@ -19,14 +40,15 @@ import {ElementRef_} from 'angular2/src/core/linker/element_ref';
|
|||||||
function _componentProviders(appComponentType: Type): Array<Type | Provider | any[]> {
|
function _componentProviders(appComponentType: Type): Array<Type | Provider | any[]> {
|
||||||
return [
|
return [
|
||||||
provide(APP_COMPONENT, {useValue: appComponentType}),
|
provide(APP_COMPONENT, {useValue: appComponentType}),
|
||||||
provide(APP_COMPONENT_REF_PROMISE, {
|
provide(APP_COMPONENT_REF_PROMISE,
|
||||||
|
{
|
||||||
useFactory: (dynamicComponentLoader: DynamicComponentLoader, appRef: ApplicationRef_,
|
useFactory: (dynamicComponentLoader: DynamicComponentLoader, appRef: ApplicationRef_,
|
||||||
injector: Injector) => {
|
injector: Injector) => {
|
||||||
// Save the ComponentRef for disposal later.
|
// Save the ComponentRef for disposal later.
|
||||||
var ref: ComponentRef;
|
var ref: ComponentRef;
|
||||||
// TODO(rado): investigate whether to support providers on root component.
|
// TODO(rado): investigate whether to support providers on root component.
|
||||||
return dynamicComponentLoader
|
return dynamicComponentLoader.loadAsRoot(appComponentType, null, injector,
|
||||||
.loadAsRoot(appComponentType, null, injector, () => { appRef._unloadComponent(ref); })
|
() => { appRef._unloadComponent(ref); })
|
||||||
.then((componentRef) => {
|
.then((componentRef) => {
|
||||||
ref = componentRef;
|
ref = componentRef;
|
||||||
var testability = injector.getOptional(Testability);
|
var testability = injector.getOptional(Testability);
|
||||||
@ -39,7 +61,8 @@ function _componentProviders(appComponentType: Type): Array<Type|Provider|any[]>
|
|||||||
},
|
},
|
||||||
deps: [DynamicComponentLoader, ApplicationRef, Injector]
|
deps: [DynamicComponentLoader, ApplicationRef, Injector]
|
||||||
}),
|
}),
|
||||||
provide(appComponentType, {
|
provide(appComponentType,
|
||||||
|
{
|
||||||
useFactory: (p: Promise<any>) => p.then(ref => ref.instance),
|
useFactory: (p: Promise<any>) => p.then(ref => ref.instance),
|
||||||
deps: [APP_COMPONENT_REF_PROMISE]
|
deps: [APP_COMPONENT_REF_PROMISE]
|
||||||
}),
|
}),
|
||||||
@ -76,7 +99,7 @@ export function platform(providers?: Array<Type|Provider|any[]>): PlatformRef {
|
|||||||
if (ListWrapper.equals(_platformProviders, providers)) {
|
if (ListWrapper.equals(_platformProviders, providers)) {
|
||||||
return _platform;
|
return _platform;
|
||||||
} else {
|
} else {
|
||||||
throw new BaseException('platform cannot be initialized with different sets of providers.');
|
throw new BaseException("platform cannot be initialized with different sets of providers.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return _createPlatform(providers);
|
return _createPlatform(providers);
|
||||||
@ -166,8 +189,7 @@ export abstract class PlatformRef {
|
|||||||
* new application. Once this promise resolves, the application will be
|
* new application. Once this promise resolves, the application will be
|
||||||
* constructed in the same manner as a normal `application()`.
|
* constructed in the same manner as a normal `application()`.
|
||||||
*/
|
*/
|
||||||
abstract asyncApplication(
|
abstract asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>,
|
||||||
bindingFn: (zone: NgZone) => Promise<Array<Type|Provider|any[]>>,
|
|
||||||
providers?: Array<Type | Provider | any[]>): Promise<ApplicationRef>;
|
providers?: Array<Type | Provider | any[]>): Promise<ApplicationRef>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -192,13 +214,12 @@ export class PlatformRef_ extends PlatformRef {
|
|||||||
var app = this._initApp(createNgZone(), providers);
|
var app = this._initApp(createNgZone(), providers);
|
||||||
if (PromiseWrapper.isPromise(app)) {
|
if (PromiseWrapper.isPromise(app)) {
|
||||||
throw new BaseException(
|
throw new BaseException(
|
||||||
'Cannot use asyncronous app initializers with application. Use asyncApplication instead.');
|
"Cannot use asyncronous app initializers with application. Use asyncApplication instead.");
|
||||||
}
|
}
|
||||||
return <ApplicationRef>app;
|
return <ApplicationRef>app;
|
||||||
}
|
}
|
||||||
|
|
||||||
asyncApplication(
|
asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>,
|
||||||
bindingFn: (zone: NgZone) => Promise<Array<Type|Provider|any[]>>,
|
|
||||||
additionalProviders?: Array<Type | Provider | any[]>): Promise<ApplicationRef> {
|
additionalProviders?: Array<Type | Provider | any[]>): Promise<ApplicationRef> {
|
||||||
var zone = createNgZone();
|
var zone = createNgZone();
|
||||||
var completer = PromiseWrapper.completer<ApplicationRef>();
|
var completer = PromiseWrapper.completer<ApplicationRef>();
|
||||||
@ -218,8 +239,9 @@ export class PlatformRef_ extends PlatformRef {
|
|||||||
return completer.promise;
|
return completer.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _initApp(zone: NgZone, providers: Array<Type|Provider|any[]>):
|
private _initApp(zone: NgZone,
|
||||||
Promise<ApplicationRef>|ApplicationRef {
|
providers: Array<Type | Provider | any[]>): Promise<ApplicationRef>|
|
||||||
|
ApplicationRef {
|
||||||
var injector: Injector;
|
var injector: Injector;
|
||||||
var app: ApplicationRef;
|
var app: ApplicationRef;
|
||||||
zone.run(() => {
|
zone.run(() => {
|
||||||
@ -316,8 +338,8 @@ export abstract class ApplicationRef {
|
|||||||
* ### Example
|
* ### Example
|
||||||
* {@example core/ts/platform/platform.ts region='longform'}
|
* {@example core/ts/platform/platform.ts region='longform'}
|
||||||
*/
|
*/
|
||||||
abstract bootstrap(componentType: Type, providers?: Array<Type|Provider|any[]>):
|
abstract bootstrap(componentType: Type,
|
||||||
Promise<ComponentRef>;
|
providers?: Array<Type | Provider | any[]>): Promise<ComponentRef>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the application {@link Injector}.
|
* Retrieve the application {@link Injector}.
|
||||||
@ -374,8 +396,8 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||||||
constructor(private _platform: PlatformRef_, private _zone: NgZone, private _injector: Injector) {
|
constructor(private _platform: PlatformRef_, private _zone: NgZone, private _injector: Injector) {
|
||||||
super();
|
super();
|
||||||
if (isPresent(this._zone)) {
|
if (isPresent(this._zone)) {
|
||||||
ObservableWrapper.subscribe(
|
ObservableWrapper.subscribe(this._zone.onMicrotaskEmpty,
|
||||||
this._zone.onMicrotaskEmpty, (_) => { this._zone.run(() => { this.tick(); }); });
|
(_) => { this._zone.run(() => { this.tick(); }); });
|
||||||
}
|
}
|
||||||
this._enforceNoNewChanges = assertionsEnabled();
|
this._enforceNoNewChanges = assertionsEnabled();
|
||||||
}
|
}
|
||||||
@ -394,7 +416,8 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||||||
ListWrapper.remove(this._changeDetectorRefs, changeDetector);
|
ListWrapper.remove(this._changeDetectorRefs, changeDetector);
|
||||||
}
|
}
|
||||||
|
|
||||||
bootstrap(componentType: Type, providers?: Array<Type|Provider|any[]>): Promise<ComponentRef> {
|
bootstrap(componentType: Type,
|
||||||
|
providers?: Array<Type | Provider | any[]>): Promise<ComponentRef> {
|
||||||
var completer = PromiseWrapper.completer();
|
var completer = PromiseWrapper.completer();
|
||||||
this._zone.run(() => {
|
this._zone.run(() => {
|
||||||
var componentProviders = _componentProviders(componentType);
|
var componentProviders = _componentProviders(componentType);
|
||||||
@ -426,7 +449,7 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||||||
let c = this._injector.get(Console);
|
let c = this._injector.get(Console);
|
||||||
if (assertionsEnabled()) {
|
if (assertionsEnabled()) {
|
||||||
c.log(
|
c.log(
|
||||||
'Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.');
|
"Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.");
|
||||||
}
|
}
|
||||||
return ref;
|
return ref;
|
||||||
});
|
});
|
||||||
@ -458,7 +481,7 @@ export class ApplicationRef_ extends ApplicationRef {
|
|||||||
|
|
||||||
tick(): void {
|
tick(): void {
|
||||||
if (this._runningTick) {
|
if (this._runningTick) {
|
||||||
throw new BaseException('ApplicationRef.tick is called recursively');
|
throw new BaseException("ApplicationRef.tick is called recursively");
|
||||||
}
|
}
|
||||||
|
|
||||||
var s = ApplicationRef_._tickScope();
|
var s = ApplicationRef_._tickScope();
|
||||||
|
@ -53,15 +53,15 @@ function _randomChar(): string {
|
|||||||
* A function that will be executed when a platform is initialized.
|
* A function that will be executed when a platform is initialized.
|
||||||
*/
|
*/
|
||||||
export const PLATFORM_INITIALIZER: OpaqueToken =
|
export const PLATFORM_INITIALIZER: OpaqueToken =
|
||||||
CONST_EXPR(new OpaqueToken('Platform Initializer'));
|
CONST_EXPR(new OpaqueToken("Platform Initializer"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function that will be executed when an application is initialized.
|
* A function that will be executed when an application is initialized.
|
||||||
*/
|
*/
|
||||||
export const APP_INITIALIZER: OpaqueToken = CONST_EXPR(new OpaqueToken('Application Initializer'));
|
export const APP_INITIALIZER: OpaqueToken = CONST_EXPR(new OpaqueToken("Application Initializer"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A token which indicates the root directory of the application
|
* A token which indicates the root directory of the application
|
||||||
*/
|
*/
|
||||||
export const PACKAGE_ROOT_URL: OpaqueToken =
|
export const PACKAGE_ROOT_URL: OpaqueToken =
|
||||||
CONST_EXPR(new OpaqueToken('Application Packages Root URL'));
|
CONST_EXPR(new OpaqueToken("Application Packages Root URL"));
|
||||||
|
@ -4,4 +4,24 @@
|
|||||||
* Change detection enables data binding in Angular.
|
* Change detection enables data binding in Angular.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export {ChangeDetectionStrategy, ExpressionChangedAfterItHasBeenCheckedException, ChangeDetectionError, ChangeDetectorRef, WrappedValue, SimpleChange, PipeTransform, IterableDiffers, IterableDiffer, IterableDifferFactory, KeyValueDiffers, KeyValueDiffer, KeyValueDifferFactory, CollectionChangeRecord, KeyValueChangeRecord, TrackByFn} from './change_detection/change_detection';
|
export {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
|
||||||
|
ExpressionChangedAfterItHasBeenCheckedException,
|
||||||
|
ChangeDetectionError,
|
||||||
|
|
||||||
|
ChangeDetectorRef,
|
||||||
|
|
||||||
|
WrappedValue,
|
||||||
|
SimpleChange,
|
||||||
|
PipeTransform,
|
||||||
|
IterableDiffers,
|
||||||
|
IterableDiffer,
|
||||||
|
IterableDifferFactory,
|
||||||
|
KeyValueDiffers,
|
||||||
|
KeyValueDiffer,
|
||||||
|
KeyValueDifferFactory,
|
||||||
|
CollectionChangeRecord,
|
||||||
|
KeyValueChangeRecord,
|
||||||
|
TrackByFn
|
||||||
|
} from './change_detection/change_detection';
|
||||||
|
@ -5,7 +5,13 @@ import {ChangeDetectorRef, ChangeDetectorRef_} from './change_detector_ref';
|
|||||||
import {DirectiveIndex} from './directive_record';
|
import {DirectiveIndex} from './directive_record';
|
||||||
import {ChangeDetector, ChangeDispatcher} from './interfaces';
|
import {ChangeDetector, ChangeDispatcher} from './interfaces';
|
||||||
import {Pipes} from './pipes';
|
import {Pipes} from './pipes';
|
||||||
import {ChangeDetectionError, ExpressionChangedAfterItHasBeenCheckedException, DehydratedException, EventEvaluationErrorContext, EventEvaluationError} from './exceptions';
|
import {
|
||||||
|
ChangeDetectionError,
|
||||||
|
ExpressionChangedAfterItHasBeenCheckedException,
|
||||||
|
DehydratedException,
|
||||||
|
EventEvaluationErrorContext,
|
||||||
|
EventEvaluationError
|
||||||
|
} from './exceptions';
|
||||||
import {BindingTarget} from './binding_record';
|
import {BindingTarget} from './binding_record';
|
||||||
import {Locals} from './parser/locals';
|
import {Locals} from './parser/locals';
|
||||||
import {ChangeDetectionStrategy, ChangeDetectorState} from './constants';
|
import {ChangeDetectionStrategy, ChangeDetectorState} from './constants';
|
||||||
@ -15,9 +21,8 @@ import {ObservableWrapper} from 'angular2/src/facade/async';
|
|||||||
var _scope_check: WtfScopeFn = wtfCreateScope(`ChangeDetector#check(ascii id, bool throwOnChange)`);
|
var _scope_check: WtfScopeFn = wtfCreateScope(`ChangeDetector#check(ascii id, bool throwOnChange)`);
|
||||||
|
|
||||||
class _Context {
|
class _Context {
|
||||||
constructor(
|
constructor(public element: any, public componentElement: any, public context: any,
|
||||||
public element: any, public componentElement: any, public context: any, public locals: any,
|
public locals: any, public injector: any, public expression: any) {}
|
||||||
public injector: any, public expression: any) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AbstractChangeDetector<T> implements ChangeDetector {
|
export class AbstractChangeDetector<T> implements ChangeDetector {
|
||||||
@ -39,8 +44,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
dispatcher: ChangeDispatcher;
|
dispatcher: ChangeDispatcher;
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(public id: string, public numberOfPropertyProtoRecords: number,
|
||||||
public id: string, public numberOfPropertyProtoRecords: number,
|
|
||||||
public bindingTargets: BindingTarget[], public directiveIndices: DirectiveIndex[],
|
public bindingTargets: BindingTarget[], public directiveIndices: DirectiveIndex[],
|
||||||
public strategy: ChangeDetectionStrategy) {
|
public strategy: ChangeDetectionStrategy) {
|
||||||
this.ref = new ChangeDetectorRef_(this);
|
this.ref = new ChangeDetectorRef_(this);
|
||||||
@ -75,8 +79,8 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
var c = this.dispatcher.getDebugContext(null, elIndex, null);
|
var c = this.dispatcher.getDebugContext(null, elIndex, null);
|
||||||
var context = isPresent(c) ?
|
var context = isPresent(c) ?
|
||||||
new EventEvaluationErrorContext(
|
new EventEvaluationErrorContext(c.element, c.componentElement, c.context,
|
||||||
c.element, c.componentElement, c.context, c.locals, c.injector) :
|
c.locals, c.injector) :
|
||||||
null;
|
null;
|
||||||
throw new EventEvaluationError(eventName, e, e.stack, context);
|
throw new EventEvaluationError(eventName, e, e.stack, context);
|
||||||
}
|
}
|
||||||
@ -267,8 +271,7 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
var error;
|
var error;
|
||||||
try {
|
try {
|
||||||
var c = this.dispatcher.getDebugContext(null, this._currentBinding().elementIndex, null);
|
var c = this.dispatcher.getDebugContext(null, this._currentBinding().elementIndex, null);
|
||||||
var context = isPresent(c) ? new _Context(
|
var context = isPresent(c) ? new _Context(c.element, c.componentElement, c.context, c.locals,
|
||||||
c.element, c.componentElement, c.context, c.locals,
|
|
||||||
c.injector, this._currentBinding().debug) :
|
c.injector, this._currentBinding().debug) :
|
||||||
null;
|
null;
|
||||||
error = new ChangeDetectionError(this._currentBinding().debug, exception, stack, context);
|
error = new ChangeDetectionError(this._currentBinding().debug, exception, stack, context);
|
||||||
@ -281,8 +284,8 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
throwOnChangeError(oldValue: any, newValue: any): void {
|
throwOnChangeError(oldValue: any, newValue: any): void {
|
||||||
throw new ExpressionChangedAfterItHasBeenCheckedException(
|
throw new ExpressionChangedAfterItHasBeenCheckedException(this._currentBinding().debug,
|
||||||
this._currentBinding().debug, oldValue, newValue, null);
|
oldValue, newValue, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
throwDehydratedError(detail: string): void { throw new DehydratedException(detail); }
|
throwDehydratedError(detail: string): void { throw new DehydratedException(detail); }
|
||||||
|
@ -3,22 +3,21 @@ import {SetterFn} from 'angular2/src/core/reflection/types';
|
|||||||
import {AST} from './parser/ast';
|
import {AST} from './parser/ast';
|
||||||
import {DirectiveIndex, DirectiveRecord} from './directive_record';
|
import {DirectiveIndex, DirectiveRecord} from './directive_record';
|
||||||
|
|
||||||
const DIRECTIVE_LIFECYCLE = 'directiveLifecycle';
|
const DIRECTIVE_LIFECYCLE = "directiveLifecycle";
|
||||||
const BINDING = 'native';
|
const BINDING = "native";
|
||||||
|
|
||||||
const DIRECTIVE = 'directive';
|
const DIRECTIVE = "directive";
|
||||||
const ELEMENT_PROPERTY = 'elementProperty';
|
const ELEMENT_PROPERTY = "elementProperty";
|
||||||
const ELEMENT_ATTRIBUTE = 'elementAttribute';
|
const ELEMENT_ATTRIBUTE = "elementAttribute";
|
||||||
const ELEMENT_CLASS = 'elementClass';
|
const ELEMENT_CLASS = "elementClass";
|
||||||
const ELEMENT_STYLE = 'elementStyle';
|
const ELEMENT_STYLE = "elementStyle";
|
||||||
const TEXT_NODE = 'textNode';
|
const TEXT_NODE = "textNode";
|
||||||
const EVENT = 'event';
|
const EVENT = "event";
|
||||||
const HOST_EVENT = 'hostEvent';
|
const HOST_EVENT = "hostEvent";
|
||||||
|
|
||||||
export class BindingTarget {
|
export class BindingTarget {
|
||||||
constructor(
|
constructor(public mode: string, public elementIndex: number, public name: string,
|
||||||
public mode: string, public elementIndex: number, public name: string, public unit: string,
|
public unit: string, public debug: string) {}
|
||||||
public debug: string) {}
|
|
||||||
|
|
||||||
isDirective(): boolean { return this.mode === DIRECTIVE; }
|
isDirective(): boolean { return this.mode === DIRECTIVE; }
|
||||||
|
|
||||||
@ -34,8 +33,7 @@ export class BindingTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class BindingRecord {
|
export class BindingRecord {
|
||||||
constructor(
|
constructor(public mode: string, public target: BindingTarget, public implicitReceiver: any,
|
||||||
public mode: string, public target: BindingTarget, public implicitReceiver: any,
|
|
||||||
public ast: AST, public setter: SetterFn, public lifecycleEvent: string,
|
public ast: AST, public setter: SetterFn, public lifecycleEvent: string,
|
||||||
public directiveRecord: DirectiveRecord) {}
|
public directiveRecord: DirectiveRecord) {}
|
||||||
|
|
||||||
@ -50,22 +48,21 @@ export class BindingRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static createDirectiveDoCheck(directiveRecord: DirectiveRecord): BindingRecord {
|
static createDirectiveDoCheck(directiveRecord: DirectiveRecord): BindingRecord {
|
||||||
return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, 'DoCheck', directiveRecord);
|
return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, "DoCheck", directiveRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createDirectiveOnInit(directiveRecord: DirectiveRecord): BindingRecord {
|
static createDirectiveOnInit(directiveRecord: DirectiveRecord): BindingRecord {
|
||||||
return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, 'OnInit', directiveRecord);
|
return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, "OnInit", directiveRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createDirectiveOnChanges(directiveRecord: DirectiveRecord): BindingRecord {
|
static createDirectiveOnChanges(directiveRecord: DirectiveRecord): BindingRecord {
|
||||||
return new BindingRecord(
|
return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, "OnChanges",
|
||||||
DIRECTIVE_LIFECYCLE, null, 0, null, null, 'OnChanges', directiveRecord);
|
directiveRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static createForDirective(
|
static createForDirective(ast: AST, propertyName: string, setter: SetterFn,
|
||||||
ast: AST, propertyName: string, setter: SetterFn,
|
|
||||||
directiveRecord: DirectiveRecord): BindingRecord {
|
directiveRecord: DirectiveRecord): BindingRecord {
|
||||||
var elementIndex = directiveRecord.directiveIndex.elementIndex;
|
var elementIndex = directiveRecord.directiveIndex.elementIndex;
|
||||||
var t = new BindingTarget(DIRECTIVE, elementIndex, propertyName, null, ast.toString());
|
var t = new BindingTarget(DIRECTIVE, elementIndex, propertyName, null, ast.toString());
|
||||||
@ -74,14 +71,14 @@ export class BindingRecord {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static createForElementProperty(ast: AST, elementIndex: number, propertyName: string):
|
static createForElementProperty(ast: AST, elementIndex: number,
|
||||||
BindingRecord {
|
propertyName: string): BindingRecord {
|
||||||
var t = new BindingTarget(ELEMENT_PROPERTY, elementIndex, propertyName, null, ast.toString());
|
var t = new BindingTarget(ELEMENT_PROPERTY, elementIndex, propertyName, null, ast.toString());
|
||||||
return new BindingRecord(BINDING, t, 0, ast, null, null, null);
|
return new BindingRecord(BINDING, t, 0, ast, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createForElementAttribute(ast: AST, elementIndex: number, attributeName: string):
|
static createForElementAttribute(ast: AST, elementIndex: number,
|
||||||
BindingRecord {
|
attributeName: string): BindingRecord {
|
||||||
var t = new BindingTarget(ELEMENT_ATTRIBUTE, elementIndex, attributeName, null, ast.toString());
|
var t = new BindingTarget(ELEMENT_ATTRIBUTE, elementIndex, attributeName, null, ast.toString());
|
||||||
return new BindingRecord(BINDING, t, 0, ast, null, null, null);
|
return new BindingRecord(BINDING, t, 0, ast, null, null, null);
|
||||||
}
|
}
|
||||||
@ -91,39 +88,39 @@ export class BindingRecord {
|
|||||||
return new BindingRecord(BINDING, t, 0, ast, null, null, null);
|
return new BindingRecord(BINDING, t, 0, ast, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createForElementStyle(ast: AST, elementIndex: number, styleName: string, unit: string):
|
static createForElementStyle(ast: AST, elementIndex: number, styleName: string,
|
||||||
BindingRecord {
|
unit: string): BindingRecord {
|
||||||
var t = new BindingTarget(ELEMENT_STYLE, elementIndex, styleName, unit, ast.toString());
|
var t = new BindingTarget(ELEMENT_STYLE, elementIndex, styleName, unit, ast.toString());
|
||||||
return new BindingRecord(BINDING, t, 0, ast, null, null, null);
|
return new BindingRecord(BINDING, t, 0, ast, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static createForHostProperty(directiveIndex: DirectiveIndex, ast: AST, propertyName: string):
|
static createForHostProperty(directiveIndex: DirectiveIndex, ast: AST,
|
||||||
BindingRecord {
|
propertyName: string): BindingRecord {
|
||||||
var t = new BindingTarget(
|
var t = new BindingTarget(ELEMENT_PROPERTY, directiveIndex.elementIndex, propertyName, null,
|
||||||
ELEMENT_PROPERTY, directiveIndex.elementIndex, propertyName, null, ast.toString());
|
ast.toString());
|
||||||
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
|
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createForHostAttribute(directiveIndex: DirectiveIndex, ast: AST, attributeName: string):
|
static createForHostAttribute(directiveIndex: DirectiveIndex, ast: AST,
|
||||||
BindingRecord {
|
attributeName: string): BindingRecord {
|
||||||
var t = new BindingTarget(
|
var t = new BindingTarget(ELEMENT_ATTRIBUTE, directiveIndex.elementIndex, attributeName, null,
|
||||||
ELEMENT_ATTRIBUTE, directiveIndex.elementIndex, attributeName, null, ast.toString());
|
ast.toString());
|
||||||
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
|
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createForHostClass(directiveIndex: DirectiveIndex, ast: AST, className: string):
|
static createForHostClass(directiveIndex: DirectiveIndex, ast: AST,
|
||||||
BindingRecord {
|
className: string): BindingRecord {
|
||||||
var t = new BindingTarget(
|
var t = new BindingTarget(ELEMENT_CLASS, directiveIndex.elementIndex, className, null,
|
||||||
ELEMENT_CLASS, directiveIndex.elementIndex, className, null, ast.toString());
|
ast.toString());
|
||||||
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
|
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createForHostStyle(
|
static createForHostStyle(directiveIndex: DirectiveIndex, ast: AST, styleName: string,
|
||||||
directiveIndex: DirectiveIndex, ast: AST, styleName: string, unit: string): BindingRecord {
|
unit: string): BindingRecord {
|
||||||
var t = new BindingTarget(
|
var t = new BindingTarget(ELEMENT_STYLE, directiveIndex.elementIndex, styleName, unit,
|
||||||
ELEMENT_STYLE, directiveIndex.elementIndex, styleName, unit, ast.toString());
|
ast.toString());
|
||||||
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
|
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,8 +138,8 @@ export class BindingRecord {
|
|||||||
return new BindingRecord(EVENT, t, 0, ast, null, null, null);
|
return new BindingRecord(EVENT, t, 0, ast, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static createForHostEvent(ast: AST, eventName: string, directiveRecord: DirectiveRecord):
|
static createForHostEvent(ast: AST, eventName: string,
|
||||||
BindingRecord {
|
directiveRecord: DirectiveRecord): BindingRecord {
|
||||||
var directiveIndex = directiveRecord.directiveIndex;
|
var directiveIndex = directiveRecord.directiveIndex;
|
||||||
var t =
|
var t =
|
||||||
new BindingTarget(HOST_EVENT, directiveIndex.elementIndex, eventName, null, ast.toString());
|
new BindingTarget(HOST_EVENT, directiveIndex.elementIndex, eventName, null, ast.toString());
|
||||||
|
@ -1,19 +1,46 @@
|
|||||||
import {IterableDiffers, IterableDifferFactory} from './differs/iterable_differs';
|
import {IterableDiffers, IterableDifferFactory} from './differs/iterable_differs';
|
||||||
import {DefaultIterableDifferFactory} from './differs/default_iterable_differ';
|
import {DefaultIterableDifferFactory} from './differs/default_iterable_differ';
|
||||||
import {KeyValueDiffers, KeyValueDifferFactory} from './differs/keyvalue_differs';
|
import {KeyValueDiffers, KeyValueDifferFactory} from './differs/keyvalue_differs';
|
||||||
import {DefaultKeyValueDifferFactory, KeyValueChangeRecord} from './differs/default_keyvalue_differ';
|
import {
|
||||||
|
DefaultKeyValueDifferFactory,
|
||||||
|
KeyValueChangeRecord
|
||||||
|
} from './differs/default_keyvalue_differ';
|
||||||
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
import {CONST_EXPR} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
export {DefaultKeyValueDifferFactory, KeyValueChangeRecord} from './differs/default_keyvalue_differ';
|
export {
|
||||||
export {DefaultIterableDifferFactory, CollectionChangeRecord} from './differs/default_iterable_differ';
|
DefaultKeyValueDifferFactory,
|
||||||
export {ASTWithSource, AST, AstTransformer, PropertyRead, LiteralArray, ImplicitReceiver} from './parser/ast';
|
KeyValueChangeRecord
|
||||||
|
} from './differs/default_keyvalue_differ';
|
||||||
|
export {
|
||||||
|
DefaultIterableDifferFactory,
|
||||||
|
CollectionChangeRecord
|
||||||
|
} from './differs/default_iterable_differ';
|
||||||
|
export {
|
||||||
|
ASTWithSource,
|
||||||
|
AST,
|
||||||
|
AstTransformer,
|
||||||
|
PropertyRead,
|
||||||
|
LiteralArray,
|
||||||
|
ImplicitReceiver
|
||||||
|
} from './parser/ast';
|
||||||
|
|
||||||
export {Lexer} from './parser/lexer';
|
export {Lexer} from './parser/lexer';
|
||||||
export {Parser} from './parser/parser';
|
export {Parser} from './parser/parser';
|
||||||
export {Locals} from './parser/locals';
|
export {Locals} from './parser/locals';
|
||||||
|
|
||||||
export {DehydratedException, ExpressionChangedAfterItHasBeenCheckedException, ChangeDetectionError} from './exceptions';
|
export {
|
||||||
export {ProtoChangeDetector, ChangeDetector, ChangeDispatcher, ChangeDetectorDefinition, DebugContext, ChangeDetectorGenConfig} from './interfaces';
|
DehydratedException,
|
||||||
|
ExpressionChangedAfterItHasBeenCheckedException,
|
||||||
|
ChangeDetectionError
|
||||||
|
} from './exceptions';
|
||||||
|
export {
|
||||||
|
ProtoChangeDetector,
|
||||||
|
ChangeDetector,
|
||||||
|
ChangeDispatcher,
|
||||||
|
ChangeDetectorDefinition,
|
||||||
|
DebugContext,
|
||||||
|
ChangeDetectorGenConfig
|
||||||
|
} from './interfaces';
|
||||||
export {ChangeDetectionStrategy, CHANGE_DETECTION_STRATEGY_VALUES} from './constants';
|
export {ChangeDetectionStrategy, CHANGE_DETECTION_STRATEGY_VALUES} from './constants';
|
||||||
export {DynamicProtoChangeDetector} from './proto_change_detector';
|
export {DynamicProtoChangeDetector} from './proto_change_detector';
|
||||||
export {JitProtoChangeDetector} from './jit_proto_change_detector';
|
export {JitProtoChangeDetector} from './jit_proto_change_detector';
|
||||||
@ -21,7 +48,12 @@ export {BindingRecord, BindingTarget} from './binding_record';
|
|||||||
export {DirectiveIndex, DirectiveRecord} from './directive_record';
|
export {DirectiveIndex, DirectiveRecord} from './directive_record';
|
||||||
export {DynamicChangeDetector} from './dynamic_change_detector';
|
export {DynamicChangeDetector} from './dynamic_change_detector';
|
||||||
export {ChangeDetectorRef} from './change_detector_ref';
|
export {ChangeDetectorRef} from './change_detector_ref';
|
||||||
export {IterableDiffers, IterableDiffer, IterableDifferFactory, TrackByFn} from './differs/iterable_differs';
|
export {
|
||||||
|
IterableDiffers,
|
||||||
|
IterableDiffer,
|
||||||
|
IterableDifferFactory,
|
||||||
|
TrackByFn
|
||||||
|
} from './differs/iterable_differs';
|
||||||
export {KeyValueDiffers, KeyValueDiffer, KeyValueDifferFactory} from './differs/keyvalue_differs';
|
export {KeyValueDiffers, KeyValueDiffer, KeyValueDifferFactory} from './differs/keyvalue_differs';
|
||||||
export {PipeTransform} from './pipe_transform';
|
export {PipeTransform} from './pipe_transform';
|
||||||
export {WrappedValue, SimpleChange} from './change_detection_util';
|
export {WrappedValue, SimpleChange} from './change_detection_util';
|
||||||
|
@ -25,8 +25,8 @@ import {createPropertyRecords, createEventRecords} from './proto_change_detector
|
|||||||
* `angular2.transform.template_compiler.change_detector_codegen` library. If you make updates
|
* `angular2.transform.template_compiler.change_detector_codegen` library. If you make updates
|
||||||
* here, please make equivalent changes there.
|
* here, please make equivalent changes there.
|
||||||
*/
|
*/
|
||||||
const IS_CHANGED_LOCAL = 'isChanged';
|
const IS_CHANGED_LOCAL = "isChanged";
|
||||||
const CHANGES_LOCAL = 'changes';
|
const CHANGES_LOCAL = "changes";
|
||||||
|
|
||||||
export class ChangeDetectorJITGenerator {
|
export class ChangeDetectorJITGenerator {
|
||||||
private _logic: CodegenLogicUtil;
|
private _logic: CodegenLogicUtil;
|
||||||
@ -41,9 +41,9 @@ export class ChangeDetectorJITGenerator {
|
|||||||
private genConfig: ChangeDetectorGenConfig;
|
private genConfig: ChangeDetectorGenConfig;
|
||||||
typeName: string;
|
typeName: string;
|
||||||
|
|
||||||
constructor(
|
constructor(definition: ChangeDetectorDefinition, private changeDetectionUtilVarName: string,
|
||||||
definition: ChangeDetectorDefinition, private changeDetectionUtilVarName: string,
|
private abstractChangeDetectorVarName: string,
|
||||||
private abstractChangeDetectorVarName: string, private changeDetectorStateVarName: string) {
|
private changeDetectorStateVarName: string) {
|
||||||
var propertyBindingRecords = createPropertyRecords(definition);
|
var propertyBindingRecords = createPropertyRecords(definition);
|
||||||
var eventBindingRecords = createEventRecords(definition);
|
var eventBindingRecords = createEventRecords(definition);
|
||||||
var propertyBindingTargets = definition.bindingRecords.map(b => b.target);
|
var propertyBindingTargets = definition.bindingRecords.map(b => b.target);
|
||||||
@ -55,10 +55,10 @@ export class ChangeDetectorJITGenerator {
|
|||||||
this.propertyBindingTargets = propertyBindingTargets;
|
this.propertyBindingTargets = propertyBindingTargets;
|
||||||
this.eventBindings = eventBindingRecords;
|
this.eventBindings = eventBindingRecords;
|
||||||
this.directiveRecords = definition.directiveRecords;
|
this.directiveRecords = definition.directiveRecords;
|
||||||
this._names = new CodegenNameUtil(
|
this._names = new CodegenNameUtil(this.records, this.eventBindings, this.directiveRecords,
|
||||||
this.records, this.eventBindings, this.directiveRecords, this.changeDetectionUtilVarName);
|
this.changeDetectionUtilVarName);
|
||||||
this._logic = new CodegenLogicUtil(
|
this._logic = new CodegenLogicUtil(this._names, this.changeDetectionUtilVarName,
|
||||||
this._names, this.changeDetectionUtilVarName, this.changeDetectorStateVarName);
|
this.changeDetectorStateVarName);
|
||||||
this.typeName = sanitizeName(`ChangeDetector_${this.id}`);
|
this.typeName = sanitizeName(`ChangeDetector_${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,10 +69,9 @@ export class ChangeDetectorJITGenerator {
|
|||||||
return new ${this.typeName}();
|
return new ${this.typeName}();
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
return new Function(
|
return new Function(this.abstractChangeDetectorVarName, this.changeDetectionUtilVarName,
|
||||||
this.abstractChangeDetectorVarName, this.changeDetectionUtilVarName,
|
this.changeDetectorStateVarName, factorySource)(
|
||||||
this.changeDetectorStateVarName,
|
AbstractChangeDetector, ChangeDetectionUtil, ChangeDetectorState);
|
||||||
factorySource)(AbstractChangeDetector, ChangeDetectionUtil, ChangeDetectorState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
generateSource(): string {
|
generateSource(): string {
|
||||||
@ -113,8 +112,8 @@ export class ChangeDetectorJITGenerator {
|
|||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_genPropertyBindingTargets(): string {
|
_genPropertyBindingTargets(): string {
|
||||||
var targets = this._logic.genPropertyBindingTargets(
|
var targets = this._logic.genPropertyBindingTargets(this.propertyBindingTargets,
|
||||||
this.propertyBindingTargets, this.genConfig.genDebugInfo);
|
this.genConfig.genDebugInfo);
|
||||||
return `${this.typeName}.gen_propertyBindingTargets = ${targets};`;
|
return `${this.typeName}.gen_propertyBindingTargets = ${targets};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +126,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_maybeGenHandleEventInternal(): string {
|
_maybeGenHandleEventInternal(): string {
|
||||||
if (this.eventBindings.length > 0) {
|
if (this.eventBindings.length > 0) {
|
||||||
var handlers = this.eventBindings.map(eb => this._genEventBinding(eb)).join('\n');
|
var handlers = this.eventBindings.map(eb => this._genEventBinding(eb)).join("\n");
|
||||||
return `
|
return `
|
||||||
${this.typeName}.prototype.handleEventInternal = function(eventName, elIndex, locals) {
|
${this.typeName}.prototype.handleEventInternal = function(eventName, elIndex, locals) {
|
||||||
var ${this._names.getPreventDefaultAccesor()} = false;
|
var ${this._names.getPreventDefaultAccesor()} = false;
|
||||||
@ -184,7 +183,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
_genMarkPathToRootAsCheckOnce(r: ProtoRecord): string {
|
_genMarkPathToRootAsCheckOnce(r: ProtoRecord): string {
|
||||||
var br = r.bindingRecord;
|
var br = r.bindingRecord;
|
||||||
if (br.isDefaultChangeDetection()) {
|
if (br.isDefaultChangeDetection()) {
|
||||||
return '';
|
return "";
|
||||||
} else {
|
} else {
|
||||||
return `${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markPathToRootAsCheckOnce();`;
|
return `${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markPathToRootAsCheckOnce();`;
|
||||||
}
|
}
|
||||||
@ -226,7 +225,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
_maybeGenAfterContentLifecycleCallbacks(): string {
|
_maybeGenAfterContentLifecycleCallbacks(): string {
|
||||||
var notifications = this._logic.genContentLifecycleCallbacks(this.directiveRecords);
|
var notifications = this._logic.genContentLifecycleCallbacks(this.directiveRecords);
|
||||||
if (notifications.length > 0) {
|
if (notifications.length > 0) {
|
||||||
var directiveNotifications = notifications.join('\n');
|
var directiveNotifications = notifications.join("\n");
|
||||||
return `
|
return `
|
||||||
${this.typeName}.prototype.afterContentLifecycleCallbacksInternal = function() {
|
${this.typeName}.prototype.afterContentLifecycleCallbacksInternal = function() {
|
||||||
${directiveNotifications}
|
${directiveNotifications}
|
||||||
@ -241,7 +240,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
_maybeGenAfterViewLifecycleCallbacks(): string {
|
_maybeGenAfterViewLifecycleCallbacks(): string {
|
||||||
var notifications = this._logic.genViewLifecycleCallbacks(this.directiveRecords);
|
var notifications = this._logic.genViewLifecycleCallbacks(this.directiveRecords);
|
||||||
if (notifications.length > 0) {
|
if (notifications.length > 0) {
|
||||||
var directiveNotifications = notifications.join('\n');
|
var directiveNotifications = notifications.join("\n");
|
||||||
return `
|
return `
|
||||||
${this.typeName}.prototype.afterViewLifecycleCallbacksInternal = function() {
|
${this.typeName}.prototype.afterViewLifecycleCallbacksInternal = function() {
|
||||||
${directiveNotifications}
|
${directiveNotifications}
|
||||||
@ -283,7 +282,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
codes.push(code);
|
codes.push(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return codes.join('\n');
|
return codes.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
@ -316,11 +315,11 @@ export class ChangeDetectorJITGenerator {
|
|||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_genDirectiveLifecycle(r: ProtoRecord): string {
|
_genDirectiveLifecycle(r: ProtoRecord): string {
|
||||||
if (r.name === 'DoCheck') {
|
if (r.name === "DoCheck") {
|
||||||
return this._genOnCheck(r);
|
return this._genOnCheck(r);
|
||||||
} else if (r.name === 'OnInit') {
|
} else if (r.name === "OnInit") {
|
||||||
return this._genOnInit(r);
|
return this._genOnInit(r);
|
||||||
} else if (r.name === 'OnChanges') {
|
} else if (r.name === "OnChanges") {
|
||||||
return this._genOnChange(r);
|
return this._genOnChange(r);
|
||||||
} else {
|
} else {
|
||||||
throw new BaseException(`Unknown lifecycle event '${r.name}'`);
|
throw new BaseException(`Unknown lifecycle event '${r.name}'`);
|
||||||
@ -330,7 +329,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_genPipeCheck(r: ProtoRecord): string {
|
_genPipeCheck(r: ProtoRecord): string {
|
||||||
var context = this._names.getLocalName(r.contextIndex);
|
var context = this._names.getLocalName(r.contextIndex);
|
||||||
var argString = r.args.map((arg) => this._names.getLocalName(arg)).join(', ');
|
var argString = r.args.map((arg) => this._names.getLocalName(arg)).join(", ");
|
||||||
|
|
||||||
var oldValue = this._names.getFieldName(r.selfIndex);
|
var oldValue = this._names.getFieldName(r.selfIndex);
|
||||||
var newValue = this._names.getLocalName(r.selfIndex);
|
var newValue = this._names.getLocalName(r.selfIndex);
|
||||||
@ -390,7 +389,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
var genCode = r.shouldBeChecked() ? `${read}${check}` : read;
|
var genCode = r.shouldBeChecked() ? `${read}${check}` : read;
|
||||||
|
|
||||||
if (r.isPureFunction()) {
|
if (r.isPureFunction()) {
|
||||||
var condition = r.args.map((a) => this._names.getChangeName(a)).join(' || ');
|
var condition = r.args.map((a) => this._names.getChangeName(a)).join(" || ");
|
||||||
if (r.isUsedByOtherRecord()) {
|
if (r.isUsedByOtherRecord()) {
|
||||||
return `if (${condition}) { ${genCode} } else { ${newValue} = ${oldValue}; }`;
|
return `if (${condition}) { ${genCode} } else { ${newValue} = ${oldValue}; }`;
|
||||||
} else {
|
} else {
|
||||||
@ -408,10 +407,10 @@ export class ChangeDetectorJITGenerator {
|
|||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_genUpdateDirectiveOrElement(r: ProtoRecord): string {
|
_genUpdateDirectiveOrElement(r: ProtoRecord): string {
|
||||||
if (!r.lastInBinding) return '';
|
if (!r.lastInBinding) return "";
|
||||||
|
|
||||||
var newValue = this._names.getLocalName(r.selfIndex);
|
var newValue = this._names.getLocalName(r.selfIndex);
|
||||||
var notifyDebug = this.genConfig.logBindingUpdate ? `this.logBindingUpdate(${newValue});` : '';
|
var notifyDebug = this.genConfig.logBindingUpdate ? `this.logBindingUpdate(${newValue});` : "";
|
||||||
|
|
||||||
var br = r.bindingRecord;
|
var br = r.bindingRecord;
|
||||||
if (br.target.isDirective()) {
|
if (br.target.isDirective()) {
|
||||||
@ -447,7 +446,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
_genAddToChanges(r: ProtoRecord): string {
|
_genAddToChanges(r: ProtoRecord): string {
|
||||||
var newValue = this._names.getLocalName(r.selfIndex);
|
var newValue = this._names.getLocalName(r.selfIndex);
|
||||||
var oldValue = this._names.getFieldName(r.selfIndex);
|
var oldValue = this._names.getFieldName(r.selfIndex);
|
||||||
if (!r.bindingRecord.callOnChanges()) return '';
|
if (!r.bindingRecord.callOnChanges()) return "";
|
||||||
return `${CHANGES_LOCAL} = this.addChange(${CHANGES_LOCAL}, ${oldValue}, ${newValue});`;
|
return `${CHANGES_LOCAL} = this.addChange(${CHANGES_LOCAL}, ${oldValue}, ${newValue});`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,7 +461,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_maybeGenLastInDirective(r: ProtoRecord): string {
|
_maybeGenLastInDirective(r: ProtoRecord): string {
|
||||||
if (!r.lastInDirective) return '';
|
if (!r.lastInDirective) return "";
|
||||||
return `
|
return `
|
||||||
${CHANGES_LOCAL} = null;
|
${CHANGES_LOCAL} = null;
|
||||||
${this._genNotifyOnPushDetectors(r)}
|
${this._genNotifyOnPushDetectors(r)}
|
||||||
@ -491,7 +490,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_genNotifyOnPushDetectors(r: ProtoRecord): string {
|
_genNotifyOnPushDetectors(r: ProtoRecord): string {
|
||||||
var br = r.bindingRecord;
|
var br = r.bindingRecord;
|
||||||
if (!r.lastInDirective || br.isDefaultChangeDetection()) return '';
|
if (!r.lastInDirective || br.isDefaultChangeDetection()) return "";
|
||||||
var retVal = `
|
var retVal = `
|
||||||
if(${IS_CHANGED_LOCAL}) {
|
if(${IS_CHANGED_LOCAL}) {
|
||||||
${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markAsCheckOnce();
|
${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markAsCheckOnce();
|
||||||
|
@ -1,6 +1,20 @@
|
|||||||
import {CONST_EXPR, isPresent, isBlank, Type, StringWrapper, looseIdentical, isPrimitive} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
CONST_EXPR,
|
||||||
|
isPresent,
|
||||||
|
isBlank,
|
||||||
|
Type,
|
||||||
|
StringWrapper,
|
||||||
|
looseIdentical,
|
||||||
|
isPrimitive
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import {ListWrapper, MapWrapper, StringMapWrapper, isListLikeIterable, areIterablesEqual} from 'angular2/src/facade/collection';
|
import {
|
||||||
|
ListWrapper,
|
||||||
|
MapWrapper,
|
||||||
|
StringMapWrapper,
|
||||||
|
isListLikeIterable,
|
||||||
|
areIterablesEqual
|
||||||
|
} from 'angular2/src/facade/collection';
|
||||||
import {ProtoRecord} from './proto_record';
|
import {ProtoRecord} from './proto_record';
|
||||||
import {ChangeDetectionStrategy, isDefaultChangeDetectionStrategy} from './constants';
|
import {ChangeDetectionStrategy, isDefaultChangeDetectionStrategy} from './constants';
|
||||||
import {implementsOnDestroy} from './pipe_lifecycle_reflector';
|
import {implementsOnDestroy} from './pipe_lifecycle_reflector';
|
||||||
@ -38,7 +52,10 @@ export class WrappedValue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _wrappedValues = [
|
var _wrappedValues = [
|
||||||
new WrappedValue(null), new WrappedValue(null), new WrappedValue(null), new WrappedValue(null),
|
new WrappedValue(null),
|
||||||
|
new WrappedValue(null),
|
||||||
|
new WrappedValue(null),
|
||||||
|
new WrappedValue(null),
|
||||||
new WrappedValue(null)
|
new WrappedValue(null)
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -166,8 +183,7 @@ export class ChangeDetectionUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bindingTarget(
|
static bindingTarget(mode: string, elementIndex: number, name: string, unit: string,
|
||||||
mode: string, elementIndex: number, name: string, unit: string,
|
|
||||||
debug: string): BindingTarget {
|
debug: string): BindingTarget {
|
||||||
return new BindingTarget(mode, elementIndex, name, unit, debug);
|
return new BindingTarget(mode, elementIndex, name, unit, debug);
|
||||||
}
|
}
|
||||||
@ -182,8 +198,8 @@ export class ChangeDetectionUtil {
|
|||||||
if (isListLikeIterable(a) && isListLikeIterable(b)) {
|
if (isListLikeIterable(a) && isListLikeIterable(b)) {
|
||||||
return areIterablesEqual(a, b, ChangeDetectionUtil.devModeEqual);
|
return areIterablesEqual(a, b, ChangeDetectionUtil.devModeEqual);
|
||||||
|
|
||||||
} else if (
|
} else if (!isListLikeIterable(a) && !isPrimitive(a) && !isListLikeIterable(b) &&
|
||||||
!isListLikeIterable(a) && !isPrimitive(a) && !isListLikeIterable(b) && !isPrimitive(b)) {
|
!isPrimitive(b)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -90,8 +90,7 @@ function _optimizeSkips(srcRecords: ProtoRecord[]): ProtoRecord[] {
|
|||||||
/**
|
/**
|
||||||
* Add a new record or re-use one of the existing records.
|
* Add a new record or re-use one of the existing records.
|
||||||
*/
|
*/
|
||||||
function _mayBeAddRecord(
|
function _mayBeAddRecord(record: ProtoRecord, dstRecords: ProtoRecord[], excludedIdxs: number[],
|
||||||
record: ProtoRecord, dstRecords: ProtoRecord[], excludedIdxs: number[],
|
|
||||||
excluded: boolean): ProtoRecord {
|
excluded: boolean): ProtoRecord {
|
||||||
let match = _findFirstMatch(record, dstRecords, excludedIdxs);
|
let match = _findFirstMatch(record, dstRecords, excludedIdxs);
|
||||||
|
|
||||||
@ -119,8 +118,8 @@ function _mayBeAddRecord(
|
|||||||
/**
|
/**
|
||||||
* Returns the first `ProtoRecord` that matches the record.
|
* Returns the first `ProtoRecord` that matches the record.
|
||||||
*/
|
*/
|
||||||
function _findFirstMatch(
|
function _findFirstMatch(record: ProtoRecord, dstRecords: ProtoRecord[],
|
||||||
record: ProtoRecord, dstRecords: ProtoRecord[], excludedIdxs: number[]): ProtoRecord {
|
excludedIdxs: number[]): ProtoRecord {
|
||||||
return dstRecords.find(
|
return dstRecords.find(
|
||||||
// TODO(vicb): optimize excludedIdxs.indexOf (sorted array)
|
// TODO(vicb): optimize excludedIdxs.indexOf (sorted array)
|
||||||
rr => excludedIdxs.indexOf(rr.selfIndex) == -1 && rr.mode !== RecordType.DirectiveLifecycle &&
|
rr => excludedIdxs.indexOf(rr.selfIndex) == -1 && rr.mode !== RecordType.DirectiveLifecycle &&
|
||||||
@ -136,16 +135,16 @@ function _findFirstMatch(
|
|||||||
* - the context,
|
* - the context,
|
||||||
* - self
|
* - self
|
||||||
*/
|
*/
|
||||||
function _cloneAndUpdateIndexes(
|
function _cloneAndUpdateIndexes(record: ProtoRecord, dstRecords: ProtoRecord[],
|
||||||
record: ProtoRecord, dstRecords: ProtoRecord[], indexMap: Map<number, number>): ProtoRecord {
|
indexMap: Map<number, number>): ProtoRecord {
|
||||||
let args = record.args.map(src => _srcToDstSelfIndex(indexMap, src));
|
let args = record.args.map(src => _srcToDstSelfIndex(indexMap, src));
|
||||||
let contextIndex = _srcToDstSelfIndex(indexMap, record.contextIndex);
|
let contextIndex = _srcToDstSelfIndex(indexMap, record.contextIndex);
|
||||||
let selfIndex = dstRecords.length + 1;
|
let selfIndex = dstRecords.length + 1;
|
||||||
|
|
||||||
return new ProtoRecord(
|
return new ProtoRecord(record.mode, record.name, record.funcOrValue, args, record.fixedArgs,
|
||||||
record.mode, record.name, record.funcOrValue, args, record.fixedArgs, contextIndex,
|
contextIndex, record.directiveIndex, selfIndex, record.bindingRecord,
|
||||||
record.directiveIndex, selfIndex, record.bindingRecord, record.lastInBinding,
|
record.lastInBinding, record.lastInDirective,
|
||||||
record.lastInDirective, record.argumentToPureFunction, record.referencedBySelf,
|
record.argumentToPureFunction, record.referencedBySelf,
|
||||||
record.propertyBindingIndex);
|
record.propertyBindingIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,9 +158,9 @@ function _srcToDstSelfIndex(indexMap: Map<number, number>, srcIdx: number): numb
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _createSelfRecord(r: ProtoRecord, contextIndex: number, selfIndex: number): ProtoRecord {
|
function _createSelfRecord(r: ProtoRecord, contextIndex: number, selfIndex: number): ProtoRecord {
|
||||||
return new ProtoRecord(
|
return new ProtoRecord(RecordType.Self, "self", null, [], r.fixedArgs, contextIndex,
|
||||||
RecordType.Self, 'self', null, [], r.fixedArgs, contextIndex, r.directiveIndex, selfIndex,
|
r.directiveIndex, selfIndex, r.bindingRecord, r.lastInBinding,
|
||||||
r.bindingRecord, r.lastInBinding, r.lastInDirective, false, false, r.propertyBindingIndex);
|
r.lastInDirective, false, false, r.propertyBindingIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _haveSameDirIndex(a: ProtoRecord, b: ProtoRecord): boolean {
|
function _haveSameDirIndex(a: ProtoRecord, b: ProtoRecord): boolean {
|
||||||
|
@ -10,8 +10,7 @@ import {BaseException} from 'angular2/src/facade/exceptions';
|
|||||||
* Class responsible for providing change detection logic for change detector classes.
|
* Class responsible for providing change detection logic for change detector classes.
|
||||||
*/
|
*/
|
||||||
export class CodegenLogicUtil {
|
export class CodegenLogicUtil {
|
||||||
constructor(
|
constructor(private _names: CodegenNameUtil, private _utilName: string,
|
||||||
private _names: CodegenNameUtil, private _utilName: string,
|
|
||||||
private _changeDetectorStateName: string) {}
|
private _changeDetectorStateName: string) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -19,8 +18,8 @@ export class CodegenLogicUtil {
|
|||||||
* value of the record. Used by property bindings.
|
* value of the record. Used by property bindings.
|
||||||
*/
|
*/
|
||||||
genPropertyBindingEvalValue(protoRec: ProtoRecord): string {
|
genPropertyBindingEvalValue(protoRec: ProtoRecord): string {
|
||||||
return this._genEvalValue(
|
return this._genEvalValue(protoRec, idx => this._names.getLocalName(idx),
|
||||||
protoRec, idx => this._names.getLocalName(idx), this._names.getLocalsAccessorName());
|
this._names.getLocalsAccessorName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,16 +27,16 @@ export class CodegenLogicUtil {
|
|||||||
* value of the record. Used by event bindings.
|
* value of the record. Used by event bindings.
|
||||||
*/
|
*/
|
||||||
genEventBindingEvalValue(eventRecord: any, protoRec: ProtoRecord): string {
|
genEventBindingEvalValue(eventRecord: any, protoRec: ProtoRecord): string {
|
||||||
return this._genEvalValue(
|
return this._genEvalValue(protoRec, idx => this._names.getEventLocalName(eventRecord, idx),
|
||||||
protoRec, idx => this._names.getEventLocalName(eventRecord, idx), 'locals');
|
"locals");
|
||||||
}
|
}
|
||||||
|
|
||||||
private _genEvalValue(protoRec: ProtoRecord, getLocalName: Function, localsAccessor: string):
|
private _genEvalValue(protoRec: ProtoRecord, getLocalName: Function,
|
||||||
string {
|
localsAccessor: string): string {
|
||||||
var context = (protoRec.contextIndex == -1) ?
|
var context = (protoRec.contextIndex == -1) ?
|
||||||
this._names.getDirectiveName(protoRec.directiveIndex) :
|
this._names.getDirectiveName(protoRec.directiveIndex) :
|
||||||
getLocalName(protoRec.contextIndex);
|
getLocalName(protoRec.contextIndex);
|
||||||
var argString = protoRec.args.map(arg => getLocalName(arg)).join(', ');
|
var argString = protoRec.args.map(arg => getLocalName(arg)).join(", ");
|
||||||
|
|
||||||
var rhs: string;
|
var rhs: string;
|
||||||
switch (protoRec.mode) {
|
switch (protoRec.mode) {
|
||||||
@ -109,12 +108,12 @@ export class CodegenLogicUtil {
|
|||||||
return `${getLocalName(protoRec.selfIndex)} = ${rhs};`;
|
return `${getLocalName(protoRec.selfIndex)} = ${rhs};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
genPropertyBindingTargets(propertyBindingTargets: BindingTarget[], genDebugInfo: boolean):
|
genPropertyBindingTargets(propertyBindingTargets: BindingTarget[],
|
||||||
string {
|
genDebugInfo: boolean): string {
|
||||||
var bs = propertyBindingTargets.map(b => {
|
var bs = propertyBindingTargets.map(b => {
|
||||||
if (isBlank(b)) return 'null';
|
if (isBlank(b)) return "null";
|
||||||
|
|
||||||
var debug = genDebugInfo ? codify(b.debug) : 'null';
|
var debug = genDebugInfo ? codify(b.debug) : "null";
|
||||||
return `${this._utilName}.bindingTarget(${codify(b.mode)}, ${b.elementIndex}, ${codify(b.name)}, ${codify(b.unit)}, ${debug})`;
|
return `${this._utilName}.bindingTarget(${codify(b.mode)}, ${b.elementIndex}, ${codify(b.name)}, ${codify(b.unit)}, ${debug})`;
|
||||||
});
|
});
|
||||||
return `[${bs.join(", ")}]`;
|
return `[${bs.join(", ")}]`;
|
||||||
@ -166,7 +165,7 @@ export class CodegenLogicUtil {
|
|||||||
res.unshift(`${statementStart} = new Array(${outputCount});`);
|
res.unshift(`${statementStart} = new Array(${outputCount});`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res.join('\n');
|
return res.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
genDirectivesOnDestroy(directiveRecords: DirectiveRecord[]): string {
|
genDirectivesOnDestroy(directiveRecords: DirectiveRecord[]): string {
|
||||||
@ -178,7 +177,7 @@ export class CodegenLogicUtil {
|
|||||||
res.push(`${dirVarName}.ngOnDestroy();`);
|
res.push(`${dirVarName}.ngOnDestroy();`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res.join('\n');
|
return res.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private _genEventHandler(boundElementIndex: number, eventName: string): string {
|
private _genEventHandler(boundElementIndex: number, eventName: string): string {
|
||||||
@ -200,7 +199,7 @@ export class CodegenLogicUtil {
|
|||||||
`${this._names.getDetectorName(r.directiveIndex)} = this.getDetectorFor(directives, ${i});`);
|
`${this._names.getDetectorName(r.directiveIndex)} = this.getDetectorFor(directives, ${i});`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res.join('\n');
|
return res.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
genContentLifecycleCallbacks(directiveRecords: DirectiveRecord[]): string[] {
|
genContentLifecycleCallbacks(directiveRecords: DirectiveRecord[]): string[] {
|
||||||
|
@ -8,16 +8,16 @@ import {EventBinding} from './event_binding';
|
|||||||
|
|
||||||
// The names of these fields must be kept in sync with abstract_change_detector.ts or change
|
// The names of these fields must be kept in sync with abstract_change_detector.ts or change
|
||||||
// detection will fail.
|
// detection will fail.
|
||||||
const _STATE_ACCESSOR = 'state';
|
const _STATE_ACCESSOR = "state";
|
||||||
const _CONTEXT_ACCESSOR = 'context';
|
const _CONTEXT_ACCESSOR = "context";
|
||||||
const _PROP_BINDING_INDEX = 'propertyBindingIndex';
|
const _PROP_BINDING_INDEX = "propertyBindingIndex";
|
||||||
const _DIRECTIVES_ACCESSOR = 'directiveIndices';
|
const _DIRECTIVES_ACCESSOR = "directiveIndices";
|
||||||
const _DISPATCHER_ACCESSOR = 'dispatcher';
|
const _DISPATCHER_ACCESSOR = "dispatcher";
|
||||||
const _LOCALS_ACCESSOR = 'locals';
|
const _LOCALS_ACCESSOR = "locals";
|
||||||
const _MODE_ACCESSOR = 'mode';
|
const _MODE_ACCESSOR = "mode";
|
||||||
const _PIPES_ACCESSOR = 'pipes';
|
const _PIPES_ACCESSOR = "pipes";
|
||||||
const _PROTOS_ACCESSOR = 'protos';
|
const _PROTOS_ACCESSOR = "protos";
|
||||||
export const CONTEXT_ACCESSOR = 'context';
|
export const CONTEXT_ACCESSOR = "context";
|
||||||
|
|
||||||
// `context` is always first.
|
// `context` is always first.
|
||||||
export const CONTEXT_INDEX = 0;
|
export const CONTEXT_INDEX = 0;
|
||||||
@ -47,8 +47,7 @@ export class CodegenNameUtil {
|
|||||||
/** @internal */
|
/** @internal */
|
||||||
_sanitizedEventNames = new Map<EventBinding, string[]>();
|
_sanitizedEventNames = new Map<EventBinding, string[]>();
|
||||||
|
|
||||||
constructor(
|
constructor(private _records: ProtoRecord[], private _eventBindings: EventBinding[],
|
||||||
private _records: ProtoRecord[], private _eventBindings: EventBinding[],
|
|
||||||
private _directiveRecords: any[], private _utilName: string) {
|
private _directiveRecords: any[], private _utilName: string) {
|
||||||
this._sanitizedNames = ListWrapper.createFixedSize(this._records.length + 1);
|
this._sanitizedNames = ListWrapper.createFixedSize(this._records.length + 1);
|
||||||
this._sanitizedNames[CONTEXT_INDEX] = CONTEXT_ACCESSOR;
|
this._sanitizedNames[CONTEXT_INDEX] = CONTEXT_ACCESSOR;
|
||||||
@ -133,7 +132,7 @@ export class CodegenNameUtil {
|
|||||||
return res.length > 1 ? `var ${res.join(',')};` : '';
|
return res.length > 1 ? `var ${res.join(',')};` : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
getPreventDefaultAccesor(): string { return 'preventDefault'; }
|
getPreventDefaultAccesor(): string { return "preventDefault"; }
|
||||||
|
|
||||||
getFieldCount(): number { return this._sanitizedNames.length; }
|
getFieldCount(): number { return this._sanitizedNames.length; }
|
||||||
|
|
||||||
|
@ -68,20 +68,25 @@ export enum ChangeDetectionStrategy {
|
|||||||
* List of possible {@link ChangeDetectionStrategy} values.
|
* List of possible {@link ChangeDetectionStrategy} values.
|
||||||
*/
|
*/
|
||||||
export var CHANGE_DETECTION_STRATEGY_VALUES = [
|
export var CHANGE_DETECTION_STRATEGY_VALUES = [
|
||||||
ChangeDetectionStrategy.CheckOnce, ChangeDetectionStrategy.Checked,
|
ChangeDetectionStrategy.CheckOnce,
|
||||||
ChangeDetectionStrategy.CheckAlways, ChangeDetectionStrategy.Detached,
|
ChangeDetectionStrategy.Checked,
|
||||||
ChangeDetectionStrategy.OnPush, ChangeDetectionStrategy.Default
|
ChangeDetectionStrategy.CheckAlways,
|
||||||
|
ChangeDetectionStrategy.Detached,
|
||||||
|
ChangeDetectionStrategy.OnPush,
|
||||||
|
ChangeDetectionStrategy.Default
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of possible {@link ChangeDetectorState} values.
|
* List of possible {@link ChangeDetectorState} values.
|
||||||
*/
|
*/
|
||||||
export var CHANGE_DETECTOR_STATE_VALUES = [
|
export var CHANGE_DETECTOR_STATE_VALUES = [
|
||||||
ChangeDetectorState.NeverChecked, ChangeDetectorState.CheckedBefore, ChangeDetectorState.Errored
|
ChangeDetectorState.NeverChecked,
|
||||||
|
ChangeDetectorState.CheckedBefore,
|
||||||
|
ChangeDetectorState.Errored
|
||||||
];
|
];
|
||||||
|
|
||||||
export function isDefaultChangeDetectionStrategy(changeDetectionStrategy: ChangeDetectionStrategy):
|
export function isDefaultChangeDetectionStrategy(
|
||||||
boolean {
|
changeDetectionStrategy: ChangeDetectionStrategy): boolean {
|
||||||
return isBlank(changeDetectionStrategy) ||
|
return isBlank(changeDetectionStrategy) ||
|
||||||
changeDetectionStrategy === ChangeDetectionStrategy.Default;
|
changeDetectionStrategy === ChangeDetectionStrategy.Default;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,14 @@ import {CONST} from 'angular2/src/facade/lang';
|
|||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from 'angular2/src/facade/exceptions';
|
||||||
import {isListLikeIterable, iterateListLike, ListWrapper} from 'angular2/src/facade/collection';
|
import {isListLikeIterable, iterateListLike, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
import {isBlank, isPresent, stringify, getMapKey, looseIdentical, isArray} from 'angular2/src/facade/lang';
|
import {
|
||||||
|
isBlank,
|
||||||
|
isPresent,
|
||||||
|
stringify,
|
||||||
|
getMapKey,
|
||||||
|
looseIdentical,
|
||||||
|
isArray
|
||||||
|
} from 'angular2/src/facade/lang';
|
||||||
|
|
||||||
import {ChangeDetectorRef} from '../change_detector_ref';
|
import {ChangeDetectorRef} from '../change_detector_ref';
|
||||||
import {IterableDiffer, IterableDifferFactory, TrackByFn} from '../differs/iterable_differs';
|
import {IterableDiffer, IterableDifferFactory, TrackByFn} from '../differs/iterable_differs';
|
||||||
@ -211,8 +218,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
|||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
_mismatch(record: CollectionChangeRecord, item: any, itemTrackBy: any, index: number):
|
_mismatch(record: CollectionChangeRecord, item: any, itemTrackBy: any,
|
||||||
CollectionChangeRecord {
|
index: number): CollectionChangeRecord {
|
||||||
// The previous record after which we will append the current one.
|
// The previous record after which we will append the current one.
|
||||||
var previousRecord: CollectionChangeRecord;
|
var previousRecord: CollectionChangeRecord;
|
||||||
|
|
||||||
@ -277,8 +284,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
|||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
_verifyReinsertion(record: CollectionChangeRecord, item: any, itemTrackBy: any, index: number):
|
_verifyReinsertion(record: CollectionChangeRecord, item: any, itemTrackBy: any,
|
||||||
CollectionChangeRecord {
|
index: number): CollectionChangeRecord {
|
||||||
var reinsertRecord: CollectionChangeRecord =
|
var reinsertRecord: CollectionChangeRecord =
|
||||||
this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy);
|
this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy);
|
||||||
if (reinsertRecord !== null) {
|
if (reinsertRecord !== null) {
|
||||||
@ -326,8 +333,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_reinsertAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, index: number):
|
_reinsertAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord,
|
||||||
CollectionChangeRecord {
|
index: number): CollectionChangeRecord {
|
||||||
if (this._unlinkedRecords !== null) {
|
if (this._unlinkedRecords !== null) {
|
||||||
this._unlinkedRecords.remove(record);
|
this._unlinkedRecords.remove(record);
|
||||||
}
|
}
|
||||||
@ -351,8 +358,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_moveAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, index: number):
|
_moveAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord,
|
||||||
CollectionChangeRecord {
|
index: number): CollectionChangeRecord {
|
||||||
this._unlink(record);
|
this._unlink(record);
|
||||||
this._insertAfter(record, prevRecord, index);
|
this._insertAfter(record, prevRecord, index);
|
||||||
this._addToMoves(record, index);
|
this._addToMoves(record, index);
|
||||||
@ -360,8 +367,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_addAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, index: number):
|
_addAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord,
|
||||||
CollectionChangeRecord {
|
index: number): CollectionChangeRecord {
|
||||||
this._insertAfter(record, prevRecord, index);
|
this._insertAfter(record, prevRecord, index);
|
||||||
|
|
||||||
if (this._additionsTail === null) {
|
if (this._additionsTail === null) {
|
||||||
@ -378,8 +385,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_insertAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, index: number):
|
_insertAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord,
|
||||||
CollectionChangeRecord {
|
index: number): CollectionChangeRecord {
|
||||||
// todo(vicb)
|
// todo(vicb)
|
||||||
// assert(record != prevRecord);
|
// assert(record != prevRecord);
|
||||||
// assert(record._next === null);
|
// assert(record._next === null);
|
||||||
@ -520,12 +527,10 @@ export class DefaultIterableDiffer implements IterableDiffer {
|
|||||||
var identityChanges = [];
|
var identityChanges = [];
|
||||||
this.forEachIdentityChange((record) => identityChanges.push(record));
|
this.forEachIdentityChange((record) => identityChanges.push(record));
|
||||||
|
|
||||||
return 'collection: ' + list.join(', ') + '\n' +
|
return "collection: " + list.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" +
|
||||||
'previous: ' + previous.join(', ') + '\n' +
|
"additions: " + additions.join(', ') + "\n" + "moves: " + moves.join(', ') + "\n" +
|
||||||
'additions: ' + additions.join(', ') + '\n' +
|
"removals: " + removals.join(', ') + "\n" + "identityChanges: " +
|
||||||
'moves: ' + moves.join(', ') + '\n' +
|
identityChanges.join(', ') + "\n";
|
||||||
'removals: ' + removals.join(', ') + '\n' +
|
|
||||||
'identityChanges: ' + identityChanges.join(', ') + '\n';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,9 +563,10 @@ export class CollectionChangeRecord {
|
|||||||
constructor(public item: any, public trackById: any) {}
|
constructor(public item: any, public trackById: any) {}
|
||||||
|
|
||||||
toString(): string {
|
toString(): string {
|
||||||
return this.previousIndex === this.currentIndex ? stringify(this.item) :
|
return this.previousIndex === this.currentIndex ?
|
||||||
stringify(this.item) + '[' +
|
stringify(this.item) :
|
||||||
stringify(this.previousIndex) + '->' + stringify(this.currentIndex) + ']';
|
stringify(this.item) + '[' + stringify(this.previousIndex) + '->' +
|
||||||
|
stringify(this.currentIndex) + ']';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,11 +318,9 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
|
|||||||
removals.push(stringify(record));
|
removals.push(stringify(record));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'map: ' + items.join(', ') + '\n' +
|
return "map: " + items.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" +
|
||||||
'previous: ' + previous.join(', ') + '\n' +
|
"additions: " + additions.join(', ') + "\n" + "changes: " + changes.join(', ') + "\n" +
|
||||||
'additions: ' + additions.join(', ') + '\n' +
|
"removals: " + removals.join(', ') + "\n";
|
||||||
'changes: ' + changes.join(', ') + '\n' +
|
|
||||||
'removals: ' + removals.join(', ') + '\n';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
|
@ -21,10 +21,9 @@ export class DirectiveRecord {
|
|||||||
// array of [emitter property name, eventName]
|
// array of [emitter property name, eventName]
|
||||||
outputs: string[][];
|
outputs: string[][];
|
||||||
|
|
||||||
constructor(
|
constructor({directiveIndex, callAfterContentInit, callAfterContentChecked, callAfterViewInit,
|
||||||
{directiveIndex, callAfterContentInit, callAfterContentChecked, callAfterViewInit,
|
callAfterViewChecked, callOnChanges, callDoCheck, callOnInit, callOnDestroy,
|
||||||
callAfterViewChecked, callOnChanges, callDoCheck, callOnInit, callOnDestroy, changeDetection,
|
changeDetection, outputs}: {
|
||||||
outputs}: {
|
|
||||||
directiveIndex?: DirectiveIndex,
|
directiveIndex?: DirectiveIndex,
|
||||||
callAfterContentInit?: boolean,
|
callAfterContentInit?: boolean,
|
||||||
callAfterContentChecked?: boolean,
|
callAfterContentChecked?: boolean,
|
||||||
|
@ -20,11 +20,11 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
localPipes: any[];
|
localPipes: any[];
|
||||||
prevContexts: any[];
|
prevContexts: any[];
|
||||||
|
|
||||||
constructor(
|
constructor(id: string, numberOfPropertyProtoRecords: number,
|
||||||
id: string, numberOfPropertyProtoRecords: number, propertyBindingTargets: BindingTarget[],
|
propertyBindingTargets: BindingTarget[], directiveIndices: DirectiveIndex[],
|
||||||
directiveIndices: DirectiveIndex[], strategy: ChangeDetectionStrategy,
|
strategy: ChangeDetectionStrategy, private _records: ProtoRecord[],
|
||||||
private _records: ProtoRecord[], private _eventBindings: EventBinding[],
|
private _eventBindings: EventBinding[], private _directiveRecords: DirectiveRecord[],
|
||||||
private _directiveRecords: DirectiveRecord[], private _genConfig: ChangeDetectorGenConfig) {
|
private _genConfig: ChangeDetectorGenConfig) {
|
||||||
super(id, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices, strategy);
|
super(id, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices, strategy);
|
||||||
var len = _records.length + 1;
|
var len = _records.length + 1;
|
||||||
this.values = ListWrapper.createFixedSize(len);
|
this.values = ListWrapper.createFixedSize(len);
|
||||||
@ -38,7 +38,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
handleEventInternal(eventName: string, elIndex: number, locals: Locals): boolean {
|
handleEventInternal(eventName: string, elIndex: number, locals: Locals): boolean {
|
||||||
var preventDefault = false;
|
var preventDefault = false;
|
||||||
|
|
||||||
this._matchingEventBindings(eventName, elIndex).forEach(rec => {
|
this._matchingEventBindings(eventName, elIndex)
|
||||||
|
.forEach(rec => {
|
||||||
var res = this._processEventBinding(rec, locals);
|
var res = this._processEventBinding(rec, locals);
|
||||||
if (res === false) {
|
if (res === false) {
|
||||||
preventDefault = true;
|
preventDefault = true;
|
||||||
@ -71,7 +72,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new BaseException('Cannot be reached');
|
throw new BaseException("Cannot be reached");
|
||||||
}
|
}
|
||||||
|
|
||||||
private _computeSkipLength(protoIndex: number, proto: ProtoRecord, values: any[]): number {
|
private _computeSkipLength(protoIndex: number, proto: ProtoRecord, values: any[]): number {
|
||||||
@ -89,7 +90,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
return condition ? 0 : proto.fixedArgs[0] - protoIndex - 1;
|
return condition ? 0 : proto.fixedArgs[0] - protoIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new BaseException('Cannot be reached');
|
throw new BaseException("Cannot be reached");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
@ -178,13 +179,12 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (proto.isLifeCycleRecord()) {
|
if (proto.isLifeCycleRecord()) {
|
||||||
if (proto.name === 'DoCheck' && !throwOnChange) {
|
if (proto.name === "DoCheck" && !throwOnChange) {
|
||||||
this._getDirectiveFor(directiveRecord.directiveIndex).ngDoCheck();
|
this._getDirectiveFor(directiveRecord.directiveIndex).ngDoCheck();
|
||||||
} else if (
|
} else if (proto.name === "OnInit" && !throwOnChange &&
|
||||||
proto.name === 'OnInit' && !throwOnChange &&
|
|
||||||
this.state == ChangeDetectorState.NeverChecked) {
|
this.state == ChangeDetectorState.NeverChecked) {
|
||||||
this._getDirectiveFor(directiveRecord.directiveIndex).ngOnInit();
|
this._getDirectiveFor(directiveRecord.directiveIndex).ngOnInit();
|
||||||
} else if (proto.name === 'OnChanges' && isPresent(changes) && !throwOnChange) {
|
} else if (proto.name === "OnChanges" && isPresent(changes) && !throwOnChange) {
|
||||||
this._getDirectiveFor(directiveRecord.directiveIndex).ngOnChanges(changes);
|
this._getDirectiveFor(directiveRecord.directiveIndex).ngOnChanges(changes);
|
||||||
}
|
}
|
||||||
} else if (proto.isSkipRecord()) {
|
} else if (proto.isSkipRecord()) {
|
||||||
@ -276,8 +276,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
private _check(proto: ProtoRecord, throwOnChange: boolean, values: any[], locals: Locals):
|
private _check(proto: ProtoRecord, throwOnChange: boolean, values: any[],
|
||||||
SimpleChange {
|
locals: Locals): SimpleChange {
|
||||||
if (proto.isPipeRecord()) {
|
if (proto.isPipeRecord()) {
|
||||||
return this._pipeCheck(proto, throwOnChange, values);
|
return this._pipeCheck(proto, throwOnChange, values);
|
||||||
} else {
|
} else {
|
||||||
@ -286,8 +286,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
private _referenceCheck(
|
private _referenceCheck(proto: ProtoRecord, throwOnChange: boolean, values: any[],
|
||||||
proto: ProtoRecord, throwOnChange: boolean, values: any[], locals: Locals) {
|
locals: Locals) {
|
||||||
if (this._pureFuncAndArgsDidNotChange(proto)) {
|
if (this._pureFuncAndArgsDidNotChange(proto)) {
|
||||||
this._setChanged(proto, false);
|
this._setChanged(proto, false);
|
||||||
return null;
|
return null;
|
||||||
@ -379,8 +379,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
|
|||||||
return args[args.length - 1];
|
return args[args.length - 1];
|
||||||
|
|
||||||
case RecordType.InvokeClosure:
|
case RecordType.InvokeClosure:
|
||||||
return FunctionWrapper.apply(
|
return FunctionWrapper.apply(this._readContext(proto, values),
|
||||||
this._readContext(proto, values), this._readArgs(proto, values));
|
this._readArgs(proto, values));
|
||||||
|
|
||||||
case RecordType.Interpolate:
|
case RecordType.Interpolate:
|
||||||
case RecordType.PrimitiveOp:
|
case RecordType.PrimitiveOp:
|
||||||
|
@ -2,7 +2,6 @@ import {DirectiveIndex} from './directive_record';
|
|||||||
import {ProtoRecord} from './proto_record';
|
import {ProtoRecord} from './proto_record';
|
||||||
|
|
||||||
export class EventBinding {
|
export class EventBinding {
|
||||||
constructor(
|
constructor(public eventName: string, public elIndex: number, public dirIndex: DirectiveIndex,
|
||||||
public eventName: string, public elIndex: number, public dirIndex: DirectiveIndex,
|
|
||||||
public records: ProtoRecord[]) {}
|
public records: ProtoRecord[]) {}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
import {BaseException, WrappedException} from "angular2/src/facade/exceptions";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An error thrown if application changes model breaking the top-down data flow.
|
* An error thrown if application changes model breaking the top-down data flow.
|
||||||
@ -35,8 +35,7 @@ import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
|||||||
*/
|
*/
|
||||||
export class ExpressionChangedAfterItHasBeenCheckedException extends BaseException {
|
export class ExpressionChangedAfterItHasBeenCheckedException extends BaseException {
|
||||||
constructor(exp: string, oldValue: any, currValue: any, context: any) {
|
constructor(exp: string, oldValue: any, currValue: any, context: any) {
|
||||||
super(
|
super(`Expression '${exp}' has changed after it was checked. ` +
|
||||||
`Expression '${exp}' has changed after it was checked. ` +
|
|
||||||
`Previous value: '${oldValue}'. Current value: '${currValue}'`);
|
`Previous value: '${oldValue}'. Current value: '${currValue}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +107,6 @@ export class EventEvaluationError extends WrappedException {
|
|||||||
* Error context included when an event handler throws an exception.
|
* Error context included when an event handler throws an exception.
|
||||||
*/
|
*/
|
||||||
export class EventEvaluationErrorContext {
|
export class EventEvaluationErrorContext {
|
||||||
constructor(
|
constructor(public element: any, public componentElement: any, public context: any,
|
||||||
public element: any, public componentElement: any, public context: any, public locals: any,
|
public locals: any, public injector: any) {}
|
||||||
public injector: any) {}
|
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,8 @@ import {ChangeDetectionStrategy} from './constants';
|
|||||||
import {ChangeDetectorRef} from './change_detector_ref';
|
import {ChangeDetectorRef} from './change_detector_ref';
|
||||||
|
|
||||||
export class DebugContext {
|
export class DebugContext {
|
||||||
constructor(
|
constructor(public element: any, public componentElement: any, public directive: any,
|
||||||
public element: any, public componentElement: any, public directive: any, public context: any,
|
public context: any, public locals: any, public injector: any) {}
|
||||||
public locals: any, public injector: any) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChangeDispatcher {
|
export interface ChangeDispatcher {
|
||||||
@ -45,13 +44,13 @@ export interface ChangeDetector {
|
|||||||
export interface ProtoChangeDetector { instantiate(): ChangeDetector; }
|
export interface ProtoChangeDetector { instantiate(): ChangeDetector; }
|
||||||
|
|
||||||
export class ChangeDetectorGenConfig {
|
export class ChangeDetectorGenConfig {
|
||||||
constructor(
|
constructor(public genDebugInfo: boolean, public logBindingUpdate: boolean,
|
||||||
public genDebugInfo: boolean, public logBindingUpdate: boolean, public useJit: boolean) {}
|
public useJit: boolean) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ChangeDetectorDefinition {
|
export class ChangeDetectorDefinition {
|
||||||
constructor(
|
constructor(public id: string, public strategy: ChangeDetectionStrategy,
|
||||||
public id: string, public strategy: ChangeDetectionStrategy, public variableNames: string[],
|
public variableNames: string[], public bindingRecords: BindingRecord[],
|
||||||
public bindingRecords: BindingRecord[], public eventRecords: BindingRecord[],
|
public eventRecords: BindingRecord[], public directiveRecords: DirectiveRecord[],
|
||||||
public directiveRecords: DirectiveRecord[], public genConfig: ChangeDetectorGenConfig) {}
|
public genConfig: ChangeDetectorGenConfig) {}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,8 @@ export class JitProtoChangeDetector implements ProtoChangeDetector {
|
|||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
_createFactory(definition: ChangeDetectorDefinition) {
|
_createFactory(definition: ChangeDetectorDefinition) {
|
||||||
return new ChangeDetectorJITGenerator(
|
return new ChangeDetectorJITGenerator(definition, 'util', 'AbstractChangeDetector',
|
||||||
definition, 'util', 'AbstractChangeDetector', 'ChangeDetectorStatus')
|
'ChangeDetectorStatus')
|
||||||
.generate();
|
.generate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from "angular2/src/facade/collection";
|
||||||
|
|
||||||
export class AST {
|
export class AST {
|
||||||
visit(visitor: AstVisitor): any { return null; }
|
visit(visitor: AstVisitor): any { return null; }
|
||||||
toString(): string { return 'AST'; }
|
toString(): string { return "AST"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +23,7 @@ export class Quote extends AST {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
visit(visitor: AstVisitor): any { return visitor.visitQuote(this); }
|
visit(visitor: AstVisitor): any { return visitor.visitQuote(this); }
|
||||||
toString(): string { return 'Quote'; }
|
toString(): string { return "Quote"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EmptyExpr extends AST {
|
export class EmptyExpr extends AST {
|
||||||
@ -55,8 +55,8 @@ export class PropertyRead extends AST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class PropertyWrite extends AST {
|
export class PropertyWrite extends AST {
|
||||||
constructor(
|
constructor(public receiver: AST, public name: string, public setter: Function,
|
||||||
public receiver: AST, public name: string, public setter: Function, public value: AST) {
|
public value: AST) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
visit(visitor: AstVisitor): any { return visitor.visitPropertyWrite(this); }
|
visit(visitor: AstVisitor): any { return visitor.visitPropertyWrite(this); }
|
||||||
@ -138,8 +138,7 @@ export class ASTWithSource extends AST {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TemplateBinding {
|
export class TemplateBinding {
|
||||||
constructor(
|
constructor(public key: string, public keyIsVar: boolean, public name: string,
|
||||||
public key: string, public keyIsVar: boolean, public name: string,
|
|
||||||
public expression: ASTWithSource) {}
|
public expression: ASTWithSource) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,8 +283,8 @@ export class AstTransformer implements AstVisitor {
|
|||||||
visitPrefixNot(ast: PrefixNot): AST { return new PrefixNot(ast.expression.visit(this)); }
|
visitPrefixNot(ast: PrefixNot): AST { return new PrefixNot(ast.expression.visit(this)); }
|
||||||
|
|
||||||
visitConditional(ast: Conditional): AST {
|
visitConditional(ast: Conditional): AST {
|
||||||
return new Conditional(
|
return new Conditional(ast.condition.visit(this), ast.trueExp.visit(this),
|
||||||
ast.condition.visit(this), ast.trueExp.visit(this), ast.falseExp.visit(this));
|
ast.falseExp.visit(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
visitPipe(ast: BindingPipe): AST {
|
visitPipe(ast: BindingPipe): AST {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user