├── .idea
├── .name
├── misc.xml
├── scopes
│ └── scope_settings.xml
├── watcherTasks.xml
├── encodings.xml
├── vcs.xml
├── dictionaries
│ ├── KG_Chromium.xml
│ └── Rob.xml
├── inspectionProfiles
│ ├── profiles_settings.xml
│ └── Project_Default.xml
├── jsLibraryMappings.xml
├── modules.xml
├── libraries
│ └── angular_next_node_modules.xml
├── webResources.xml
└── angular-next.iml
├── .npmignore
├── lib
└── systemjs-register
│ └── initialize-register.js
├── examples
├── hello-jspm
│ ├── jspm_packages
│ │ ├── .loaderversions
│ │ └── github
│ │ │ └── robianmcd
│ │ │ └── angular-next@0.0.3
│ │ │ ├── .jspm-hash
│ │ │ ├── ng2
│ │ │ ├── ngElement.js
│ │ │ ├── bootstrap.js
│ │ │ ├── template.js
│ │ │ ├── templateConfig.js
│ │ │ ├── decorator.js
│ │ │ ├── component.js
│ │ │ └── directive.js
│ │ │ ├── ngNext
│ │ │ ├── injectNgOne.js
│ │ │ ├── polyfillPromise.js
│ │ │ └── angular2Adapter.js
│ │ │ ├── angular2.js
│ │ │ ├── .jspm.json
│ │ │ └── rtts-assert.js
│ ├── package.json
│ ├── app.js
│ ├── config.js
│ ├── index.html
│ └── README.md
├── color-slider
│ ├── build
│ │ ├── css
│ │ │ ├── css
│ │ │ │ └── styles.css
│ │ │ ├── styles.css
│ │ │ └── blue-grey-theme.css
│ │ ├── app.js
│ │ ├── components
│ │ │ ├── colorSettings
│ │ │ │ ├── colorSettings.html
│ │ │ │ ├── ng1ColorSettings.js
│ │ │ │ └── ng2ColorSettings.js
│ │ │ └── base
│ │ │ │ ├── baseComponent.html
│ │ │ │ └── baseComponent.js
│ │ ├── index.html
│ │ ├── decorators
│ │ │ └── backgroundColor.js
│ │ ├── services
│ │ │ └── colorUtil.js
│ │ └── vendor
│ │ │ └── angular-aria.js
│ ├── bower.json
│ ├── src
│ │ ├── app.ats.js
│ │ ├── css
│ │ │ └── styles.css
│ │ ├── decorators
│ │ │ └── backgroundColor.ats.js
│ │ ├── components
│ │ │ ├── base
│ │ │ │ ├── baseComponent.ats.js
│ │ │ │ └── baseComponent.html
│ │ │ └── colorSettings
│ │ │ │ ├── colorSettings.html
│ │ │ │ ├── ng1ColorSettings.js
│ │ │ │ └── ng2ColorSettings.ats.js
│ │ ├── services
│ │ │ └── colorUtil.ats.js
│ │ └── index.html
│ ├── package.json
│ ├── readme.md
│ └── gulpfile.js
├── feature-sandbox
│ ├── src
│ │ ├── myChildService.js
│ │ ├── app.js
│ │ ├── myService.js
│ │ ├── colorDec.js
│ │ ├── helloComponent.js
│ │ ├── index.html
│ │ └── childComponent.js
│ ├── package.json
│ ├── bower.json
│ └── gulpfile.js
└── hello-world
│ ├── package.json
│ ├── src
│ └── app.js
│ ├── index.html
│ ├── build
│ └── app.js
│ └── README.md
├── src
└── angular2
│ ├── ng2
│ ├── ngElement.js
│ ├── template.js
│ ├── bootstrap.js
│ ├── decorator.js
│ ├── component.js
│ └── directive.js
│ ├── ngNext
│ ├── injectNgOne.js
│ ├── polyfillPromise.js
│ ├── registerNg2Directives.js
│ └── angular2Adapter.js
│ ├── angular2.js
│ └── rtts-assert.js
├── dist
└── es6
│ └── angular2
│ ├── ng2
│ ├── ngElement.js
│ ├── template.js
│ ├── bootstrap.js
│ ├── templateConfig.js
│ ├── decorator.js
│ ├── component.js
│ └── directive.js
│ ├── ngNext
│ ├── injectNgOne.js
│ ├── polyfillPromise.js
│ ├── registerNg2Directives.js
│ └── angular2Adapter.js
│ ├── angular2.js
│ └── rtts-assert.js
├── .gitignore
├── karma.conf.js
├── .travis.yml
├── package.json
├── bower.json
├── testMain.js
├── CHANGELOG.md
├── gulpfile.js
├── test
└── ngNext
│ └── angular2AdapterTest.js
├── README.md
└── LICENSE
/.idea/.name:
--------------------------------------------------------------------------------
1 | angular-next
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /*
2 | /*/
3 | !/src/
4 | !src/*
--------------------------------------------------------------------------------
/lib/systemjs-register/initialize-register.js:
--------------------------------------------------------------------------------
1 | register(System);
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/.loaderversions:
--------------------------------------------------------------------------------
1 | ^0.13.1,^0.13.2,^0.0.82,
--------------------------------------------------------------------------------
/examples/color-slider/build/css/css/styles.css:
--------------------------------------------------------------------------------
1 | .container {
2 | width:600px;margin:auto;
3 | }
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/angular2/ng2/ngElement.js:
--------------------------------------------------------------------------------
1 | class NgElement {
2 | constructor($element) {
3 | this.domElement = $element[0];
4 | }
5 | }
6 |
7 | export {NgElement};
--------------------------------------------------------------------------------
/dist/es6/angular2/ng2/ngElement.js:
--------------------------------------------------------------------------------
1 | class NgElement {
2 | constructor($element) {
3 | this.domElement = $element[0];
4 | }
5 | }
6 |
7 | export {NgElement};
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/.jspm-hash:
--------------------------------------------------------------------------------
1 | b0e6be91820f18c079f193246a374791d3eceb3899914b932bd37a50b983c5e7c90ae93bjspm-github@0.100.13
--------------------------------------------------------------------------------
/src/angular2/ngNext/injectNgOne.js:
--------------------------------------------------------------------------------
1 | class InjectNgOne {
2 | constructor(typeStr: assert.string) {
3 | this.typeStr = typeStr;
4 | }
5 | }
6 |
7 | export {InjectNgOne};
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/watcherTasks.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/dist/es6/angular2/ngNext/injectNgOne.js:
--------------------------------------------------------------------------------
1 | class InjectNgOne {
2 | constructor(typeStr: assert.string) {
3 | this.typeStr = typeStr;
4 | }
5 | }
6 |
7 | export {InjectNgOne};
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | /.idea/workspace.xml
3 | /bower_components
4 | /test-build
5 |
6 | /examples/feature-sandbox/build/
7 | /examples/feature-sandbox/bower_components
8 |
9 | /examples/color-slider/bower_components
--------------------------------------------------------------------------------
/examples/feature-sandbox/src/myChildService.js:
--------------------------------------------------------------------------------
1 | class MyChildService {
2 | constructor() {
3 |
4 | }
5 |
6 | getChildStr() {
7 | return 'child service'
8 | }
9 | }
10 |
11 | export default MyChildService;
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ng2/ngElement.js:
--------------------------------------------------------------------------------
1 | /* */
2 | class NgElement {
3 | constructor($element) {
4 | this.domElement = $element[0];
5 | }
6 | }
7 |
8 | export {NgElement};
--------------------------------------------------------------------------------
/examples/feature-sandbox/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularNextExample",
3 | "version": "0.0.0",
4 | "dependencies": {
5 | "bower": "~1.3.12",
6 | "gulp": "~3.8.10",
7 | "gulp-traceur": "0.15.0"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config) {
2 | config.set({
3 | basePath: '',
4 | autoWatch: true,
5 | frameworks: ['jasmine'],
6 | reporters: ['progress'],
7 | browsers: ['Firefox']
8 | });
9 | };
10 |
--------------------------------------------------------------------------------
/src/angular2/ng2/template.js:
--------------------------------------------------------------------------------
1 | class Template {
2 | constructor(options) {
3 | this.inline = options.inline;
4 | this.url = options.url;
5 | this.directives = options.directives;
6 | }
7 | }
8 |
9 | export {Template};
--------------------------------------------------------------------------------
/dist/es6/angular2/ng2/template.js:
--------------------------------------------------------------------------------
1 | class Template {
2 | constructor(options) {
3 | this.inline = options.inline;
4 | this.url = options.url;
5 | this.directives = options.directives;
6 | }
7 | }
8 |
9 | export {Template};
--------------------------------------------------------------------------------
/examples/color-slider/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularNextColorSlider",
3 | "version": "1.0.0",
4 | "dependencies": {
5 | "angular": "1.3.8",
6 | "angular-next": "0.0.3",
7 | "angular-material": "~0.6.1"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/feature-sandbox/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-next-example",
3 | "private": true,
4 | "version": "0.0.0",
5 | "license": "Apache License, Version 2.0",
6 | "dependencies": {
7 | "angular": "1.3.1"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ngNext/injectNgOne.js:
--------------------------------------------------------------------------------
1 | /* */
2 | class InjectNgOne {
3 | constructor(typeStr: assert.string) {
4 | this.typeStr = typeStr;
5 | }
6 | }
7 |
8 | export {InjectNgOne};
--------------------------------------------------------------------------------
/examples/color-slider/src/app.ats.js:
--------------------------------------------------------------------------------
1 | import {bootstrap} from 'angular2/angular2.js';
2 | import BaseComponent from 'components/base/baseComponent.js';
3 |
4 | export function main() {
5 | bootstrap(BaseComponent, {moduleName: 'colorSlider'});
6 | }
7 |
--------------------------------------------------------------------------------
/src/angular2/ng2/bootstrap.js:
--------------------------------------------------------------------------------
1 | import {Angular2Adapter} from '../ngNext/angular2Adapter.js';
2 |
3 | export function bootstrap (component, config = {}) {
4 | var adapter = new Angular2Adapter(config);
5 | adapter.bootstrapComponent(component);
6 | };
7 |
--------------------------------------------------------------------------------
/.idea/dictionaries/KG_Chromium.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | backport
5 | livereload
6 | versioning
7 |
8 |
9 |
--------------------------------------------------------------------------------
/dist/es6/angular2/ng2/bootstrap.js:
--------------------------------------------------------------------------------
1 | import {Angular2Adapter} from '../ngNext/angular2Adapter';
2 |
3 | export function bootstrap (component, config = {}) {
4 | var adapter = new Angular2Adapter(config);
5 | adapter.bootstrapComponent(component);
6 | };
7 |
--------------------------------------------------------------------------------
/dist/es6/angular2/ng2/templateConfig.js:
--------------------------------------------------------------------------------
1 | class TemplateConfig {
2 | constructor(options) {
3 | this.inline = options.inline;
4 | this.url = options.url;
5 | this.directives = options.directives;
6 | }
7 | }
8 |
9 | export {TemplateConfig};
--------------------------------------------------------------------------------
/examples/hello-jspm/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "jspm": {
3 | "directories": {
4 | "lib": ".",
5 | "packages": "jspm_packages"
6 | },
7 | "dependencies": {
8 | "angular2": "github:robianmcd/angular-next@^0.0.3"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/examples/feature-sandbox/src/app.js:
--------------------------------------------------------------------------------
1 | import {bootstrap} from 'angular2/angular2.js';
2 | import HelloComponent from 'helloComponent.js';
3 |
4 | export function main() {
5 | var app = angular.module('myApp', []);
6 |
7 | bootstrap(HelloComponent, {moduleName: 'myApp'});
8 | }
9 |
--------------------------------------------------------------------------------
/examples/color-slider/build/css/styles.css:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 550px;
3 | margin: 50px auto;
4 | border: 2px solid #777;
5 | }
6 |
7 | .title {
8 | text-align: center;
9 | }
10 |
11 | .content {
12 | padding: 10px;
13 | }
14 |
15 | p {
16 | margin-top: 0;
17 | }
--------------------------------------------------------------------------------
/examples/color-slider/src/css/styles.css:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 550px;
3 | margin: 50px auto;
4 | border: 2px solid #777;
5 | }
6 |
7 | .title {
8 | text-align: center;
9 | }
10 |
11 | .content {
12 | padding: 10px;
13 | }
14 |
15 | p {
16 | margin-top: 0;
17 | }
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/examples/color-slider/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularNextColorSlider",
3 | "version": "1.0.0",
4 | "dependencies": {
5 | "bower": "~1.3.12",
6 | "gulp": "~3.8.10",
7 | "gulp-connect": "^2.2.0",
8 | "gulp-traceur": "0.15.0",
9 | "lazypipe": "~0.2.2"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/.idea/dictionaries/Rob.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | anno
5 | hammerjs
6 | lazypipe
7 | transpile
8 | uninjectable
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.idea/jsLibraryMappings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ng2/bootstrap.js:
--------------------------------------------------------------------------------
1 | /* */
2 | import {Angular2Adapter} from '../ngNext/angular2Adapter';
3 |
4 | export function bootstrap (component, config = {}) {
5 | var adapter = new Angular2Adapter(config);
6 | adapter.bootstrapComponent(component);
7 | };
8 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ng2/template.js:
--------------------------------------------------------------------------------
1 | /* */
2 | class Template {
3 | constructor(options) {
4 | this.inline = options.inline;
5 | this.url = options.url;
6 | this.directives = options.directives;
7 | }
8 | }
9 |
10 | export {Template};
--------------------------------------------------------------------------------
/dist/es6/angular2/angular2.js:
--------------------------------------------------------------------------------
1 | export * from './ng2/bootstrap';
2 | export * from './ng2/directive';
3 | export * from './ng2/component';
4 | export * from './ng2/decorator';
5 | export * from './ng2/template';
6 | export * from './ng2/ngElement';
7 |
8 | export * from './ngNext/injectNgOne';
9 | export * from './ngNext/angular2Adapter';
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ng2/templateConfig.js:
--------------------------------------------------------------------------------
1 | /* */
2 | class TemplateConfig {
3 | constructor(options) {
4 | this.inline = options.inline;
5 | this.url = options.url;
6 | this.directives = options.directives;
7 | }
8 | }
9 |
10 | export {TemplateConfig};
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 | before_script:
5 | - export DISPLAY=:99.0
6 | - sh -e /etc/init.d/xvfb start
7 | - npm install
8 | - npm install -g gulp
9 | - npm install -g bower
10 | - bower install
11 | script:
12 | - gulp build
13 | - gulp test
14 | branches:
15 | only:
16 | - gh-pages
--------------------------------------------------------------------------------
/src/angular2/angular2.js:
--------------------------------------------------------------------------------
1 | export * from './ng2/bootstrap.js';
2 | export * from './ng2/directive.js';
3 | export * from './ng2/component.js';
4 | export * from './ng2/decorator.js';
5 | export * from './ng2/template.js';
6 | export * from './ng2/ngElement.js';
7 |
8 | export * from './ngNext/injectNgOne.js';
9 | export * from './ngNext/angular2Adapter.js';
--------------------------------------------------------------------------------
/examples/hello-world/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularNextHelloWorld",
3 | "version": "1.0.0",
4 | "dependencies": {
5 | "traceur": "0.0.74",
6 | "http-server": "0.7.1"
7 | },
8 | "scripts": {
9 | "build": "traceur --dir src build --modules=instantiate --annotations=true",
10 | "start": "http-server"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/angular2.js:
--------------------------------------------------------------------------------
1 | /* */
2 | export * from './ng2/bootstrap';
3 | export * from './ng2/directive';
4 | export * from './ng2/component';
5 | export * from './ng2/decorator';
6 | export * from './ng2/template';
7 | export * from './ng2/ngElement';
8 |
9 | export * from './ngNext/injectNgOne';
10 | export * from './ngNext/angular2Adapter';
--------------------------------------------------------------------------------
/examples/hello-jspm/app.js:
--------------------------------------------------------------------------------
1 | import {bootstrap, Component, Template} from 'angular2/angular2';
2 |
3 | @Component({
4 | selector: 'hello-component'
5 | })
6 | @Template({inline: '
{{ctrl.message}} '})
7 | class HelloComponent {
8 | constructor() {
9 | this.message = 'Hello jspm';
10 | }
11 | }
12 |
13 | export function main() {
14 | angular.module('myApp', []);
15 |
16 | bootstrap(HelloComponent, {moduleName: 'myApp'});
17 | }
--------------------------------------------------------------------------------
/examples/hello-jspm/config.js:
--------------------------------------------------------------------------------
1 | System.config({
2 | "baseURL": ".",
3 | "paths": {
4 | "*": "*.js",
5 | "github:*": "jspm_packages/github/*.js"
6 | },
7 | "traceurOptions": {
8 | "annotations": true,
9 | "types": true,
10 | "typeAssertions": true,
11 | "typeAssertionModule": "angular2/rtts-assert"
12 | }
13 | });
14 |
15 | System.config({
16 | "map": {
17 | "angular2": "github:robianmcd/angular-next@0.0.3"
18 | }
19 | });
20 |
21 |
--------------------------------------------------------------------------------
/examples/hello-world/src/app.js:
--------------------------------------------------------------------------------
1 | import {bootstrap, Component, Template} from 'angular2/angular2.js';
2 |
3 | @Component({
4 | selector: 'hello-component'
5 | })
6 | @Template({
7 | inline: '{{ctrl.message}} '
8 | })
9 | class HelloComponent {
10 | constructor() {
11 | this.message = 'Hello World';
12 | }
13 | }
14 |
15 | export function main() {
16 | angular.module('myApp', []);
17 |
18 | bootstrap(HelloComponent, {moduleName: 'myApp'});
19 | }
--------------------------------------------------------------------------------
/examples/feature-sandbox/src/myService.js:
--------------------------------------------------------------------------------
1 | import MyChildService from 'myChildService.js';
2 | import {InjectNgOne} from 'angular2/angular2.js';
3 |
4 | class MyService {
5 | constructor(childService: MyChildService, @InjectNgOne('$log') $log) {
6 | $log.info('successfully injected angular 1 service');
7 | this.childService = childService;
8 | }
9 |
10 | getStr() {
11 | return this.childService.getChildStr();
12 | }
13 | }
14 |
15 | export default MyService;
--------------------------------------------------------------------------------
/.idea/libraries/angular_next_node_modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/feature-sandbox/src/colorDec.js:
--------------------------------------------------------------------------------
1 | import {Decorator, NgElement} from 'angular2/angular2.js';
2 |
3 | @Decorator({
4 | selector: '[color]',
5 | bind: {color: 'color'},
6 | observe: {color: 'onColorChange'}
7 | })
8 | class ColorDec {
9 | constructor(el:NgElement) {
10 | this.element = el;
11 | this.onColorChange(this.color);
12 | }
13 |
14 | onColorChange(newValue) {
15 | this.element.domElement.style.color = newValue;
16 | }
17 | }
18 |
19 | export default ColorDec;
--------------------------------------------------------------------------------
/.idea/webResources.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/hello-world/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Angular Next - Hello World
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/hello-jspm/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/color-slider/build/app.js:
--------------------------------------------------------------------------------
1 | System.register("app.js", ["angular2/angular2.js", "components/base/baseComponent.js"], function($__export) {
2 | "use strict";
3 | var __moduleName = "app.js";
4 | var bootstrap,
5 | BaseComponent;
6 | function main() {
7 | bootstrap(BaseComponent, {moduleName: 'colorSlider'});
8 | }
9 | $__export("main", main);
10 | return {
11 | setters: [function(m) {
12 | bootstrap = m.bootstrap;
13 | }, function(m) {
14 | BaseComponent = m.default;
15 | }],
16 | execute: function() {
17 | }
18 | };
19 | });
20 | //# sourceURL=app.js
--------------------------------------------------------------------------------
/examples/color-slider/src/decorators/backgroundColor.ats.js:
--------------------------------------------------------------------------------
1 | import {Decorator, NgElement} from 'angular2/angular2.js';
2 |
3 | @Decorator({
4 | selector: '[background-color]',
5 | bind: {backgroundColor: 'backgroundColor'},
6 | observe: {backgroundColor: 'onColorChange'}
7 | })
8 | class BackgroundColor {
9 | constructor(el:NgElement) {
10 | this.element = el;
11 | this.onColorChange(this.backgroundColor);
12 | }
13 |
14 | onColorChange(newValue) {
15 | this.element.domElement.style['background-color'] = newValue;
16 | }
17 | }
18 |
19 | export default BackgroundColor;
20 |
--------------------------------------------------------------------------------
/examples/feature-sandbox/src/helloComponent.js:
--------------------------------------------------------------------------------
1 | import {Component, Template, NgElement} from 'angular2/angular2.js';
2 | import ChildComponent from 'childComponent.js';
3 | import MyService from 'myService.js';
4 | import MyChildService from 'myChildService.js';
5 |
6 |
7 | @Component({
8 | selector: '[hello-component]',
9 | componentServices: [MyService, MyChildService, NgElement]
10 | })
11 | @Template({
12 | inline: 'Hello {{ctrl.test}} ',
13 | directives: [ChildComponent]
14 | })
15 | class HelloComponent {
16 | constructor(test: MyService) {
17 | this.test = test.getStr();
18 | }
19 | }
20 |
21 | export default HelloComponent;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularNext",
3 | "version": "0.0.3",
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/robianmcd/angular-next.git"
7 | },
8 | "devDependencies": {
9 | "bower": "~1.3.12",
10 | "gulp": "~3.8.10",
11 | "gulp-concat": "~2.4.1",
12 | "gulp-insert": "~0.4.0",
13 | "gulp-traceur": "0.17.0",
14 | "gulp-rename": "~1.2.0",
15 | "gulp-replace": "~0.5.3",
16 | "karma": "~0.12.30",
17 | "gulp-karma": "0.0.4",
18 | "jasmine-core": "~2.1.3",
19 | "karma-jasmine": "~0.3.3",
20 | "karma-firefox-launcher": "~0.1.4"
21 | },
22 | "main": false,
23 | "directories": {
24 | "lib": "dist/es6/angular2"
25 | },
26 | "format": "es6"
27 | }
28 |
--------------------------------------------------------------------------------
/examples/color-slider/src/components/base/baseComponent.ats.js:
--------------------------------------------------------------------------------
1 | import {Component, Template} from 'angular2/angular2.js';
2 | import BackgroundColor from 'decorators/backgroundColor.js';
3 | import ColorUtil from 'services/colorUtil.js';
4 | import Ng2ColorSettings from 'components/colorSettings/ng2ColorSettings.js';
5 |
6 | @Component({
7 | selector: 'base-component',
8 | componentServices: [ColorUtil]
9 | })
10 | @Template({
11 | url: 'components/base/baseComponent.html',
12 | directives: [BackgroundColor, Ng2ColorSettings]
13 | })
14 | class BaseComponent {
15 | constructor() {
16 | this.backgroundColor = '#fff';
17 | }
18 |
19 | setBackgroundColor(hash) {
20 | this.backgroundColor = hash;
21 | }
22 | }
23 |
24 | export default BaseComponent;
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-next",
3 | "description": "Angular Next brings the power of Angular 2 to Angular 1 and gives you an incremental migration path.",
4 | "version": "0.0.3",
5 | "homepage": "https://github.com/robianmcd/angular-next",
6 | "authors": [
7 | "Rob "
8 | ],
9 | "keywords": [
10 | "javascript",
11 | "angularjs",
12 | "angular"
13 | ],
14 | "license": "Apache License, Version 2.0",
15 | "ignore": [
16 | "*",
17 | "!dist/",
18 | "!dist/*"
19 | ],
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/robianmcd/angular-next.git"
23 | },
24 | "devDependencies": {
25 | "traceur-runtime": "0.0.84",
26 | "es6-module-loader": "~0.10.0",
27 | "angular": "~1.3.8"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/.jspm.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularNext",
3 | "version": "0.0.2",
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/robianmcd/angular-next.git"
7 | },
8 | "devDependencies": {
9 | "bower": "~1.3.12",
10 | "gulp": "~3.8.10",
11 | "gulp-concat": "~2.4.1",
12 | "gulp-insert": "~0.4.0",
13 | "gulp-traceur": "0.17.0",
14 | "gulp-rename": "~1.2.0",
15 | "gulp-replace": "~0.5.3",
16 | "karma": "~0.12.30",
17 | "gulp-karma": "0.0.4",
18 | "jasmine-core": "~2.1.3",
19 | "karma-jasmine": "~0.3.3",
20 | "karma-firefox-launcher": "~0.1.4"
21 | },
22 | "main": false,
23 | "directories": {
24 | "lib": "dist/es6/angular2"
25 | },
26 | "format": "es6",
27 | "jspm": {}
28 | }
--------------------------------------------------------------------------------
/testMain.js:
--------------------------------------------------------------------------------
1 | //This file is based off of: https://github.com/gocardless/es6-angularjs/blob/master/config/karma-spec-loader.config.js
2 |
3 | // make karma wait for a call to __karma__.start() to start running tests.
4 | __karma__.loaded = function () {
5 | };
6 |
7 | Promise.all(
8 | // All files served by Karma.
9 | Object.keys(__karma__.files)
10 | //Filter out everything other than test spec files
11 | .filter(function (path) {
12 | return /test-build/.test(path);
13 | })
14 | //Import all the test spec modules
15 | .map(function (path) {
16 | return System.import(path.replace('/base/test-build/', ''));
17 | })
18 | )
19 | .then(function () {
20 | __karma__.start();
21 | }, function (error) {
22 | console.error(error.stack || error);
23 | __karma__.start();
24 | });
--------------------------------------------------------------------------------
/examples/feature-sandbox/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angular Next
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/examples/feature-sandbox/src/childComponent.js:
--------------------------------------------------------------------------------
1 | import {Component, Template, NgElement} from 'angular2/angular2.js';
2 | import ColorDec from 'colorDec.js';
3 | import HelloComponent from 'helloComponent.js';
4 |
5 | @Component({
6 | selector: 'child-component',
7 | controllerAs: 'ctrl'
8 | })
9 | @Template({
10 | inline: '' +
11 | 'child: {{ctrl.test}}
' +
12 | '
' +
13 | 'decorated {{ctrl.color}} text
',
14 | directives: [ColorDec]
15 | })
16 | class ChildComponent {
17 | constructor(element: NgElement, hello: HelloComponent) {
18 | element.domElement.style.color = 'blue';
19 |
20 | this.color = 'red';
21 | this.test = hello.test;
22 | }
23 |
24 | getTestStr() {
25 | return 'blue text';
26 | }
27 |
28 | clicked() {
29 | console.log('clicked');
30 | }
31 | }
32 |
33 | export default ChildComponent;
--------------------------------------------------------------------------------
/examples/color-slider/build/components/colorSettings/colorSettings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Use the slider to adjust the background color of the parent component.
4 |
5 |
10 |
11 |
12 | Hue
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Set Parent Color
21 |
22 |
--------------------------------------------------------------------------------
/examples/color-slider/src/components/colorSettings/colorSettings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Use the slider to adjust the background color of the parent component.
4 |
5 |
10 |
11 |
12 | Hue
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Set Parent Color
21 |
22 |
--------------------------------------------------------------------------------
/examples/hello-world/build/app.js:
--------------------------------------------------------------------------------
1 | System.register(["angular2/angular2.js"], function($__export) {
2 | "use strict";
3 | var bootstrap,
4 | Component,
5 | Template,
6 | HelloComponent;
7 | function main() {
8 | angular.module('myApp', []);
9 | bootstrap(HelloComponent, {moduleName: 'myApp'});
10 | }
11 | $__export("main", main);
12 | return {
13 | setters: [function(m) {
14 | bootstrap = m.bootstrap;
15 | Component = m.Component;
16 | Template = m.Template;
17 | }],
18 | execute: function() {
19 | HelloComponent = (function() {
20 | var HelloComponent = function HelloComponent() {
21 | this.message = 'Hello World';
22 | };
23 | return ($traceurRuntime.createClass)(HelloComponent, {}, {});
24 | }());
25 | Object.defineProperty(HelloComponent, "annotations", {get: function() {
26 | return [new Component({selector: 'hello-component'}), new Template({inline: '{{ctrl.message}} '})];
27 | }});
28 | }
29 | };
30 | });
31 |
--------------------------------------------------------------------------------
/src/angular2/ng2/decorator.js:
--------------------------------------------------------------------------------
1 | import {Directive} from './directive.js';
2 |
3 | //Like ng-class, ng-show
4 | class Decorator extends Directive {
5 | constructor(options:Object) {
6 | super(options);
7 | }
8 | }
9 |
10 | var DecoratorClass = assert.define('DecoratorClass', function (decoratorClass) {
11 | assert.type(decoratorClass, Object);
12 |
13 | var numDirAnnos;
14 | var numComponentAnnos;
15 | if (decoratorClass.annotations) {
16 | numDirAnnos = decoratorClass.annotations.filter(anno => anno instanceof Directive).length;
17 | numComponentAnnos = decoratorClass.annotations.filter(anno => anno instanceof Decorator).length;
18 | } else {
19 | numDirAnnos = 0;
20 | numComponentAnnos = 0;
21 | }
22 |
23 |
24 | if (numComponentAnnos === 0) {
25 | assert.fail('A DecoratorClass must have a Decorator annotation');
26 | }
27 | if (numDirAnnos > 1) {
28 | asssert.fail('You cannot have more than one Directive annotations on a class.');
29 | }
30 | });
31 |
32 | export {Decorator, DecoratorClass};
--------------------------------------------------------------------------------
/dist/es6/angular2/ng2/decorator.js:
--------------------------------------------------------------------------------
1 | import {Directive} from './directive';
2 |
3 | //Like ng-class, ng-show
4 | class Decorator extends Directive {
5 | constructor(options:Object) {
6 | super(options);
7 | }
8 | }
9 |
10 | var DecoratorClass = assert.define('DecoratorClass', function (decoratorClass) {
11 | assert.type(decoratorClass, Object);
12 |
13 | var numDirAnnos;
14 | var numComponentAnnos;
15 | if (decoratorClass.annotations) {
16 | numDirAnnos = decoratorClass.annotations.filter(anno => anno instanceof Directive).length;
17 | numComponentAnnos = decoratorClass.annotations.filter(anno => anno instanceof Decorator).length;
18 | } else {
19 | numDirAnnos = 0;
20 | numComponentAnnos = 0;
21 | }
22 |
23 |
24 | if (numComponentAnnos === 0) {
25 | assert.fail('A DecoratorClass must have a Decorator annotation');
26 | }
27 | if (numDirAnnos > 1) {
28 | asssert.fail('You cannot have more than one Directive annotations on a class.');
29 | }
30 | });
31 |
32 | export {Decorator, DecoratorClass};
--------------------------------------------------------------------------------
/examples/feature-sandbox/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | traceur = require('gulp-traceur');
3 |
4 | var appFiles = 'src/**/*.js';
5 | var vendorFiles = [
6 | 'bower_components/angular/angular.js',
7 | '../../dist/angularNext-standalone.js'
8 | ];
9 | var indexFile = 'src/index.html';
10 |
11 | gulp.task('vendor', function () {
12 | return gulp.src(vendorFiles)
13 | .pipe(gulp.dest('build/vendor'));
14 | });
15 |
16 | gulp.task('app', function () {
17 | return gulp.src(appFiles)
18 | .pipe(traceur({experimental: true, modules: 'instantiate', moduleName: true, annotations: true, types: true, typeAssertions: true, typeAssertionModule: "angular2/rtts-assert.js"}))
19 | .pipe(gulp.dest('build'));
20 | });
21 |
22 | gulp.task('index', function () {
23 | return gulp.src(indexFile)
24 | .pipe(gulp.dest('build'));
25 | });
26 |
27 | gulp.task('build', ['vendor', 'app', 'index']);
28 |
29 | gulp.task('default', ['build'], function () {
30 | gulp.watch(appFiles, ['app']);
31 | gulp.watch(vendorFiles, ['vendor']);
32 | gulp.watch(indexFile, ['index']);
33 | });
--------------------------------------------------------------------------------
/examples/hello-world/README.md:
--------------------------------------------------------------------------------
1 | # Angular Next - Hello World
2 |
3 | This is a bare bones, self contained example that uses Angular Next to create a directive that says "Hello World".
4 |
5 | ### Demo
6 |
7 | [http://robianmcd.github.io/angular-next/examples/hello-world/](http://robianmcd.github.io/angular-next/examples/hello-world/) - **Spoiler Alert:** It says "Hello World"...
8 |
9 | ### Run locally
10 |
11 | ```sh
12 | git clone https://github.com/robianmcd/angular-next.git
13 | cd angular-next/examples/hello-world
14 | npm install
15 | npm run build
16 | npm start
17 | ```
18 |
19 | You can now access the app at [http://localhost:8080/](http://localhost:8080/)
20 |
21 |
22 | ### Files
23 |
24 | * *build/*
25 | * *app.js* - The result of compiling src/app.js into ES5 with Traceur
26 | * *src/*
27 | * *app.js* - Sets up the angular app and defines the `helloComponent` directive
28 | * *index.html* - Runs the app's main function which bootstraps the angular app.
29 | * *package.json* - This just includes Traceur which is used to compile src/app.js into ES5, and http-server which is used to statically serve the app
30 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ng2/decorator.js:
--------------------------------------------------------------------------------
1 | /* */
2 | import {Directive} from './directive';
3 |
4 | //Like ng-class, ng-show
5 | class Decorator extends Directive {
6 | constructor(options:Object) {
7 | super(options);
8 | }
9 | }
10 |
11 | var DecoratorClass = assert.define('DecoratorClass', function (decoratorClass) {
12 | assert.type(decoratorClass, Object);
13 |
14 | var numDirAnnos;
15 | var numComponentAnnos;
16 | if (decoratorClass.annotations) {
17 | numDirAnnos = decoratorClass.annotations.filter(anno => anno instanceof Directive).length;
18 | numComponentAnnos = decoratorClass.annotations.filter(anno => anno instanceof Decorator).length;
19 | } else {
20 | numDirAnnos = 0;
21 | numComponentAnnos = 0;
22 | }
23 |
24 |
25 | if (numComponentAnnos === 0) {
26 | assert.fail('A DecoratorClass must have a Decorator annotation');
27 | }
28 | if (numDirAnnos > 1) {
29 | asssert.fail('You cannot have more than one Directive annotations on a class.');
30 | }
31 | });
32 |
33 | export {Decorator, DecoratorClass};
--------------------------------------------------------------------------------
/examples/color-slider/src/components/colorSettings/ng1ColorSettings.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | angular.module('colorSlider').directive('ng1ColorSettings', function () {
3 | return {
4 | restrict: 'E',
5 | templateUrl: 'components/colorSettings/colorSettings.html',
6 | controller: Ng1ColorSettingsCtrl,
7 | controllerAs: 'ctrl',
8 | require: '^baseComponent',
9 | link: function (scope, lElement, attrs, base) {
10 | scope.ctrl.base = base;
11 | }
12 | };
13 | });
14 |
15 | var Ng1ColorSettingsCtrl = function (colorUtil, $log) {
16 | this.colorUtil = colorUtil;
17 | this.$log = $log;
18 |
19 | this.hue = 0;
20 | };
21 |
22 | Ng1ColorSettingsCtrl.$inject = ['colorUtil', '$log'];
23 |
24 | Ng1ColorSettingsCtrl.prototype.hueToHash = function(hue) {
25 | return this.colorUtil.hslToHash(hue / 100, 0.7, 0.4);
26 | };
27 |
28 | Ng1ColorSettingsCtrl.prototype.setParentColor = function() {
29 | var hash = this.hueToHash(this.hue);
30 | this.$log.info("setting the base component's background color to " + hash);
31 | this.base.setBackgroundColor(hash);
32 | };
33 |
34 | })();
--------------------------------------------------------------------------------
/examples/color-slider/build/components/colorSettings/ng1ColorSettings.js:
--------------------------------------------------------------------------------
1 | (function(){
2 | angular.module('colorSlider').directive('ng1ColorSettings', function () {
3 | return {
4 | restrict: 'E',
5 | templateUrl: 'components/colorSettings/colorSettings.html',
6 | controller: Ng1ColorSettingsCtrl,
7 | controllerAs: 'ctrl',
8 | require: '^baseComponent',
9 | link: function (scope, lElement, attrs, base) {
10 | scope.ctrl.base = base;
11 | }
12 | };
13 | });
14 |
15 | var Ng1ColorSettingsCtrl = function (colorUtil, $log) {
16 | this.colorUtil = colorUtil;
17 | this.$log = $log;
18 |
19 | this.hue = 0;
20 | };
21 |
22 | Ng1ColorSettingsCtrl.$inject = ['colorUtil', '$log'];
23 |
24 | Ng1ColorSettingsCtrl.prototype.hueToHash = function(hue) {
25 | return this.colorUtil.hslToHash(hue / 100, 0.7, 0.4);
26 | };
27 |
28 | Ng1ColorSettingsCtrl.prototype.setParentColor = function() {
29 | var hash = this.hueToHash(this.hue);
30 | this.$log.info("setting the base component's background color to " + hash);
31 | this.base.setBackgroundColor(hash);
32 | };
33 |
34 | })();
--------------------------------------------------------------------------------
/examples/color-slider/src/components/colorSettings/ng2ColorSettings.ats.js:
--------------------------------------------------------------------------------
1 | import {Component, Template, InjectNgOne} from 'angular2/angular2.js';
2 | import BackgroundColor from 'decorators/backgroundColor.js';
3 | import ColorUtil from 'services/colorUtil.js';
4 | import BaseComponent from 'components/base/baseComponent.js';
5 |
6 | @Component({
7 | selector: 'ng2-color-settings'
8 | })
9 | @Template({
10 | url: 'components/colorSettings/colorSettings.html',
11 | directives: [BackgroundColor]
12 | })
13 | class Ng2ColorSettings {
14 | //Notice how this constructor injects a service, a parent component, and an Angular 1 service.
15 | constructor(colorUtil:ColorUtil, base: BaseComponent, @InjectNgOne('$log') $log) {
16 | this.colorUtil = colorUtil;
17 | this.base = base;
18 | this.$log = $log;
19 |
20 | this.hue = 0;
21 | }
22 |
23 | hueToHash(hue) {
24 | return this.colorUtil.hslToHash(hue / 100, 0.8, 0.5);
25 | }
26 |
27 | setParentColor() {
28 | var hash = this.hueToHash(this.hue);
29 | this.$log.info(`setting the base component's background color to ${hash}`);
30 | this.base.setBackgroundColor(hash);
31 | }
32 | }
33 |
34 | export default Ng2ColorSettings;
--------------------------------------------------------------------------------
/examples/color-slider/src/services/colorUtil.ats.js:
--------------------------------------------------------------------------------
1 | class ColorUtil {
2 | constructor() {
3 |
4 | }
5 |
6 | //Taken from http://stackoverflow.com/a/9493060/373655
7 | hslToRgb(h, s, l) {
8 | var r, g, b;
9 |
10 | if (s == 0) {
11 | r = g = b = l; // achromatic
12 | } else {
13 | function hue2rgb(p, q, t) {
14 | if (t < 0) t += 1;
15 | if (t > 1) t -= 1;
16 | if (t < 1 / 6) return p + (q - p) * 6 * t;
17 | if (t < 1 / 2) return q;
18 | if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
19 | return p;
20 | }
21 |
22 | var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
23 | var p = 2 * l - q;
24 | r = hue2rgb(p, q, h + 1 / 3);
25 | g = hue2rgb(p, q, h);
26 | b = hue2rgb(p, q, h - 1 / 3);
27 | }
28 |
29 | return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
30 | }
31 |
32 | hslToHash(h, s, l) {
33 | return this.rgbToHash(...this.hslToRgb(h, s, l));
34 | }
35 |
36 | rgbToHash(r, g, b) {
37 | return `#${r.toString(16)}${g.toString(16)}${b.toString(16)}`
38 | }
39 | }
40 |
41 | export default ColorUtil;
--------------------------------------------------------------------------------
/examples/hello-jspm/README.md:
--------------------------------------------------------------------------------
1 | # Angular Next - Hello jspm
2 |
3 | This is a hello world app that uses Angular Next and [jspm](http://jspm.io/).
4 |
5 | ### Demo
6 |
7 | [http://robianmcd.github.io/angular-next/examples/hello-jspm/](http://robianmcd.github.io/angular-next/examples/hello-jspm/)
8 |
9 | ### Run locally
10 |
11 | ```sh
12 | git clone https://github.com/robianmcd/angular-next.git
13 | cd angular-next/examples/hello-jspm
14 | npm insatll -g jspm
15 | jspm install
16 | python -m SimpleHTTPServer
17 | ```
18 |
19 | You can now access the app at [http://localhost:8000/](http://localhost:8000/). Note: the `python` command depends on Python 2.7 and just serves your files. In Python 3 the command would be `python -m http.server`.
20 |
21 |
22 | ### Files
23 |
24 | * *jspm_packages/* - Generated by running `jspm install`. This is basically node_modules for jspm.
25 | * *app.js* - Sets up the angular app and defines the `helloComponent` directive.
26 | * *config.js* - Configuration file for jspm. Note the custom `traceurOptions` that are required to work with Angular Next. This file also aliases the Angular Next module as angular2.
27 | * *index.html* - Runs the app's main function which bootstraps the angular app.
28 | * *package.json* - Specifies the dependency on Angular Next.
29 |
--------------------------------------------------------------------------------
/examples/color-slider/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angular Next - Color Slider
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/examples/color-slider/build/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Angular Next - Color Slider
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 | All notable changes to this project will be documented in this file.
3 |
4 | ## [Unreleased][unreleased]
5 |
6 | ### Added
7 | - Added support for Angular 2 style events and property bindings in templates
8 |
9 | ## [0.0.3] - 2015-02-23
10 |
11 | ### Added
12 | - Replaced ES6 Promise implementation with one based on $q so they are integrated with Angular's digest cycle.
13 | - Created an example using jspm
14 |
15 | ### Changed
16 | - Replaced template option in Component directives with a new `@Template` annotation
17 | - Renamed assert.js module to angular2/rtts-assert.js
18 |
19 | ## [0.0.2] - 2015-01-26
20 |
21 | ### Changed
22 | - replace core/core.js module with angular/angular.js to reflect [this change in angular 2.0](https://github.com/angular/angular/commit/ec5cb3eb66aa343bbc7f67c182c1cc021ce04096)
23 |
24 | ### Added
25 | - Started versioning releases in the dist folder
26 | - Created a changelog based on [keepachangelog.com](http://keepachangelog.com/)
27 |
28 | ## [0.0.1] - 2015-01-18
29 | ### Added
30 | - Setup foundation for Angular Next
31 |
32 | [unreleased]: https://github.com/robianmcd/angular-next/compare/...HEAD
33 | [0.0.3]: https://github.com/robianmcd/angular-next/compare/0.0.2...0.0.3
34 | [0.0.2]: https://github.com/robianmcd/angular-next/compare/0.0.1...0.0.2
35 | [0.0.1]: https://github.com/robianmcd/angular-next/compare/0.0.0...0.0.1
--------------------------------------------------------------------------------
/src/angular2/ngNext/polyfillPromise.js:
--------------------------------------------------------------------------------
1 | export default function polyfillPromise(ngModule) {
2 | ngModule.run(['$q', '$window', function ($q, $window) {
3 | $window.Promise = function (executor) {
4 | return $q(executor);
5 | };
6 |
7 | $window.Promise.all = $q.all.bind($q);
8 | $window.Promise.reject = $q.reject.bind($q);
9 | $window.Promise.resolve = $q.when.bind($q);
10 |
11 | $window.Promise.race = function (promises) {
12 | var promiseMgr = $q.defer();
13 |
14 | for (var i = 0; i < promises.length; i++) {
15 | promises[i].then(function (result) {
16 | if (promiseMgr) {
17 | promiseMgr.resolve(result);
18 | promiseMgr = null;
19 | }
20 | });
21 |
22 | promises[i].catch(function (result) {
23 | if (promiseMgr) {
24 | promiseMgr.reject(result);
25 | promiseMgr = null;
26 | }
27 | });
28 | }
29 |
30 | return promiseMgr.promise;
31 | };
32 |
33 | }]);
34 |
35 | //Make sure the run block we just added gets executed before any other run blocks
36 | if (angular.isArray(ngModule._runBlocks)) {
37 | ngModule._runBlocks.unshift(ngModule._runBlocks.pop());
38 | }
39 | }
--------------------------------------------------------------------------------
/dist/es6/angular2/ngNext/polyfillPromise.js:
--------------------------------------------------------------------------------
1 | export default function polyfillPromise(ngModule) {
2 | ngModule.run(['$q', '$window', function ($q, $window) {
3 | $window.Promise = function (executor) {
4 | return $q(executor);
5 | };
6 |
7 | $window.Promise.all = $q.all.bind($q);
8 | $window.Promise.reject = $q.reject.bind($q);
9 | $window.Promise.resolve = $q.when.bind($q);
10 |
11 | $window.Promise.race = function (promises) {
12 | var promiseMgr = $q.defer();
13 |
14 | for (var i = 0; i < promises.length; i++) {
15 | promises[i].then(function (result) {
16 | if (promiseMgr) {
17 | promiseMgr.resolve(result);
18 | promiseMgr = null;
19 | }
20 | });
21 |
22 | promises[i].catch(function (result) {
23 | if (promiseMgr) {
24 | promiseMgr.reject(result);
25 | promiseMgr = null;
26 | }
27 | });
28 | }
29 |
30 | return promiseMgr.promise;
31 | };
32 |
33 | }]);
34 |
35 | //Make sure the run block we just added gets executed before any other run blocks
36 | if (angular.isArray(ngModule._runBlocks)) {
37 | ngModule._runBlocks.unshift(ngModule._runBlocks.pop());
38 | }
39 | }
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ngNext/polyfillPromise.js:
--------------------------------------------------------------------------------
1 | /* */
2 | export default function polyfillPromise(ngModule) {
3 | ngModule.run(['$q', '$window', function ($q, $window) {
4 | $window.Promise = function (executor) {
5 | return $q(executor);
6 | };
7 |
8 | $window.Promise.all = $q.all.bind($q);
9 | $window.Promise.reject = $q.reject.bind($q);
10 | $window.Promise.resolve = $q.when.bind($q);
11 |
12 | $window.Promise.race = function (promises) {
13 | var promiseMgr = $q.defer();
14 |
15 | for (var i = 0; i < promises.length; i++) {
16 | promises[i].then(function (result) {
17 | if (promiseMgr) {
18 | promiseMgr.resolve(result);
19 | promiseMgr = null;
20 | }
21 | });
22 |
23 | promises[i].catch(function (result) {
24 | if (promiseMgr) {
25 | promiseMgr.reject(result);
26 | promiseMgr = null;
27 | }
28 | });
29 | }
30 |
31 | return promiseMgr.promise;
32 | };
33 |
34 | }]);
35 |
36 | //Make sure the run block we just added gets executed before any other run blocks
37 | if (angular.isArray(ngModule._runBlocks)) {
38 | ngModule._runBlocks.unshift(ngModule._runBlocks.pop());
39 | }
40 | }
--------------------------------------------------------------------------------
/examples/color-slider/build/components/base/baseComponent.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Angular Next - Color Slider
4 |
5 |
6 |
7 |
8 | This app is built using Angular Next and Angular Material. The two tabs below are
9 | identical except that the one on the left is implemented with a standard
10 | Angular 1 directive
11 | while the one on the right is implemented with an
12 | Angular 2 style component .
13 |
14 |
15 | Back to code
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/color-slider/src/components/base/baseComponent.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Angular Next - Color Slider
4 |
5 |
6 |
7 |
8 | This app is built using Angular Next and Angular Material. The two tabs below are
9 | identical except that the one on the left is implemented with a standard
10 | Angular 1 directive
11 | while the one on the right is implemented with an
12 | Angular 2 style component .
13 |
14 |
15 | Back to code
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/examples/color-slider/build/decorators/backgroundColor.js:
--------------------------------------------------------------------------------
1 | System.register("decorators/backgroundColor.js", ["angular2/rtts-assert.js", "angular2/angular2.js"], function($__export) {
2 | "use strict";
3 | var __moduleName = "decorators/backgroundColor.js";
4 | var assert,
5 | Decorator,
6 | NgElement,
7 | BackgroundColor;
8 | return {
9 | setters: [function(m) {
10 | assert = m.assert;
11 | }, function(m) {
12 | Decorator = m.Decorator;
13 | NgElement = m.NgElement;
14 | }],
15 | execute: function() {
16 | BackgroundColor = (function() {
17 | var BackgroundColor = function BackgroundColor(el) {
18 | assert.argumentTypes(el, NgElement);
19 | this.element = el;
20 | this.onColorChange(this.backgroundColor);
21 | };
22 | return ($traceurRuntime.createClass)(BackgroundColor, {onColorChange: function(newValue) {
23 | this.element.domElement.style['background-color'] = newValue;
24 | }}, {});
25 | }());
26 | Object.defineProperty(BackgroundColor, "annotations", {get: function() {
27 | return [new Decorator({
28 | selector: '[background-color]',
29 | bind: {backgroundColor: 'backgroundColor'},
30 | observe: {backgroundColor: 'onColorChange'}
31 | })];
32 | }});
33 | Object.defineProperty(BackgroundColor, "parameters", {get: function() {
34 | return [[NgElement]];
35 | }});
36 | $__export('default', BackgroundColor);
37 | }
38 | };
39 | });
40 | //# sourceURL=decorators/backgroundColor.js
--------------------------------------------------------------------------------
/.idea/angular-next.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ng2/component.js:
--------------------------------------------------------------------------------
1 | /* */
2 | import {Directive} from './directive';
3 |
4 | //Like a panel
5 | class Component extends Directive {
6 | constructor(options: ComponentOptions) {
7 | this.componentServices = options.componentServices;
8 | delete options.componentServices;
9 | super(options);
10 | }
11 | }
12 |
13 | var ComponentOptions = assert.define('ComponentOptions', function(options) {
14 | //Required fields
15 | assert(options).is(assert.structure({
16 | selector: assert.string
17 | }));
18 |
19 | //Optional fields
20 | if(options.componentServices) {
21 | assert(options.componentServices).is(assert.arrayOf(Object));
22 | }
23 | });
24 |
25 | var ComponentClass = assert.define('ComponentClass', function (componentClass) {
26 | assert.type(componentClass, Object);
27 |
28 | var numDirAnnos;
29 | var numComponentAnnos;
30 | if(componentClass.annotations) {
31 | numDirAnnos = componentClass.annotations.filter(anno => anno instanceof Directive).length;
32 | numComponentAnnos = componentClass.annotations.filter(anno => anno instanceof Component).length;
33 | } else {
34 | numDirAnnos = 0;
35 | numComponentAnnos = 0;
36 | }
37 |
38 |
39 | if (numComponentAnnos === 0) {
40 | assert.fail('A ComponentClass must have a Component annotation');
41 | }
42 | if(numDirAnnos > 1) {
43 | asssert.fail('You cannot have more than one Directive annotations on a class.');
44 | }
45 | });
46 |
47 | export {Component, ComponentOptions, ComponentClass};
--------------------------------------------------------------------------------
/examples/color-slider/build/components/base/baseComponent.js:
--------------------------------------------------------------------------------
1 | System.register("components/base/baseComponent.js", ["angular2/angular2.js", "decorators/backgroundColor.js", "services/colorUtil.js", "components/colorSettings/ng2ColorSettings.js"], function($__export) {
2 | "use strict";
3 | var __moduleName = "components/base/baseComponent.js";
4 | var Component,
5 | Template,
6 | BackgroundColor,
7 | ColorUtil,
8 | Ng2ColorSettings,
9 | BaseComponent;
10 | return {
11 | setters: [function(m) {
12 | Component = m.Component;
13 | Template = m.Template;
14 | }, function(m) {
15 | BackgroundColor = m.default;
16 | }, function(m) {
17 | ColorUtil = m.default;
18 | }, function(m) {
19 | Ng2ColorSettings = m.default;
20 | }],
21 | execute: function() {
22 | BaseComponent = (function() {
23 | var BaseComponent = function BaseComponent() {
24 | this.backgroundColor = '#fff';
25 | };
26 | return ($traceurRuntime.createClass)(BaseComponent, {setBackgroundColor: function(hash) {
27 | this.backgroundColor = hash;
28 | }}, {});
29 | }());
30 | Object.defineProperty(BaseComponent, "annotations", {get: function() {
31 | return [new Component({
32 | selector: 'base-component',
33 | componentServices: [ColorUtil]
34 | }), new Template({
35 | url: 'components/base/baseComponent.html',
36 | directives: [BackgroundColor, Ng2ColorSettings]
37 | })];
38 | }});
39 | $__export('default', BaseComponent);
40 | }
41 | };
42 | });
43 | //# sourceURL=components/base/baseComponent.js
--------------------------------------------------------------------------------
/src/angular2/ng2/component.js:
--------------------------------------------------------------------------------
1 | import {Directive} from './directive.js';
2 |
3 | //Like a panel
4 | class Component extends Directive {
5 | constructor(options: ComponentOptions) {
6 | //We can't assign this to `this` before calling super
7 | var componentServices = options.componentServices;
8 | delete options.componentServices;
9 | super(options);
10 |
11 | this.componentServices = componentServices;
12 | }
13 | }
14 |
15 | var ComponentOptions = assert.define('ComponentOptions', function(options) {
16 | //Required fields
17 | assert(options).is(assert.structure({
18 | selector: assert.string
19 | }));
20 |
21 | //Optional fields
22 | if(options.componentServices) {
23 | assert(options.componentServices).is(assert.arrayOf(Object));
24 | }
25 | });
26 |
27 | var ComponentClass = assert.define('ComponentClass', function (componentClass) {
28 | assert.type(componentClass, Object);
29 |
30 | var numDirAnnos;
31 | var numComponentAnnos;
32 | if(componentClass.annotations) {
33 | numDirAnnos = componentClass.annotations.filter(anno => anno instanceof Directive).length;
34 | numComponentAnnos = componentClass.annotations.filter(anno => anno instanceof Component).length;
35 | } else {
36 | numDirAnnos = 0;
37 | numComponentAnnos = 0;
38 | }
39 |
40 |
41 | if (numComponentAnnos === 0) {
42 | assert.fail('A ComponentClass must have a Component annotation');
43 | }
44 | if(numDirAnnos > 1) {
45 | asssert.fail('You cannot have more than one Directive annotations on a class.');
46 | }
47 | });
48 |
49 | export {Component, ComponentOptions, ComponentClass};
--------------------------------------------------------------------------------
/dist/es6/angular2/ng2/component.js:
--------------------------------------------------------------------------------
1 | import {Directive} from './directive';
2 |
3 | //Like a panel
4 | class Component extends Directive {
5 | constructor(options: ComponentOptions) {
6 | //We can't assign this to `this` before calling super
7 | var componentServices = options.componentServices;
8 | delete options.componentServices;
9 | super(options);
10 |
11 | this.componentServices = componentServices;
12 | }
13 | }
14 |
15 | var ComponentOptions = assert.define('ComponentOptions', function(options) {
16 | //Required fields
17 | assert(options).is(assert.structure({
18 | selector: assert.string
19 | }));
20 |
21 | //Optional fields
22 | if(options.componentServices) {
23 | assert(options.componentServices).is(assert.arrayOf(Object));
24 | }
25 | });
26 |
27 | var ComponentClass = assert.define('ComponentClass', function (componentClass) {
28 | assert.type(componentClass, Object);
29 |
30 | var numDirAnnos;
31 | var numComponentAnnos;
32 | if(componentClass.annotations) {
33 | numDirAnnos = componentClass.annotations.filter(anno => anno instanceof Directive).length;
34 | numComponentAnnos = componentClass.annotations.filter(anno => anno instanceof Component).length;
35 | } else {
36 | numDirAnnos = 0;
37 | numComponentAnnos = 0;
38 | }
39 |
40 |
41 | if (numComponentAnnos === 0) {
42 | assert.fail('A ComponentClass must have a Component annotation');
43 | }
44 | if(numDirAnnos > 1) {
45 | asssert.fail('You cannot have more than one Directive annotations on a class.');
46 | }
47 | });
48 |
49 | export {Component, ComponentOptions, ComponentClass};
--------------------------------------------------------------------------------
/examples/color-slider/build/services/colorUtil.js:
--------------------------------------------------------------------------------
1 | System.register("services/colorUtil.js", [], function($__export) {
2 | "use strict";
3 | var __moduleName = "services/colorUtil.js";
4 | var ColorUtil;
5 | return {
6 | setters: [],
7 | execute: function() {
8 | ColorUtil = (function() {
9 | var ColorUtil = function ColorUtil() {};
10 | return ($traceurRuntime.createClass)(ColorUtil, {
11 | hslToRgb: function(h, s, l) {
12 | var r,
13 | g,
14 | b;
15 | if (s == 0) {
16 | r = g = b = l;
17 | } else {
18 | var hue2rgb = function(p, q, t) {
19 | if (t < 0)
20 | t += 1;
21 | if (t > 1)
22 | t -= 1;
23 | if (t < 1 / 6)
24 | return p + (q - p) * 6 * t;
25 | if (t < 1 / 2)
26 | return q;
27 | if (t < 2 / 3)
28 | return p + (q - p) * (2 / 3 - t) * 6;
29 | return p;
30 | };
31 | var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
32 | var p = 2 * l - q;
33 | r = hue2rgb(p, q, h + 1 / 3);
34 | g = hue2rgb(p, q, h);
35 | b = hue2rgb(p, q, h - 1 / 3);
36 | }
37 | return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
38 | },
39 | hslToHash: function(h, s, l) {
40 | var $__1;
41 | return ($__1 = this).rgbToHash.apply($__1, $traceurRuntime.spread(this.hslToRgb(h, s, l)));
42 | },
43 | rgbToHash: function(r, g, b) {
44 | return ("#" + r.toString(16) + g.toString(16) + b.toString(16));
45 | }
46 | }, {});
47 | }());
48 | $__export('default', ColorUtil);
49 | }
50 | };
51 | });
52 | //# sourceURL=services/colorUtil.js
--------------------------------------------------------------------------------
/src/angular2/ng2/directive.js:
--------------------------------------------------------------------------------
1 | //See here for detailed annotation implimentations https://github.com/angular/angular/tree/master/modules/core/src/annotations
2 | class Directive {
3 | constructor(options:DirectiveOptions) {
4 | this.selector = options.selector;
5 | this.bind = options.bind;
6 | this.controllerAs = options.controllerAs || 'ctrl';
7 | this.observe = options.observe;
8 | }
9 | }
10 |
11 | var DirectiveOptions = assert.define('DirectiveOptions', function (options) {
12 | //Required fields
13 | assert(options).is(assert.structure({
14 | selector: assert.string
15 | }));
16 |
17 | //Optional fields
18 | if (options.bind) {
19 | assert.type(options.bind, Object);
20 | }
21 | if (options.controllerAs) {
22 | assert.type(options.controllerAs, assert.string);
23 | }
24 | if (options.observe) {
25 | assert.type(options.observe, Object);
26 | }
27 |
28 | for (var key in options) {
29 | if (options.hasOwnProperty(key)) {
30 | if (key !== 'selector' && key !== 'bind' && key !== 'controllerAs' && key !== 'observe') {
31 | assert.fail(`${key} is not a valid directive field`);
32 | }
33 | }
34 | }
35 | });
36 |
37 | var DirectiveClass = assert.define('DirectiveClass', function (dirClass) {
38 | assert.type(dirClass, Object);
39 |
40 | var numDirAnnos;
41 | if(dirClass.annotations) {
42 | numDirAnnos = dirClass.annotations.filter(anno => anno instanceof Directive).length;
43 | } else {
44 | numDirAnnos = 0;
45 | }
46 |
47 |
48 | if (numDirAnnos === 0) {
49 | assert.fail('A DirectiveClass must have a Directive annotation');
50 | } else if(numDirAnnos > 1) {
51 | asssert.fail('You cannot have more than one Directive annotations on a class.');
52 | }
53 | });
54 |
55 | export {Directive, DirectiveOptions, DirectiveClass};
--------------------------------------------------------------------------------
/dist/es6/angular2/ng2/directive.js:
--------------------------------------------------------------------------------
1 | //See here for detailed annotation implimentations https://github.com/angular/angular/tree/master/modules/core/src/annotations
2 | class Directive {
3 | constructor(options:DirectiveOptions) {
4 | this.selector = options.selector;
5 | this.bind = options.bind;
6 | this.controllerAs = options.controllerAs || 'ctrl';
7 | this.observe = options.observe;
8 | }
9 | }
10 |
11 | var DirectiveOptions = assert.define('DirectiveOptions', function (options) {
12 | //Required fields
13 | assert(options).is(assert.structure({
14 | selector: assert.string
15 | }));
16 |
17 | //Optional fields
18 | if (options.bind) {
19 | assert.type(options.bind, Object);
20 | }
21 | if (options.controllerAs) {
22 | assert.type(options.controllerAs, assert.string);
23 | }
24 | if (options.observe) {
25 | assert.type(options.observe, Object);
26 | }
27 |
28 | for (var key in options) {
29 | if (options.hasOwnProperty(key)) {
30 | if (key !== 'selector' && key !== 'bind' && key !== 'controllerAs' && key !== 'observe') {
31 | assert.fail(`${key} is not a valid directive field`);
32 | }
33 | }
34 | }
35 | });
36 |
37 | var DirectiveClass = assert.define('DirectiveClass', function (dirClass) {
38 | assert.type(dirClass, Object);
39 |
40 | var numDirAnnos;
41 | if(dirClass.annotations) {
42 | numDirAnnos = dirClass.annotations.filter(anno => anno instanceof Directive).length;
43 | } else {
44 | numDirAnnos = 0;
45 | }
46 |
47 |
48 | if (numDirAnnos === 0) {
49 | assert.fail('A DirectiveClass must have a Directive annotation');
50 | } else if(numDirAnnos > 1) {
51 | asssert.fail('You cannot have more than one Directive annotations on a class.');
52 | }
53 | });
54 |
55 | export {Directive, DirectiveOptions, DirectiveClass};
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ng2/directive.js:
--------------------------------------------------------------------------------
1 | //See here for detailed annotation implimentations https://github.com/angular/angular/tree/master/modules/core/src/annotations
2 | class Directive {
3 | constructor(options:DirectiveOptions) {
4 | this.selector = options.selector;
5 | this.bind = options.bind;
6 | this.controllerAs = options.controllerAs || 'ctrl';
7 | this.observe = options.observe;
8 | }
9 | }
10 |
11 | var DirectiveOptions = assert.define('DirectiveOptions', function (options) {
12 | //Required fields
13 | assert(options).is(assert.structure({
14 | selector: assert.string
15 | }));
16 |
17 | //Optional fields
18 | if (options.bind) {
19 | assert.type(options.bind, Object);
20 | }
21 | if (options.controllerAs) {
22 | assert.type(options.controllerAs, assert.string);
23 | }
24 | if (options.observe) {
25 | assert.type(options.observe, Object);
26 | }
27 |
28 | for (var key in options) {
29 | if (options.hasOwnProperty(key)) {
30 | if (key !== 'selector' && key !== 'bind' && key !== 'controllerAs' && key !== 'observe') {
31 | assert.fail(`${key} is not a valid directive field`);
32 | }
33 | }
34 | }
35 | });
36 |
37 | var DirectiveClass = assert.define('DirectiveClass', function (dirClass) {
38 | assert.type(dirClass, Object);
39 |
40 | var numDirAnnos;
41 | if(dirClass.annotations) {
42 | numDirAnnos = dirClass.annotations.filter(anno => anno instanceof Directive).length;
43 | } else {
44 | numDirAnnos = 0;
45 | }
46 |
47 |
48 | if (numDirAnnos === 0) {
49 | assert.fail('A DirectiveClass must have a Directive annotation');
50 | } else if(numDirAnnos > 1) {
51 | asssert.fail('You cannot have more than one Directive annotations on a class.');
52 | }
53 | });
54 |
55 | export {Directive, DirectiveOptions, DirectiveClass};
--------------------------------------------------------------------------------
/examples/color-slider/readme.md:
--------------------------------------------------------------------------------
1 | # Angular Next - Color Slider
2 |
3 | This app demonstrates many of the Angular 2 features that Angular Next lets you start using. It also shows how you use these features along side existing Angular 1 code. Angular 2 relies on ES6 modules but you may not want to use modules for your existing Angular 1 code. To deal with this the [gulpfile](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/gulpfile.js#L29-L49) for this project will only treat files ending with `.ats.js` as ES6 modules and compile them into ES5 with Traceur.
4 |
5 | ### Demo
6 |
7 | [http://robianmcd.github.io/angular-next/examples/color-slider/build](http://robianmcd.github.io/angular-next/examples/color-slider/build)
8 |
9 | ### Demonstrated Features
10 | * [Bootstrapping an app](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/src/app.ats.js#L5)
11 | * [Component directive](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/src/components/colorSettings/ng2ColorSettings.ats.js)
12 | * [Decorator directive](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/src/decorators/backgroundColor.ats.js)
13 | * [Directive selector](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/src/components/colorSettings/ng2ColorSettings.ats.js#L7)
14 | * [Directive bind and observe](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/src/decorators/backgroundColor.ats.js#L5-L6)
15 | * [Service](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/src/services/colorUtil.ats.js)
16 | * [Injecting NgElement into directive controller](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/src/decorators/backgroundColor.ats.js#L9)
17 | * [Injecting an Angular 2 Service, a parent component, and an Angular 1 Service](https://github.com/robianmcd/angular-next/blob/gh-pages/examples/color-slider/src/components/colorSettings/ng2ColorSettings.ats.js#L15)
18 |
19 | ### Run locally
20 |
21 | ```sh
22 | git clone https://github.com/robianmcd/angular-next.git
23 | cd angular-next/examples/color-slider
24 | npm install
25 | bower install
26 | gulp
27 | ```
28 |
29 | You can now access the app at [http://localhost:8080/](http://localhost:8080/)
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | traceur = require('gulp-traceur'),
3 | concat = require('gulp-concat'),
4 | karma = require('gulp-karma'),
5 | replace = require('gulp-replace');
6 |
7 | var appFiles = 'src/**/*.js';
8 | var testFiles = 'test/**/*.js';
9 |
10 | var filesForKarma = [
11 | 'bower_components/angular/angular.js',
12 | 'dist/angularNext-standalone.js',
13 | 'test-build/**/*.js',
14 | 'testMain.js'
15 | ];
16 |
17 | var traceurOptions = {
18 | experimental: true,
19 | modules: 'instantiate',
20 | moduleName: true,
21 | annotations: true,
22 | types: true,
23 | typeAssertions: true,
24 | typeAssertionModule: "angular2/rtts-assert.js"
25 | };
26 |
27 | gulp.task('build-angular-next', function () {
28 | gulp.src(appFiles)
29 | .pipe(replace(/(import|export)( .*? from '.*?)\.js(';)/g, '$1$2$3'))
30 | .pipe(gulp.dest('dist/es6'));
31 |
32 | return gulp.src(appFiles)
33 | .pipe(traceur(traceurOptions))
34 | .pipe(concat('angularNext.js'))
35 | .pipe(gulp.dest('dist'));
36 | });
37 |
38 | gulp.task('build-test-files', function () {
39 | return gulp.src(testFiles)
40 | .pipe(traceur(traceurOptions))
41 | .pipe(gulp.dest('test-build'));
42 | });
43 |
44 | gulp.task('build', ['build-angular-next', 'build-test-files'], function () {
45 | gulp.src([
46 | 'bower_components/traceur-runtime/traceur-runtime.js',
47 | 'bower_components/es6-module-loader/dist/es6-module-loader.src.js',
48 | 'lib/systemjs-register/extension-register.js',
49 | 'lib/systemjs-register/initialize-register.js',
50 | 'dist/angularNext.js'])
51 | .pipe(concat('angularNext-standalone.js'))
52 | .pipe(gulp.dest('dist'));
53 | });
54 |
55 | gulp.task('test', function () {
56 | return gulp.src(filesForKarma)
57 | .pipe(karma({
58 | configFile: 'karma.conf.js',
59 | action: 'run'
60 | }));
61 | });
62 |
63 | gulp.task('default', ['build'], function () {
64 | gulp.watch([appFiles], ['build']);
65 | gulp.watch([testFiles], ['build-test-files']);
66 |
67 | gulp.src(filesForKarma)
68 | .pipe(karma({
69 | configFile: 'karma.conf.js',
70 | action: 'watch'
71 | }));
72 | });
--------------------------------------------------------------------------------
/examples/color-slider/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | traceur = require('gulp-traceur'),
3 | connect = require('gulp-connect'),
4 | gulpIf = require('gulp-if'),
5 | rename = require('gulp-rename'),
6 | lazypipe = require('lazypipe');
7 |
8 | var vendorFiles = [
9 | 'bower_components/angular-next/dist/angularNext-standalone.js',
10 | 'bower_components/angular/angular.js',
11 | 'bower_components/angular-animate/angular-animate.js',
12 | 'bower_components/angular-aria/angular-aria.js',
13 | 'bower_components/hammerjs/hammer.js',
14 | 'bower_components/angular-material/angular-material.js'
15 | ];
16 |
17 | var cssFiles = [
18 | 'bower_components/angular-material/angular-material.css',
19 | 'bower_components/angular-material/themes/blue-grey-theme.css',
20 | 'src/css/**/*.css'
21 | ];
22 |
23 | gulp.task('html', function () {
24 | gulp.src('src/**/*.html')
25 | .pipe(gulp.dest('build'))
26 | .pipe(connect.reload());
27 | });
28 |
29 | gulp.task('js', function () {
30 | var buildAtScript = lazypipe()
31 | .pipe(rename, function (path) {
32 | //remove .ats from the filename
33 | path.basename = path.basename.substring(0, path.basename.length - 4);
34 | })
35 | .pipe(traceur, {
36 | modules: 'instantiate',
37 | moduleName: true,
38 | annotations: true,
39 | types: true,
40 | typeAssertions: true,
41 | typeAssertionModule: 'angular2/rtts-assert.js'
42 | });
43 |
44 | gulp.src('src/**/*.js')
45 | //Only files ending in .ats.js will be treated as AtScript and transpiled with Traceur
46 | .pipe(gulpIf(/\.ats\.js$/, buildAtScript()))
47 | .pipe(gulp.dest('build'))
48 | .pipe(connect.reload());
49 | });
50 |
51 | gulp.task('css', function () {
52 | gulp.src(cssFiles)
53 | .pipe(gulp.dest('build/css'))
54 | .pipe(connect.reload());
55 | });
56 |
57 | gulp.task('vendor', function () {
58 | gulp.src(vendorFiles)
59 | .pipe(gulp.dest('build/vendor'))
60 | });
61 |
62 | gulp.task('default', ['js', 'html', 'css', 'vendor'], function () {
63 | connect.server({
64 | livereload: true,
65 | root: 'build'
66 | });
67 |
68 | gulp.watch(['src/**/*.html'], ['html']);
69 | gulp.watch(['src/**/*.js'], ['js']);
70 | gulp.watch([cssFiles], ['css']);
71 | });
--------------------------------------------------------------------------------
/examples/color-slider/build/components/colorSettings/ng2ColorSettings.js:
--------------------------------------------------------------------------------
1 | System.register("components/colorSettings/ng2ColorSettings.js", ["angular2/rtts-assert.js", "angular2/angular2.js", "decorators/backgroundColor.js", "services/colorUtil.js", "components/base/baseComponent.js"], function($__export) {
2 | "use strict";
3 | var __moduleName = "components/colorSettings/ng2ColorSettings.js";
4 | var assert,
5 | Component,
6 | Template,
7 | InjectNgOne,
8 | BackgroundColor,
9 | ColorUtil,
10 | BaseComponent,
11 | Ng2ColorSettings;
12 | return {
13 | setters: [function(m) {
14 | assert = m.assert;
15 | }, function(m) {
16 | Component = m.Component;
17 | Template = m.Template;
18 | InjectNgOne = m.InjectNgOne;
19 | }, function(m) {
20 | BackgroundColor = m.default;
21 | }, function(m) {
22 | ColorUtil = m.default;
23 | }, function(m) {
24 | BaseComponent = m.default;
25 | }],
26 | execute: function() {
27 | Ng2ColorSettings = (function() {
28 | var Ng2ColorSettings = function Ng2ColorSettings(colorUtil, base, $log) {
29 | assert.argumentTypes(colorUtil, ColorUtil, base, BaseComponent, $log, $traceurRuntime.type.any);
30 | this.colorUtil = colorUtil;
31 | this.base = base;
32 | this.$log = $log;
33 | this.hue = 0;
34 | };
35 | return ($traceurRuntime.createClass)(Ng2ColorSettings, {
36 | hueToHash: function(hue) {
37 | return this.colorUtil.hslToHash(hue / 100, 0.8, 0.5);
38 | },
39 | setParentColor: function() {
40 | var hash = this.hueToHash(this.hue);
41 | this.$log.info(("setting the base component's background color to " + hash));
42 | this.base.setBackgroundColor(hash);
43 | }
44 | }, {});
45 | }());
46 | Object.defineProperty(Ng2ColorSettings, "annotations", {get: function() {
47 | return [new Component({selector: 'ng2-color-settings'}), new Template({
48 | url: 'components/colorSettings/colorSettings.html',
49 | directives: [BackgroundColor]
50 | })];
51 | }});
52 | Object.defineProperty(Ng2ColorSettings, "parameters", {get: function() {
53 | return [[ColorUtil], [BaseComponent], [new InjectNgOne('$log')]];
54 | }});
55 | $__export('default', Ng2ColorSettings);
56 | }
57 | };
58 | });
59 | //# sourceURL=components/colorSettings/ng2ColorSettings.js
--------------------------------------------------------------------------------
/test/ngNext/angular2AdapterTest.js:
--------------------------------------------------------------------------------
1 | import {Angular2Adapter, Decorator, Component, Template, InjectNgOne} from 'angular2/angular2.js';
2 |
3 | describe('Angular2Adapter', function () {
4 |
5 | var adapter;
6 |
7 | class MyService {
8 |
9 | }
10 |
11 | @Decorator({selector: '[my-dec]'})
12 | class MyDec {
13 | constructor(myService:MyService) {
14 |
15 | }
16 | }
17 |
18 | @Component({
19 | selector: 'my-component',
20 | controllerAs: 'myCtrl',
21 | bind: {param1: 'param1'}
22 | })
23 | @Template({inline: 'hello world'})
24 | class MyComp {
25 | constructor(param1:Object) {
26 |
27 | }
28 | }
29 |
30 |
31 | beforeEach(function () {
32 | angular.module('myApp', []);
33 | adapter = new Angular2Adapter({moduleName: 'myApp'});
34 | });
35 |
36 | describe('getNg1DirectiveInfo', function () {
37 | it('should generate ddo for attribute selector directive', function () {
38 | expect(adapter.getNg1DirectiveInfo(MyDec)).toEqual({
39 | name: 'myDec',
40 | ddo: {
41 | restrict: 'A',
42 | controller: MyDec,
43 | controllerAs: 'ctrl',
44 | scope: {},
45 | bindToController: true
46 | }
47 | });
48 | });
49 |
50 | it('should generate ddo for element selector directive', function () {
51 | expect(adapter.getNg1DirectiveInfo(MyComp)).toEqual({
52 | name: 'myComponent',
53 | ddo: {
54 | restrict: 'E',
55 | controller: MyComp,
56 | controllerAs: 'myCtrl',
57 | scope: {param1: '=param1'},
58 | bindToController: true,
59 | template: 'hello world'
60 | }
61 | });
62 | });
63 | });
64 |
65 | describe('getInjectArray', function () {
66 | it('should get a decorator\'s $inject array', function () {
67 | expect(adapter.getInjectArray(MyDec)).toEqual(['myService']);
68 | });
69 | });
70 |
71 | describe('getInjectStrFromParamAnnotations', function () {
72 | it('should return the correct string', function () {
73 | expect(adapter.getInjectStrFromParamAnnotations([MyDec])).toEqual('myDec');
74 | expect(adapter.getInjectStrFromParamAnnotations([new InjectNgOne('$scope')])).toEqual('$scope');
75 |
76 | var callWithInvalidParam = function () {
77 | adapter.getInjectStrFromParamAnnotations([]);
78 | };
79 | expect(callWithInvalidParam).toThrow();
80 | });
81 | });
82 |
83 | describe('getDirAnno', function () {
84 | it('should return the annotation', function () {
85 | var anno = adapter.getDirAnno(MyDec);
86 | expect(anno).toEqual(jasmine.any(Decorator));
87 | expect(anno.selector).toEqual('[my-dec]');
88 | });
89 | });
90 |
91 | describe('lowerCaseFirstLetter', function () {
92 | it('should make the first character lower case', function () {
93 | expect(adapter.lowerCaseFirstLetter('MyClassName')).toEqual('myClassName');
94 | expect(adapter.lowerCaseFirstLetter('alreadyLower')).toEqual('alreadyLower');
95 | expect(adapter.lowerCaseFirstLetter('A')).toEqual('a');
96 | expect(adapter.lowerCaseFirstLetter('$Thing')).toEqual('$Thing');
97 | expect(adapter.lowerCaseFirstLetter('')).toEqual('');
98 | });
99 | });
100 |
101 |
102 | describe('getFunctionName', function () {
103 | it('should return the name of a class', function () {
104 | expect(adapter.getFunctionName(MyDec)).toEqual('MyDec');
105 | });
106 | });
107 |
108 | describe('isDirClass', function () {
109 | it('should return true for decorator', function () {
110 | expect(adapter.isDirClass(MyDec)).toBe(true);
111 | });
112 |
113 | it('should return false for nonDirective', function () {
114 | var MyClass = function () {
115 |
116 | };
117 | MyClass.annotations = [{selector: 'not-a-real-directive'}];
118 | expect(adapter.isDirClass(MyClass)).toBe(false);
119 | });
120 |
121 | });
122 |
123 |
124 | });
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](http://badge.fury.io/bo/angular-next) [](https://travis-ci.org/robianmcd/angular-next)
2 |
3 | # Deprecated! This project is way out of date and is not maintained.
4 |
5 | # angular-next
6 |
7 | > Angular Next brings the power of **Angular 2** to Angular 1 and gives you an incremental **migration path**.
8 |
9 | This library lets you start writing Angular 2 style directives and services and use them in an existing Angular 1 app. This allows you to incrementally adopt features from Angular 2 instead of needing to migrate all at once.
10 |
11 | **Warning: Angular Next is still highly experimental. It could change drastically as more information is released about Angular 2.0**
12 |
13 | ## Sample App: Angular 1 + Angular Next
14 |
15 | index.html
16 | ```html
17 |
18 |
19 |
20 |
21 |
26 | ```
27 |
28 | app.js
29 | ```javascript
30 | import {bootstrap, Component, TemplateConfig} from 'angular2/angular2.js';
31 |
32 | @Component({
33 | selector: 'hello-component',
34 | template: new TemplateConfig({
35 | inline: '{{ctrl.message}} '
36 | })
37 | })
38 | class HelloComponent {
39 | constructor() {
40 | this.message = 'Hello World';
41 | }
42 | }
43 |
44 | export function main() {
45 | angular.module('myApp', []);
46 | bootstrap(HelloComponent, {moduleName: 'myApp'});
47 | }
48 | ```
49 |
50 | ## Demos
51 |
52 | **[Hello World](https://github.com/robianmcd/angular-next/tree/gh-pages/examples/hello-world)**
53 | * A working demo of the hello world example shown above.
54 |
55 | **[Hello jspm](https://github.com/robianmcd/angular-next/tree/gh-pages/examples/hello-jspm)**
56 | * Uses [jspm](http://jspm.io/) to load the Angular Next modules into the browser.
57 |
58 | **[Color Slider](https://github.com/robianmcd/angular-next/tree/gh-pages/examples/color-slider)**
59 | * Demonstrates usage of: components, decorators, services, bootstrapping, selector, bind, observe, NgElement, injecting parent directives, injecting Angular 1 services, gulp, Traceur, etc.
60 |
61 | ## Get Angular Next
62 | Angular Next distributes two files
63 | * **angularNext-standalone.js** - Contains the Angular Next library along with all of its dependencies. This includes [traceur-runtime](https://github.com/jmcriffey/bower-traceur-runtime), [es6-module-loader](https://github.com/ModuleLoader/es6-module-loader), [the register extension for systemjs](https://github.com/systemjs/systemjs/blob/master/lib/extension-register.js), and [assert.js](http://angular.github.io/assert/)
64 | * **angularNext.js** - Just the Angular Next library. If you use this you'll need to manually include all of the dependencies.
65 |
66 | You can get Angular Next through bower
67 |
68 | ```sh
69 | bower install angular-next
70 | ```
71 |
72 | or from the CDN
73 |
74 | ```html
75 |
76 | ```
77 |
78 | or from jspm. See the [jspm example](https://github.com/robianmcd/angular-next/tree/gh-pages/examples/hello-jspm) for details.
79 | ```sh
80 | jspm install angular2=github:robianmcd/angular-next
81 | ```
82 |
83 | ## Documentation
84 | For documentation on the supported features checkout the [Wiki](https://github.com/robianmcd/angular-next/wiki).
85 |
86 | ## Changelog
87 |
88 | ## 0.0.3 - 2015-02-23
89 |
90 | ### Added
91 | - Replaced ES6 Promise implementation with one based on $q so they are integrated with Angular's digest cycle.
92 | - Created an example using jspm
93 |
94 | ### Changed
95 | - Replaced template option in Component directives with a new `@Template` annotation
96 | - Renamed assert.js module to angular2/rtts-assert.js
97 |
98 | [Click here for the full changelog](https://github.com/robianmcd/angular-next/blob/gh-pages/CHANGELOG.md)
99 |
100 | ## Roadmap
101 | 1. support as much of the new template syntax as possible
102 | 1. improve jspm example to include bundeling
103 | 1. Improve unit tests and add e2e tests
104 | 1. Look into integrating with the new [router](https://github.com/angular/router)
105 | 1. Add better logging for common errors
106 | 1. Support template directives. **Blocked**: Waiting for more details to be released
107 | 1. Support querying child directives. **Blocked**: Waiting for more details to be released
108 |
--------------------------------------------------------------------------------
/src/angular2/ngNext/registerNg2Directives.js:
--------------------------------------------------------------------------------
1 | function registerPropertyDirectives(ngModule) {
2 | const ALL_PROPERTIES = ['abbr', 'accept', 'acceptCharset', 'accessKey', 'accessKeyLabel', 'action', 'allowfullscreen', 'alt', 'areas', 'async', 'attributes', 'audioTracks', 'autocomplete', 'autofocus', 'autoplay', 'baseURI', 'buffered', 'caption', 'cellIndex', 'cells', 'challenge', 'charset', 'checked', 'childElementCount', 'childNodes', 'children', 'cite', 'classList', 'className', 'clientHeight', 'clientLeft', 'clientTop', 'clientWidth', 'color', 'cols', 'colSpan', 'complete', 'content', 'contentDocument', 'contentEditable', 'contentWindow', 'contextMenu', 'control', 'controller', 'controls', 'coords', 'crossOrigin', 'currentSrc', 'currentTime', 'data', 'dataset', 'datetime', 'default', 'defaultChecked', 'defaultMuted', 'defaultPlaybackRate', 'defaultSelected', 'defaultValue', 'defer', 'dir', 'dirName', 'disabled', 'download', 'draggable', 'dropzone', 'duration', 'elements', 'encoding', 'enctype', 'ended', 'error', 'face', 'files', 'firstChild', 'firstElementChild', 'form', 'formAction', 'formEncType', 'formMethod', 'formNoValidate', 'formTarget', 'hash', 'headers', 'height', 'hidden', 'high', 'host', 'hostname', 'href', 'hreflang', 'htmlFor', 'httpEquiv', 'id', 'images', 'indeterminate', 'index', 'innerHTML', 'inputMode', 'isContentEditable', 'isMap', 'itemId', 'itemProp', 'itemRef', 'itemScope', 'itemType', 'itemValue', 'keySystem', 'keytype', 'kind', 'label', 'labels', 'lang', 'lastChild', 'lastElementChild', 'length', 'list', 'loop', 'low', 'max', 'maxLength', 'media', 'mediaGroup', 'menu', 'method', 'min', 'multiple', 'muted', 'name', 'naturalHeight', 'naturalWidth', 'networkState', 'nextElementSibling', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue', 'noValidate', 'offsetHeight', 'offsetLeft', 'offsetParent', 'offsetTop', 'offsetWidth', 'optimum', 'options', 'origin', 'outerHTML', 'ownerDocument', 'parentElement', 'parentNode', 'password', 'pathname', 'pattern', 'paused', 'placeholder', 'playbackRate', 'played', 'port', 'position', 'poster', 'preload', 'previousElementSibling', 'previousSibling', 'properties', 'protocol', 'readOnly', 'readyState', 'rel', 'relList', 'required', 'reversed', 'rowIndex', 'rows', 'rowSpan', 'sandbox', 'scope', 'scoped', 'scrollHeight', 'scrollLeft', 'scrollTop', 'scrollWidth', 'seamless', 'search', 'sectionRowIndex', 'seekable', 'seeking', 'select', 'selected', 'selectedIndex', 'selectedOptions', 'selectionDirection', 'selectionEnd', 'selectionStart', 'shadowRoot', 'sheet', 'size', 'sizes', 'sortable', 'sorted', 'span', 'spellcheck', 'src', 'srcdoc', 'srclang', 'srcset', 'start', 'step', 'style', 'tabIndex', 'tagName', 'target', 'tBodies', 'text', 'textContent', 'textLength', 'textTracks', 'tFoot', 'tHead', 'title', 'track', 'translate', 'type', 'typeMustMatch', 'undoManager', 'undoScope', 'useMap', 'username', 'validationMessage', 'validity', 'value', 'valueAsDate', 'valueAsNumber', 'videoHeight', 'videoTracks', 'videoWidth', 'volume', 'width', 'willValidate', 'wrap'];
3 |
4 | angular.forEach(ALL_PROPERTIES, function (prop) {
5 | var directiveName = `[${prop}]`;
6 | ngModule.directive(directiveName, ['$parse', '$timeout', function ($parse, $timeout) {
7 | return {
8 | restrict: 'A',
9 | link: function (scope, element, attrs) {
10 | var domElement = element[0];
11 |
12 | var bindExpression = $parse(attrs[directiveName]);
13 |
14 | var curValue = bindExpression(scope);
15 | if (curValue === undefined) {
16 | curValue = domElement[prop];
17 | if (curValue !== undefined) {
18 | bindExpression.assign(scope, curValue);
19 | }
20 | } else {
21 | domElement[prop] = curValue;
22 | }
23 |
24 |
25 | //Note that this will only be called on a digest and changes to a property won't necessarily trigger a digest.
26 | scope.$watch(() => domElement[prop],
27 | function (newValue) {
28 | if (newValue !== curValue) {
29 | curValue = newValue;
30 | bindExpression.assign(scope, newValue);
31 | }
32 | });
33 |
34 | scope.$watch(attrs[directiveName], function (newValue) {
35 | if (newValue !== curValue) {
36 | curValue = newValue;
37 | domElement[prop] = newValue;
38 | }
39 | });
40 |
41 |
42 | if (domElement.nodeName === 'INPUT' || domElement.nodeName === 'TEXTAREA') {
43 | domElement.addEventListener('input', function () {
44 | var newValue = domElement[prop];
45 | if (newValue !== curValue) {
46 | curValue = newValue;
47 | bindExpression.assign(scope, newValue);
48 | scope.$apply();
49 | }
50 | });
51 | }
52 |
53 | }
54 | };
55 | }]);
56 | });
57 | }
58 |
59 | //Taken from https://github.com/angular/angular.js/blob/master/src/ng/directive/ngEventDirs.js
60 | function registerEventDirectives(ngModule) {
61 | var forceAsyncEvents = {
62 | 'blur': true,
63 | 'focus': true
64 | };
65 | angular.forEach(
66 | 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
67 | function (eventName) {
68 | var directiveName = `(${eventName})`;
69 | ngModule.directive(directiveName, ['$parse', '$rootScope', function ($parse, $rootScope) {
70 | return {
71 | restrict: 'A',
72 | compile: function ($element, attr) {
73 | // We expose the powerful $event object on the scope that provides access to the Window,
74 | // etc. that isn't protected by the fast paths in $parse. We explicitly request better
75 | // checks at the cost of speed since event handler expressions are not executed as
76 | // frequently as regular change detection.
77 | var fn = $parse(attr[directiveName], /* interceptorFn */ null, /* expensiveChecks */ true);
78 | return function ngEventHandler(scope, element) {
79 | element.on(eventName, function (event) {
80 | var callback = function () {
81 | fn(scope, {$event: event});
82 | };
83 | if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
84 | scope.$evalAsync(callback);
85 | } else {
86 | scope.$apply(callback);
87 | }
88 | });
89 | };
90 | }
91 | };
92 | }]);
93 | }
94 | );
95 | }
96 |
97 | export default function (ngModule) {
98 | registerPropertyDirectives(ngModule);
99 | registerEventDirectives(ngModule);
100 | };
--------------------------------------------------------------------------------
/dist/es6/angular2/ngNext/registerNg2Directives.js:
--------------------------------------------------------------------------------
1 | function registerPropertyDirectives(ngModule) {
2 | const ALL_PROPERTIES = ['abbr', 'accept', 'acceptCharset', 'accessKey', 'accessKeyLabel', 'action', 'allowfullscreen', 'alt', 'areas', 'async', 'attributes', 'audioTracks', 'autocomplete', 'autofocus', 'autoplay', 'baseURI', 'buffered', 'caption', 'cellIndex', 'cells', 'challenge', 'charset', 'checked', 'childElementCount', 'childNodes', 'children', 'cite', 'classList', 'className', 'clientHeight', 'clientLeft', 'clientTop', 'clientWidth', 'color', 'cols', 'colSpan', 'complete', 'content', 'contentDocument', 'contentEditable', 'contentWindow', 'contextMenu', 'control', 'controller', 'controls', 'coords', 'crossOrigin', 'currentSrc', 'currentTime', 'data', 'dataset', 'datetime', 'default', 'defaultChecked', 'defaultMuted', 'defaultPlaybackRate', 'defaultSelected', 'defaultValue', 'defer', 'dir', 'dirName', 'disabled', 'download', 'draggable', 'dropzone', 'duration', 'elements', 'encoding', 'enctype', 'ended', 'error', 'face', 'files', 'firstChild', 'firstElementChild', 'form', 'formAction', 'formEncType', 'formMethod', 'formNoValidate', 'formTarget', 'hash', 'headers', 'height', 'hidden', 'high', 'host', 'hostname', 'href', 'hreflang', 'htmlFor', 'httpEquiv', 'id', 'images', 'indeterminate', 'index', 'innerHTML', 'inputMode', 'isContentEditable', 'isMap', 'itemId', 'itemProp', 'itemRef', 'itemScope', 'itemType', 'itemValue', 'keySystem', 'keytype', 'kind', 'label', 'labels', 'lang', 'lastChild', 'lastElementChild', 'length', 'list', 'loop', 'low', 'max', 'maxLength', 'media', 'mediaGroup', 'menu', 'method', 'min', 'multiple', 'muted', 'name', 'naturalHeight', 'naturalWidth', 'networkState', 'nextElementSibling', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue', 'noValidate', 'offsetHeight', 'offsetLeft', 'offsetParent', 'offsetTop', 'offsetWidth', 'optimum', 'options', 'origin', 'outerHTML', 'ownerDocument', 'parentElement', 'parentNode', 'password', 'pathname', 'pattern', 'paused', 'placeholder', 'playbackRate', 'played', 'port', 'position', 'poster', 'preload', 'previousElementSibling', 'previousSibling', 'properties', 'protocol', 'readOnly', 'readyState', 'rel', 'relList', 'required', 'reversed', 'rowIndex', 'rows', 'rowSpan', 'sandbox', 'scope', 'scoped', 'scrollHeight', 'scrollLeft', 'scrollTop', 'scrollWidth', 'seamless', 'search', 'sectionRowIndex', 'seekable', 'seeking', 'select', 'selected', 'selectedIndex', 'selectedOptions', 'selectionDirection', 'selectionEnd', 'selectionStart', 'shadowRoot', 'sheet', 'size', 'sizes', 'sortable', 'sorted', 'span', 'spellcheck', 'src', 'srcdoc', 'srclang', 'srcset', 'start', 'step', 'style', 'tabIndex', 'tagName', 'target', 'tBodies', 'text', 'textContent', 'textLength', 'textTracks', 'tFoot', 'tHead', 'title', 'track', 'translate', 'type', 'typeMustMatch', 'undoManager', 'undoScope', 'useMap', 'username', 'validationMessage', 'validity', 'value', 'valueAsDate', 'valueAsNumber', 'videoHeight', 'videoTracks', 'videoWidth', 'volume', 'width', 'willValidate', 'wrap'];
3 |
4 | angular.forEach(ALL_PROPERTIES, function (prop) {
5 | var directiveName = `[${prop}]`;
6 | ngModule.directive(directiveName, ['$parse', '$timeout', function ($parse, $timeout) {
7 | return {
8 | restrict: 'A',
9 | link: function (scope, element, attrs) {
10 | var domElement = element[0];
11 |
12 | var bindExpression = $parse(attrs[directiveName]);
13 |
14 | var curValue = bindExpression(scope);
15 | if (curValue === undefined) {
16 | curValue = domElement[prop];
17 | if (curValue !== undefined) {
18 | bindExpression.assign(scope, curValue);
19 | }
20 | } else {
21 | domElement[prop] = curValue;
22 | }
23 |
24 |
25 | //Note that this will only be called on a digest and changes to a property won't necessarily trigger a digest.
26 | scope.$watch(() => domElement[prop],
27 | function (newValue) {
28 | if (newValue !== curValue) {
29 | curValue = newValue;
30 | bindExpression.assign(scope, newValue);
31 | }
32 | });
33 |
34 | scope.$watch(attrs[directiveName], function (newValue) {
35 | if (newValue !== curValue) {
36 | curValue = newValue;
37 | domElement[prop] = newValue;
38 | }
39 | });
40 |
41 |
42 | if (domElement.nodeName === 'INPUT' || domElement.nodeName === 'TEXTAREA') {
43 | domElement.addEventListener('input', function () {
44 | var newValue = domElement[prop];
45 | if (newValue !== curValue) {
46 | curValue = newValue;
47 | bindExpression.assign(scope, newValue);
48 | scope.$apply();
49 | }
50 | });
51 | }
52 |
53 | }
54 | };
55 | }]);
56 | });
57 | }
58 |
59 | //Taken from https://github.com/angular/angular.js/blob/master/src/ng/directive/ngEventDirs.js
60 | function registerEventDirectives(ngModule) {
61 | var forceAsyncEvents = {
62 | 'blur': true,
63 | 'focus': true
64 | };
65 | angular.forEach(
66 | 'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
67 | function (eventName) {
68 | var directiveName = `(${eventName})`;
69 | ngModule.directive(directiveName, ['$parse', '$rootScope', function ($parse, $rootScope) {
70 | return {
71 | restrict: 'A',
72 | compile: function ($element, attr) {
73 | // We expose the powerful $event object on the scope that provides access to the Window,
74 | // etc. that isn't protected by the fast paths in $parse. We explicitly request better
75 | // checks at the cost of speed since event handler expressions are not executed as
76 | // frequently as regular change detection.
77 | var fn = $parse(attr[directiveName], /* interceptorFn */ null, /* expensiveChecks */ true);
78 | return function ngEventHandler(scope, element) {
79 | element.on(eventName, function (event) {
80 | var callback = function () {
81 | fn(scope, {$event: event});
82 | };
83 | if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
84 | scope.$evalAsync(callback);
85 | } else {
86 | scope.$apply(callback);
87 | }
88 | });
89 | };
90 | }
91 | };
92 | }]);
93 | }
94 | );
95 | }
96 |
97 | export default function (ngModule) {
98 | registerPropertyDirectives(ngModule);
99 | registerEventDirectives(ngModule);
100 | };
--------------------------------------------------------------------------------
/examples/color-slider/build/css/blue-grey-theme.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Angular Material Design
3 | * https://github.com/angular/material
4 | * @license MIT
5 | * v0.6.1
6 | */
7 | md-backdrop.md-opaque.md-blue-grey-theme {
8 | background-color: rgba(0, 0, 0, 0.3);
9 | position: absolute; }
10 |
11 | md-bottom-sheet.md-blue-grey-theme {
12 | background-color: #fafafa;
13 | border-top-color: #bdbdbd; }
14 | md-bottom-sheet.md-blue-grey-theme.md-list md-item {
15 | color: rgba(0, 0, 0, 0.54); }
16 | md-bottom-sheet.md-blue-grey-theme .md-subheader {
17 | background-color: #fafafa; }
18 | md-bottom-sheet.md-blue-grey-theme .md-subheader {
19 | color: rgba(0, 0, 0, 0.54); }
20 |
21 | .md-button.md-blue-grey-theme {
22 | border-radius: 3px; }
23 | .md-button.md-blue-grey-theme:not([disabled]):hover, .md-button.md-blue-grey-theme:not([disabled]):focus {
24 | background-color: rgba(158, 158, 158, 0.2); }
25 | .md-button.md-blue-grey-theme.md-fab {
26 | border-radius: 50%; }
27 | .md-button.md-blue-grey-theme.md-primary {
28 | color: #78909c;
29 | fill: #78909c; }
30 | .md-button.md-blue-grey-theme.md-warn {
31 | color: #ef5350;
32 | fill: #ef5350; }
33 | .md-button.md-blue-grey-theme.md-raised, .md-button.md-blue-grey-theme.md-fab {
34 | background-color: rgba(158, 158, 158, 0.185); }
35 | .md-button.md-blue-grey-theme.md-raised:not([disabled]):hover, .md-button.md-blue-grey-theme.md-raised:not([disabled]):focus, .md-button.md-blue-grey-theme.md-fab:not([disabled]):hover, .md-button.md-blue-grey-theme.md-fab:not([disabled]):focus {
36 | background-color: rgba(158, 158, 158, 0.3); }
37 | .md-button.md-blue-grey-theme.md-raised.md-primary, .md-button.md-blue-grey-theme.md-fab.md-primary {
38 | color: white;
39 | background-color: #607d8b; }
40 | .md-button.md-blue-grey-theme.md-raised.md-primary:not([disabled]):hover, .md-button.md-blue-grey-theme.md-raised.md-primary:not([disabled]):focus, .md-button.md-blue-grey-theme.md-fab.md-primary:not([disabled]):hover, .md-button.md-blue-grey-theme.md-fab.md-primary:not([disabled]):focus {
41 | background-color: #546e7a; }
42 | .md-button.md-blue-grey-theme.md-raised.md-warn, .md-button.md-blue-grey-theme.md-fab.md-warn {
43 | color: white;
44 | background-color: #f44336; }
45 | .md-button.md-blue-grey-theme.md-raised.md-warn:not([disabled]):hover, .md-button.md-blue-grey-theme.md-raised.md-warn:not([disabled]):focus, .md-button.md-blue-grey-theme.md-fab.md-warn:not([disabled]):hover, .md-button.md-blue-grey-theme.md-fab.md-warn:not([disabled]):focus {
46 | background-color: #d32f2f; }
47 | .md-button.md-blue-grey-theme[disabled], .md-button.md-blue-grey-theme.md-raised[disabled], .md-button.md-blue-grey-theme.md-fab[disabled] {
48 | color: rgba(0, 0, 0, 0.26);
49 | fill: rgba(0, 0, 0, 0.26);
50 | background-color: transparent;
51 | cursor: not-allowed; }
52 |
53 | md-card.md-blue-grey-theme {
54 | border-radius: 2px; }
55 | md-card.md-blue-grey-theme .md-card-image {
56 | border-radius: 2px 2px 0 0; }
57 |
58 | md-checkbox.md-blue-grey-theme .md-ripple {
59 | color: #43a047; }
60 | md-checkbox.md-blue-grey-theme.md-checked .md-ripple {
61 | color: #757575; }
62 | md-checkbox.md-blue-grey-theme .md-icon {
63 | border-color: rgba(0, 0, 0, 0.54); }
64 | md-checkbox.md-blue-grey-theme.md-checked .md-icon {
65 | background-color: rgba(102, 187, 106, 0.87); }
66 | md-checkbox.md-blue-grey-theme.md-checked .md-icon:after {
67 | border-color: #eeeeee; }
68 | md-checkbox.md-blue-grey-theme[disabled] .md-icon {
69 | border-color: rgba(0, 0, 0, 0.26); }
70 | md-checkbox.md-blue-grey-theme[disabled].md-checked .md-icon {
71 | background-color: rgba(0, 0, 0, 0.26); }
72 |
73 | md-content.md-blue-grey-theme {
74 | background-color: #ffffff; }
75 |
76 | md-dialog.md-blue-grey-theme {
77 | border-radius: 4px;
78 | background-color: #ffffff; }
79 | md-dialog.md-blue-grey-theme.md-content-overflow .md-actions {
80 | border-top-color: rgba(0, 0, 0, 0.12); }
81 |
82 | md-divider.md-blue-grey-theme {
83 | border-top-color: rgba(0, 0, 0, 0.12); }
84 |
85 | md-progress-circular.md-blue-grey-theme {
86 | background-color: transparent; }
87 | md-progress-circular.md-blue-grey-theme .md-inner .md-gap {
88 | border-top-color: #607d8b;
89 | border-bottom-color: #607d8b; }
90 | md-progress-circular.md-blue-grey-theme .md-inner .md-left .md-half-circle, md-progress-circular.md-blue-grey-theme .md-inner .md-right .md-half-circle {
91 | border-top-color: #607d8b; }
92 | md-progress-circular.md-blue-grey-theme .md-inner .md-right .md-half-circle {
93 | border-right-color: #607d8b; }
94 | md-progress-circular.md-blue-grey-theme .md-inner .md-left .md-half-circle {
95 | border-left-color: #607d8b; }
96 |
97 | md-progress-linear.md-blue-grey-theme .md-container {
98 | background-color: #cfd8dc; }
99 | md-progress-linear.md-blue-grey-theme .md-bar {
100 | background-color: #607d8b; }
101 | md-progress-linear.md-blue-grey-theme[md-mode=buffer] .md-dashed:before {
102 | background: radial-gradient(#cfd8dc 0%, #cfd8dc 16%, transparent 42%); }
103 | md-progress-linear.md-blue-grey-theme[md-mode=buffer] .md-bar1 {
104 | background-color: #cfd8dc; }
105 |
106 | md-radio-button.md-blue-grey-theme .md-container .md-ripple, md-switch.md-blue-grey-theme .md-switch-thumb .md-container .md-ripple {
107 | color: #43a047; }
108 | md-radio-button.md-blue-grey-theme .md-off, md-switch.md-blue-grey-theme .md-switch-thumb .md-off {
109 | border-color: rgba(0, 0, 0, 0.54); }
110 | md-radio-button.md-blue-grey-theme .md-on, md-switch.md-blue-grey-theme .md-switch-thumb .md-on {
111 | background-color: rgba(102, 187, 106, 0.87); }
112 | md-radio-button.md-blue-grey-theme.md-checked .md-off, md-switch.md-blue-grey-theme .md-switch-thumb.md-checked .md-off {
113 | border-color: rgba(102, 187, 106, 0.87); }
114 | md-radio-button.md-blue-grey-theme.md-checked .md-ink-ripple, md-switch.md-blue-grey-theme .md-switch-thumb.md-checked .md-ink-ripple {
115 | color: rgba(102, 187, 106, 0.87); }
116 |
117 | md-radio-group.md-blue-grey-theme:focus {
118 | border-color: rgba(0, 0, 0, 0.73); }
119 |
120 | md-slider.md-blue-grey-theme .md-track {
121 | background-color: rgba(0, 0, 0, 0.26); }
122 | md-slider.md-blue-grey-theme .md-track-fill {
123 | background-color: #607d8b; }
124 | md-slider.md-blue-grey-theme .md-thumb:after {
125 | border-color: #607d8b;
126 | background-color: #607d8b; }
127 | md-slider.md-blue-grey-theme .md-sign {
128 | background-color: #607d8b; }
129 | md-slider.md-blue-grey-theme .md-sign:after {
130 | border-top-color: #607d8b; }
131 | md-slider.md-blue-grey-theme .md-thumb-text {
132 | color: white; }
133 | md-slider.md-blue-grey-theme .md-focus-thumb {
134 | background-color: rgba(0, 0, 0, 0.54); }
135 | md-slider.md-blue-grey-theme .md-focus-ring {
136 | border-color: rgba(0, 0, 0, 0.12); }
137 | md-slider.md-blue-grey-theme .md-disabled-thumb {
138 | border-color: #ffffff; }
139 | md-slider.md-blue-grey-theme.md-min .md-thumb:after {
140 | background-color: #ffffff; }
141 | md-slider.md-blue-grey-theme[disabled] .md-thumb:after {
142 | border-color: #bdbdbd; }
143 | md-slider.md-blue-grey-theme[disabled]:not(.md-min) .md-thumb:after {
144 | background-color: #bdbdbd; }
145 |
146 | .md-subheader.md-blue-grey-theme {
147 | color: rgba(0, 0, 0, 0.54);
148 | background-color: #ffffff; }
149 | .md-subheader.md-blue-grey-theme.md-primary {
150 | color: #607d8b; }
151 |
152 | md-switch.md-blue-grey-theme .md-switch-bar {
153 | background-color: rgba(0, 0, 0, 0.54); }
154 | md-switch.md-blue-grey-theme .md-switch-thumb:focus .md-label {
155 | border: 1px dotted black; }
156 |
157 | md-tabs.md-blue-grey-theme .md-header {
158 | background-color: #607d8b; }
159 | md-tabs.md-blue-grey-theme md-tabs-ink-bar {
160 | color: #ffff85;
161 | background: #ffff85; }
162 | md-tabs.md-blue-grey-theme md-tab {
163 | color: #cfd8dc; }
164 | md-tabs.md-blue-grey-theme md-tab.active {
165 | color: white; }
166 | md-tabs.md-blue-grey-theme md-tab[disabled] {
167 | color: rgba(0, 0, 0, 0.12); }
168 | md-tabs.md-blue-grey-theme md-tab:focus {
169 | border-color: rgba(0, 0, 0, 0.73); }
170 | md-tabs.md-blue-grey-theme md-tab .md-ripple-container {
171 | color: #ffff85; }
172 |
173 | md-input-group.md-blue-grey-theme input, md-input-group.md-blue-grey-theme textarea {
174 | text-shadow: none; }
175 | md-input-group.md-blue-grey-theme input:-ms-input-placeholder, md-input-group.md-blue-grey-theme textarea:-ms-input-placeholder {
176 | color: rgba(0, 0, 0, 0.26); }
177 | md-input-group.md-blue-grey-theme input::-webkit-input-placeholder, md-input-group.md-blue-grey-theme textarea::-webkit-input-placeholder {
178 | color: rgba(0, 0, 0, 0.26); }
179 | md-input-group.md-blue-grey-theme label {
180 | text-shadow: none;
181 | color: rgba(0, 0, 0, 0.26); }
182 | md-input-group.md-blue-grey-theme input, md-input-group.md-blue-grey-theme textarea {
183 | color: rgba(0, 0, 0, 0.73);
184 | border-color: rgba(0, 0, 0, 0.12); }
185 | md-input-group.md-blue-grey-theme.md-input-focused input, md-input-group.md-blue-grey-theme.md-input-focused textarea {
186 | border-color: #607d8b; }
187 | md-input-group.md-blue-grey-theme.md-input-focused label {
188 | color: #607d8b; }
189 | md-input-group.md-blue-grey-theme.md-input-has-value:not(.md-input-focused) label {
190 | color: rgba(0, 0, 0, 0.372); }
191 | md-input-group.md-blue-grey-theme[disabled] input, md-input-group.md-blue-grey-theme[disabled] textarea {
192 | border-bottom-color: rgba(0, 0, 0, 0.12);
193 | color: rgba(0, 0, 0, 0.26);
194 | background-image: linear-gradient(to right, rgba(0, 0, 0, 0.19) 0%, rgba(0, 0, 0, 0.19) 50%, rgba(0, 0, 0, 0) 0%); }
195 |
196 | md-toast.md-blue-grey-theme {
197 | background-color: #323232;
198 | color: white; }
199 | md-toast.md-blue-grey-theme .md-button {
200 | color: white; }
201 | md-toast.md-blue-grey-theme .md-action {
202 | }
203 |
204 | md-toolbar.md-blue-grey-theme {
205 | background-color: #607d8b;
206 | color: white; }
207 | md-toolbar.md-blue-grey-theme .md-button {
208 | color: white; }
209 |
210 | md-tooltip.md-blue-grey-theme {
211 | color: #ffffff; }
212 | md-tooltip.md-blue-grey-theme .md-background {
213 | background-color: rgba(0, 0, 0, 0.52); }
214 |
--------------------------------------------------------------------------------
/src/angular2/rtts-assert.js:
--------------------------------------------------------------------------------
1 | var _global = typeof window === 'object' ? window : global;
2 |
3 | // TODO(vojta):
4 | // - extract into multiple files
5 | // - different error types
6 | // - simplify/humanize error messages
7 | // - throw when invalid input (such as odd number of args into assert.argumentTypes)
8 |
9 | var POSITION_NAME = ['', '1st', '2nd', '3rd'];
10 | function argPositionName(i) {
11 | var position = (i / 2) + 1;
12 |
13 | return POSITION_NAME[position] || (position + 'th');
14 | }
15 |
16 | var primitives;
17 | var genericType;
18 |
19 | if (typeof $traceurRuntime === 'object') {
20 | primitives = $traceurRuntime.type;
21 | genericType = $traceurRuntime.genericType;
22 | } else {
23 | // Allow to work without traceur runtime as well!
24 | primitives = {
25 | any: {name: 'any'},
26 | boolean: {name: 'boolean'},
27 | number: {name: 'number'},
28 | string: {name: 'string'},
29 | symbol: {name: 'symbol'},
30 | void: {name: 'void'}
31 | };
32 | genericType = function(type, args) {
33 | return {
34 | type: type,
35 | args: args
36 | }
37 | }
38 | }
39 | Object.keys(primitives).forEach(function(name) {
40 | primitives[name].__assertName = name;
41 | });
42 |
43 | export function proxy(){
44 | }
45 |
46 | function assertArgumentTypes(...params) {
47 | var actual, type;
48 | var currentArgErrors;
49 | var errors = [];
50 | var msg;
51 |
52 | for (var i = 0, l = params.length; i < l; i = i + 2) {
53 | actual = params[i];
54 | type = params[i + 1];
55 |
56 | currentArgErrors = [];
57 |
58 | // currentStack = [];
59 | //
60 |
61 | if (!isType(actual, type, currentArgErrors)) {
62 |
63 | // console.log(JSON.stringify(errors, null, ' '));
64 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
65 | errors.push(argPositionName(i) + ' argument has to be an instance of ' + prettyPrint(type) + ', got ' + prettyPrint(actual));
66 | if (currentArgErrors.length) {
67 | errors.push(currentArgErrors);
68 | }
69 | }
70 | }
71 |
72 | if (errors.length) {
73 | throw new Error('Invalid arguments given!\n' + formatErrors(errors));
74 | }
75 | }
76 |
77 | function prettyPrint(value) {
78 | if (typeof value === 'undefined') {
79 | return 'undefined';
80 | }
81 |
82 | if (typeof value === 'string') {
83 | return '"' + value + '"';
84 | }
85 |
86 | if (typeof value === 'boolean') {
87 | return value.toString();
88 | }
89 |
90 | if (value === null) {
91 | return 'null';
92 | }
93 |
94 | if (typeof value === 'object') {
95 | if (value.__assertName) {
96 | return value.__assertName;
97 | }
98 |
99 | if (value.map) {
100 | return '[' + value.map(prettyPrint).join(', ') + ']';
101 | }
102 |
103 | var properties = Object.keys(value);
104 | return '{' + properties.map((p) => p + ': ' + prettyPrint(value[p])).join(', ') + '}';
105 | }
106 |
107 | return value.__assertName || value.name || value.toString();
108 | }
109 |
110 | function isType(value, T, errors) {
111 | if (T && T.type) {
112 | // needed for generics.
113 | // TODO(tbosch): read out T.args and do assertions based on them as well!
114 | T = T.type;
115 | }
116 | if (T === primitives.void) {
117 | return typeof value === 'undefined';
118 | }
119 |
120 | if (_isProxy(value)) {
121 | return true;
122 | }
123 |
124 | if (T === primitives.any || value === null) {
125 | return true;
126 | }
127 |
128 | if (T === primitives.string) {
129 | return typeof value === 'string';
130 | }
131 |
132 | if (T === primitives.number) {
133 | return typeof value === 'number';
134 | }
135 |
136 | if (T === primitives.boolean) {
137 | return typeof value === 'boolean';
138 | }
139 |
140 | // var parentStack = currentStack;
141 | // currentStack = [];
142 |
143 | // shouldnt this create new stack?
144 | if (typeof T.assert === 'function') {
145 | var parentStack = currentStack;
146 | var isValid;
147 | currentStack = errors;
148 | try {
149 | isValid = T.assert(value) ;
150 | } catch (e) {
151 | fail(e.message);
152 | isValid = false;
153 | }
154 |
155 | currentStack = parentStack;
156 |
157 | if (typeof isValid === 'undefined') {
158 | isValid = errors.length === 0;
159 | }
160 |
161 | return isValid;
162 |
163 | // if (!currentStack.length) {
164 | // currentStack = parentStack;
165 | // return [];
166 | // }
167 | // var res = currentStack;
168 | // currentStack = parentStack;
169 | // return ['not instance of ' + prettyPrint(T), res];
170 | }
171 |
172 | return value instanceof T;
173 |
174 | // if (!(value instanceof T)) {
175 | // fail('not instance of ' + prettyPrint(T));
176 | // }
177 |
178 | // var res = currentStack;
179 | // currentStack = parentStack;
180 |
181 | // return res;
182 | }
183 |
184 | function _isProxy(obj) {
185 | if (!obj || !obj.constructor || !obj.constructor.annotations) return false;
186 | return obj.constructor.annotations.filter((a) => a instanceof proxy).length > 0;
187 | }
188 |
189 | function formatErrors(errors, indent = ' ') {
190 | return errors.map((e) => {
191 | if (typeof e === 'string') return indent + '- ' + e;
192 | return formatErrors(e, indent + ' ');
193 | }).join('\n');
194 | }
195 |
196 |
197 | // assert a type of given value and throw if does not pass
198 | function type(actual, T) {
199 | var errors = [];
200 | // currentStack = [];
201 |
202 | if (!isType(actual, T, errors)) {
203 | // console.log(JSON.stringify(errors, null, ' '));
204 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
205 | var msg = 'Expected an instance of ' + prettyPrint(T) + ', got ' + prettyPrint(actual) + '!';
206 | if (errors.length) {
207 | msg += '\n' + formatErrors(errors);
208 | }
209 |
210 | throw new Error(msg);
211 | }
212 | return actual;
213 | }
214 |
215 | function returnType(actual, T) {
216 | var errors = [];
217 | // currentStack = [];
218 |
219 | if (!isType(actual, T, errors)) {
220 | // console.log(JSON.stringify(errors, null, ' '));
221 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
222 | var msg = 'Expected to return an instance of ' + prettyPrint(T) + ', got ' + prettyPrint(actual) + '!';
223 | if (errors.length) {
224 | msg += '\n' + formatErrors(errors);
225 | }
226 |
227 | throw new Error(msg);
228 | }
229 |
230 | return actual;
231 | }
232 |
233 | // TODO(vojta): define these with DSL?
234 | var string = type.string = define('string', function(value) {
235 | return typeof value === 'string';
236 | });
237 |
238 | var boolean = type.boolean = define('boolean', function(value) {
239 | return typeof value === 'boolean';
240 | });
241 |
242 | var number = type.number = define('number', function(value) {
243 | return typeof value === 'number';
244 | });
245 |
246 | function arrayOf(...types) {
247 | return assert.define('array of ' + types.map(prettyPrint).join('/'), function(value) {
248 | if (assert(value).is(Array)) {
249 | for (var item of value) {
250 | assert(item).is(...types);
251 | }
252 | }
253 | });
254 | }
255 |
256 | function structure(definition) {
257 | var properties = Object.keys(definition);
258 | return assert.define('object with properties ' + properties.join(', '), function(value) {
259 | if (assert(value).is(Object)) {
260 | for (var property of properties) {
261 | assert(value[property]).is(definition[property]);
262 | }
263 | }
264 | })
265 | }
266 |
267 |
268 |
269 | // I'm sorry, bad global state... to make the API nice ;-)
270 | var currentStack = [];
271 |
272 | function fail(message) {
273 | currentStack.push(message);
274 | }
275 |
276 | function define(classOrName, check) {
277 | var cls = classOrName;
278 |
279 | if (typeof classOrName === 'string') {
280 | cls = function() {};
281 | cls.__assertName = classOrName;
282 | }
283 |
284 | cls.assert = function(value) {
285 | // var parentStack = currentStack;
286 |
287 | // currentStack = [];
288 |
289 | return check(value);
290 |
291 | // if (currentStack.length) {
292 | // parentStack.push(currentStack)
293 | // }
294 | // currentStack = parentStack;
295 | };
296 |
297 | return cls;
298 | }
299 |
300 |
301 |
302 | function assert(value) {
303 | return {
304 | is: function is(...types) {
305 | // var errors = []
306 | var allErrors = [];
307 | var errors;
308 |
309 | for (var type of types) {
310 | errors = [];
311 |
312 | if (isType(value, type, errors)) {
313 | return true;
314 | }
315 |
316 | // if no errors, merge multiple "is not instance of " into x/y/z ?
317 | allErrors.push(prettyPrint(value) + ' is not instance of ' + prettyPrint(type))
318 | if (errors.length) {
319 | allErrors.push(errors);
320 | }
321 | }
322 |
323 | // if (types.length > 1) {
324 | // currentStack.push(['has to be ' + types.map(prettyPrint).join(' or '), ...allErrors]);
325 | // } else {
326 | currentStack.push(...allErrors);
327 | // }
328 | return false;
329 | }
330 | };
331 | }
332 |
333 |
334 | // PUBLIC API
335 |
336 | // asserting API
337 |
338 | // throw if no type provided
339 | assert.type = type;
340 | for (var prop in primitives) {
341 | assert.type[prop] = primitives[prop];
342 | }
343 | assert.genericType = genericType;
344 |
345 | // throw if odd number of args
346 | assert.argumentTypes = assertArgumentTypes;
347 | assert.returnType = returnType;
348 |
349 |
350 | // define AP;
351 | assert.define = define;
352 | assert.fail = fail;
353 |
354 | // primitive value type;
355 | assert.string = string;
356 | assert.number = number;
357 | assert.boolean = boolean;
358 |
359 | // custom types
360 | assert.arrayOf = arrayOf;
361 | assert.structure = structure;
362 |
363 |
364 | export {assert}
365 |
--------------------------------------------------------------------------------
/dist/es6/angular2/rtts-assert.js:
--------------------------------------------------------------------------------
1 | var _global = typeof window === 'object' ? window : global;
2 |
3 | // TODO(vojta):
4 | // - extract into multiple files
5 | // - different error types
6 | // - simplify/humanize error messages
7 | // - throw when invalid input (such as odd number of args into assert.argumentTypes)
8 |
9 | var POSITION_NAME = ['', '1st', '2nd', '3rd'];
10 | function argPositionName(i) {
11 | var position = (i / 2) + 1;
12 |
13 | return POSITION_NAME[position] || (position + 'th');
14 | }
15 |
16 | var primitives;
17 | var genericType;
18 |
19 | if (typeof $traceurRuntime === 'object') {
20 | primitives = $traceurRuntime.type;
21 | genericType = $traceurRuntime.genericType;
22 | } else {
23 | // Allow to work without traceur runtime as well!
24 | primitives = {
25 | any: {name: 'any'},
26 | boolean: {name: 'boolean'},
27 | number: {name: 'number'},
28 | string: {name: 'string'},
29 | symbol: {name: 'symbol'},
30 | void: {name: 'void'}
31 | };
32 | genericType = function(type, args) {
33 | return {
34 | type: type,
35 | args: args
36 | }
37 | }
38 | }
39 | Object.keys(primitives).forEach(function(name) {
40 | primitives[name].__assertName = name;
41 | });
42 |
43 | export function proxy(){
44 | }
45 |
46 | function assertArgumentTypes(...params) {
47 | var actual, type;
48 | var currentArgErrors;
49 | var errors = [];
50 | var msg;
51 |
52 | for (var i = 0, l = params.length; i < l; i = i + 2) {
53 | actual = params[i];
54 | type = params[i + 1];
55 |
56 | currentArgErrors = [];
57 |
58 | // currentStack = [];
59 | //
60 |
61 | if (!isType(actual, type, currentArgErrors)) {
62 |
63 | // console.log(JSON.stringify(errors, null, ' '));
64 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
65 | errors.push(argPositionName(i) + ' argument has to be an instance of ' + prettyPrint(type) + ', got ' + prettyPrint(actual));
66 | if (currentArgErrors.length) {
67 | errors.push(currentArgErrors);
68 | }
69 | }
70 | }
71 |
72 | if (errors.length) {
73 | throw new Error('Invalid arguments given!\n' + formatErrors(errors));
74 | }
75 | }
76 |
77 | function prettyPrint(value) {
78 | if (typeof value === 'undefined') {
79 | return 'undefined';
80 | }
81 |
82 | if (typeof value === 'string') {
83 | return '"' + value + '"';
84 | }
85 |
86 | if (typeof value === 'boolean') {
87 | return value.toString();
88 | }
89 |
90 | if (value === null) {
91 | return 'null';
92 | }
93 |
94 | if (typeof value === 'object') {
95 | if (value.__assertName) {
96 | return value.__assertName;
97 | }
98 |
99 | if (value.map) {
100 | return '[' + value.map(prettyPrint).join(', ') + ']';
101 | }
102 |
103 | var properties = Object.keys(value);
104 | return '{' + properties.map((p) => p + ': ' + prettyPrint(value[p])).join(', ') + '}';
105 | }
106 |
107 | return value.__assertName || value.name || value.toString();
108 | }
109 |
110 | function isType(value, T, errors) {
111 | if (T && T.type) {
112 | // needed for generics.
113 | // TODO(tbosch): read out T.args and do assertions based on them as well!
114 | T = T.type;
115 | }
116 | if (T === primitives.void) {
117 | return typeof value === 'undefined';
118 | }
119 |
120 | if (_isProxy(value)) {
121 | return true;
122 | }
123 |
124 | if (T === primitives.any || value === null) {
125 | return true;
126 | }
127 |
128 | if (T === primitives.string) {
129 | return typeof value === 'string';
130 | }
131 |
132 | if (T === primitives.number) {
133 | return typeof value === 'number';
134 | }
135 |
136 | if (T === primitives.boolean) {
137 | return typeof value === 'boolean';
138 | }
139 |
140 | // var parentStack = currentStack;
141 | // currentStack = [];
142 |
143 | // shouldnt this create new stack?
144 | if (typeof T.assert === 'function') {
145 | var parentStack = currentStack;
146 | var isValid;
147 | currentStack = errors;
148 | try {
149 | isValid = T.assert(value) ;
150 | } catch (e) {
151 | fail(e.message);
152 | isValid = false;
153 | }
154 |
155 | currentStack = parentStack;
156 |
157 | if (typeof isValid === 'undefined') {
158 | isValid = errors.length === 0;
159 | }
160 |
161 | return isValid;
162 |
163 | // if (!currentStack.length) {
164 | // currentStack = parentStack;
165 | // return [];
166 | // }
167 | // var res = currentStack;
168 | // currentStack = parentStack;
169 | // return ['not instance of ' + prettyPrint(T), res];
170 | }
171 |
172 | return value instanceof T;
173 |
174 | // if (!(value instanceof T)) {
175 | // fail('not instance of ' + prettyPrint(T));
176 | // }
177 |
178 | // var res = currentStack;
179 | // currentStack = parentStack;
180 |
181 | // return res;
182 | }
183 |
184 | function _isProxy(obj) {
185 | if (!obj || !obj.constructor || !obj.constructor.annotations) return false;
186 | return obj.constructor.annotations.filter((a) => a instanceof proxy).length > 0;
187 | }
188 |
189 | function formatErrors(errors, indent = ' ') {
190 | return errors.map((e) => {
191 | if (typeof e === 'string') return indent + '- ' + e;
192 | return formatErrors(e, indent + ' ');
193 | }).join('\n');
194 | }
195 |
196 |
197 | // assert a type of given value and throw if does not pass
198 | function type(actual, T) {
199 | var errors = [];
200 | // currentStack = [];
201 |
202 | if (!isType(actual, T, errors)) {
203 | // console.log(JSON.stringify(errors, null, ' '));
204 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
205 | var msg = 'Expected an instance of ' + prettyPrint(T) + ', got ' + prettyPrint(actual) + '!';
206 | if (errors.length) {
207 | msg += '\n' + formatErrors(errors);
208 | }
209 |
210 | throw new Error(msg);
211 | }
212 | return actual;
213 | }
214 |
215 | function returnType(actual, T) {
216 | var errors = [];
217 | // currentStack = [];
218 |
219 | if (!isType(actual, T, errors)) {
220 | // console.log(JSON.stringify(errors, null, ' '));
221 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
222 | var msg = 'Expected to return an instance of ' + prettyPrint(T) + ', got ' + prettyPrint(actual) + '!';
223 | if (errors.length) {
224 | msg += '\n' + formatErrors(errors);
225 | }
226 |
227 | throw new Error(msg);
228 | }
229 |
230 | return actual;
231 | }
232 |
233 | // TODO(vojta): define these with DSL?
234 | var string = type.string = define('string', function(value) {
235 | return typeof value === 'string';
236 | });
237 |
238 | var boolean = type.boolean = define('boolean', function(value) {
239 | return typeof value === 'boolean';
240 | });
241 |
242 | var number = type.number = define('number', function(value) {
243 | return typeof value === 'number';
244 | });
245 |
246 | function arrayOf(...types) {
247 | return assert.define('array of ' + types.map(prettyPrint).join('/'), function(value) {
248 | if (assert(value).is(Array)) {
249 | for (var item of value) {
250 | assert(item).is(...types);
251 | }
252 | }
253 | });
254 | }
255 |
256 | function structure(definition) {
257 | var properties = Object.keys(definition);
258 | return assert.define('object with properties ' + properties.join(', '), function(value) {
259 | if (assert(value).is(Object)) {
260 | for (var property of properties) {
261 | assert(value[property]).is(definition[property]);
262 | }
263 | }
264 | })
265 | }
266 |
267 |
268 |
269 | // I'm sorry, bad global state... to make the API nice ;-)
270 | var currentStack = [];
271 |
272 | function fail(message) {
273 | currentStack.push(message);
274 | }
275 |
276 | function define(classOrName, check) {
277 | var cls = classOrName;
278 |
279 | if (typeof classOrName === 'string') {
280 | cls = function() {};
281 | cls.__assertName = classOrName;
282 | }
283 |
284 | cls.assert = function(value) {
285 | // var parentStack = currentStack;
286 |
287 | // currentStack = [];
288 |
289 | return check(value);
290 |
291 | // if (currentStack.length) {
292 | // parentStack.push(currentStack)
293 | // }
294 | // currentStack = parentStack;
295 | };
296 |
297 | return cls;
298 | }
299 |
300 |
301 |
302 | function assert(value) {
303 | return {
304 | is: function is(...types) {
305 | // var errors = []
306 | var allErrors = [];
307 | var errors;
308 |
309 | for (var type of types) {
310 | errors = [];
311 |
312 | if (isType(value, type, errors)) {
313 | return true;
314 | }
315 |
316 | // if no errors, merge multiple "is not instance of " into x/y/z ?
317 | allErrors.push(prettyPrint(value) + ' is not instance of ' + prettyPrint(type))
318 | if (errors.length) {
319 | allErrors.push(errors);
320 | }
321 | }
322 |
323 | // if (types.length > 1) {
324 | // currentStack.push(['has to be ' + types.map(prettyPrint).join(' or '), ...allErrors]);
325 | // } else {
326 | currentStack.push(...allErrors);
327 | // }
328 | return false;
329 | }
330 | };
331 | }
332 |
333 |
334 | // PUBLIC API
335 |
336 | // asserting API
337 |
338 | // throw if no type provided
339 | assert.type = type;
340 | for (var prop in primitives) {
341 | assert.type[prop] = primitives[prop];
342 | }
343 | assert.genericType = genericType;
344 |
345 | // throw if odd number of args
346 | assert.argumentTypes = assertArgumentTypes;
347 | assert.returnType = returnType;
348 |
349 |
350 | // define AP;
351 | assert.define = define;
352 | assert.fail = fail;
353 |
354 | // primitive value type;
355 | assert.string = string;
356 | assert.number = number;
357 | assert.boolean = boolean;
358 |
359 | // custom types
360 | assert.arrayOf = arrayOf;
361 | assert.structure = structure;
362 |
363 |
364 | export {assert}
365 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/rtts-assert.js:
--------------------------------------------------------------------------------
1 | /* */
2 | var _global = typeof window === 'object' ? window : global;
3 |
4 | // TODO(vojta):
5 | // - extract into multiple files
6 | // - different error types
7 | // - simplify/humanize error messages
8 | // - throw when invalid input (such as odd number of args into assert.argumentTypes)
9 |
10 | var POSITION_NAME = ['', '1st', '2nd', '3rd'];
11 | function argPositionName(i) {
12 | var position = (i / 2) + 1;
13 |
14 | return POSITION_NAME[position] || (position + 'th');
15 | }
16 |
17 | var primitives;
18 | var genericType;
19 |
20 | if (typeof $traceurRuntime === 'object') {
21 | primitives = $traceurRuntime.type;
22 | genericType = $traceurRuntime.genericType;
23 | } else {
24 | // Allow to work without traceur runtime as well!
25 | primitives = {
26 | any: {name: 'any'},
27 | boolean: {name: 'boolean'},
28 | number: {name: 'number'},
29 | string: {name: 'string'},
30 | symbol: {name: 'symbol'},
31 | void: {name: 'void'}
32 | };
33 | genericType = function(type, args) {
34 | return {
35 | type: type,
36 | args: args
37 | }
38 | }
39 | }
40 | Object.keys(primitives).forEach(function(name) {
41 | primitives[name].__assertName = name;
42 | });
43 |
44 | export function proxy(){
45 | }
46 |
47 | function assertArgumentTypes(...params) {
48 | var actual, type;
49 | var currentArgErrors;
50 | var errors = [];
51 | var msg;
52 |
53 | for (var i = 0, l = params.length; i < l; i = i + 2) {
54 | actual = params[i];
55 | type = params[i + 1];
56 |
57 | currentArgErrors = [];
58 |
59 | // currentStack = [];
60 | //
61 |
62 | if (!isType(actual, type, currentArgErrors)) {
63 |
64 | // console.log(JSON.stringify(errors, null, ' '));
65 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
66 | errors.push(argPositionName(i) + ' argument has to be an instance of ' + prettyPrint(type) + ', got ' + prettyPrint(actual));
67 | if (currentArgErrors.length) {
68 | errors.push(currentArgErrors);
69 | }
70 | }
71 | }
72 |
73 | if (errors.length) {
74 | throw new Error('Invalid arguments given!\n' + formatErrors(errors));
75 | }
76 | }
77 |
78 | function prettyPrint(value) {
79 | if (typeof value === 'undefined') {
80 | return 'undefined';
81 | }
82 |
83 | if (typeof value === 'string') {
84 | return '"' + value + '"';
85 | }
86 |
87 | if (typeof value === 'boolean') {
88 | return value.toString();
89 | }
90 |
91 | if (value === null) {
92 | return 'null';
93 | }
94 |
95 | if (typeof value === 'object') {
96 | if (value.__assertName) {
97 | return value.__assertName;
98 | }
99 |
100 | if (value.map) {
101 | return '[' + value.map(prettyPrint).join(', ') + ']';
102 | }
103 |
104 | var properties = Object.keys(value);
105 | return '{' + properties.map((p) => p + ': ' + prettyPrint(value[p])).join(', ') + '}';
106 | }
107 |
108 | return value.__assertName || value.name || value.toString();
109 | }
110 |
111 | function isType(value, T, errors) {
112 | if (T && T.type) {
113 | // needed for generics.
114 | // TODO(tbosch): read out T.args and do assertions based on them as well!
115 | T = T.type;
116 | }
117 | if (T === primitives.void) {
118 | return typeof value === 'undefined';
119 | }
120 |
121 | if (_isProxy(value)) {
122 | return true;
123 | }
124 |
125 | if (T === primitives.any || value === null) {
126 | return true;
127 | }
128 |
129 | if (T === primitives.string) {
130 | return typeof value === 'string';
131 | }
132 |
133 | if (T === primitives.number) {
134 | return typeof value === 'number';
135 | }
136 |
137 | if (T === primitives.boolean) {
138 | return typeof value === 'boolean';
139 | }
140 |
141 | // var parentStack = currentStack;
142 | // currentStack = [];
143 |
144 | // shouldnt this create new stack?
145 | if (typeof T.assert === 'function') {
146 | var parentStack = currentStack;
147 | var isValid;
148 | currentStack = errors;
149 | try {
150 | isValid = T.assert(value) ;
151 | } catch (e) {
152 | fail(e.message);
153 | isValid = false;
154 | }
155 |
156 | currentStack = parentStack;
157 |
158 | if (typeof isValid === 'undefined') {
159 | isValid = errors.length === 0;
160 | }
161 |
162 | return isValid;
163 |
164 | // if (!currentStack.length) {
165 | // currentStack = parentStack;
166 | // return [];
167 | // }
168 | // var res = currentStack;
169 | // currentStack = parentStack;
170 | // return ['not instance of ' + prettyPrint(T), res];
171 | }
172 |
173 | return value instanceof T;
174 |
175 | // if (!(value instanceof T)) {
176 | // fail('not instance of ' + prettyPrint(T));
177 | // }
178 |
179 | // var res = currentStack;
180 | // currentStack = parentStack;
181 |
182 | // return res;
183 | }
184 |
185 | function _isProxy(obj) {
186 | if (!obj || !obj.constructor || !obj.constructor.annotations) return false;
187 | return obj.constructor.annotations.filter((a) => a instanceof proxy).length > 0;
188 | }
189 |
190 | function formatErrors(errors, indent = ' ') {
191 | return errors.map((e) => {
192 | if (typeof e === 'string') return indent + '- ' + e;
193 | return formatErrors(e, indent + ' ');
194 | }).join('\n');
195 | }
196 |
197 |
198 | // assert a type of given value and throw if does not pass
199 | function type(actual, T) {
200 | var errors = [];
201 | // currentStack = [];
202 |
203 | if (!isType(actual, T, errors)) {
204 | // console.log(JSON.stringify(errors, null, ' '));
205 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
206 | var msg = 'Expected an instance of ' + prettyPrint(T) + ', got ' + prettyPrint(actual) + '!';
207 | if (errors.length) {
208 | msg += '\n' + formatErrors(errors);
209 | }
210 |
211 | throw new Error(msg);
212 | }
213 | return actual;
214 | }
215 |
216 | function returnType(actual, T) {
217 | var errors = [];
218 | // currentStack = [];
219 |
220 | if (!isType(actual, T, errors)) {
221 | // console.log(JSON.stringify(errors, null, ' '));
222 | // TODO(vojta): print "an instance of" only if T starts with uppercase.
223 | var msg = 'Expected to return an instance of ' + prettyPrint(T) + ', got ' + prettyPrint(actual) + '!';
224 | if (errors.length) {
225 | msg += '\n' + formatErrors(errors);
226 | }
227 |
228 | throw new Error(msg);
229 | }
230 |
231 | return actual;
232 | }
233 |
234 | // TODO(vojta): define these with DSL?
235 | var string = type.string = define('string', function(value) {
236 | return typeof value === 'string';
237 | });
238 |
239 | var boolean = type.boolean = define('boolean', function(value) {
240 | return typeof value === 'boolean';
241 | });
242 |
243 | var number = type.number = define('number', function(value) {
244 | return typeof value === 'number';
245 | });
246 |
247 | function arrayOf(...types) {
248 | return assert.define('array of ' + types.map(prettyPrint).join('/'), function(value) {
249 | if (assert(value).is(Array)) {
250 | for (var item of value) {
251 | assert(item).is(...types);
252 | }
253 | }
254 | });
255 | }
256 |
257 | function structure(definition) {
258 | var properties = Object.keys(definition);
259 | return assert.define('object with properties ' + properties.join(', '), function(value) {
260 | if (assert(value).is(Object)) {
261 | for (var property of properties) {
262 | assert(value[property]).is(definition[property]);
263 | }
264 | }
265 | })
266 | }
267 |
268 |
269 |
270 | // I'm sorry, bad global state... to make the API nice ;-)
271 | var currentStack = [];
272 |
273 | function fail(message) {
274 | currentStack.push(message);
275 | }
276 |
277 | function define(classOrName, check) {
278 | var cls = classOrName;
279 |
280 | if (typeof classOrName === 'string') {
281 | cls = function() {};
282 | cls.__assertName = classOrName;
283 | }
284 |
285 | cls.assert = function(value) {
286 | // var parentStack = currentStack;
287 |
288 | // currentStack = [];
289 |
290 | return check(value);
291 |
292 | // if (currentStack.length) {
293 | // parentStack.push(currentStack)
294 | // }
295 | // currentStack = parentStack;
296 | };
297 |
298 | return cls;
299 | }
300 |
301 |
302 |
303 | function assert(value) {
304 | return {
305 | is: function is(...types) {
306 | // var errors = []
307 | var allErrors = [];
308 | var errors;
309 |
310 | for (var type of types) {
311 | errors = [];
312 |
313 | if (isType(value, type, errors)) {
314 | return true;
315 | }
316 |
317 | // if no errors, merge multiple "is not instance of " into x/y/z ?
318 | allErrors.push(prettyPrint(value) + ' is not instance of ' + prettyPrint(type))
319 | if (errors.length) {
320 | allErrors.push(errors);
321 | }
322 | }
323 |
324 | // if (types.length > 1) {
325 | // currentStack.push(['has to be ' + types.map(prettyPrint).join(' or '), ...allErrors]);
326 | // } else {
327 | currentStack.push(...allErrors);
328 | // }
329 | return false;
330 | }
331 | };
332 | }
333 |
334 |
335 | // PUBLIC API
336 |
337 | // asserting API
338 |
339 | // throw if no type provided
340 | assert.type = type;
341 | for (var prop in primitives) {
342 | assert.type[prop] = primitives[prop];
343 | }
344 | assert.genericType = genericType;
345 |
346 | // throw if odd number of args
347 | assert.argumentTypes = assertArgumentTypes;
348 | assert.returnType = returnType;
349 |
350 |
351 | // define AP;
352 | assert.define = define;
353 | assert.fail = fail;
354 |
355 | // primitive value type;
356 | assert.string = string;
357 | assert.number = number;
358 | assert.boolean = boolean;
359 |
360 | // custom types
361 | assert.arrayOf = arrayOf;
362 | assert.structure = structure;
363 |
364 |
365 | export {assert}
366 |
--------------------------------------------------------------------------------
/examples/hello-jspm/jspm_packages/github/robianmcd/angular-next@0.0.3/ngNext/angular2Adapter.js:
--------------------------------------------------------------------------------
1 | /* */
2 | import {Directive, DirectiveClass} from '../ng2/directive';
3 | import {Component, ComponentClass} from '../ng2/component';
4 | import {Template} from '../ng2/template';
5 | import {NgElement} from '../ng2/ngElement';
6 | import {InjectNgOne} from './injectNgOne';
7 | import polyfillPromise from './polyfillPromise';
8 |
9 | class Angular2Adapter {
10 | constructor({moduleName, logLevel = 0}) {
11 | this.moduleName = moduleName;
12 | this.app = angular.module(moduleName);
13 | //not currently used
14 | this.logLevel = logLevel;
15 |
16 | this.registeredDirectives = new Set();
17 |
18 | polyfillPromise(this.app);
19 | }
20 |
21 | bootstrapComponent(rootComponent:ComponentClass) {
22 | var rootComponentAnno:Component;
23 | rootComponentAnno = this.getDirAnno(rootComponent);
24 |
25 | var rootElement = document.querySelector(rootComponentAnno.selector);
26 |
27 | angular.element(rootElement).ready(() => {
28 | this.registerDirectiveTree(rootComponent);
29 | angular.bootstrap(rootElement, [this.moduleName]);
30 | });
31 | }
32 |
33 | registerDirectiveTree(dir:DirectiveClass) {
34 | if(this.registeredDirectives.has(dir)) {
35 | return;
36 | } else {
37 | this.registeredDirectives.add(dir);
38 | }
39 |
40 | this.registerDirective(dir);
41 |
42 | var templateAnno = this.getTemplateAnno(dir);
43 | if (templateAnno && templateAnno.directives) {
44 | templateAnno.directives.forEach((childDir) => {
45 | this.registerDirectiveTree(childDir);
46 | });
47 | }
48 | }
49 |
50 | registerDirective(dir:DirectiveClass) {
51 | dir = this.wrapDir(dir);
52 | dir.$inject = this.getInjectArray(dir);
53 |
54 | this.registerComponentServices(dir);
55 |
56 | var dirInfo = this.getNg1DirectiveInfo(dir);
57 |
58 | this.app.directive(dirInfo.name, function () {
59 | return dirInfo.ddo;
60 | });
61 | }
62 |
63 | registerComponentServices(dir:DirectiveClass) {
64 | var dirAnno = this.getDirAnno(dir);
65 |
66 | //Register component services
67 | if (dirAnno.componentServices) {
68 | dirAnno.componentServices.forEach((serviceType) => {
69 | serviceType.$inject = this.getInjectArray(serviceType);
70 | this.app.service(this.lowerCaseFirstLetter(this.getFunctionName(serviceType)), serviceType);
71 | });
72 | }
73 | }
74 |
75 | //Returns name and ddo for a directive class
76 | getNg1DirectiveInfo(dir:DirectiveClass) {
77 | var dirAnno = this.getDirAnno(dir);
78 |
79 | var restrict;
80 | var dashesDirectiveName;
81 |
82 | //Try and match an attribute selector. e.g. "[attr]"
83 | //If it matches store the attribute name in match[1]
84 | var match;
85 | if (match = dirAnno.selector.match(/^\[(.*)\]$/)) {
86 | restrict = 'A';
87 | dashesDirectiveName = match[1];
88 |
89 | //Try to match a class selector. e.g. ".class"
90 | } else if (match = dirAnno.selector.match(/^\.(.*)$/)) {
91 | restrict = 'C';
92 | dashesDirectiveName = match[1];
93 |
94 | } else {
95 | restrict = 'E';
96 | dashesDirectiveName = dirAnno.selector;
97 | }
98 |
99 | var scope = {};
100 |
101 | for (var key in dirAnno.bind) {
102 | if (dirAnno.bind.hasOwnProperty(key)) {
103 | scope[key] = '=' + dirAnno.bind[key];
104 | }
105 | }
106 |
107 | var ddo = {
108 | restrict: restrict,
109 | controller: dir,
110 | controllerAs: dirAnno.controllerAs,
111 | scope: scope,
112 | bindToController: true
113 | };
114 |
115 | var templateAnno = this.getTemplateAnno(dir);
116 | if(templateAnno) {
117 | if(templateAnno.inline) {
118 | ddo.template = templateAnno.inline;
119 | } else if (templateAnno.url) {
120 | ddo.templateUrl = templateAnno.url;
121 | }
122 | }
123 |
124 | //Convert the directive name from dash separated to camelCase
125 | var name = dashesDirectiveName.replace(/-([a-z])/g, char => char[1].toUpperCase());
126 |
127 | return {name, ddo};
128 | }
129 |
130 | //Services that require $element (e.g. NgElement) cannot be injected normally as $element can only be injected
131 | //directly into the controller of a directive. If the directive passed in requires any of these services then it
132 | //will be wrapped (inherited) by a function that injects $element and manually initialized the $element based
133 | //services before passing them in.
134 | wrapDir(dirType:DirectiveClass) {
135 | var adapter = this;
136 |
137 | var dirAnno = this.getDirAnno(dirType);
138 |
139 | var retDirType = dirType;
140 |
141 | if (dirType.parameters) {
142 | var injectableServices = [];
143 |
144 | //e.g. {pos: 3, type: MyDir}
145 | var uninjectableParams = [];
146 | var requiresElement = false;
147 | var requiresScope = false;
148 |
149 | for (var i = 0; i < dirType.parameters.length; i++) {
150 | var curParamType = dirType.parameters[i][0];
151 |
152 | //TODO: should check if they are already injecting $element or $scope so we don't end up injecting it twice
153 |
154 | if (curParamType === NgElement || this.isDirClass(curParamType)) {
155 | uninjectableParams.push({pos: i, type: curParamType});
156 | requiresElement = true;
157 | } else {
158 | injectableServices.push(curParamType);
159 | }
160 | }
161 |
162 | if (dirAnno.observe) {
163 | requiresScope = true;
164 | }
165 |
166 |
167 | //If the directive needs to be wrapped
168 | if (uninjectableParams.length || requiresElement || requiresScope) {
169 |
170 | retDirType = function (...args) {
171 | var element, scope;
172 |
173 | if (requiresScope) {
174 | scope = args.pop();
175 | }
176 |
177 | if (requiresElement) {
178 | element = args.pop();
179 | }
180 |
181 | var origDirParams = angular.copy(args);
182 |
183 | //Manually create each parameter that could not be injected
184 | uninjectableParams.forEach((param) => {
185 | var model;
186 | if (param.type === NgElement) {
187 | model = new NgElement(element);
188 | } else if (adapter.isDirClass(param.type)) {
189 | var dirName = adapter.lowerCaseFirstLetter(adapter.getFunctionName(param.type));
190 | model = element.inheritedData(`$${dirName}Controller`);
191 | }
192 | origDirParams.splice(param.pos, 0, model);
193 | });
194 |
195 | //Setup any watches specified in dirAnno.observe
196 | if (dirAnno.observe) {
197 | for (let key in dirAnno.observe) {
198 | if (dirAnno.observe.hasOwnProperty(key)) {
199 | let functionName = dirAnno.observe[key];
200 |
201 | scope.$watch(`${dirAnno.controllerAs}.${key}`, (newValue, oldValue) => {
202 | if (this[functionName]) {
203 | this[functionName](newValue, oldValue);
204 | } else {
205 | console.warn(`'${key}' has changed but observe function, '${functionName}' does not exist.`);
206 | }
207 | });
208 | }
209 | }
210 | }
211 |
212 | //Steal constructor
213 | dirType.apply(this, origDirParams);
214 | };
215 |
216 | //Inherit prototype
217 | retDirType.prototype = Object.create(dirType.prototype);
218 | retDirType.annotations = dirType.annotations;
219 | retDirType.parameters = injectableServices.map(type => [type]);
220 |
221 | if (requiresElement) {
222 | retDirType.parameters.push([new InjectNgOne('$element')]);
223 | }
224 | if (requiresScope) {
225 | retDirType.parameters.push([new InjectNgOne('$scope')]);
226 | }
227 | }
228 | }
229 |
230 | return retDirType;
231 | }
232 |
233 | getInjectArray(aClass:Function) {
234 | var $inject = [];
235 |
236 | if (aClass.parameters) {
237 | aClass.parameters.forEach((paramAnnotations) => {
238 | $inject.push(this.getInjectStrFromParamAnnotations(paramAnnotations));
239 | });
240 | }
241 |
242 | return $inject;
243 | }
244 |
245 | getInjectStrFromParamAnnotations(paramAnnotations) {
246 | for (var i = 0; i < paramAnnotations.length; i++) {
247 | var paramAnno = paramAnnotations[i];
248 |
249 | if (paramAnno instanceof InjectNgOne) {
250 | return paramAnno.typeStr;
251 | } else if (paramAnno instanceof Function) {
252 | return this.lowerCaseFirstLetter(this.getFunctionName(paramAnno));
253 | }
254 | }
255 |
256 | if(paramAnnotations.length === 0) {
257 | throw `Could not inject parameter. You must either specify its type or annotate it with @InjectNgOne('...').`;
258 | } else {
259 | throw `Could not determine how to inject parameter with annotations: ${paramAnnotations}`;
260 | }
261 |
262 | }
263 |
264 | getDirAnno(directive:DirectiveClass) {
265 | var dirAnnos = directive.annotations.filter((annotation) => annotation instanceof Directive);
266 |
267 | return dirAnnos.length ? dirAnnos[0] : undefined;
268 | }
269 |
270 | getTemplateAnno(directive:DirectiveClass) {
271 | var dirAnnos = directive.annotations.filter((annotation) => annotation instanceof Template);
272 |
273 | return dirAnnos.length ? dirAnnos[0] : undefined;
274 | }
275 |
276 | lowerCaseFirstLetter(str) {
277 | return str.charAt(0).toLowerCase() + str.slice(1);
278 | }
279 |
280 | getFunctionName(func:Function) {
281 | if (func.name) {
282 | return func.name;
283 |
284 | //IE doesn't support function.name and neither does traceur.
285 | } else {
286 | var ret = func.toString();
287 | ret = ret.substr('function '.length);
288 | ret = ret.substr(0, ret.indexOf('('));
289 | return ret;
290 | }
291 | }
292 |
293 | isDirClass(obj) {
294 | return !!(obj.annotations && obj.annotations.filter(anno => anno instanceof Directive).length);
295 | }
296 |
297 | }
298 |
299 | export {Angular2Adapter};
--------------------------------------------------------------------------------
/dist/es6/angular2/ngNext/angular2Adapter.js:
--------------------------------------------------------------------------------
1 | import {Directive, DirectiveClass} from '../ng2/directive';
2 | import {Component, ComponentClass} from '../ng2/component';
3 | import {Template} from '../ng2/template';
4 | import {NgElement} from '../ng2/ngElement';
5 | import {InjectNgOne} from './injectNgOne';
6 | import polyfillPromise from './polyfillPromise';
7 | import registerNg2Directives from './registerNg2Directives';
8 |
9 | class Angular2Adapter {
10 | constructor({moduleName, logLevel = 0}) {
11 | this.moduleName = moduleName;
12 | this.app = angular.module(moduleName);
13 | //not currently used
14 | this.logLevel = logLevel;
15 |
16 | this.registeredDirectives = new Set();
17 |
18 | polyfillPromise(this.app);
19 | registerNg2Directives(this.app);
20 |
21 | }
22 |
23 | bootstrapComponent(rootComponent:ComponentClass) {
24 | var rootComponentAnno:Component;
25 | rootComponentAnno = this.getDirAnno(rootComponent);
26 |
27 | var rootElement = document.querySelector(rootComponentAnno.selector);
28 |
29 | angular.element(rootElement).ready(() => {
30 | this.registerDirectiveTree(rootComponent);
31 | angular.bootstrap(rootElement, [this.moduleName]);
32 | });
33 | }
34 |
35 | registerDirectiveTree(dir:DirectiveClass) {
36 | if(this.registeredDirectives.has(dir)) {
37 | return;
38 | } else {
39 | this.registeredDirectives.add(dir);
40 | }
41 |
42 | this.registerDirective(dir);
43 |
44 | var templateAnno = this.getTemplateAnno(dir);
45 | if (templateAnno && templateAnno.directives) {
46 | templateAnno.directives.forEach((childDir) => {
47 | this.registerDirectiveTree(childDir);
48 | });
49 | }
50 | }
51 |
52 | registerDirective(dir:DirectiveClass) {
53 | dir = this.wrapDir(dir);
54 | dir.$inject = this.getInjectArray(dir);
55 |
56 | this.registerComponentServices(dir);
57 |
58 | var dirInfo = this.getNg1DirectiveInfo(dir);
59 |
60 | this.app.directive(dirInfo.name, function () {
61 | return dirInfo.ddo;
62 | });
63 | }
64 |
65 | registerComponentServices(dir:DirectiveClass) {
66 | var dirAnno = this.getDirAnno(dir);
67 |
68 | //Register component services
69 | if (dirAnno.componentServices) {
70 | dirAnno.componentServices.forEach((serviceType) => {
71 | serviceType.$inject = this.getInjectArray(serviceType);
72 | this.app.service(this.lowerCaseFirstLetter(this.getFunctionName(serviceType)), serviceType);
73 | });
74 | }
75 | }
76 |
77 | //Returns name and ddo for a directive class
78 | getNg1DirectiveInfo(dir:DirectiveClass) {
79 | var dirAnno = this.getDirAnno(dir);
80 |
81 | var restrict;
82 | var dashesDirectiveName;
83 |
84 | //Try and match an attribute selector. e.g. "[attr]"
85 | //If it matches store the attribute name in match[1]
86 | var match;
87 | if (match = dirAnno.selector.match(/^\[(.*)\]$/)) {
88 | restrict = 'A';
89 | dashesDirectiveName = match[1];
90 |
91 | //Try to match a class selector. e.g. ".class"
92 | } else if (match = dirAnno.selector.match(/^\.(.*)$/)) {
93 | restrict = 'C';
94 | dashesDirectiveName = match[1];
95 |
96 | } else {
97 | restrict = 'E';
98 | dashesDirectiveName = dirAnno.selector;
99 | }
100 |
101 | var scope = {};
102 |
103 | for (var key in dirAnno.bind) {
104 | if (dirAnno.bind.hasOwnProperty(key)) {
105 | scope[key] = '=' + dirAnno.bind[key];
106 | }
107 | }
108 |
109 | var ddo = {
110 | restrict: restrict,
111 | controller: dir,
112 | controllerAs: dirAnno.controllerAs,
113 | scope: scope,
114 | bindToController: true
115 | };
116 |
117 | var templateAnno = this.getTemplateAnno(dir);
118 | if(templateAnno) {
119 | if(templateAnno.inline) {
120 | ddo.template = templateAnno.inline;
121 | } else if (templateAnno.url) {
122 | ddo.templateUrl = templateAnno.url;
123 | }
124 | }
125 |
126 | //Convert the directive name from dash separated to camelCase
127 | var name = dashesDirectiveName.replace(/-([a-z])/g, char => char[1].toUpperCase());
128 |
129 | return {name, ddo};
130 | }
131 |
132 | //Services that require $element (e.g. NgElement) cannot be injected normally as $element can only be injected
133 | //directly into the controller of a directive. If the directive passed in requires any of these services then it
134 | //will be wrapped (inherited) by a function that injects $element and manually initialized the $element based
135 | //services before passing them in.
136 | wrapDir(dirType:DirectiveClass) {
137 | var adapter = this;
138 |
139 | var dirAnno = this.getDirAnno(dirType);
140 |
141 | var retDirType = dirType;
142 |
143 | if (dirType.parameters) {
144 | var injectableServices = [];
145 |
146 | //e.g. {pos: 3, type: MyDir}
147 | var uninjectableParams = [];
148 | var requiresElement = false;
149 | var requiresScope = false;
150 |
151 | for (var i = 0; i < dirType.parameters.length; i++) {
152 | var curParamType = dirType.parameters[i][0];
153 |
154 | //TODO: should check if they are already injecting $element or $scope so we don't end up injecting it twice
155 |
156 | if (curParamType === NgElement || this.isDirClass(curParamType)) {
157 | uninjectableParams.push({pos: i, type: curParamType});
158 | requiresElement = true;
159 | } else {
160 | injectableServices.push(curParamType);
161 | }
162 | }
163 |
164 | if (dirAnno.observe) {
165 | requiresScope = true;
166 | }
167 |
168 |
169 | //If the directive needs to be wrapped
170 | if (uninjectableParams.length || requiresElement || requiresScope) {
171 |
172 | retDirType = function (...args) {
173 | var element, scope;
174 |
175 | if (requiresScope) {
176 | scope = args.pop();
177 | }
178 |
179 | if (requiresElement) {
180 | element = args.pop();
181 | }
182 |
183 | var origDirParams = angular.copy(args);
184 |
185 | //Manually create each parameter that could not be injected
186 | uninjectableParams.forEach((param) => {
187 | var model;
188 | if (param.type === NgElement) {
189 | model = new NgElement(element);
190 | } else if (adapter.isDirClass(param.type)) {
191 | var dirName = adapter.lowerCaseFirstLetter(adapter.getFunctionName(param.type));
192 | model = element.inheritedData(`$${dirName}Controller`);
193 | }
194 | origDirParams.splice(param.pos, 0, model);
195 | });
196 |
197 | //Setup any watches specified in dirAnno.observe
198 | if (dirAnno.observe) {
199 | for (let key in dirAnno.observe) {
200 | if (dirAnno.observe.hasOwnProperty(key)) {
201 | let functionName = dirAnno.observe[key];
202 |
203 | scope.$watch(`${dirAnno.controllerAs}.${key}`, (newValue, oldValue) => {
204 | if (this[functionName]) {
205 | this[functionName](newValue, oldValue);
206 | } else {
207 | console.warn(`'${key}' has changed but observe function, '${functionName}' does not exist.`);
208 | }
209 | });
210 | }
211 | }
212 | }
213 |
214 | //Steal constructor
215 | dirType.apply(this, origDirParams);
216 | };
217 |
218 | //Inherit prototype
219 | retDirType.prototype = Object.create(dirType.prototype);
220 | retDirType.annotations = dirType.annotations;
221 | retDirType.parameters = injectableServices.map(type => [type]);
222 |
223 | if (requiresElement) {
224 | retDirType.parameters.push([new InjectNgOne('$element')]);
225 | }
226 | if (requiresScope) {
227 | retDirType.parameters.push([new InjectNgOne('$scope')]);
228 | }
229 | }
230 | }
231 |
232 | return retDirType;
233 | }
234 |
235 | getInjectArray(aClass:Function) {
236 | var $inject = [];
237 |
238 | if (aClass.parameters) {
239 | aClass.parameters.forEach((paramAnnotations) => {
240 | $inject.push(this.getInjectStrFromParamAnnotations(paramAnnotations));
241 | });
242 | }
243 |
244 | return $inject;
245 | }
246 |
247 | getInjectStrFromParamAnnotations(paramAnnotations) {
248 | for (var i = 0; i < paramAnnotations.length; i++) {
249 | var paramAnno = paramAnnotations[i];
250 |
251 | if (paramAnno instanceof InjectNgOne) {
252 | return paramAnno.typeStr;
253 | } else if (paramAnno instanceof Function) {
254 | return this.lowerCaseFirstLetter(this.getFunctionName(paramAnno));
255 | }
256 | }
257 |
258 | if(paramAnnotations.length === 0) {
259 | throw `Could not inject parameter. You must either specify its type or annotate it with @InjectNgOne('...').`;
260 | } else {
261 | throw `Could not determine how to inject parameter with annotations: ${paramAnnotations}`;
262 | }
263 |
264 | }
265 |
266 | getDirAnno(directive:DirectiveClass) {
267 | var dirAnnos = directive.annotations.filter((annotation) => annotation instanceof Directive);
268 |
269 | return dirAnnos.length ? dirAnnos[0] : undefined;
270 | }
271 |
272 | getTemplateAnno(directive:DirectiveClass) {
273 | var dirAnnos = directive.annotations.filter((annotation) => annotation instanceof Template);
274 |
275 | return dirAnnos.length ? dirAnnos[0] : undefined;
276 | }
277 |
278 | lowerCaseFirstLetter(str) {
279 | return str.charAt(0).toLowerCase() + str.slice(1);
280 | }
281 |
282 | getFunctionName(func:Function) {
283 | if (func.name) {
284 | return func.name;
285 |
286 | //IE doesn't support function.name and neither does traceur.
287 | } else {
288 | var ret = func.toString();
289 | ret = ret.substr('function '.length);
290 | ret = ret.substr(0, ret.indexOf('('));
291 | return ret;
292 | }
293 | }
294 |
295 | isDirClass(obj) {
296 | return !!(obj.annotations && obj.annotations.filter(anno => anno instanceof Directive).length);
297 | }
298 |
299 | }
300 |
301 | export {Angular2Adapter};
--------------------------------------------------------------------------------
/src/angular2/ngNext/angular2Adapter.js:
--------------------------------------------------------------------------------
1 | import {Directive, DirectiveClass} from '../ng2/directive.js';
2 | import {Component, ComponentClass} from '../ng2/component.js';
3 | import {Template} from '../ng2/template.js';
4 | import {NgElement} from '../ng2/ngElement.js';
5 | import {InjectNgOne} from './injectNgOne.js';
6 | import polyfillPromise from './polyfillPromise.js';
7 | import registerNg2Directives from './registerNg2Directives.js';
8 |
9 | class Angular2Adapter {
10 | constructor({moduleName, logLevel = 0}) {
11 | this.moduleName = moduleName;
12 | this.app = angular.module(moduleName);
13 | //not currently used
14 | this.logLevel = logLevel;
15 |
16 | this.registeredDirectives = new Set();
17 |
18 | polyfillPromise(this.app);
19 | registerNg2Directives(this.app);
20 |
21 | }
22 |
23 | bootstrapComponent(rootComponent:ComponentClass) {
24 | var rootComponentAnno:Component;
25 | rootComponentAnno = this.getDirAnno(rootComponent);
26 |
27 | var rootElement = document.querySelector(rootComponentAnno.selector);
28 |
29 | angular.element(rootElement).ready(() => {
30 | this.registerDirectiveTree(rootComponent);
31 | angular.bootstrap(rootElement, [this.moduleName]);
32 | });
33 | }
34 |
35 | registerDirectiveTree(dir:DirectiveClass) {
36 | if(this.registeredDirectives.has(dir)) {
37 | return;
38 | } else {
39 | this.registeredDirectives.add(dir);
40 | }
41 |
42 | this.registerDirective(dir);
43 |
44 | var templateAnno = this.getTemplateAnno(dir);
45 | if (templateAnno && templateAnno.directives) {
46 | templateAnno.directives.forEach((childDir) => {
47 | this.registerDirectiveTree(childDir);
48 | });
49 | }
50 | }
51 |
52 | registerDirective(dir:DirectiveClass) {
53 | dir = this.wrapDir(dir);
54 | dir.$inject = this.getInjectArray(dir);
55 |
56 | this.registerComponentServices(dir);
57 |
58 | var dirInfo = this.getNg1DirectiveInfo(dir);
59 |
60 | this.app.directive(dirInfo.name, function () {
61 | return dirInfo.ddo;
62 | });
63 | }
64 |
65 | registerComponentServices(dir:DirectiveClass) {
66 | var dirAnno = this.getDirAnno(dir);
67 |
68 | //Register component services
69 | if (dirAnno.componentServices) {
70 | dirAnno.componentServices.forEach((serviceType) => {
71 | serviceType.$inject = this.getInjectArray(serviceType);
72 | this.app.service(this.lowerCaseFirstLetter(this.getFunctionName(serviceType)), serviceType);
73 | });
74 | }
75 | }
76 |
77 | //Returns name and ddo for a directive class
78 | getNg1DirectiveInfo(dir:DirectiveClass) {
79 | var dirAnno = this.getDirAnno(dir);
80 |
81 | var restrict;
82 | var dashesDirectiveName;
83 |
84 | //Try and match an attribute selector. e.g. "[attr]"
85 | //If it matches store the attribute name in match[1]
86 | var match;
87 | if (match = dirAnno.selector.match(/^\[(.*)\]$/)) {
88 | restrict = 'A';
89 | dashesDirectiveName = match[1];
90 |
91 | //Try to match a class selector. e.g. ".class"
92 | } else if (match = dirAnno.selector.match(/^\.(.*)$/)) {
93 | restrict = 'C';
94 | dashesDirectiveName = match[1];
95 |
96 | } else {
97 | restrict = 'E';
98 | dashesDirectiveName = dirAnno.selector;
99 | }
100 |
101 | var scope = {};
102 |
103 | for (var key in dirAnno.bind) {
104 | if (dirAnno.bind.hasOwnProperty(key)) {
105 | scope[key] = '=' + dirAnno.bind[key];
106 | }
107 | }
108 |
109 | var ddo = {
110 | restrict: restrict,
111 | controller: dir,
112 | controllerAs: dirAnno.controllerAs,
113 | scope: scope,
114 | bindToController: true
115 | };
116 |
117 | var templateAnno = this.getTemplateAnno(dir);
118 | if(templateAnno) {
119 | if(templateAnno.inline) {
120 | ddo.template = templateAnno.inline;
121 | } else if (templateAnno.url) {
122 | ddo.templateUrl = templateAnno.url;
123 | }
124 | }
125 |
126 | //Convert the directive name from dash separated to camelCase
127 | var name = dashesDirectiveName.replace(/-([a-z])/g, char => char[1].toUpperCase());
128 |
129 | return {name, ddo};
130 | }
131 |
132 | //Services that require $element (e.g. NgElement) cannot be injected normally as $element can only be injected
133 | //directly into the controller of a directive. If the directive passed in requires any of these services then it
134 | //will be wrapped (inherited) by a function that injects $element and manually initialized the $element based
135 | //services before passing them in.
136 | wrapDir(dirType:DirectiveClass) {
137 | var adapter = this;
138 |
139 | var dirAnno = this.getDirAnno(dirType);
140 |
141 | var retDirType = dirType;
142 |
143 | if (dirType.parameters) {
144 | var injectableServices = [];
145 |
146 | //e.g. {pos: 3, type: MyDir}
147 | var uninjectableParams = [];
148 | var requiresElement = false;
149 | var requiresScope = false;
150 |
151 | for (var i = 0; i < dirType.parameters.length; i++) {
152 | var curParamType = dirType.parameters[i][0];
153 |
154 | //TODO: should check if they are already injecting $element or $scope so we don't end up injecting it twice
155 |
156 | if (curParamType === NgElement || this.isDirClass(curParamType)) {
157 | uninjectableParams.push({pos: i, type: curParamType});
158 | requiresElement = true;
159 | } else {
160 | injectableServices.push(curParamType);
161 | }
162 | }
163 |
164 | if (dirAnno.observe) {
165 | requiresScope = true;
166 | }
167 |
168 |
169 | //If the directive needs to be wrapped
170 | if (uninjectableParams.length || requiresElement || requiresScope) {
171 |
172 | retDirType = function (...args) {
173 | var element, scope;
174 |
175 | if (requiresScope) {
176 | scope = args.pop();
177 | }
178 |
179 | if (requiresElement) {
180 | element = args.pop();
181 | }
182 |
183 | var origDirParams = angular.copy(args);
184 |
185 | //Manually create each parameter that could not be injected
186 | uninjectableParams.forEach((param) => {
187 | var model;
188 | if (param.type === NgElement) {
189 | model = new NgElement(element);
190 | } else if (adapter.isDirClass(param.type)) {
191 | var dirName = adapter.lowerCaseFirstLetter(adapter.getFunctionName(param.type));
192 | model = element.inheritedData(`$${dirName}Controller`);
193 | }
194 | origDirParams.splice(param.pos, 0, model);
195 | });
196 |
197 | //Setup any watches specified in dirAnno.observe
198 | if (dirAnno.observe) {
199 | for (let key in dirAnno.observe) {
200 | if (dirAnno.observe.hasOwnProperty(key)) {
201 | let functionName = dirAnno.observe[key];
202 |
203 | scope.$watch(`${dirAnno.controllerAs}.${key}`, (newValue, oldValue) => {
204 | if (this[functionName]) {
205 | this[functionName](newValue, oldValue);
206 | } else {
207 | console.warn(`'${key}' has changed but observe function, '${functionName}' does not exist.`);
208 | }
209 | });
210 | }
211 | }
212 | }
213 |
214 | //Steal constructor
215 | dirType.apply(this, origDirParams);
216 | };
217 |
218 | //Inherit prototype
219 | retDirType.prototype = Object.create(dirType.prototype);
220 | retDirType.annotations = dirType.annotations;
221 | retDirType.parameters = injectableServices.map(type => [type]);
222 |
223 | if (requiresElement) {
224 | retDirType.parameters.push([new InjectNgOne('$element')]);
225 | }
226 | if (requiresScope) {
227 | retDirType.parameters.push([new InjectNgOne('$scope')]);
228 | }
229 | }
230 | }
231 |
232 | return retDirType;
233 | }
234 |
235 | getInjectArray(aClass:Function) {
236 | var $inject = [];
237 |
238 | if (aClass.parameters) {
239 | aClass.parameters.forEach((paramAnnotations) => {
240 | $inject.push(this.getInjectStrFromParamAnnotations(paramAnnotations));
241 | });
242 | }
243 |
244 | return $inject;
245 | }
246 |
247 | getInjectStrFromParamAnnotations(paramAnnotations) {
248 | for (var i = 0; i < paramAnnotations.length; i++) {
249 | var paramAnno = paramAnnotations[i];
250 |
251 | if (paramAnno instanceof InjectNgOne) {
252 | return paramAnno.typeStr;
253 | } else if (paramAnno instanceof Function) {
254 | return this.lowerCaseFirstLetter(this.getFunctionName(paramAnno));
255 | }
256 | }
257 |
258 | if(paramAnnotations.length === 0) {
259 | throw `Could not inject parameter. You must either specify its type or annotate it with @InjectNgOne('...').`;
260 | } else {
261 | throw `Could not determine how to inject parameter with annotations: ${paramAnnotations}`;
262 | }
263 |
264 | }
265 |
266 | getDirAnno(directive:DirectiveClass) {
267 | var dirAnnos = directive.annotations.filter((annotation) => annotation instanceof Directive);
268 |
269 | return dirAnnos.length ? dirAnnos[0] : undefined;
270 | }
271 |
272 | getTemplateAnno(directive:DirectiveClass) {
273 | var dirAnnos = directive.annotations.filter((annotation) => annotation instanceof Template);
274 |
275 | return dirAnnos.length ? dirAnnos[0] : undefined;
276 | }
277 |
278 | lowerCaseFirstLetter(str) {
279 | return str.charAt(0).toLowerCase() + str.slice(1);
280 | }
281 |
282 | getFunctionName(func:Function) {
283 | if (func.name) {
284 | return func.name;
285 |
286 | //IE doesn't support function.name and neither does traceur.
287 | } else {
288 | var ret = func.toString();
289 | ret = ret.substr('function '.length);
290 | ret = ret.substr(0, ret.indexOf('('));
291 | return ret;
292 | }
293 | }
294 |
295 | isDirClass(obj) {
296 | return !!(obj.annotations && obj.annotations.filter(anno => anno instanceof Directive).length);
297 | }
298 |
299 | }
300 |
301 | export {Angular2Adapter};
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/examples/color-slider/build/vendor/angular-aria.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.3.8
3 | * (c) 2010-2014 Google, Inc. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular, undefined) {'use strict';
7 |
8 | /**
9 | * @ngdoc module
10 | * @name ngAria
11 | * @description
12 | *
13 | * The `ngAria` module provides support for common
14 | * [ARIA ](http://www.w3.org/TR/wai-aria/)
15 | * attributes that convey state or semantic information about the application for users
16 | * of assistive technologies, such as screen readers.
17 | *
18 | *
19 | *
20 | * ## Usage
21 | *
22 | * For ngAria to do its magic, simply include the module as a dependency. The directives supported
23 | * by ngAria are:
24 | * `ngModel`, `ngDisabled`, `ngShow`, `ngHide`, `ngClick`, `ngDblClick`, and `ngMessages`.
25 | *
26 | * Below is a more detailed breakdown of the attributes handled by ngAria:
27 | *
28 | * | Directive | Supported Attributes |
29 | * |---------------------------------------------|----------------------------------------------------------------------------------------|
30 | * | {@link ng.directive:ngModel ngModel} | aria-checked, aria-valuemin, aria-valuemax, aria-valuenow, aria-invalid, aria-required |
31 | * | {@link ng.directive:ngDisabled ngDisabled} | aria-disabled |
32 | * | {@link ng.directive:ngShow ngShow} | aria-hidden |
33 | * | {@link ng.directive:ngHide ngHide} | aria-hidden |
34 | * | {@link ng.directive:ngClick ngClick} | tabindex, keypress event |
35 | * | {@link ng.directive:ngDblclick ngDblclick} | tabindex |
36 | * | {@link module:ngMessages ngMessages} | aria-live |
37 | *
38 | * Find out more information about each directive by reading the
39 | * {@link guide/accessibility ngAria Developer Guide}.
40 | *
41 | * ##Example
42 | * Using ngDisabled with ngAria:
43 | * ```html
44 | *
45 | * ```
46 | * Becomes:
47 | * ```html
48 | *
49 | * ```
50 | *
51 | * ##Disabling Attributes
52 | * It's possible to disable individual attributes added by ngAria with the
53 | * {@link ngAria.$ariaProvider#config config} method. For more details, see the
54 | * {@link guide/accessibility Developer Guide}.
55 | */
56 | /* global -ngAriaModule */
57 | var ngAriaModule = angular.module('ngAria', ['ng']).
58 | provider('$aria', $AriaProvider);
59 |
60 | /**
61 | * @ngdoc provider
62 | * @name $ariaProvider
63 | *
64 | * @description
65 | *
66 | * Used for configuring the ARIA attributes injected and managed by ngAria.
67 | *
68 | * ```js
69 | * angular.module('myApp', ['ngAria'], function config($ariaProvider) {
70 | * $ariaProvider.config({
71 | * ariaValue: true,
72 | * tabindex: false
73 | * });
74 | * });
75 | *```
76 | *
77 | * ## Dependencies
78 | * Requires the {@link ngAria} module to be installed.
79 | *
80 | */
81 | function $AriaProvider() {
82 | var config = {
83 | ariaHidden: true,
84 | ariaChecked: true,
85 | ariaDisabled: true,
86 | ariaRequired: true,
87 | ariaInvalid: true,
88 | ariaMultiline: true,
89 | ariaValue: true,
90 | tabindex: true,
91 | bindKeypress: true
92 | };
93 |
94 | /**
95 | * @ngdoc method
96 | * @name $ariaProvider#config
97 | *
98 | * @param {object} config object to enable/disable specific ARIA attributes
99 | *
100 | * - **ariaHidden** – `{boolean}` – Enables/disables aria-hidden tags
101 | * - **ariaChecked** – `{boolean}` – Enables/disables aria-checked tags
102 | * - **ariaDisabled** – `{boolean}` – Enables/disables aria-disabled tags
103 | * - **ariaRequired** – `{boolean}` – Enables/disables aria-required tags
104 | * - **ariaInvalid** – `{boolean}` – Enables/disables aria-invalid tags
105 | * - **ariaMultiline** – `{boolean}` – Enables/disables aria-multiline tags
106 | * - **ariaValue** – `{boolean}` – Enables/disables aria-valuemin, aria-valuemax and aria-valuenow tags
107 | * - **tabindex** – `{boolean}` – Enables/disables tabindex tags
108 | * - **bindKeypress** – `{boolean}` – Enables/disables keypress event binding on ng-click
109 | *
110 | * @description
111 | * Enables/disables various ARIA attributes
112 | */
113 | this.config = function(newConfig) {
114 | config = angular.extend(config, newConfig);
115 | };
116 |
117 | function watchExpr(attrName, ariaAttr, negate) {
118 | return function(scope, elem, attr) {
119 | var ariaCamelName = attr.$normalize(ariaAttr);
120 | if (config[ariaCamelName] && !attr[ariaCamelName]) {
121 | scope.$watch(attr[attrName], function(boolVal) {
122 | if (negate) {
123 | boolVal = !boolVal;
124 | }
125 | elem.attr(ariaAttr, boolVal);
126 | });
127 | }
128 | };
129 | }
130 |
131 | /**
132 | * @ngdoc service
133 | * @name $aria
134 | *
135 | * @description
136 | *
137 | * The $aria service contains helper methods for applying common
138 | * [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives.
139 | *
140 | * ngAria injects common accessibility attributes that tell assistive technologies when HTML
141 | * elements are enabled, selected, hidden, and more. To see how this is performed with ngAria,
142 | * let's review a code snippet from ngAria itself:
143 | *
144 | *```js
145 | * ngAriaModule.directive('ngDisabled', ['$aria', function($aria) {
146 | * return $aria.$$watchExpr('ngDisabled', 'aria-disabled');
147 | * }])
148 | *```
149 | * Shown above, the ngAria module creates a directive with the same signature as the
150 | * traditional `ng-disabled` directive. But this ngAria version is dedicated to
151 | * solely managing accessibility attributes. The internal `$aria` service is used to watch the
152 | * boolean attribute `ngDisabled`. If it has not been explicitly set by the developer,
153 | * `aria-disabled` is injected as an attribute with its value synchronized to the value in
154 | * `ngDisabled`.
155 | *
156 | * Because ngAria hooks into the `ng-disabled` directive, developers do not have to do
157 | * anything to enable this feature. The `aria-disabled` attribute is automatically managed
158 | * simply as a silent side-effect of using `ng-disabled` with the ngAria module.
159 | *
160 | * The full list of directives that interface with ngAria:
161 | * * **ngModel**
162 | * * **ngShow**
163 | * * **ngHide**
164 | * * **ngClick**
165 | * * **ngDblclick**
166 | * * **ngMessages**
167 | * * **ngDisabled**
168 | *
169 | * Read the {@link guide/accessibility ngAria Developer Guide} for a thorough explanation of each
170 | * directive.
171 | *
172 | *
173 | * ## Dependencies
174 | * Requires the {@link ngAria} module to be installed.
175 | */
176 | this.$get = function() {
177 | return {
178 | config: function(key) {
179 | return config[key];
180 | },
181 | $$watchExpr: watchExpr
182 | };
183 | };
184 | }
185 |
186 |
187 | ngAriaModule.directive('ngShow', ['$aria', function($aria) {
188 | return $aria.$$watchExpr('ngShow', 'aria-hidden', true);
189 | }])
190 | .directive('ngHide', ['$aria', function($aria) {
191 | return $aria.$$watchExpr('ngHide', 'aria-hidden', false);
192 | }])
193 | .directive('ngModel', ['$aria', function($aria) {
194 |
195 | function shouldAttachAttr(attr, normalizedAttr, elem) {
196 | return $aria.config(normalizedAttr) && !elem.attr(attr);
197 | }
198 |
199 | function getShape(attr, elem) {
200 | var type = attr.type,
201 | role = attr.role;
202 |
203 | return ((type || role) === 'checkbox' || role === 'menuitemcheckbox') ? 'checkbox' :
204 | ((type || role) === 'radio' || role === 'menuitemradio') ? 'radio' :
205 | (type === 'range' || role === 'progressbar' || role === 'slider') ? 'range' :
206 | (type || role) === 'textbox' || elem[0].nodeName === 'TEXTAREA' ? 'multiline' : '';
207 | }
208 |
209 | return {
210 | restrict: 'A',
211 | require: '?ngModel',
212 | link: function(scope, elem, attr, ngModel) {
213 | var shape = getShape(attr, elem);
214 | var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem);
215 |
216 | function ngAriaWatchModelValue() {
217 | return ngModel.$modelValue;
218 | }
219 |
220 | function getRadioReaction() {
221 | if (needsTabIndex) {
222 | needsTabIndex = false;
223 | return function ngAriaRadioReaction(newVal) {
224 | var boolVal = newVal === attr.value;
225 | elem.attr('aria-checked', boolVal);
226 | elem.attr('tabindex', 0 - !boolVal);
227 | };
228 | } else {
229 | return function ngAriaRadioReaction(newVal) {
230 | elem.attr('aria-checked', newVal === attr.value);
231 | };
232 | }
233 | }
234 |
235 | function ngAriaCheckboxReaction(newVal) {
236 | elem.attr('aria-checked', !!newVal);
237 | }
238 |
239 | switch (shape) {
240 | case 'radio':
241 | case 'checkbox':
242 | if (shouldAttachAttr('aria-checked', 'ariaChecked', elem)) {
243 | scope.$watch(ngAriaWatchModelValue, shape === 'radio' ?
244 | getRadioReaction() : ngAriaCheckboxReaction);
245 | }
246 | break;
247 | case 'range':
248 | if ($aria.config('ariaValue')) {
249 | if (attr.min && !elem.attr('aria-valuemin')) {
250 | elem.attr('aria-valuemin', attr.min);
251 | }
252 | if (attr.max && !elem.attr('aria-valuemax')) {
253 | elem.attr('aria-valuemax', attr.max);
254 | }
255 | if (!elem.attr('aria-valuenow')) {
256 | scope.$watch(ngAriaWatchModelValue, function ngAriaValueNowReaction(newVal) {
257 | elem.attr('aria-valuenow', newVal);
258 | });
259 | }
260 | }
261 | break;
262 | case 'multiline':
263 | if (shouldAttachAttr('aria-multiline', 'ariaMultiline', elem)) {
264 | elem.attr('aria-multiline', true);
265 | }
266 | break;
267 | }
268 |
269 | if (needsTabIndex) {
270 | elem.attr('tabindex', 0);
271 | }
272 |
273 | if (ngModel.$validators.required && shouldAttachAttr('aria-required', 'ariaRequired', elem)) {
274 | scope.$watch(function ngAriaRequiredWatch() {
275 | return ngModel.$error.required;
276 | }, function ngAriaRequiredReaction(newVal) {
277 | elem.attr('aria-required', !!newVal);
278 | });
279 | }
280 |
281 | if (shouldAttachAttr('aria-invalid', 'ariaInvalid', elem)) {
282 | scope.$watch(function ngAriaInvalidWatch() {
283 | return ngModel.$invalid;
284 | }, function ngAriaInvalidReaction(newVal) {
285 | elem.attr('aria-invalid', !!newVal);
286 | });
287 | }
288 | }
289 | };
290 | }])
291 | .directive('ngDisabled', ['$aria', function($aria) {
292 | return $aria.$$watchExpr('ngDisabled', 'aria-disabled');
293 | }])
294 | .directive('ngMessages', function() {
295 | return {
296 | restrict: 'A',
297 | require: '?ngMessages',
298 | link: function(scope, elem, attr, ngMessages) {
299 | if (!elem.attr('aria-live')) {
300 | elem.attr('aria-live', 'assertive');
301 | }
302 | }
303 | };
304 | })
305 | .directive('ngClick',['$aria', '$parse', function($aria, $parse) {
306 | return {
307 | restrict: 'A',
308 | compile: function(elem, attr) {
309 | var fn = $parse(attr.ngClick, /* interceptorFn */ null, /* expensiveChecks */ true);
310 | return function(scope, elem, attr) {
311 | if ($aria.config('tabindex') && !elem.attr('tabindex')) {
312 | elem.attr('tabindex', 0);
313 | }
314 |
315 | if ($aria.config('bindKeypress') && !attr.ngKeypress) {
316 | elem.on('keypress', function(event) {
317 | if (event.keyCode === 32 || event.keyCode === 13) {
318 | scope.$apply(callback);
319 | }
320 |
321 | function callback() {
322 | fn(scope, { $event: event });
323 | }
324 | });
325 | }
326 | };
327 | }
328 | };
329 | }])
330 | .directive('ngDblclick', ['$aria', function($aria) {
331 | return function(scope, elem, attr) {
332 | if ($aria.config('tabindex') && !elem.attr('tabindex')) {
333 | elem.attr('tabindex', 0);
334 | }
335 | };
336 | }]);
337 |
338 |
339 | })(window, window.angular);
340 |
--------------------------------------------------------------------------------