├── .gitignore ├── .jshintrc ├── .travis.yml ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── bower.json ├── config.json ├── dist ├── a1atscript.bundle.js ├── a1atscript.bundle.js.map ├── a1atscript.system.bundle.js └── a1atscript.system.bundle.js.map ├── gulpfile.js ├── index.html ├── karma.conf.babel.js ├── karma.conf.js ├── karma_sourcemaps.js ├── package.json ├── scripts └── make-systemjs-bundle.js ├── src ├── a1atscript.js └── a1atscript │ ├── AnnotationFinder.js │ ├── DirectiveObject.js │ ├── Injector.js │ ├── Router.js │ ├── ToAnnotation.js │ ├── annotations.js │ ├── applyAnnotation.js │ ├── bootstrap.js │ ├── injectorTypes.js │ ├── ng2Directives │ ├── BindBuilder.js │ ├── Component.js │ ├── ComponentInjector.js │ ├── EventsBuilder.js │ ├── Ng2Directive.js │ ├── Ng2DirectiveDefinitionObject.js │ ├── PropertiesBuilder.js │ └── SelectorMatcher.js │ └── router │ ├── ComponentMapper.js │ ├── RouteConfig.js │ ├── RouteInitializer.js │ └── RouteReader.js ├── test-babel └── ToAnnotation_spec.js ├── test-help └── main.js ├── test ├── AnnotationFinder_spec.js ├── ComponentMapper_spec.js ├── Component_spec.js ├── DirectiveObject_spec.js ├── EventsBuilder_spec.js ├── Ng2DirectiveDefinitionObject_spec.js ├── NoRouterPresent_spec.js ├── PropertiesBuilder_spec.js ├── RoutableComponent_spec.js ├── RouteInitializer_spec.js ├── RouteReader_spec.js ├── SelectorMatcher_spec.js ├── ToAnnotation_spec.js ├── annotations_spec.js └── injector_spec.js ├── wait_for_watcher.js ├── webpack.config.js └── webstorm_traceur.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /bower_components 3 | /build 4 | .DS_Store 5 | /.idea 6 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | before_script: 5 | - npm install -g bower 6 | - bower install 7 | - export DISPLAY=:99.0 8 | - sh -e /etc/init.d/xvfb start 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 0.5.0 / 2016-02-18 2 | ================== 3 | 4 | * Universalize code between Babel and Traceur. Both now compile to code that is functionally the same 5 | * Add a SystemJS Bundle of package 6 | 7 | 0.4.5 / 2015-10-18 8 | ================== 9 | * Add applyAnnotation function to maintain compatibility between Babel / Traceur 10 | 11 | 0.4.4 / 2015-07-08 12 | ================== 13 | * BREAKING - removed ES6 files from the dist directory -- no need for double copies. 14 | * BREAKING - removed amd build in favor of webpack global 15 | * [Fix] support appInjector property instead of injectables on Component 16 | * [Fix] support array notation for properties and events on Component 17 | 18 | 0.4.3 / 2015-07-07 19 | ================== 20 | * [Fix] Bad export in a1atscript.js 21 | 22 | 0.4.2 / 2015-07-07 23 | ================== 24 | * [Fix] Bad import in ComponentMapper 25 | 26 | 0.4.1 / 2015-07-03 27 | ================== 28 | * [Feature] Add component hooks to component injector 29 | 30 | 0.4.0 / 2015-07-01 31 | ================== 32 | * [Fix] Multiple instances of components can use different bind types 33 | * [Fix] Make symbol exports explicit 34 | * [Fix] Make ngNewRouter not a dependency even if you have routeConfigs 35 | 36 | 0.3.9 / 2015-06-25 37 | ================== 38 | * [Fix] Component property getters 39 | 40 | 0.3.8 / 2015-06-19 41 | ================== 42 | * [Fix] Error with using bind-attr and attr at once from Tim Kindberg 43 | 44 | 0.3.7 / 2015-05-20 45 | ================== 46 | * Add a CJS distribution for JSPM 47 | 48 | 0.3.6 / 2015-05-08 49 | ================== 50 | * Add events to components 51 | 52 | 0.3.5 / 2015-05-07 53 | ================== 54 | * Fixed a bug in route initialization 55 | 56 | 0.3.2 / 2015-05-06 57 | ================== 58 | * Minor fixes 59 | 60 | 0.3.0 / 2015-05-05 61 | ================== 62 | * Add support for the new Angular Router! 63 | 64 | 0.2.5 / 2015-04-30 65 | ================== 66 | * Set properties enumerable when they get an annotation 67 | 68 | 0.2.4 / 2015-04-30 69 | ================== 70 | * [Fix] Make ToAnnotation work on a class/object property 71 | 72 | 0.2.3 / 2015-04-30 73 | ================== 74 | * Make ToAnnotation work on a class/object property 75 | 76 | 0.2.2 / 2015-04-29 77 | ================== 78 | * Make ToAnnotation a non default export so it can be used externally 79 | 80 | 0.2.1 / 2015-04-28 81 | ================== 82 | 83 | * Feature: Works with Babel.js and ESNext compilers that support ES7 decorator spec 84 | * Updated syntax for Components to latest Angular 2 names 85 | * directive selectors can now be written dasherized like an HTML selector 86 | 87 | 0.2.0 / 2015-02-17 88 | ================== 89 | * FEATURE: Components. Define Angular Components using an Angular 2 like syntax 90 | * FEATURE: abbreviated form of calling the injector by just calling bootstrap 91 | * FEATURE: include transpiled AMD version of library 92 | 93 | 0.1.4 / 2015-02-17 94 | ================== 95 | * BREAKING: Updated to the latest version of Traceur. This changes the way relative file imports are done. See [https://github.com/google/traceur-compiler/issues/1221](https://github.com/google/traceur-compiler/issues/1221) -- you can no longer use an implied .js extension on relative imports. If you have used the implied .js extension you may have to update 96 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Hannah Howard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Code Climate](https://codeclimate.com/github/hannahhoward/a1atscript/badges/gpa.svg)](https://codeclimate.com/github/hannahhoward/a1atscript) [![Build Status](https://travis-ci.org/hannahhoward/a1atscript.svg?branch=master)](https://travis-ci.org/hannahhoward/a1atscript) 2 | 3 | # A-1 AtScript 4 | 5 | [![Join the chat at https://gitter.im/hannahhoward/a1atscript](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/hannahhoward/a1atscript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 6 | 7 | This is a package that uses annotations to provide syntactic sugar around Angular 1.x's Dependency Injection mechanism. It is designed to be a "bridge" to Angular 2.0 -- to get you as close as possible to writing Angular 2.0 like code in Angular 1.x. More features will be added as Angular 2.0's feature set becomes more clear. 8 | 9 | ## Initial setup 10 | 11 | > You must be building your Angular 1.x with an ES Next transpiler. The system has been tested with both Babel.js and Traceur. See "Using a transpiler other than Traceur" for important caveats if you are not using Traceur. Check for tutorials on the internet for how to setup a JS build system that incorporates ES6. 12 | 13 | #### Install the module 14 | 15 | ```bash 16 | bower install a1atscript --save 17 | ``` 18 | 19 | or 20 | 21 | ```bash 22 | npm install a1atscript 23 | ``` 24 | 25 | #### Angular Type Annotations 26 | 27 | ```javascript 28 | import {Controller, Service} from 'bower_components/dist/a1atscript.js'; 29 | // or appropriate path for your project 30 | 31 | @Controller('ExampleController', ['$scope', 'SomeService']) 32 | export class ExampleController { 33 | constructor($scope, SomeService) { 34 | } 35 | } 36 | 37 | @Service('ExampleService', ['SomeService']) 38 | export class ExampleService { 39 | constructor(SomeService) { 40 | } 41 | } 42 | ``` 43 | 44 | #### Setting up modules 45 | 46 | 47 | ```javascript 48 | import {Module} from 'bower_components/dist/a1atscript.js'; 49 | import { 50 | ExampleController, 51 | ExampleService 52 | } from './theCodeBlockRightAbove'; 53 | import { AnotherModule } from './anotherA1AtScriptModule'; 54 | 55 | export var MyModule = new Module('MyModule', [ 56 | AnotherModule, 57 | ExampleController, 58 | ExampleService, 59 | 'aRegularAngularModule' 60 | ]); 61 | ``` 62 | 63 | Note you can mix other modules, controllers, and services all together in the list -- A1AtScript will figure out how to sort out the module definition. 64 | 65 | You can include regular angular modules by just referencing them as strings. 66 | 67 | #### Shortform notation 68 | 69 | If you want to quickly define a module with only one component... just use two annotations 70 | 71 | ```javascript 72 | @AsModule('ServiceModule') 73 | @Service('ExampleService') 74 | class ExampleService { 75 | constructor() { 76 | this.value = 'Test Value'; 77 | } 78 | } 79 | ``` 80 | 81 | #### Compile your main app module 82 | 83 | ```javascript 84 | import {bootstrap, Module} from 'bower_components/dist/a1atscript.js'; 85 | import { MyModule } from './myModule' 86 | 87 | var AppModule = Module('AppModule', [ 88 | MyModule 89 | ]); 90 | 91 | // The string passed in is prefixed to then names 92 | // of all of the modules when they are instantiated with 93 | // Angular 94 | bootstrap(AppModule, "myAppPrefix"); 95 | ``` 96 | 97 | ## Get ready for Angular 2! 98 | 99 | Angular 2 introduces an entirely new syntax for working with directives. The most common type of directive is a Component. The good news is with A1AtScript you can write components right now, using a syntax remarkably similar to Angular 2. 100 | 101 | ```javascript 102 | @Component({ 103 | selector: "awesome", 104 | properties: [ "apple" ], 105 | appInjector: ["ExampleService"] 106 | }) 107 | @View({ 108 | templateUrl: "awesome.tpl.html" 109 | }) 110 | class AwesomeComponent { 111 | constructor(exampleService) { 112 | this.exampleService = exampleService; 113 | this.test = "test"; 114 | } 115 | setValue() { 116 | this.value = this.exampleService.value; 117 | } 118 | } 119 | ``` 120 | 121 | ```html 122 | 123 | 124 | ``` 125 | 126 | ### Routeable Components 127 | 128 | You can take your Angular 2 prep a step further by using A1AtScript with the new Angular router, using routable component syntax from Angular 2. 129 | 130 | make sure to install the new router: 131 | 132 | ``` 133 | npm install angular-new-router 134 | ``` 135 | 136 | Then you can build an amazing route aware app using a super simple syntax like this: 137 | 138 | app.js: 139 | 140 | ```javascript 141 | @Component({}) 142 | @View({ 143 | template: "

Sub

" 144 | }) 145 | class SubComponent { 146 | 147 | } 148 | 149 | @Component({}) 150 | @View({ 151 | template: "

Home

" 152 | }) 153 | @RouteConfig({ 154 | path: "/sub", component: SubComponent 155 | }) 156 | class HomeComponent { 157 | } 158 | 159 | // the AsModule annotation is an extra need to setup Angular's module system on the top level component for now 160 | @AsModule('AppModule', ['templates', 'ngNewRouter', HomeComponent, SubComponent]) 161 | @Component({ 162 | selector: "awesome" 163 | }) 164 | @View({ 165 | templateUrl: "app.tpl.html" 166 | }) 167 | @RouteConfig({ 168 | path: "/home", component: HomeComponent 169 | }) 170 | class AppComponent { 171 | } 172 | 173 | bootstrap(AppComponent) 174 | ``` 175 | 176 | app.tpl.html: 177 | ```html 178 | 179 | ``` 180 | 181 | index.html: 182 | ```html 183 | 184 | 185 | 186 | ``` 187 | 188 | navigate to /home/sub would yield: 189 | ```html 190 | 191 | 192 | 193 |

Home

194 | 195 |

Sub

196 |
197 |
198 |
199 | 200 | ``` 201 | 202 | That's what Angular 2 routing is likely to look like -- except you can use this today! 203 | 204 | *Note: the name of the ng-viewport directive is about to change in the next release of the new Angular router to ng-outlet* 205 | 206 | ### Notes: 207 | 208 | functionally the initial component declaration above is equivalent to: 209 | 210 | ```javascript 211 | angular.directive('awesome', function() { 212 | return { 213 | restrict: 'E', 214 | bindToController: { 215 | apple: "@apple" 216 | // a setter is created automatically on your 217 | // controller so that your controller can access this.apple 218 | ___bindable___apple: "=?bindApple" 219 | }, 220 | controller, ['ExampleService', AwesomeComponent] 221 | controllerAs: 'awesome', 222 | scope: {}, 223 | templateUrl: "awesome.tpl.html", 224 | } 225 | function AwesomeComponent(exampleService) { 226 | this.exampleService = exampleService; 227 | this.test = "test"; 228 | } 229 | AwesomeComponent.prototype.setValue = function() { 230 | this.value = this.exampleService.value 231 | } 232 | }); 233 | ``` 234 | 235 | The syntax is supported in a Angular 1.3+ (in 1.3 it will set bindToController to true, and set properties on scope, because bindToController object syntax is 1.4 only). If angular 1.x adopts a built-in component feature (see [https://github.com/angular/angular.js/issues/10007](https://github.com/angular/angular.js/issues/10007)) then this module will be updated to use that feature when it is available. 236 | 237 | Other features: 238 | 239 | 1. Selector is a very, very basic css selector. If you pass '[awesome]', your directive will be called awesome and it'll be set restrict: 'A', and if you pass '.awesome' it'll be set restrict: 'C' 240 | 2. What about properties? Well, rather than force you to use Angular 1's bizarre character syntax, we try to emulate Angular 2's behavior. if you call your directive with a plain old attribute, it's just interpreted as a string literal. If you call it with a bind- prefix, it gets passed the value of the expression. Sorry, no [] abbreviated syntax here -- Angular 1.x doesn't let you specify scope properties that have [] characters in them 241 | 2. Services is optional for injecting dependencies into your component class 242 | 3. Class inheritance does work with components, but you'll need to define annotations on the child class 243 | 4. Component supports somes Angular1 customizations. You can specify a require or transclude property. You can also specify a custom controllerAs value. 244 | 5. Template annotation supports simply "url" for templateUrls and 'inline' for inline templates 245 | 246 | Angular 2's Directive will be supported in a future release. I'm still examining the best way to port this to Angular 1.x and maintain a similar feature set and syntax to 2.0. 247 | 248 | ## Wrapping up 249 | 250 | #### More Info 251 | 252 | Check out the [Wiki](https://github.com/hannahhoward/a1atscript/wiki) for more specialized topics. 253 | 254 | #### What's included? 255 | 256 | The /src folder contains the es6 source files so that you can package up A1AtScript using whatever packaging system is most comfortable for you. However, if you want an ES5 global build, in dist is a1atscript.bundle.js that will load everything as global. 257 | 258 | 259 | ### Wait a second, I thought AtScript was called TypeScript now 260 | 261 | A new name is coming as soon as I get big enough to be able to lose what little brand recognition I have. 262 | 263 | # That's It. Enjoy 264 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "a1atscript", 3 | "version": "0.5.0", 4 | "homepage": "https://github.com/hannahhoward/a1atscript", 5 | "authors": [ 6 | "Hannah Howard " 7 | ], 8 | "description": "Use AtScript To Simplify Angular 1.x", 9 | "main": [ 10 | "dist/a1atscript.js", 11 | "dist/a1atscript/annotations.js", 12 | "dist/a1atscript/DirectiveObject.js", 13 | "dist/a1atscript/Injector.js", 14 | "dist/a1atscript/injectorTypes.js", 15 | "dist/a1atscript/ToAnnotation.js", 16 | "dist/a1atscript/Router.js", 17 | "dist/a1atscript/bootstrap.js", 18 | "dist/a1atscript/AnnotationFinder.js", 19 | "dist/a1atscript/ng2Directives/Component.js", 20 | "dist/a1atscript/ng2Directives/ComponentInjector.js", 21 | "dist/a1atscript/ng2Directives/Ng2Directive.js", 22 | "dist/a1atscript/ng2Directives/Ng2DirectiveDefinitionObject.js", 23 | "dist/a1atscript/ng2Directives/SelectorMatcher.js", 24 | "dist/a1atscript/ng2Directives/BindBuilder.js", 25 | "dist/a1atscript/ng2Directives/EventsBuilder.js", 26 | "dist/a1atscript/ng2Directives/PropertiesBuilder.js", 27 | "dist/a1atscript/router/ComponentMapper.js", 28 | "dist/a1atscript/router/RouteConfig.js", 29 | "dist/a1atscript/router/RouteInitializer.js", 30 | "dist/a1atscript/router/RouteReader.js" 31 | ], 32 | "keywords": [ 33 | "angular", 34 | "atscript", 35 | "dependency", 36 | "injection" 37 | ], 38 | "license": "MIT", 39 | "ignore": [ 40 | "**/.*", 41 | "node_modules", 42 | "bower_components", 43 | "test", 44 | "tests" 45 | ], 46 | "dependencies": { 47 | "angular": "~1.3.12" 48 | }, 49 | "devDependencies": { 50 | "angular-mocks": "~1.3.12" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "traceur": { 3 | "modules": "amd", 4 | "script": false, 5 | "types": true, 6 | "typeAssertions": true, 7 | "typeAssertionModule": "assert", 8 | "annotations": true, 9 | "sourceMaps": "file" 10 | }, 11 | "babel": { 12 | "sourceMaps": "inline", 13 | "stage": 0 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /dist/a1atscript.system.bundle.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/a1atscript/ng2Directives/Ng2DirectiveDefinitionObject.js","../src/a1atscript/ng2Directives/PropertiesBuilder.js","../src/a1atscript/ng2Directives/BindBuilder.js","../src/a1atscript/ng2Directives/EventsBuilder.js","../src/a1atscript/ng2Directives/ComponentInjector.js","../src/a1atscript/DirectiveObject.js","../src/a1atscript/injectorTypes.js","../src/a1atscript/Injector.js","../src/a1atscript/bootstrap.js","../src/a1atscript/annotations.js","../src/a1atscript/ng2Directives/Ng2Directive.js","../src/a1atscript/ng2Directives/Component.js","../src/a1atscript/ng2Directives/SelectorMatcher.js","../src/a1atscript/router/ComponentMapper.js","../src/a1atscript/AnnotationFinder.js","../src/a1atscript/router/RouteReader.js","../src/a1atscript/router/RouteInitializer.js","../src/a1atscript/ToAnnotation.js","../src/a1atscript/router/RouteConfig.js","../src/a1atscript/Router.js","../src/a1atscript/applyAnnotation.js","../src/a1atscript.js"],"names":[],"mappings":"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","file":"a1atscript.system.bundle.js","sourcesContent":["import SelectorMatcher from \"./SelectorMatcher.js\";\n\nexport default class Ng2DirectiveDefinitionObject {\n\n constructor(controller, annotation, template = {}, bind = null) {\n this._annotation = annotation;\n this._controller = controller;\n this._template = template;\n this._bind = bind;\n }\n\n get selectorMatcher() {\n this._selectorMatcher = this._selectorMatcher ||\n new SelectorMatcher(this._annotation.selector);\n return this._selectorMatcher;\n }\n\n get restrict() {\n return this.selectorMatcher.restrict;\n }\n\n get controllerAs() {\n return this._annotation.controllerAs || this.name;\n }\n\n get bindToController() {\n // bindToController as object syntax only supported on 1.4\n if (angular.version.major == 1 && angular.version.minor >= 4) {\n return this._bind || this._annotation.properties;\n } else {\n return true;\n }\n\n }\n\n get scope() {\n // bindToController as object syntax only supported on 1.4\n if (angular.version.major == 1 && angular.version.minor >= 4) {\n return {};\n } else {\n return this._bind || this._annotation.properties;\n }\n }\n\n get template() {\n return this._template.template;\n }\n\n get templateUrl() {\n return this._template.templateUrl;\n }\n\n get transclude() {\n return this._annotation.transclude;\n }\n\n get require() {\n return this._annotation.require;\n }\n\n get controller() {\n return this._controller;\n }\n\n get name() {\n return this.selectorMatcher.name;\n }\n\n get factoryFn() {\n return () => {\n return {\n scope: this.scope,\n restrict: this.restrict,\n template: this.template,\n require: this.require,\n transclude: this.transclude,\n templateUrl: this.templateUrl,\n controller: this.controller,\n bindToController: this.bindToController,\n controllerAs: this.controllerAs\n };\n };\n }\n}\n","import BindBuilder from \"./BindBuilder.js\"\n\nconst BIND_PREFIX = \"_=_\";\nconst STRING_PREFIX = \"_@_\";\nconst BINDING = BIND_PREFIX;\nconst RAW_STRING = STRING_PREFIX;\n\nexport default class PropertiesBuilder extends BindBuilder {\n\n setupProperty(key, properties) {\n properties[STRING_PREFIX + key] = \"@\" + this.bindObj[key];\n properties[BIND_PREFIX + key] = \"=?bind\" + this.bindObj[key][0].toUpperCase() + this.bindObj[key].slice(1);\n\n\n // This property is used when user uses the `bind-property` attribute on a directive to bind an expression\n Object.defineProperty(this._component.prototype, BIND_PREFIX + key, {\n enumerable: true,\n configurable: true,\n set: genericSetter(BINDING, RAW_STRING),\n get: function() {\n return this[key];\n }\n });\n\n // This property is used when user uses the `property` attribute on a directive to bind a string\n Object.defineProperty(this._component.prototype, STRING_PREFIX + key, {\n enumerable: true,\n configurable: true,\n set: genericSetter(RAW_STRING, BINDING),\n get: function() {\n return this[key];\n }\n });\n\n function genericSetter(use, errorOn) {\n return function(value) {\n this.__using_binding__ = this.__using_binding__ || {};\n\n if (this.__using_binding__[key] === errorOn) {\n if (value !== undefined) {\n throw new Error(`Cannot use bind-${key} and ${key} simultaneously`);\n }\n\n return;\n }\n\n if (value !== undefined) {\n this.__using_binding__[key] = use;\n }\n\n this[key] = value;\n };\n }\n }\n}\n","export default class BindBuilder {\n constructor(bindParam, component) {\n this._bindParam = bindParam;\n this._component = component;\n }\n\n get bindObj() {\n if (!this._bindObj) {\n if (Array.isArray(this._bindParam)) {\n this._bindObj = {};\n var splitBind;\n this._bindParam.forEach((bind) => {\n splitBind = bind.split(/\\s*:\\s*/);\n if (splitBind.length == 1) {\n this._bindObj[bind] = bind;\n } else {\n this._bindObj[splitBind[0]] = splitBind[1];\n }\n })\n } else {\n this._bindObj = this._bindParam\n }\n }\n return this._bindObj;\n }\n\n build() {\n var properties = {};\n Object.keys(this.bindObj).forEach((key) => {\n this.setupProperty(key, properties)\n });\n return properties;\n }\n}\n","import BindBuilder from \"./BindBuilder.js\"\n\nvar prefix = \"___bindable___\"\n\nexport default class EventsBuilder extends BindBuilder {\n\n setupProperty(key, events) {\n events[key] = \"=?on\"+this.bindObj[key][0].toUpperCase() + this.bindObj[key].slice(1);\n }\n\n}\n","import {registerInjector} from '../Injector.js';\nimport {Component, ViewBase} from './Component.js';\nimport {ListInjector} from \"../injectorTypes.js\";\nimport Ng2DirectiveDefinitionObject from \"./Ng2DirectiveDefinitionObject.js\";\nimport PropertiesBuilder from \"./PropertiesBuilder.js\";\nimport EventsBuilder from \"./EventsBuilder.js\";\nimport {Router} from \"../Router.js\";\n\nclass ComponentInjector extends ListInjector {\n constructor() {\n super();\n this.componentHooks = {before: [], after: []};\n }\n\n get annotationClass() {\n return Component;\n }\n\n _template(component) {\n return component.annotations.find((annotation) => annotation instanceof ViewBase) || {};\n }\n\n instantiateOne(module, component, annotation) {\n if (annotation.appInjector) {\n component.$inject = annotation.appInjector;\n }\n Router.routeReader.read(component);\n var template = this._template(component);\n var properties = {},\n events = {},\n bind;\n if (annotation.properties) {\n properties = (new PropertiesBuilder(annotation.properties, component)).build();\n }\n if (annotation.events) {\n events = (new EventsBuilder(annotation.events, component)).build();\n }\n bind = Object.assign({}, properties, events);\n if (bind === {}) bind = null;\n if (annotation.selector) {\n var ddo = new Ng2DirectiveDefinitionObject(component, annotation, template, bind);\n this.hooks('before', module, ddo);\n module.directive(ddo.name, ddo.factoryFn);\n this.hooks('after', module, ddo);\n }\n }\n\n hooks(phase, module, ddo) {\n this.componentHooks[phase].forEach((hook) => {\n hook(module, ddo);\n });\n}\n}\n\nregisterInjector('component', ComponentInjector);\n","import {ListInjector} from './injectorTypes.js';\nimport {registerInjector} from './Injector.js';\nimport {ToAnnotation} from './ToAnnotation.js';\n\nclass DirectiveObjectAnnotation {\n constructor(token, dependencies = []) {\n this.dependencies = dependencies;\n this.token = token;\n }\n}\n\nexport const DirectiveObject = ToAnnotation(DirectiveObjectAnnotation);\n\nclass DirectiveObjectInjector extends ListInjector {\n get annotationClass() {\n return DirectiveObject;\n }\n\n _createFactoryArray(ConstructorFn) {\n // get the array of dependencies that are needed by this component (as contained in the `$inject` array)\n var args = ConstructorFn.$inject || [];\n var factoryArray = args.slice(); // create a copy of the array\n // The factoryArray uses Angular's array notation whereby each element of the array is the name of a\n // dependency, and the final item is the factory function itself.\n factoryArray.push((...args) => {\n var directive = new ConstructorFn(...args);\n for (var key in directive) {\n directive[key] = directive[key];\n }\n return directive;\n });\n\n return factoryArray;\n }\n\n _cloneFunction(original) {\n return function() {\n return original.apply(this, arguments);\n };\n }\n\n _override(object, methodName, callback) {\n object[methodName] = callback(object[methodName]);\n }\n\n instantiateOne(module, directiveObject, metadata) {\n directiveObject['$inject'] = metadata.dependencies;\n\n if (!directiveObject.prototype.compile) {\n // create an empty compile function if none was defined.\n directiveObject.prototype.compile = () => {};\n }\n\n var originalCompileFn = this._cloneFunction(directiveObject.prototype.compile);\n\n // Decorate the compile method to automatically return the link method (if it exists)\n // and bind it to the context of the constructor (so `this` works correctly).\n // This gets around the problem of a non-lexical \"this\" which occurs when the directive class itself\n // returns `this.link` from within the compile function.\n this._override(directiveObject.prototype, 'compile', function () {\n return function () {\n\n originalCompileFn.apply(this, arguments);\n\n if (directiveObject.prototype.link) {\n return directiveObject.prototype.link.bind(this);\n }\n };\n });\n\n var factoryArray = this._createFactoryArray(directiveObject);\n\n module.directive(metadata.token, factoryArray);\n }\n}\n\nregisterInjector('directiveObject', DirectiveObjectInjector);\n\n\n/*\n var originalCompileFn = _cloneFunction(constructorFn.prototype.compile);\n\n // Decorate the compile method to automatically return the link method (if it exists)\n // and bind it to the context of the constructor (so `this` works correctly).\n // This gets around the problem of a non-lexical \"this\" which occurs when the directive class itself\n // returns `this.link` from within the compile function.\n _override(constructorFn.prototype, 'compile', function () {\n return function () {\n originalCompileFn.apply(this, arguments);\n\n if (constructorFn.prototype.link) {\n return constructorFn.prototype.link.bind(this);\n }\n };\n });\n\n var factoryArray = _createFactoryArray(constructorFn);\n\n app.directive(name, factoryArray);\n return this;\n }\n*/\n","import {\n Config,\n Run,\n Controller,\n Directive,\n Service,\n Factory,\n Provider,\n Value,\n Constant,\n Animation,\n Filter\n} from './annotations.js';\nimport {Router} from \"./Router.js\";\n\nexport class ListInjector {\n instantiate(module, dependencyList) {\n dependencyList.forEach((dependencyObject) => {\n this.instantiateOne(module, dependencyObject.dependency, dependencyObject.metadata);\n });\n }\n}\n\nexport class ConfigInjector extends ListInjector {\n\n get annotationClass() {\n return Config;\n }\n\n instantiateOne(module, config, metadata) {\n config['$inject'] = metadata.dependencies;\n module.config(config);\n }\n}\n\nexport class RunInjector extends ListInjector {\n\n get annotationClass() {\n return Run;\n }\n\n instantiateOne(module, run, metadata) {\n run['$inject'] = metadata.dependencies;\n module.run(run);\n }\n}\n\nexport class ControllerInjector extends ListInjector {\n\n get annotationClass() {\n return Controller;\n }\n\n instantiateOne(module, controller, metadata) {\n controller['$inject'] = metadata.dependencies;\n Router.routeReader.read(controller);\n module.controller(metadata.token, controller);\n }\n\n}\n\nexport class DirectiveInjector extends ListInjector {\n\n get annotationClass() {\n return Directive;\n }\n\n instantiateOne(module, directive, metadata) {\n directive['$inject'] = metadata.dependencies;\n module.directive(metadata.token, directive);\n }\n\n}\n\nexport class ServiceInjector extends ListInjector {\n\n get annotationClass() {\n return Service;\n }\n\n instantiateOne(module, service, metadata) {\n service['$inject'] = metadata.dependencies;\n module.service(metadata.token, service);\n }\n\n}\n\nexport class FactoryInjector extends ListInjector {\n\n get annotationClass() {\n return Factory;\n }\n\n instantiateOne(module, factory, metadata) {\n factory['$inject'] = metadata.dependencies;\n module.factory(metadata.token, factory);\n }\n\n}\n\nexport class ProviderInjector extends ListInjector {\n\n get annotationClass() {\n return Provider;\n }\n\n instantiateOne(module, provider, metadata) {\n provider['$inject'] = metadata.dependencies;\n module.provider(metadata.token, provider);\n }\n\n}\n\nexport class ValueInjector extends ListInjector {\n\n get annotationClass() {\n return Value;\n }\n\n instantiateOne(module, value, metadata) {\n value['$inject'] = metadata.dependencies;\n module.value(metadata.token, value);\n }\n\n}\n\nexport class ConstantInjector extends ListInjector {\n\n get annotationClass() {\n return Constant;\n }\n\n instantiateOne(module, constant, metadata) {\n constant['$inject'] = metadata.dependencies;\n module.constant(metadata.token, constant);\n }\n\n}\n\nexport class AnimationInjector extends ListInjector {\n\n get annotationClass() {\n return Animation;\n }\n\n instantiateOne(module, animation, metadata) {\n animation['$inject'] = metadata.dependencies;\n module.animation(metadata.token, animation);\n }\n\n}\n\nexport class FilterInjector extends ListInjector {\n\n get annotationClass() {\n return Filter;\n }\n\n instantiateOne(module, filter, metadata) {\n filter['$inject'] = metadata.dependencies;\n module.filter(metadata.token, filter);\n }\n\n}\n","import { AsModule, Module } from './annotations.js';\nimport { AnnotationFinder} from './AnnotationFinder.js';\n\nimport {\n ConfigInjector,\n RunInjector,\n ControllerInjector,\n DirectiveInjector,\n ServiceInjector,\n FactoryInjector,\n ProviderInjector,\n ValueInjector,\n ConstantInjector,\n AnimationInjector,\n FilterInjector\n} from './injectorTypes.js';\n\nvar registeredInjectors = {}\n\nexport function registerInjector(name, InjectorClass) {\n registeredInjectors[name] = new InjectorClass();\n}\n\nexport function getInjector(name) {\n return registeredInjectors[name];\n}\n\nregisterInjector('config', ConfigInjector);\nregisterInjector('run', RunInjector);\nregisterInjector('controller', ControllerInjector);\nregisterInjector('directive', DirectiveInjector);\nregisterInjector('service', ServiceInjector);\nregisterInjector('factory', FactoryInjector);\nregisterInjector('provider', ProviderInjector);\nregisterInjector('value', ValueInjector);\nregisterInjector('constant', ConstantInjector);\nregisterInjector('animation', AnimationInjector);\nregisterInjector('filter', FilterInjector);\n\nexport class Injector {\n constructor(appNamePrefix = \"\") {\n this.appNamePrefix = appNamePrefix;\n this.injectedModules = {};\n }\n\n get annotationClass() {\n return Module;\n }\n\n instantiate(moduleClass) {\n var metadata = this._getAnnotatedClass(moduleClass);\n if (!metadata) {\n return undefined;\n }\n if (this.injectedModules[metadata.token]) {\n return this.injectedModules[metadata.token];\n }\n var sortedDependencies = this._sortModuleDependencies(metadata);\n sortedDependencies = this._sortSelf(metadata, moduleClass, sortedDependencies);\n var moduleDependencies = this._instantiateModuleDependencies(sortedDependencies.module);\n var moduleName = metadata.token;\n if (this.appNamePrefix && moduleName != this.appNamePrefix) {\n moduleName = `${this.appNamePrefix}.${moduleName}`;\n }\n var instantiatedModule = angular.module(moduleName, moduleDependencies);\n delete sortedDependencies.module;\n this._instantiateOtherDependencies(sortedDependencies, instantiatedModule);\n this.injectedModules[metadata.token] = moduleName;\n return moduleName;\n }\n\n _sortSelf(metadata, moduleClass, sortedDependencies) {\n if (metadata == moduleClass) {\n return sortedDependencies;\n } else {\n var selfDependency = this._sortDependency(moduleClass, false);\n return this._mergeSortedDependencies(sortedDependencies, selfDependency);\n }\n }\n\n _getAnnotatedClass(moduleClass) {\n if (moduleClass instanceof Module) {\n moduleClass.injectable = false;\n return moduleClass;\n } else {\n var metadata = this._getModuleAnnotation(moduleClass);\n return metadata;\n }\n }\n\n _getDependencyType(dependency) {\n var annotations = dependency.annotations;\n for (var i=0; i < annotations.length; i++) {\n var annotation = annotations[i];\n var foundInjector = Object.keys(registeredInjectors).find(\n (key) => {\n var annotationClass = registeredInjectors[key].annotationClass;\n annotationClass = annotationClass.originalClass || annotationClass;\n return annotation instanceof annotationClass;\n });\n if (foundInjector) {\n return {\n key: foundInjector,\n metadata: annotation\n };\n }\n }\n return null;\n }\n\n _getModuleAnnotation(dependency) {\n return (new AnnotationFinder(dependency)).annotationFor(Module);\n }\n\n _mergeSortedDependencies(sorted1, sorted2) {\n var newSorted = {}\n Object.assign(newSorted, sorted1)\n Object.keys(sorted2).forEach((key) => {\n if (newSorted[key]) {\n newSorted[key] = newSorted[key].concat(sorted2[key]);\n } else {\n newSorted[key] = sorted2[key];\n }\n });\n return newSorted;\n }\n\n _sortDependency(dependency, checkModule = true) {\n var sorted = {};\n\n if (typeof dependency === \"string\" || dependency instanceof Module) {\n sorted.module = [dependency];\n } else if (dependency.annotations) {\n if (checkModule && this._getModuleAnnotation(dependency)) {\n sorted.module = [dependency];\n } else {\n var dependencyType = this._getDependencyType(dependency);\n if (dependencyType) {\n sorted[dependencyType.key] = [{\n dependency: dependency,\n metadata: dependencyType.metadata\n }];\n }\n }\n } else {\n Object.keys(dependency).forEach((key) => {\n var subDependency = dependency[key];\n var sortedSubDependencies = this._sortDependency(subDependency);\n sorted = this._mergeSortedDependencies(sorted, sortedSubDependencies);\n });\n }\n return sorted;\n }\n\n _sortModuleDependencies(moduleClass) {\n var sorted = {};\n moduleClass.dependencies.forEach((dependency) => {\n var newSortedDependencies = this._sortDependency(dependency);\n sorted = this._mergeSortedDependencies(sorted, newSortedDependencies);\n });\n\n return sorted;\n }\n\n _moduleMetadata(moduleClass) {\n return moduleClass.annotations.find((value) => value instanceof Module || value instanceof AsModule);\n }\n\n _instantiateModuleDependencies(moduleDependencies) {\n var returnedDependencies = [];\n\n if (moduleDependencies) {\n moduleDependencies.forEach((moduleDependency) => {\n if (typeof moduleDependency === \"string\") {\n returnedDependencies.push(moduleDependency);\n } else {\n returnedDependencies.push(this.instantiate(moduleDependency));\n }\n });\n\n }\n\n return returnedDependencies;\n }\n\n _instantiateOtherDependencies(sortedDependencies, instantiatedModule) {\n Object.keys(sortedDependencies).forEach((dependencyType) => {\n registeredInjectors[dependencyType].instantiate(\n instantiatedModule,\n sortedDependencies[dependencyType]\n );\n });\n }\n}\n","import {Injector} from \"./Injector.js\";\nimport {Router} from \"./Router.js\";\n\nexport function bootstrap(appModule, appPrefix = \"\") {\n var injector = new Injector(appPrefix);\n var moduleName = injector.instantiate(appModule);\n Router.routeInitializer.initialize(moduleName, appModule);\n}\n","import {ToAnnotation} from './ToAnnotation.js';\n\nclass NgAnnotation {\n constructor(...dependencies) {\n this.dependencies = dependencies;\n }\n}\n\nclass NgNamedAnnotation {\n constructor(token, dependencies = []) {\n this.dependencies = dependencies;\n this.token = token;\n }\n}\n\nclass ConfigAnnotation extends NgAnnotation {\n}\n\nexport const Config = ToAnnotation(ConfigAnnotation);\n\nclass RunAnnotation extends NgAnnotation {\n\n}\n\nexport const Run = ToAnnotation(RunAnnotation);\n\nclass ControllerAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Controller = ToAnnotation(ControllerAnnotation);\n\nclass DirectiveAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Directive = ToAnnotation(DirectiveAnnotation);\n\nclass ServiceAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Service = ToAnnotation(ServiceAnnotation);\n\n\nclass FactoryAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Factory = ToAnnotation(FactoryAnnotation);\n\nclass ProviderAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Provider = ToAnnotation(ProviderAnnotation);\n\nclass ValueAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Value = ToAnnotation(ValueAnnotation);\n\nclass ConstantAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Constant = ToAnnotation(ConstantAnnotation);\n\nclass FilterAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Filter = ToAnnotation(FilterAnnotation);\n\nclass AnimationAnnotation extends NgNamedAnnotation {\n\n}\n\nexport const Animation = ToAnnotation(AnimationAnnotation);\n\nexport class Module extends NgNamedAnnotation {\n\n}\n\nexport const AsModule = ToAnnotation(Module);\n","export default class Ng2Directive {\n constructor(descriptor) {\n this.selector = descriptor.selector;\n this.properties = descriptor.properties || descriptor.bind;\n this.controllerAs = descriptor.controllerAs;\n this.require = descriptor.require;\n this.transclude = descriptor.transclude;\n this.events = descriptor.events;\n }\n}\n","import Ng2Directive from './Ng2Directive.js';\nimport {ToAnnotation} from '../ToAnnotation.js';\n\nclass ComponentAnnotation extends Ng2Directive {\n constructor(descriptor) {\n super(descriptor)\n this.appInjector = descriptor.appInjector || descriptor.injectables || descriptor.services;\n }\n}\n\nexport const Component = ToAnnotation(ComponentAnnotation);\n\nexport class ViewBase {\n constructor(descriptor) {\n this.templateUrl = descriptor.templateUrl || descriptor.url;\n this.template = descriptor.template || descriptor.inline;\n }\n}\n\nexport const Template = ToAnnotation(ViewBase);\n\nexport const View = ToAnnotation(ViewBase);\n","var SPECIAL_CHARS_REGEXP = /([\\:\\-\\_]+(.))/g;\nvar MOZ_HACK_REGEXP = /^moz([A-Z])/;\n\nexport default class SelectorMatcher {\n constructor(selector: string) {\n this._selector = selector;\n }\n\n _camelizeName() {\n this._name = this._name.replace(SPECIAL_CHARS_REGEXP,\n (_, separator, letter, offset) => offset ? letter.toUpperCase() : letter ).\n replace(MOZ_HACK_REGEXP, 'Moz$1');\n }\n\n _split() {\n if (this._selector[0] == \".\") {\n this._restrict = \"C\";\n this._name = this._selector.substring(1);\n } else if (this._selector[0] == \"[\" &&\n this._selector[this._selector.length-1] == \"]\") {\n this._restrict = \"A\";\n this._name = this._selector.substring(1, this._selector.length-1);\n } else {\n this._restrict = \"E\";\n this._name = this._selector;\n }\n }\n\n get name() {\n if (!this._name) {\n this._split();\n }\n this._camelizeName();\n return this._name;\n }\n\n get restrict() {\n if (!this._restrict) {\n this._split();\n }\n return this._restrict;\n }\n\n}\n","import {Controller} from \"../annotations.js\";\nimport {Component, ViewBase} from \"../ng2Directives/Component.js\";\nimport {AnnotationFinder} from \"../AnnotationFinder.js\";\nimport SelectorMatcher from \"../ng2Directives/SelectorMatcher.js\";\n\nvar DEFAULT_CONTROLLER_SUFFIX = \"Controller\";\nvar DEFAULT_COMPONENT_PREFIX = \"a1atscript\";\nvar DEFAULT_CONTROLLER_PREFIX = \"A1AtScript\";\n\nclass ComponentMapping {\n constructor(component, componentMapper) {\n this.component = component;\n this.componentMapper = componentMapper;\n }\n\n get componentName() {\n return this.componentMapper.map.get(this.component);\n }\n\n get templateUrl() {\n return this.componentMapper.registry[this.componentName].templateUrl;\n }\n\n get isController() {\n return this.componentMapper.registry[this.componentName].isController;\n }\n\n get controllerName() {\n return this.componentMapper.registry[this.componentName].controllerName;\n }\n}\n\nexport class ComponentMapper {\n register(component) {\n if (!this.map.get(component)) {\n this._setupComponent(component);\n }\n return new ComponentMapping(component, this);\n }\n\n _getControllerComponentName(component) {\n var name = this._getControllerName(component);\n if (name) {\n if (name.endsWith(DEFAULT_CONTROLLER_SUFFIX)) {\n return name[0].toLowerCase() + name.substr(1, name.length - DEFAULT_CONTROLLER_SUFFIX.length - 1);\n } else {\n return name[0].toLowerCase() + name.substr(1, name.length - 1);\n }\n } else {\n return null;\n }\n }\n\n _getControllerName(component) {\n var controllerAnnotation = (new AnnotationFinder(component)).annotationFor(Controller);\n if (controllerAnnotation) {\n return controllerAnnotation.token;\n } else {\n return null;\n }\n }\n\n _isController(component) {\n var controllerAnnotation = (new AnnotationFinder(component)).annotationFor(Controller);\n if (controllerAnnotation) {\n return true;\n } else {\n return false;\n }\n }\n _getComponentName(component) {\n var componentAnnotation = (new AnnotationFinder(component)).annotationFor(Component);\n if (componentAnnotation) {\n if (componentAnnotation.controllerAs) {\n return componentAnnotation.controllerAs;\n } else if (componentAnnotation.selector) {\n var selectorMatcher = new SelectorMatcher(componentAnnotation.selector);\n return selectorMatcher.name;\n } else {\n return null;\n }\n } else {\n return null;\n }\n }\n\n _getGeneratedName() {\n this._componentIndex = this._componentIndex || 0;\n var name = `${DEFAULT_COMPONENT_PREFIX}Component_${this._componentIndex}`;\n this._componentIndex = this._componentIndex + 1;\n return name;\n }\n\n _generateName(component) {\n var name = this._getControllerComponentName(component);\n name = name || this._getComponentName(component);\n name = name || this._getGeneratedName();\n return name;\n }\n\n _generateTemplate(name, component) {\n var viewAnnotation = (new AnnotationFinder(component)).annotationFor(ViewBase);\n if (viewAnnotation && viewAnnotation.templateUrl) {\n return viewAnnotation.templateUrl;\n } else {\n return `./components/${name}/${name}.html`;\n }\n }\n\n _readInlineTemplate(templateUrl, component) {\n var viewAnnotation = (new AnnotationFinder(component)).annotationFor(ViewBase);\n if (viewAnnotation && viewAnnotation.template) {\n this.inlineTemplateCache[templateUrl] = viewAnnotation.template;\n }\n }\n\n _generateControllerName(name) {\n var componentBase;\n if (name.startsWith(DEFAULT_COMPONENT_PREFIX)) {\n componentBase = name.substring(DEFAULT_COMPONENT_PREFIX.length, name.length)\n } else {\n componentBase = name;\n }\n return DEFAULT_CONTROLLER_PREFIX + componentBase[0].toUpperCase() + componentBase.substring(1, componentBase.length) + DEFAULT_CONTROLLER_SUFFIX;\n }\n\n _setupComponent(component) {\n var name = this._generateName(component);\n var templateUrl = this._generateTemplate(name, component);\n var controllerName = this._getControllerName(component);\n var isController;\n if (controllerName) {\n isController = true;\n } else {\n isController = false;\n controllerName = this._generateControllerName(name);\n }\n this.map.set(component, name);\n this.registry[name] = { component: component, templateUrl: templateUrl, isController: isController, controllerName: controllerName }\n this.controllerRegistry[controllerName] = name;\n this._readInlineTemplate(templateUrl, component);\n }\n\n get registry() {\n this._componentRegistry = this._componentRegistry || {}\n return this._componentRegistry;\n }\n\n get map() {\n this._componentMap = this._componentMap || new Map();\n return this._componentMap;\n }\n\n getComponent(componentName) {\n return this.registry[componentName].component;\n }\n\n getTemplateUrl(componentName) {\n return this.registry[componentName].templateUrl;\n }\n\n getComponentName(component) {\n return this.map.get(component);\n }\n\n get controllerRegistry() {\n this._controllerRegistry = this._controllerRegistry || {}\n return this._controllerRegistry;\n }\n\n get inlineTemplateCache() {\n this._inlineTemplateCache = this._inlineTemplateCache || {}\n return this._inlineTemplateCache;\n }\n}\n","export class AnnotationFinder {\n constructor(AnnotatedClass) {\n this.AnnotatedClass = AnnotatedClass;\n }\n\n annotationFor(AnnotationClass) {\n var OriginalClass = AnnotationClass.originalClass || AnnotationClass;\n if (this.AnnotatedClass.annotations) {\n return this.AnnotatedClass.annotations.find((annotation) => annotation instanceof OriginalClass)\n } else {\n return null;\n }\n }\n\n annotationsFor(AnnotationClass) {\n var OriginalClass = AnnotationClass.originalClass || AnnotationClass;\n if (this.AnnotatedClass.annotations) {\n return this.AnnotatedClass.annotations.filter((annotation) => annotation instanceof OriginalClass)\n } else {\n return null;\n }\n }\n}\n","import {RouteConfig} from \"./RouteConfig.js\";\nimport {AnnotationFinder} from \"../AnnotationFinder.js\";\n\nexport class RouteReader {\n constructor(componentMapper) {\n this.componentMapper = componentMapper;\n }\n\n _routeConfigAnnotations(component) {\n return (new AnnotationFinder(component)).annotationsFor(RouteConfig);\n }\n\n _routeConfig(component) {\n return this._routeConfigAnnotations(component).map(this._convertConfig.bind(this));\n }\n\n _componentName(component) {\n if (typeof(component) === \"string\") {\n return component\n } else {\n return this.componentMapper.register(component).componentName;\n }\n }\n\n _convertConfig(routeConfigAnnotation) {\n var routeDescription = Object.assign({}, routeConfigAnnotation.routeDescription);\n if (routeDescription.component) {\n routeDescription.component = this._componentName(routeDescription.component);\n }\n\n if (routeDescription.components) {\n var components = {};\n Object.keys(routeDescription.components).forEach((key) => {\n components[key] = this._componentName(routeDescription.components[key]);\n });\n routeDescription.components = components;\n }\n\n return routeDescription;\n }\n\n read(component) {\n var mapping = this.componentMapper.register(component);\n component.$routeConfig = this._routeConfig(component);\n }\n}\n","export class RouteInitializer {\n constructor(componentMapper) {\n this.componentMapper = componentMapper;\n }\n\n configurationFunction(componentMapperName) {\n var componentMapper = this.componentMapper;\n return function($injector) {\n var $componentMapper;\n try {\n $componentMapper = $injector.get(componentMapperName);\n } catch(e) {\n return;\n }\n $componentMapper.setCtrlNameMapping(function(name) {\n return componentMapper.registry[name].controllerName;\n });\n $componentMapper.setTemplateMapping(function(name) {\n return componentMapper.registry[name].templateUrl;\n });\n $componentMapper.setComponentFromCtrlMapping(function(controllerName) {\n return componentMapper.controllerRegistry[controllerName];\n });\n }\n }\n\n topRouteConfig(routerName, routeConfig) {\n return function($injector) {\n var $router;\n try {\n $router = $injector.get(routerName);\n\n } catch(e) {\n return;\n }\n $router.config(routeConfig);\n };\n }\n\n setupComponentControllers() {\n Object.keys(this.componentMapper.registry).forEach((component) => {\n var config = this.componentMapper.registry[component];\n if (!config.isController && config.component != this.topComponent) {\n this.module.controller(\n config.controllerName,\n config.component\n );\n }\n });\n }\n\n setupInlineTemplates() {\n var inlineTemplateCache = this.componentMapper.inlineTemplateCache;\n return function($templateCache) {\n Object.keys(inlineTemplateCache).forEach((templateUrl) => {\n $templateCache.put(templateUrl, inlineTemplateCache[templateUrl]);\n });\n };\n }\n initialize(ngModuleName, topComponent = null) {\n this.module = angular.module(ngModuleName);\n\n // ng-new-router changed the name of its componentMapper service recently\n // essentially the approach here is to try to configure the mapper with both names\n // catch exceptions if they don't exist.\n // if both throw an exception, than there is no component router present\n this.module.config(['$injector', this.configurationFunction('$componentLoaderProvider')]);\n this.module.run(['$injector', this.configurationFunction('$componentMapper')]);\n\n if (topComponent && topComponent.$routeConfig) {\n this.topComponent = topComponent;\n this.module.run(['$injector', this.topRouteConfig('$router', topComponent.$routeConfig)])\n }\n\n this.setupComponentControllers();\n\n this.module.run(['$templateCache', this.setupInlineTemplates()]);\n\n }\n}\n","function defineAnnotation(target, AnnotationClass, callParams) {\n var oldAnnotation = Object.getOwnPropertyDescriptor(target, 'annotations');\n if (oldAnnotation) {\n var oldGetter = oldAnnotation.get\n Object.defineProperty(target, 'annotations', {\n configurable: true,\n get: function() {\n var oldValue = oldGetter();\n oldValue.unshift(new (Function.prototype.bind.apply(AnnotationClass, callParams)));\n return oldValue;\n }});\n } else {\n Object.defineProperty(target, 'annotations', {\n configurable: true,\n get: function() {\n return [new (Function.prototype.bind.apply(AnnotationClass, callParams))];\n }});\n }\n}\n\nfunction handleProperty(descriptor, AnnotationClass, callParams) {\n var value;\n if (descriptor.initializer) {\n value = descriptor.initializer();\n } else {\n value = descriptor.value;\n }\n defineAnnotation(value, AnnotationClass, callParams);\n if (descriptor.initializer) {\n descriptor.initializer = function() { return value; }\n }\n descriptor.enumerable = true;\n return descriptor;\n}\n\nexport function ToAnnotation(AnnotationClass) {\n var decorator = function(...callParams) {\n if (this instanceof decorator) {\n return new AnnotationClass(...callParams)\n } else {\n callParams.unshift(null);\n return function(targetClass, ...otherParams) {\n if (otherParams.length >= 2) {\n return handleProperty(otherParams[1], AnnotationClass, callParams);\n } else {\n defineAnnotation(targetClass, AnnotationClass, callParams)\n return targetClass;\n }\n };\n }\n };\n decorator.originalClass = AnnotationClass;\n return decorator;\n}\n","import {ToAnnotation} from '../ToAnnotation.js';\n\nclass RouteConfigAnnotation {\n constructor(routeDescription) {\n this.routeDescription = routeDescription;\n }\n}\n\nexport const RouteConfig = ToAnnotation(RouteConfigAnnotation);\n","import {ComponentMapper} from \"./router/ComponentMapper.js\";\nimport {RouteReader} from \"./router/RouteReader.js\";\nimport { RouteInitializer } from \"./router/RouteInitializer.js\";\nexport { RouteConfig } from \"./router/RouteConfig.js\";\n\nvar componentMapper = new ComponentMapper();\nvar routeReader = new RouteReader(componentMapper);\nvar routeInitializer = new RouteInitializer(componentMapper);\n\nexport var Router = {\n componentMapper: componentMapper,\n routeReader: routeReader,\n routeInitializer: routeInitializer\n};\n","export function applyAnnotation(target, annotationClass, ...params) {\n var AnnotationVersion = annotationClass.originalClass || annotationClass;\n target.annotations = target.annotations || [];\n target.annotations.push(new AnnotationVersion(...params))\n}\n","export {\n registerInjector,\n getInjector,\n Injector\n} from './a1atscript/Injector.js';\n\nexport {\n Config,\n Run,\n Controller,\n Directive,\n Service,\n Factory,\n Provider,\n Value,\n Constant,\n Filter,\n Animation,\n Module,\n AsModule\n} from './a1atscript/annotations.js';\n\nexport { DirectiveObject } from './a1atscript/DirectiveObject.js';\n\nimport './a1atscript/ng2Directives/ComponentInjector.js';\n\nexport {\n Component,\n Template,\n View\n} from \"./a1atscript/ng2Directives/Component.js\";\n\nexport { ToAnnotation } from './a1atscript/ToAnnotation.js';\n\nexport { bootstrap } from './a1atscript/bootstrap.js';\n\nexport { Router, RouteConfig } from './a1atscript/Router.js';\n\nexport { applyAnnotation} from \"./a1atscript/applyAnnotation.js\";\n"]} -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var traceur = require('gulp-traceur'); 3 | var connect = require('gulp-connect'); 4 | var rename_ = require('gulp-rename'); 5 | var bump = require('gulp-bump'); 6 | 7 | var TRACEUR_OPTIONS = require('./config').traceur; 8 | var PATH = { 9 | DIST: './dist/', 10 | BUILD: './build/', 11 | SRC: './src/**/*.js', 12 | TEST: './test/**/*.js' 13 | }; 14 | 15 | // A wrapper around gulp-rename to support `dirnamePrefix`. 16 | function rename(obj) { 17 | return rename_(function(parsedPath) { 18 | return { 19 | extname: obj.extname || parsedPath.extname, 20 | dirname: (obj.dirnamePrefix || '') + parsedPath.dirname, 21 | basename: parsedPath.basename 22 | }; 23 | }); 24 | } 25 | 26 | gulp.task('dist', function() { 27 | gulp.src(PATH.SRC, {base: '.'}) 28 | // Rename before Traceur, so that Traceur has the knowledge of both input and output paths. 29 | .pipe(rename({extname: '.js', dirnamePrefix: PATH.DIST})) 30 | .pipe(gulp.dest('.')); 31 | }); 32 | 33 | // TRANSPILE AT SCRIPT 34 | gulp.task('build/src', function() { 35 | gulp.src(PATH.SRC, {base: '.'}) 36 | // Rename before Traceur, so that Traceur has the knowledge of both input and output paths. 37 | .pipe(rename({extname: '.js', dirnamePrefix: PATH.BUILD})) 38 | .pipe(traceur(TRACEUR_OPTIONS)) 39 | .pipe(gulp.dest('.')); 40 | }); 41 | 42 | gulp.task('build/test', function() { 43 | gulp.src(PATH.TEST, {base: '.'}) 44 | // Rename before Traceur, so that Traceur has the knowledge of both input and output paths. 45 | .pipe(rename({extname: '.js', dirnamePrefix: PATH.BUILD})) 46 | .pipe(traceur(TRACEUR_OPTIONS)) 47 | .pipe(gulp.dest('.')); 48 | }); 49 | 50 | gulp.task('dist', function() { 51 | gulp.src(PATH.SRC, {base: './src'}) 52 | // Rename before Traceur, so that Traceur has the knowledge of both input and output paths. 53 | .pipe(rename({extname: '.js', dirnamePrefix: PATH.DIST})) 54 | .pipe(gulp.dest('.')); 55 | }); 56 | 57 | gulp.task('build', ['build/src', 'build/test']); 58 | 59 | // WATCH FILES FOR CHANGES 60 | gulp.task('watch', function() { 61 | gulp.watch(PATH.SRC, ['build']); 62 | }); 63 | 64 | 65 | // WEB SERVER 66 | gulp.task('serve', function() { 67 | connect.server({ 68 | root: [__dirname], 69 | port: 8000, 70 | livereload: false 71 | }); 72 | }); 73 | 74 | // Basic usage: 75 | // Will patch the version 76 | gulp.task('bump:patch', function(){ 77 | gulp.src(['./bower.json', './package.json']) 78 | .pipe(bump()) 79 | .pipe(gulp.dest('./')); 80 | }); 81 | 82 | // Defined method of updating: 83 | // Semantic 84 | gulp.task('bump:minor', function(){ 85 | gulp.src(['./bower.json', './package.json']) 86 | .pipe(bump({type:'minor'})) 87 | .pipe(gulp.dest('./')); 88 | }); 89 | 90 | // Defined method of updating: 91 | // Semantic major 92 | gulp.task('bump:major', function(){ 93 | gulp.src(['./bower.json', './package.json']) 94 | .pipe(bump({type:'major'})) 95 | .pipe(gulp.dest('./')); 96 | }); 97 | 98 | gulp.task('default', ['serve', 'watch']); 99 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | AtScript playground 4 | 5 | 6 | 7 | Check out the console;-) 8 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /karma.conf.babel.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Fri Mar 14 2014 15:01:19 GMT-0700 (PDT) 3 | 4 | var babelOptions = require('./config').babel; 5 | 6 | module.exports = function(config) { 7 | 8 | var files; 9 | 10 | files = [ 11 | 'test/**/*.js', 'test-babel/ToAnnotation_spec.js' 12 | ]; 13 | 14 | config.set({ 15 | frameworks: ['jasmine', 'browserify', 'sourcemaps'], 16 | 17 | files: [ 18 | 'node_modules/karma-babel-preprocessor/node_modules/babel-core/browser-polyfill.js' 19 | // The entry point that dynamically imports all the specs. 20 | //{pattern: 'test-help/main.js', included: true}, 21 | 22 | // The runtime assertion library. 23 | //'node_modules/rtts-assert/dist/cjs/assert.js', 24 | //'node_modules/angular/angular.js', 25 | //'node_modules/angular-mocks/angular-mocks.js' 26 | ].concat(files), 27 | 28 | preprocessors: { 29 | 'test/**/*.js': ['browserify'], 30 | 'test-babel/ToAnnotation_spec.js': ['browserify'] 31 | }, 32 | 33 | browsers: ['Chrome'], 34 | 35 | browserify: { 36 | debug: true, 37 | transform: [ ['babelify', babelOptions] ] 38 | } 39 | 40 | }); 41 | 42 | config.plugins.push(require('./karma_sourcemaps')); 43 | }; 44 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Fri Mar 14 2014 15:01:19 GMT-0700 (PDT) 3 | 4 | var traceurOptions = require('./config').traceur; 5 | 6 | module.exports = function(config) { 7 | 8 | var isWebstorm = /karma-intellij/.test(process.argv[1]); 9 | var files; 10 | 11 | if (isWebstorm) { 12 | // Running within WebStorm - WebStorm takes care of transpiling. 13 | // Serve already transpiled files, including source maps. 14 | files = [ 15 | {pattern: 'build/src/**/*.js', included: false}, 16 | {pattern: 'build/test/**/*.js', included: false}, 17 | {pattern: 'build/src/**/*.map', included: false}, 18 | {pattern: 'build/test/**/*.map', included: false} 19 | ]; 20 | } else { 21 | // Running outside WebStorm (eg. from commandline). 22 | // Karma transpiles the *.ats sources with karma-traceur-preprocessor. 23 | files = [ 24 | {pattern: 'src/**/*.js', included: false}, 25 | {pattern: 'test/**/*.js', included: false} 26 | 27 | ]; 28 | } 29 | 30 | config.set({ 31 | frameworks: ['jasmine', 'requirejs', 'traceur', 'sourcemaps'], 32 | 33 | files: [ 34 | // The entry point that dynamically imports all the specs. 35 | {pattern: 'test-help/main.js', included: true}, 36 | 37 | // The runtime assertion library. 38 | {pattern: 'node_modules/rtts-assert/dist/amd/assert.js', included: false}, 39 | {pattern: 'bower_components/angular/angular.js', included: false }, 40 | {pattern: 'bower_components/angular-mocks/angular-mocks.js', included: false}, 41 | {pattern: 'node_modules/angular-new-router/dist/router.es5.js', included: false} 42 | 43 | ].concat(files), 44 | 45 | preprocessors: { 46 | 'src/**/*.js': ['traceur'], 47 | 'test/**/*.js': ['traceur'] 48 | }, 49 | 50 | browsers: ['Chrome'], 51 | 52 | traceurPreprocessor: { 53 | options: traceurOptions, 54 | transformPath: function(path) { 55 | // Traceur preprocessor is only used when running Karma outside of WebStorm. 56 | // We change the path to `build/**` so that the paths are the same as with WebStorm. 57 | return path.replace(config.basePath, config.basePath + '/build'); 58 | } 59 | } 60 | }); 61 | 62 | config.plugins.push(require('./karma_sourcemaps')); 63 | }; 64 | -------------------------------------------------------------------------------- /karma_sourcemaps.js: -------------------------------------------------------------------------------- 1 | var SOURCE_MAP = /\.map$/; 2 | 3 | function findFile(files, path) { 4 | for (var i = 0, ii = files.length; i < ii; i++) { 5 | if (files[i].path === path) { 6 | return files[i]; 7 | } 8 | } 9 | 10 | return null; 11 | } 12 | 13 | function createSourceMapsPlugin(emitter, basePath, logger) { 14 | var log = logger.create('sourcemaps'); 15 | 16 | emitter.on('file_list_modified', function(filesPromise) { 17 | filesPromise.then(function(files) { 18 | files.served.forEach(function(file) { 19 | if (SOURCE_MAP.test(file.path)) { 20 | var sourceMap = JSON.parse(file.content); 21 | 22 | if (!sourceMap) { 23 | log.warn('Invalid source map file', file.originalPath); 24 | return; 25 | } 26 | 27 | var sourceFile = findFile(files.served, basePath + '/' + sourceMap.file); 28 | 29 | if (!sourceFile) { 30 | log.warn('Can not find source file for map', file.originalPath); 31 | return 32 | } 33 | 34 | sourceMap.sourceRoot = basePath; 35 | sourceFile.sourceMap = sourceMap; 36 | } 37 | }); 38 | }); 39 | }); 40 | } 41 | 42 | createSourceMapsPlugin.$inject = ['emitter', 'config.basePath', 'logger']; 43 | 44 | module.exports = { 45 | 'framework:sourcemaps': ['factory', createSourceMapsPlugin] 46 | }; 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "a1atscript", 3 | "private": false, 4 | "version": "0.5.0", 5 | "description": "The Angular 2 Polyfill.", 6 | "homepage": "https://github.com/hannahhoward/a1atscript", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/hannahhoward/a1atscript.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/hannahhoward/a1atscript/issues" 13 | }, 14 | "main": "dist/a1atscript.bundle.js", 15 | "devDependencies": { 16 | "angular": "^1.3.15", 17 | "angular-mocks": "^1.3.15", 18 | "angular-new-router": "^0.5.3", 19 | "assert": "angular/assert#dist", 20 | "babel": "^5.4.4", 21 | "babel-loader": "^5.3.2", 22 | "babelify": "^6.0.2", 23 | "gulp": "^3.8.9", 24 | "gulp-bump": "^0.2.2", 25 | "gulp-connect": "^2.0.6", 26 | "gulp-rename": "^1.2.0", 27 | "gulp-traceur": "vojtajina/gulp-traceur#fix-sourcemaps", 28 | "karma": "^0.12.24", 29 | "karma-babel-preprocessor": "^5.1.0", 30 | "karma-browserify": "^4.1.2", 31 | "karma-chrome-launcher": "^0.1.5", 32 | "karma-cli": "0.0.4", 33 | "karma-commonjs": "0.0.13", 34 | "karma-firefox-launcher": "^0.1.4", 35 | "karma-jasmine": "^0.2.2", 36 | "karma-requirejs": "^0.2.2", 37 | "karma-traceur-preprocessor": "^0.4.0", 38 | "node-libs-browser": "^0.5.2", 39 | "requirejs": "^2.1.15", 40 | "systemjs-builder": "^0.15.7", 41 | "traceur": "^0.0.86", 42 | "webpack": "^1.10.1" 43 | }, 44 | "scripts": { 45 | "test": "karma start --browsers Firefox --single-run; karma start karma.conf.babel.js --browsers Firefox --single-run", 46 | "dist": "webpack; node scripts/make-systemjs-bundle.js" 47 | }, 48 | "jspm": { 49 | "main": "dist/a1atscript.bundle.js", 50 | "format": "global" 51 | }, 52 | "author": "Hannah Howard ", 53 | "license": "Apache-2.0" 54 | } 55 | -------------------------------------------------------------------------------- /scripts/make-systemjs-bundle.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var Builder = require('systemjs-builder'); 3 | 4 | var config = { 5 | baseURL: 'dist', 6 | paths: { 7 | 'a1atscript': "./src/a1atscript.js", 8 | 'a1atscript/*': './src/a1atscript/*' 9 | }, 10 | transpiler: 'babel', 11 | babelOptions: { 12 | stage: 0 13 | } 14 | }; 15 | 16 | 17 | build('a1atscript', '../dist/a1atscript.system.bundle.js'); 18 | 19 | function build(name, outputFile) { 20 | var devBuilder = new Builder(); 21 | 22 | devBuilder.config(config); 23 | 24 | devBuilder.bundle(name, path.resolve(__dirname, outputFile), {normalize: true, sourceMaps: true, sourceMapContents: true}).then(function() { 25 | process.exit(0); 26 | }, function(err) { 27 | console.error('dev died', err); 28 | process.exit(1); 29 | }); 30 | } 31 | 32 | process.stdin.resume(); 33 | -------------------------------------------------------------------------------- /src/a1atscript.js: -------------------------------------------------------------------------------- 1 | export { 2 | registerInjector, 3 | getInjector, 4 | Injector 5 | } from './a1atscript/Injector.js'; 6 | 7 | export { 8 | Config, 9 | Run, 10 | Controller, 11 | Directive, 12 | Service, 13 | Factory, 14 | Provider, 15 | Value, 16 | Constant, 17 | Filter, 18 | Animation, 19 | Module, 20 | AsModule 21 | } from './a1atscript/annotations.js'; 22 | 23 | export { DirectiveObject } from './a1atscript/DirectiveObject.js'; 24 | 25 | import './a1atscript/ng2Directives/ComponentInjector.js'; 26 | 27 | export { 28 | Component, 29 | Template, 30 | View 31 | } from "./a1atscript/ng2Directives/Component.js"; 32 | 33 | export { ToAnnotation } from './a1atscript/ToAnnotation.js'; 34 | 35 | export { bootstrap } from './a1atscript/bootstrap.js'; 36 | 37 | export { Router, RouteConfig } from './a1atscript/Router.js'; 38 | 39 | export { applyAnnotation} from "./a1atscript/applyAnnotation.js"; 40 | -------------------------------------------------------------------------------- /src/a1atscript/AnnotationFinder.js: -------------------------------------------------------------------------------- 1 | export class AnnotationFinder { 2 | constructor(AnnotatedClass) { 3 | this.AnnotatedClass = AnnotatedClass; 4 | } 5 | 6 | annotationFor(AnnotationClass) { 7 | var OriginalClass = AnnotationClass.originalClass || AnnotationClass; 8 | if (this.AnnotatedClass.annotations) { 9 | return this.AnnotatedClass.annotations.find((annotation) => annotation instanceof OriginalClass) 10 | } else { 11 | return null; 12 | } 13 | } 14 | 15 | annotationsFor(AnnotationClass) { 16 | var OriginalClass = AnnotationClass.originalClass || AnnotationClass; 17 | if (this.AnnotatedClass.annotations) { 18 | return this.AnnotatedClass.annotations.filter((annotation) => annotation instanceof OriginalClass) 19 | } else { 20 | return null; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/a1atscript/DirectiveObject.js: -------------------------------------------------------------------------------- 1 | import {ListInjector} from './injectorTypes.js'; 2 | import {registerInjector} from './Injector.js'; 3 | import {ToAnnotation} from './ToAnnotation.js'; 4 | 5 | class DirectiveObjectAnnotation { 6 | constructor(token, dependencies = []) { 7 | this.dependencies = dependencies; 8 | this.token = token; 9 | } 10 | } 11 | 12 | export const DirectiveObject = ToAnnotation(DirectiveObjectAnnotation); 13 | 14 | class DirectiveObjectInjector extends ListInjector { 15 | get annotationClass() { 16 | return DirectiveObject; 17 | } 18 | 19 | _createFactoryArray(ConstructorFn) { 20 | // get the array of dependencies that are needed by this component (as contained in the `$inject` array) 21 | var args = ConstructorFn.$inject || []; 22 | var factoryArray = args.slice(); // create a copy of the array 23 | // The factoryArray uses Angular's array notation whereby each element of the array is the name of a 24 | // dependency, and the final item is the factory function itself. 25 | factoryArray.push((...args) => { 26 | var directive = new ConstructorFn(...args); 27 | for (var key in directive) { 28 | directive[key] = directive[key]; 29 | } 30 | return directive; 31 | }); 32 | 33 | return factoryArray; 34 | } 35 | 36 | _cloneFunction(original) { 37 | return function() { 38 | return original.apply(this, arguments); 39 | }; 40 | } 41 | 42 | _override(object, methodName, callback) { 43 | object[methodName] = callback(object[methodName]); 44 | } 45 | 46 | instantiateOne(module, directiveObject, metadata) { 47 | directiveObject['$inject'] = metadata.dependencies; 48 | 49 | if (!directiveObject.prototype.compile) { 50 | // create an empty compile function if none was defined. 51 | directiveObject.prototype.compile = () => {}; 52 | } 53 | 54 | var originalCompileFn = this._cloneFunction(directiveObject.prototype.compile); 55 | 56 | // Decorate the compile method to automatically return the link method (if it exists) 57 | // and bind it to the context of the constructor (so `this` works correctly). 58 | // This gets around the problem of a non-lexical "this" which occurs when the directive class itself 59 | // returns `this.link` from within the compile function. 60 | this._override(directiveObject.prototype, 'compile', function () { 61 | return function () { 62 | 63 | originalCompileFn.apply(this, arguments); 64 | 65 | if (directiveObject.prototype.link) { 66 | return directiveObject.prototype.link.bind(this); 67 | } 68 | }; 69 | }); 70 | 71 | var factoryArray = this._createFactoryArray(directiveObject); 72 | 73 | module.directive(metadata.token, factoryArray); 74 | } 75 | } 76 | 77 | registerInjector('directiveObject', DirectiveObjectInjector); 78 | 79 | 80 | /* 81 | var originalCompileFn = _cloneFunction(constructorFn.prototype.compile); 82 | 83 | // Decorate the compile method to automatically return the link method (if it exists) 84 | // and bind it to the context of the constructor (so `this` works correctly). 85 | // This gets around the problem of a non-lexical "this" which occurs when the directive class itself 86 | // returns `this.link` from within the compile function. 87 | _override(constructorFn.prototype, 'compile', function () { 88 | return function () { 89 | originalCompileFn.apply(this, arguments); 90 | 91 | if (constructorFn.prototype.link) { 92 | return constructorFn.prototype.link.bind(this); 93 | } 94 | }; 95 | }); 96 | 97 | var factoryArray = _createFactoryArray(constructorFn); 98 | 99 | app.directive(name, factoryArray); 100 | return this; 101 | } 102 | */ 103 | -------------------------------------------------------------------------------- /src/a1atscript/Injector.js: -------------------------------------------------------------------------------- 1 | import { AsModule, Module } from './annotations.js'; 2 | import { AnnotationFinder} from './AnnotationFinder.js'; 3 | 4 | import { 5 | ConfigInjector, 6 | RunInjector, 7 | ControllerInjector, 8 | DirectiveInjector, 9 | ServiceInjector, 10 | FactoryInjector, 11 | ProviderInjector, 12 | ValueInjector, 13 | ConstantInjector, 14 | AnimationInjector, 15 | FilterInjector 16 | } from './injectorTypes.js'; 17 | 18 | var registeredInjectors = {} 19 | 20 | export function registerInjector(name, InjectorClass) { 21 | registeredInjectors[name] = new InjectorClass(); 22 | } 23 | 24 | export function getInjector(name) { 25 | return registeredInjectors[name]; 26 | } 27 | 28 | registerInjector('config', ConfigInjector); 29 | registerInjector('run', RunInjector); 30 | registerInjector('controller', ControllerInjector); 31 | registerInjector('directive', DirectiveInjector); 32 | registerInjector('service', ServiceInjector); 33 | registerInjector('factory', FactoryInjector); 34 | registerInjector('provider', ProviderInjector); 35 | registerInjector('value', ValueInjector); 36 | registerInjector('constant', ConstantInjector); 37 | registerInjector('animation', AnimationInjector); 38 | registerInjector('filter', FilterInjector); 39 | 40 | export class Injector { 41 | constructor(appNamePrefix = "") { 42 | this.appNamePrefix = appNamePrefix; 43 | this.injectedModules = {}; 44 | } 45 | 46 | get annotationClass() { 47 | return Module; 48 | } 49 | 50 | instantiate(moduleClass) { 51 | var metadata = this._getAnnotatedClass(moduleClass); 52 | if (!metadata) { 53 | return undefined; 54 | } 55 | if (this.injectedModules[metadata.token]) { 56 | return this.injectedModules[metadata.token]; 57 | } 58 | var sortedDependencies = this._sortModuleDependencies(metadata); 59 | sortedDependencies = this._sortSelf(metadata, moduleClass, sortedDependencies); 60 | var moduleDependencies = this._instantiateModuleDependencies(sortedDependencies.module); 61 | var moduleName = metadata.token; 62 | if (this.appNamePrefix && moduleName != this.appNamePrefix) { 63 | moduleName = `${this.appNamePrefix}.${moduleName}`; 64 | } 65 | var instantiatedModule = angular.module(moduleName, moduleDependencies); 66 | delete sortedDependencies.module; 67 | this._instantiateOtherDependencies(sortedDependencies, instantiatedModule); 68 | this.injectedModules[metadata.token] = moduleName; 69 | return moduleName; 70 | } 71 | 72 | _sortSelf(metadata, moduleClass, sortedDependencies) { 73 | if (metadata == moduleClass) { 74 | return sortedDependencies; 75 | } else { 76 | var selfDependency = this._sortDependency(moduleClass, false); 77 | return this._mergeSortedDependencies(sortedDependencies, selfDependency); 78 | } 79 | } 80 | 81 | _getAnnotatedClass(moduleClass) { 82 | if (moduleClass instanceof Module) { 83 | moduleClass.injectable = false; 84 | return moduleClass; 85 | } else { 86 | var metadata = this._getModuleAnnotation(moduleClass); 87 | return metadata; 88 | } 89 | } 90 | 91 | _getDependencyType(dependency) { 92 | var annotations = dependency.annotations; 93 | for (var i=0; i < annotations.length; i++) { 94 | var annotation = annotations[i]; 95 | var foundInjector = Object.keys(registeredInjectors).find( 96 | (key) => { 97 | var annotationClass = registeredInjectors[key].annotationClass; 98 | annotationClass = annotationClass.originalClass || annotationClass; 99 | return annotation instanceof annotationClass; 100 | }); 101 | if (foundInjector) { 102 | return { 103 | key: foundInjector, 104 | metadata: annotation 105 | }; 106 | } 107 | } 108 | return null; 109 | } 110 | 111 | _getModuleAnnotation(dependency) { 112 | return (new AnnotationFinder(dependency)).annotationFor(Module); 113 | } 114 | 115 | _mergeSortedDependencies(sorted1, sorted2) { 116 | var newSorted = {} 117 | Object.assign(newSorted, sorted1) 118 | Object.keys(sorted2).forEach((key) => { 119 | if (newSorted[key]) { 120 | newSorted[key] = newSorted[key].concat(sorted2[key]); 121 | } else { 122 | newSorted[key] = sorted2[key]; 123 | } 124 | }); 125 | return newSorted; 126 | } 127 | 128 | _sortDependency(dependency, checkModule = true) { 129 | var sorted = {}; 130 | 131 | if (typeof dependency === "string" || dependency instanceof Module) { 132 | sorted.module = [dependency]; 133 | } else if (dependency.annotations) { 134 | if (checkModule && this._getModuleAnnotation(dependency)) { 135 | sorted.module = [dependency]; 136 | } else { 137 | var dependencyType = this._getDependencyType(dependency); 138 | if (dependencyType) { 139 | sorted[dependencyType.key] = [{ 140 | dependency: dependency, 141 | metadata: dependencyType.metadata 142 | }]; 143 | } 144 | } 145 | } else { 146 | Object.keys(dependency).forEach((key) => { 147 | var subDependency = dependency[key]; 148 | var sortedSubDependencies = this._sortDependency(subDependency); 149 | sorted = this._mergeSortedDependencies(sorted, sortedSubDependencies); 150 | }); 151 | } 152 | return sorted; 153 | } 154 | 155 | _sortModuleDependencies(moduleClass) { 156 | var sorted = {}; 157 | moduleClass.dependencies.forEach((dependency) => { 158 | var newSortedDependencies = this._sortDependency(dependency); 159 | sorted = this._mergeSortedDependencies(sorted, newSortedDependencies); 160 | }); 161 | 162 | return sorted; 163 | } 164 | 165 | _moduleMetadata(moduleClass) { 166 | return moduleClass.annotations.find((value) => value instanceof Module || value instanceof AsModule); 167 | } 168 | 169 | _instantiateModuleDependencies(moduleDependencies) { 170 | var returnedDependencies = []; 171 | 172 | if (moduleDependencies) { 173 | moduleDependencies.forEach((moduleDependency) => { 174 | if (typeof moduleDependency === "string") { 175 | returnedDependencies.push(moduleDependency); 176 | } else { 177 | returnedDependencies.push(this.instantiate(moduleDependency)); 178 | } 179 | }); 180 | 181 | } 182 | 183 | return returnedDependencies; 184 | } 185 | 186 | _instantiateOtherDependencies(sortedDependencies, instantiatedModule) { 187 | Object.keys(sortedDependencies).forEach((dependencyType) => { 188 | registeredInjectors[dependencyType].instantiate( 189 | instantiatedModule, 190 | sortedDependencies[dependencyType] 191 | ); 192 | }); 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/a1atscript/Router.js: -------------------------------------------------------------------------------- 1 | import {ComponentMapper} from "./router/ComponentMapper.js"; 2 | import {RouteReader} from "./router/RouteReader.js"; 3 | import { RouteInitializer } from "./router/RouteInitializer.js"; 4 | export { RouteConfig } from "./router/RouteConfig.js"; 5 | 6 | var componentMapper = new ComponentMapper(); 7 | var routeReader = new RouteReader(componentMapper); 8 | var routeInitializer = new RouteInitializer(componentMapper); 9 | 10 | export var Router = { 11 | componentMapper: componentMapper, 12 | routeReader: routeReader, 13 | routeInitializer: routeInitializer 14 | }; 15 | -------------------------------------------------------------------------------- /src/a1atscript/ToAnnotation.js: -------------------------------------------------------------------------------- 1 | function defineAnnotation(target, AnnotationClass, callParams) { 2 | var oldAnnotation = Object.getOwnPropertyDescriptor(target, 'annotations'); 3 | if (oldAnnotation) { 4 | var oldGetter = oldAnnotation.get 5 | Object.defineProperty(target, 'annotations', { 6 | configurable: true, 7 | get: function() { 8 | var oldValue = oldGetter(); 9 | oldValue.unshift(new (Function.prototype.bind.apply(AnnotationClass, callParams))); 10 | return oldValue; 11 | }}); 12 | } else { 13 | Object.defineProperty(target, 'annotations', { 14 | configurable: true, 15 | get: function() { 16 | return [new (Function.prototype.bind.apply(AnnotationClass, callParams))]; 17 | }}); 18 | } 19 | } 20 | 21 | function handleProperty(descriptor, AnnotationClass, callParams) { 22 | var value; 23 | if (descriptor.initializer) { 24 | value = descriptor.initializer(); 25 | } else { 26 | value = descriptor.value; 27 | } 28 | defineAnnotation(value, AnnotationClass, callParams); 29 | if (descriptor.initializer) { 30 | descriptor.initializer = function() { return value; } 31 | } 32 | descriptor.enumerable = true; 33 | return descriptor; 34 | } 35 | 36 | export function ToAnnotation(AnnotationClass) { 37 | var decorator = function(...callParams) { 38 | if (this instanceof decorator) { 39 | return new AnnotationClass(...callParams) 40 | } else { 41 | callParams.unshift(null); 42 | return function(targetClass, ...otherParams) { 43 | if (otherParams.length >= 2) { 44 | return handleProperty(otherParams[1], AnnotationClass, callParams); 45 | } else { 46 | defineAnnotation(targetClass, AnnotationClass, callParams) 47 | return targetClass; 48 | } 49 | }; 50 | } 51 | }; 52 | decorator.originalClass = AnnotationClass; 53 | return decorator; 54 | } 55 | -------------------------------------------------------------------------------- /src/a1atscript/annotations.js: -------------------------------------------------------------------------------- 1 | import {ToAnnotation} from './ToAnnotation.js'; 2 | 3 | class NgAnnotation { 4 | constructor(...dependencies) { 5 | this.dependencies = dependencies; 6 | } 7 | } 8 | 9 | class NgNamedAnnotation { 10 | constructor(token, dependencies = []) { 11 | this.dependencies = dependencies; 12 | this.token = token; 13 | } 14 | } 15 | 16 | class ConfigAnnotation extends NgAnnotation { 17 | } 18 | 19 | export const Config = ToAnnotation(ConfigAnnotation); 20 | 21 | class RunAnnotation extends NgAnnotation { 22 | 23 | } 24 | 25 | export const Run = ToAnnotation(RunAnnotation); 26 | 27 | class ControllerAnnotation extends NgNamedAnnotation { 28 | 29 | } 30 | 31 | export const Controller = ToAnnotation(ControllerAnnotation); 32 | 33 | class DirectiveAnnotation extends NgNamedAnnotation { 34 | 35 | } 36 | 37 | export const Directive = ToAnnotation(DirectiveAnnotation); 38 | 39 | class ServiceAnnotation extends NgNamedAnnotation { 40 | 41 | } 42 | 43 | export const Service = ToAnnotation(ServiceAnnotation); 44 | 45 | 46 | class FactoryAnnotation extends NgNamedAnnotation { 47 | 48 | } 49 | 50 | export const Factory = ToAnnotation(FactoryAnnotation); 51 | 52 | class ProviderAnnotation extends NgNamedAnnotation { 53 | 54 | } 55 | 56 | export const Provider = ToAnnotation(ProviderAnnotation); 57 | 58 | class ValueAnnotation extends NgNamedAnnotation { 59 | 60 | } 61 | 62 | export const Value = ToAnnotation(ValueAnnotation); 63 | 64 | class ConstantAnnotation extends NgNamedAnnotation { 65 | 66 | } 67 | 68 | export const Constant = ToAnnotation(ConstantAnnotation); 69 | 70 | class FilterAnnotation extends NgNamedAnnotation { 71 | 72 | } 73 | 74 | export const Filter = ToAnnotation(FilterAnnotation); 75 | 76 | class AnimationAnnotation extends NgNamedAnnotation { 77 | 78 | } 79 | 80 | export const Animation = ToAnnotation(AnimationAnnotation); 81 | 82 | export class Module extends NgNamedAnnotation { 83 | 84 | } 85 | 86 | export const AsModule = ToAnnotation(Module); 87 | -------------------------------------------------------------------------------- /src/a1atscript/applyAnnotation.js: -------------------------------------------------------------------------------- 1 | export function applyAnnotation(target, annotationClass, ...params) { 2 | var AnnotationVersion = annotationClass.originalClass || annotationClass; 3 | target.annotations = target.annotations || []; 4 | target.annotations.push(new AnnotationVersion(...params)) 5 | } 6 | -------------------------------------------------------------------------------- /src/a1atscript/bootstrap.js: -------------------------------------------------------------------------------- 1 | import {Injector} from "./Injector.js"; 2 | import {Router} from "./Router.js"; 3 | 4 | export function bootstrap(appModule, appPrefix = "") { 5 | var injector = new Injector(appPrefix); 6 | var moduleName = injector.instantiate(appModule); 7 | Router.routeInitializer.initialize(moduleName, appModule); 8 | } 9 | -------------------------------------------------------------------------------- /src/a1atscript/injectorTypes.js: -------------------------------------------------------------------------------- 1 | import { 2 | Config, 3 | Run, 4 | Controller, 5 | Directive, 6 | Service, 7 | Factory, 8 | Provider, 9 | Value, 10 | Constant, 11 | Animation, 12 | Filter 13 | } from './annotations.js'; 14 | import {Router} from "./Router.js"; 15 | 16 | export class ListInjector { 17 | instantiate(module, dependencyList) { 18 | dependencyList.forEach((dependencyObject) => { 19 | this.instantiateOne(module, dependencyObject.dependency, dependencyObject.metadata); 20 | }); 21 | } 22 | } 23 | 24 | export class ConfigInjector extends ListInjector { 25 | 26 | get annotationClass() { 27 | return Config; 28 | } 29 | 30 | instantiateOne(module, config, metadata) { 31 | config['$inject'] = metadata.dependencies; 32 | module.config(config); 33 | } 34 | } 35 | 36 | export class RunInjector extends ListInjector { 37 | 38 | get annotationClass() { 39 | return Run; 40 | } 41 | 42 | instantiateOne(module, run, metadata) { 43 | run['$inject'] = metadata.dependencies; 44 | module.run(run); 45 | } 46 | } 47 | 48 | export class ControllerInjector extends ListInjector { 49 | 50 | get annotationClass() { 51 | return Controller; 52 | } 53 | 54 | instantiateOne(module, controller, metadata) { 55 | controller['$inject'] = metadata.dependencies; 56 | Router.routeReader.read(controller); 57 | module.controller(metadata.token, controller); 58 | } 59 | 60 | } 61 | 62 | export class DirectiveInjector extends ListInjector { 63 | 64 | get annotationClass() { 65 | return Directive; 66 | } 67 | 68 | instantiateOne(module, directive, metadata) { 69 | directive['$inject'] = metadata.dependencies; 70 | module.directive(metadata.token, directive); 71 | } 72 | 73 | } 74 | 75 | export class ServiceInjector extends ListInjector { 76 | 77 | get annotationClass() { 78 | return Service; 79 | } 80 | 81 | instantiateOne(module, service, metadata) { 82 | service['$inject'] = metadata.dependencies; 83 | module.service(metadata.token, service); 84 | } 85 | 86 | } 87 | 88 | export class FactoryInjector extends ListInjector { 89 | 90 | get annotationClass() { 91 | return Factory; 92 | } 93 | 94 | instantiateOne(module, factory, metadata) { 95 | factory['$inject'] = metadata.dependencies; 96 | module.factory(metadata.token, factory); 97 | } 98 | 99 | } 100 | 101 | export class ProviderInjector extends ListInjector { 102 | 103 | get annotationClass() { 104 | return Provider; 105 | } 106 | 107 | instantiateOne(module, provider, metadata) { 108 | provider['$inject'] = metadata.dependencies; 109 | module.provider(metadata.token, provider); 110 | } 111 | 112 | } 113 | 114 | export class ValueInjector extends ListInjector { 115 | 116 | get annotationClass() { 117 | return Value; 118 | } 119 | 120 | instantiateOne(module, value, metadata) { 121 | value['$inject'] = metadata.dependencies; 122 | module.value(metadata.token, value); 123 | } 124 | 125 | } 126 | 127 | export class ConstantInjector extends ListInjector { 128 | 129 | get annotationClass() { 130 | return Constant; 131 | } 132 | 133 | instantiateOne(module, constant, metadata) { 134 | constant['$inject'] = metadata.dependencies; 135 | module.constant(metadata.token, constant); 136 | } 137 | 138 | } 139 | 140 | export class AnimationInjector extends ListInjector { 141 | 142 | get annotationClass() { 143 | return Animation; 144 | } 145 | 146 | instantiateOne(module, animation, metadata) { 147 | animation['$inject'] = metadata.dependencies; 148 | module.animation(metadata.token, animation); 149 | } 150 | 151 | } 152 | 153 | export class FilterInjector extends ListInjector { 154 | 155 | get annotationClass() { 156 | return Filter; 157 | } 158 | 159 | instantiateOne(module, filter, metadata) { 160 | filter['$inject'] = metadata.dependencies; 161 | module.filter(metadata.token, filter); 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /src/a1atscript/ng2Directives/BindBuilder.js: -------------------------------------------------------------------------------- 1 | export default class BindBuilder { 2 | constructor(bindParam, component) { 3 | this._bindParam = bindParam; 4 | this._component = component; 5 | } 6 | 7 | get bindObj() { 8 | if (!this._bindObj) { 9 | if (Array.isArray(this._bindParam)) { 10 | this._bindObj = {}; 11 | var splitBind; 12 | this._bindParam.forEach((bind) => { 13 | splitBind = bind.split(/\s*:\s*/); 14 | if (splitBind.length == 1) { 15 | this._bindObj[bind] = bind; 16 | } else { 17 | this._bindObj[splitBind[0]] = splitBind[1]; 18 | } 19 | }) 20 | } else { 21 | this._bindObj = this._bindParam 22 | } 23 | } 24 | return this._bindObj; 25 | } 26 | 27 | build() { 28 | var properties = {}; 29 | Object.keys(this.bindObj).forEach((key) => { 30 | this.setupProperty(key, properties) 31 | }); 32 | return properties; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/a1atscript/ng2Directives/Component.js: -------------------------------------------------------------------------------- 1 | import Ng2Directive from './Ng2Directive.js'; 2 | import {ToAnnotation} from '../ToAnnotation.js'; 3 | 4 | class ComponentAnnotation extends Ng2Directive { 5 | constructor(descriptor) { 6 | super(descriptor) 7 | this.appInjector = descriptor.appInjector || descriptor.injectables || descriptor.services; 8 | } 9 | } 10 | 11 | export const Component = ToAnnotation(ComponentAnnotation); 12 | 13 | export class ViewBase { 14 | constructor(descriptor) { 15 | this.templateUrl = descriptor.templateUrl || descriptor.url; 16 | this.template = descriptor.template || descriptor.inline; 17 | } 18 | } 19 | 20 | export const Template = ToAnnotation(ViewBase); 21 | 22 | export const View = ToAnnotation(ViewBase); 23 | -------------------------------------------------------------------------------- /src/a1atscript/ng2Directives/ComponentInjector.js: -------------------------------------------------------------------------------- 1 | import {registerInjector} from '../Injector.js'; 2 | import {Component, ViewBase} from './Component.js'; 3 | import {ListInjector} from "../injectorTypes.js"; 4 | import Ng2DirectiveDefinitionObject from "./Ng2DirectiveDefinitionObject.js"; 5 | import PropertiesBuilder from "./PropertiesBuilder.js"; 6 | import EventsBuilder from "./EventsBuilder.js"; 7 | import {Router} from "../Router.js"; 8 | 9 | class ComponentInjector extends ListInjector { 10 | constructor() { 11 | super(); 12 | this.componentHooks = {before: [], after: []}; 13 | } 14 | 15 | get annotationClass() { 16 | return Component; 17 | } 18 | 19 | _template(component) { 20 | return component.annotations.find((annotation) => annotation instanceof ViewBase) || {}; 21 | } 22 | 23 | instantiateOne(module, component, annotation) { 24 | if (annotation.appInjector) { 25 | component.$inject = annotation.appInjector; 26 | } 27 | Router.routeReader.read(component); 28 | var template = this._template(component); 29 | var properties = {}, 30 | events = {}, 31 | bind; 32 | if (annotation.properties) { 33 | properties = (new PropertiesBuilder(annotation.properties, component)).build(); 34 | } 35 | if (annotation.events) { 36 | events = (new EventsBuilder(annotation.events, component)).build(); 37 | } 38 | bind = Object.assign({}, properties, events); 39 | if (bind === {}) bind = null; 40 | if (annotation.selector) { 41 | var ddo = new Ng2DirectiveDefinitionObject(component, annotation, template, bind); 42 | this.hooks('before', module, ddo); 43 | module.directive(ddo.name, ddo.factoryFn); 44 | this.hooks('after', module, ddo); 45 | } 46 | } 47 | 48 | hooks(phase, module, ddo) { 49 | this.componentHooks[phase].forEach((hook) => { 50 | hook(module, ddo); 51 | }); 52 | } 53 | } 54 | 55 | registerInjector('component', ComponentInjector); 56 | -------------------------------------------------------------------------------- /src/a1atscript/ng2Directives/EventsBuilder.js: -------------------------------------------------------------------------------- 1 | import BindBuilder from "./BindBuilder.js" 2 | 3 | var prefix = "___bindable___" 4 | 5 | export default class EventsBuilder extends BindBuilder { 6 | 7 | setupProperty(key, events) { 8 | events[key] = "=?on"+this.bindObj[key][0].toUpperCase() + this.bindObj[key].slice(1); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/a1atscript/ng2Directives/Ng2Directive.js: -------------------------------------------------------------------------------- 1 | export default class Ng2Directive { 2 | constructor(descriptor) { 3 | this.selector = descriptor.selector; 4 | this.properties = descriptor.properties || descriptor.bind; 5 | this.controllerAs = descriptor.controllerAs; 6 | this.require = descriptor.require; 7 | this.transclude = descriptor.transclude; 8 | this.events = descriptor.events; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/a1atscript/ng2Directives/Ng2DirectiveDefinitionObject.js: -------------------------------------------------------------------------------- 1 | import SelectorMatcher from "./SelectorMatcher.js"; 2 | 3 | export default class Ng2DirectiveDefinitionObject { 4 | 5 | constructor(controller, annotation, template = {}, bind = null) { 6 | this._annotation = annotation; 7 | this._controller = controller; 8 | this._template = template; 9 | this._bind = bind; 10 | } 11 | 12 | get selectorMatcher() { 13 | this._selectorMatcher = this._selectorMatcher || 14 | new SelectorMatcher(this._annotation.selector); 15 | return this._selectorMatcher; 16 | } 17 | 18 | get restrict() { 19 | return this.selectorMatcher.restrict; 20 | } 21 | 22 | get controllerAs() { 23 | return this._annotation.controllerAs || this.name; 24 | } 25 | 26 | get bindToController() { 27 | // bindToController as object syntax only supported on 1.4 28 | if (angular.version.major == 1 && angular.version.minor >= 4) { 29 | return this._bind || this._annotation.properties; 30 | } else { 31 | return true; 32 | } 33 | 34 | } 35 | 36 | get scope() { 37 | // bindToController as object syntax only supported on 1.4 38 | if (angular.version.major == 1 && angular.version.minor >= 4) { 39 | return {}; 40 | } else { 41 | return this._bind || this._annotation.properties; 42 | } 43 | } 44 | 45 | get template() { 46 | return this._template.template; 47 | } 48 | 49 | get templateUrl() { 50 | return this._template.templateUrl; 51 | } 52 | 53 | get transclude() { 54 | return this._annotation.transclude; 55 | } 56 | 57 | get require() { 58 | return this._annotation.require; 59 | } 60 | 61 | get controller() { 62 | return this._controller; 63 | } 64 | 65 | get name() { 66 | return this.selectorMatcher.name; 67 | } 68 | 69 | get factoryFn() { 70 | return () => { 71 | return { 72 | scope: this.scope, 73 | restrict: this.restrict, 74 | template: this.template, 75 | require: this.require, 76 | transclude: this.transclude, 77 | templateUrl: this.templateUrl, 78 | controller: this.controller, 79 | bindToController: this.bindToController, 80 | controllerAs: this.controllerAs 81 | }; 82 | }; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/a1atscript/ng2Directives/PropertiesBuilder.js: -------------------------------------------------------------------------------- 1 | import BindBuilder from "./BindBuilder.js" 2 | 3 | const BIND_PREFIX = "_=_"; 4 | const STRING_PREFIX = "_@_"; 5 | const BINDING = BIND_PREFIX; 6 | const RAW_STRING = STRING_PREFIX; 7 | 8 | export default class PropertiesBuilder extends BindBuilder { 9 | 10 | setupProperty(key, properties) { 11 | properties[STRING_PREFIX + key] = "@" + this.bindObj[key]; 12 | properties[BIND_PREFIX + key] = "=?bind" + this.bindObj[key][0].toUpperCase() + this.bindObj[key].slice(1); 13 | 14 | 15 | // This property is used when user uses the `bind-property` attribute on a directive to bind an expression 16 | Object.defineProperty(this._component.prototype, BIND_PREFIX + key, { 17 | enumerable: true, 18 | configurable: true, 19 | set: genericSetter(BINDING, RAW_STRING), 20 | get: function() { 21 | return this[key]; 22 | } 23 | }); 24 | 25 | // This property is used when user uses the `property` attribute on a directive to bind a string 26 | Object.defineProperty(this._component.prototype, STRING_PREFIX + key, { 27 | enumerable: true, 28 | configurable: true, 29 | set: genericSetter(RAW_STRING, BINDING), 30 | get: function() { 31 | return this[key]; 32 | } 33 | }); 34 | 35 | function genericSetter(use, errorOn) { 36 | return function(value) { 37 | this.__using_binding__ = this.__using_binding__ || {}; 38 | 39 | if (this.__using_binding__[key] === errorOn) { 40 | if (value !== undefined) { 41 | throw new Error(`Cannot use bind-${key} and ${key} simultaneously`); 42 | } 43 | 44 | return; 45 | } 46 | 47 | if (value !== undefined) { 48 | this.__using_binding__[key] = use; 49 | } 50 | 51 | this[key] = value; 52 | }; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/a1atscript/ng2Directives/SelectorMatcher.js: -------------------------------------------------------------------------------- 1 | var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g; 2 | var MOZ_HACK_REGEXP = /^moz([A-Z])/; 3 | 4 | export default class SelectorMatcher { 5 | constructor(selector: string) { 6 | this._selector = selector; 7 | } 8 | 9 | _camelizeName() { 10 | this._name = this._name.replace(SPECIAL_CHARS_REGEXP, 11 | (_, separator, letter, offset) => offset ? letter.toUpperCase() : letter ). 12 | replace(MOZ_HACK_REGEXP, 'Moz$1'); 13 | } 14 | 15 | _split() { 16 | if (this._selector[0] == ".") { 17 | this._restrict = "C"; 18 | this._name = this._selector.substring(1); 19 | } else if (this._selector[0] == "[" && 20 | this._selector[this._selector.length-1] == "]") { 21 | this._restrict = "A"; 22 | this._name = this._selector.substring(1, this._selector.length-1); 23 | } else { 24 | this._restrict = "E"; 25 | this._name = this._selector; 26 | } 27 | } 28 | 29 | get name() { 30 | if (!this._name) { 31 | this._split(); 32 | } 33 | this._camelizeName(); 34 | return this._name; 35 | } 36 | 37 | get restrict() { 38 | if (!this._restrict) { 39 | this._split(); 40 | } 41 | return this._restrict; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/a1atscript/router/ComponentMapper.js: -------------------------------------------------------------------------------- 1 | import {Controller} from "../annotations.js"; 2 | import {Component, ViewBase} from "../ng2Directives/Component.js"; 3 | import {AnnotationFinder} from "../AnnotationFinder.js"; 4 | import SelectorMatcher from "../ng2Directives/SelectorMatcher.js"; 5 | 6 | var DEFAULT_CONTROLLER_SUFFIX = "Controller"; 7 | var DEFAULT_COMPONENT_PREFIX = "a1atscript"; 8 | var DEFAULT_CONTROLLER_PREFIX = "A1AtScript"; 9 | 10 | class ComponentMapping { 11 | constructor(component, componentMapper) { 12 | this.component = component; 13 | this.componentMapper = componentMapper; 14 | } 15 | 16 | get componentName() { 17 | return this.componentMapper.map.get(this.component); 18 | } 19 | 20 | get templateUrl() { 21 | return this.componentMapper.registry[this.componentName].templateUrl; 22 | } 23 | 24 | get isController() { 25 | return this.componentMapper.registry[this.componentName].isController; 26 | } 27 | 28 | get controllerName() { 29 | return this.componentMapper.registry[this.componentName].controllerName; 30 | } 31 | } 32 | 33 | export class ComponentMapper { 34 | register(component) { 35 | if (!this.map.get(component)) { 36 | this._setupComponent(component); 37 | } 38 | return new ComponentMapping(component, this); 39 | } 40 | 41 | _getControllerComponentName(component) { 42 | var name = this._getControllerName(component); 43 | if (name) { 44 | if (name.endsWith(DEFAULT_CONTROLLER_SUFFIX)) { 45 | return name[0].toLowerCase() + name.substr(1, name.length - DEFAULT_CONTROLLER_SUFFIX.length - 1); 46 | } else { 47 | return name[0].toLowerCase() + name.substr(1, name.length - 1); 48 | } 49 | } else { 50 | return null; 51 | } 52 | } 53 | 54 | _getControllerName(component) { 55 | var controllerAnnotation = (new AnnotationFinder(component)).annotationFor(Controller); 56 | if (controllerAnnotation) { 57 | return controllerAnnotation.token; 58 | } else { 59 | return null; 60 | } 61 | } 62 | 63 | _isController(component) { 64 | var controllerAnnotation = (new AnnotationFinder(component)).annotationFor(Controller); 65 | if (controllerAnnotation) { 66 | return true; 67 | } else { 68 | return false; 69 | } 70 | } 71 | _getComponentName(component) { 72 | var componentAnnotation = (new AnnotationFinder(component)).annotationFor(Component); 73 | if (componentAnnotation) { 74 | if (componentAnnotation.controllerAs) { 75 | return componentAnnotation.controllerAs; 76 | } else if (componentAnnotation.selector) { 77 | var selectorMatcher = new SelectorMatcher(componentAnnotation.selector); 78 | return selectorMatcher.name; 79 | } else { 80 | return null; 81 | } 82 | } else { 83 | return null; 84 | } 85 | } 86 | 87 | _getGeneratedName() { 88 | this._componentIndex = this._componentIndex || 0; 89 | var name = `${DEFAULT_COMPONENT_PREFIX}Component_${this._componentIndex}`; 90 | this._componentIndex = this._componentIndex + 1; 91 | return name; 92 | } 93 | 94 | _generateName(component) { 95 | var name = this._getControllerComponentName(component); 96 | name = name || this._getComponentName(component); 97 | name = name || this._getGeneratedName(); 98 | return name; 99 | } 100 | 101 | _generateTemplate(name, component) { 102 | var viewAnnotation = (new AnnotationFinder(component)).annotationFor(ViewBase); 103 | if (viewAnnotation && viewAnnotation.templateUrl) { 104 | return viewAnnotation.templateUrl; 105 | } else { 106 | return `./components/${name}/${name}.html`; 107 | } 108 | } 109 | 110 | _readInlineTemplate(templateUrl, component) { 111 | var viewAnnotation = (new AnnotationFinder(component)).annotationFor(ViewBase); 112 | if (viewAnnotation && viewAnnotation.template) { 113 | this.inlineTemplateCache[templateUrl] = viewAnnotation.template; 114 | } 115 | } 116 | 117 | _generateControllerName(name) { 118 | var componentBase; 119 | if (name.startsWith(DEFAULT_COMPONENT_PREFIX)) { 120 | componentBase = name.substring(DEFAULT_COMPONENT_PREFIX.length, name.length) 121 | } else { 122 | componentBase = name; 123 | } 124 | return DEFAULT_CONTROLLER_PREFIX + componentBase[0].toUpperCase() + componentBase.substring(1, componentBase.length) + DEFAULT_CONTROLLER_SUFFIX; 125 | } 126 | 127 | _setupComponent(component) { 128 | var name = this._generateName(component); 129 | var templateUrl = this._generateTemplate(name, component); 130 | var controllerName = this._getControllerName(component); 131 | var isController; 132 | if (controllerName) { 133 | isController = true; 134 | } else { 135 | isController = false; 136 | controllerName = this._generateControllerName(name); 137 | } 138 | this.map.set(component, name); 139 | this.registry[name] = { component: component, templateUrl: templateUrl, isController: isController, controllerName: controllerName } 140 | this.controllerRegistry[controllerName] = name; 141 | this._readInlineTemplate(templateUrl, component); 142 | } 143 | 144 | get registry() { 145 | this._componentRegistry = this._componentRegistry || {} 146 | return this._componentRegistry; 147 | } 148 | 149 | get map() { 150 | this._componentMap = this._componentMap || new Map(); 151 | return this._componentMap; 152 | } 153 | 154 | getComponent(componentName) { 155 | return this.registry[componentName].component; 156 | } 157 | 158 | getTemplateUrl(componentName) { 159 | return this.registry[componentName].templateUrl; 160 | } 161 | 162 | getComponentName(component) { 163 | return this.map.get(component); 164 | } 165 | 166 | get controllerRegistry() { 167 | this._controllerRegistry = this._controllerRegistry || {} 168 | return this._controllerRegistry; 169 | } 170 | 171 | get inlineTemplateCache() { 172 | this._inlineTemplateCache = this._inlineTemplateCache || {} 173 | return this._inlineTemplateCache; 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/a1atscript/router/RouteConfig.js: -------------------------------------------------------------------------------- 1 | import {ToAnnotation} from '../ToAnnotation.js'; 2 | 3 | class RouteConfigAnnotation { 4 | constructor(routeDescription) { 5 | this.routeDescription = routeDescription; 6 | } 7 | } 8 | 9 | export const RouteConfig = ToAnnotation(RouteConfigAnnotation); 10 | -------------------------------------------------------------------------------- /src/a1atscript/router/RouteInitializer.js: -------------------------------------------------------------------------------- 1 | export class RouteInitializer { 2 | constructor(componentMapper) { 3 | this.componentMapper = componentMapper; 4 | } 5 | 6 | configurationFunction(componentMapperName) { 7 | var componentMapper = this.componentMapper; 8 | return function($injector) { 9 | var $componentMapper; 10 | try { 11 | $componentMapper = $injector.get(componentMapperName); 12 | } catch(e) { 13 | return; 14 | } 15 | $componentMapper.setCtrlNameMapping(function(name) { 16 | return componentMapper.registry[name].controllerName; 17 | }); 18 | $componentMapper.setTemplateMapping(function(name) { 19 | return componentMapper.registry[name].templateUrl; 20 | }); 21 | $componentMapper.setComponentFromCtrlMapping(function(controllerName) { 22 | return componentMapper.controllerRegistry[controllerName]; 23 | }); 24 | } 25 | } 26 | 27 | topRouteConfig(routerName, routeConfig) { 28 | return function($injector) { 29 | var $router; 30 | try { 31 | $router = $injector.get(routerName); 32 | 33 | } catch(e) { 34 | return; 35 | } 36 | $router.config(routeConfig); 37 | }; 38 | } 39 | 40 | setupComponentControllers() { 41 | Object.keys(this.componentMapper.registry).forEach((component) => { 42 | var config = this.componentMapper.registry[component]; 43 | if (!config.isController && config.component != this.topComponent) { 44 | this.module.controller( 45 | config.controllerName, 46 | config.component 47 | ); 48 | } 49 | }); 50 | } 51 | 52 | setupInlineTemplates() { 53 | var inlineTemplateCache = this.componentMapper.inlineTemplateCache; 54 | return function($templateCache) { 55 | Object.keys(inlineTemplateCache).forEach((templateUrl) => { 56 | $templateCache.put(templateUrl, inlineTemplateCache[templateUrl]); 57 | }); 58 | }; 59 | } 60 | initialize(ngModuleName, topComponent = null) { 61 | this.module = angular.module(ngModuleName); 62 | 63 | // ng-new-router changed the name of its componentMapper service recently 64 | // essentially the approach here is to try to configure the mapper with both names 65 | // catch exceptions if they don't exist. 66 | // if both throw an exception, than there is no component router present 67 | this.module.config(['$injector', this.configurationFunction('$componentLoaderProvider')]); 68 | this.module.run(['$injector', this.configurationFunction('$componentMapper')]); 69 | 70 | if (topComponent && topComponent.$routeConfig) { 71 | this.topComponent = topComponent; 72 | this.module.run(['$injector', this.topRouteConfig('$router', topComponent.$routeConfig)]) 73 | } 74 | 75 | this.setupComponentControllers(); 76 | 77 | this.module.run(['$templateCache', this.setupInlineTemplates()]); 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/a1atscript/router/RouteReader.js: -------------------------------------------------------------------------------- 1 | import {RouteConfig} from "./RouteConfig.js"; 2 | import {AnnotationFinder} from "../AnnotationFinder.js"; 3 | 4 | export class RouteReader { 5 | constructor(componentMapper) { 6 | this.componentMapper = componentMapper; 7 | } 8 | 9 | _routeConfigAnnotations(component) { 10 | return (new AnnotationFinder(component)).annotationsFor(RouteConfig); 11 | } 12 | 13 | _routeConfig(component) { 14 | return this._routeConfigAnnotations(component).map(this._convertConfig.bind(this)); 15 | } 16 | 17 | _componentName(component) { 18 | if (typeof(component) === "string") { 19 | return component 20 | } else { 21 | return this.componentMapper.register(component).componentName; 22 | } 23 | } 24 | 25 | _convertConfig(routeConfigAnnotation) { 26 | var routeDescription = Object.assign({}, routeConfigAnnotation.routeDescription); 27 | if (routeDescription.component) { 28 | routeDescription.component = this._componentName(routeDescription.component); 29 | } 30 | 31 | if (routeDescription.components) { 32 | var components = {}; 33 | Object.keys(routeDescription.components).forEach((key) => { 34 | components[key] = this._componentName(routeDescription.components[key]); 35 | }); 36 | routeDescription.components = components; 37 | } 38 | 39 | return routeDescription; 40 | } 41 | 42 | read(component) { 43 | var mapping = this.componentMapper.register(component); 44 | component.$routeConfig = this._routeConfig(component); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test-babel/ToAnnotation_spec.js: -------------------------------------------------------------------------------- 1 | import {ToAnnotation} from '../src/a1atscript/ToAnnotation.js'; 2 | 3 | class AnnoClassAnnotation { 4 | 5 | } 6 | 7 | const AnnoClass = ToAnnotation(AnnoClassAnnotation); 8 | 9 | class Anno2ClassAnnotation { 10 | constructor(awesome, awesomeness) { 11 | this.awesome = awesome; 12 | this.awesomeness = awesomeness; 13 | } 14 | } 15 | 16 | const Anno2Class = ToAnnotation(Anno2ClassAnnotation); 17 | 18 | @AnnoClass() 19 | @Anno2Class("cheese", "grater") 20 | class TargetClass { 21 | 22 | @AnnoClass() 23 | method() { 24 | 25 | } 26 | } 27 | 28 | var literal = { 29 | @AnnoClass() 30 | awesome() {} 31 | } 32 | 33 | describe("ToAnnotation decorator", function() { 34 | 35 | it("operating on class", function() { 36 | expect(TargetClass.annotations).toEqual([new (AnnoClass.originalClass)(), new (Anno2Class.originalClass)("cheese", "grater")]); 37 | }); 38 | 39 | it("operating on method", function() { 40 | expect(TargetClass.prototype.method.annotations).toEqual([new (AnnoClass.originalClass)()]); 41 | }); 42 | 43 | it("operating on literal property", function() { 44 | expect(literal.awesome.annotations).toEqual([new (AnnoClass.originalClass)()]); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /test-help/main.js: -------------------------------------------------------------------------------- 1 | // The entry point for unit tests. 2 | 3 | console.log("loaded"); 4 | 5 | var TEST_REGEXP = /_spec\.js$/; 6 | 7 | function pathToModule(path) { 8 | return path.replace(/^\/base\//, '').replace(/\.js$/, ''); 9 | } 10 | 11 | function onlySpecs(path) { 12 | return TEST_REGEXP.test(path); 13 | } 14 | 15 | function getAllSpecs() { 16 | return Object.keys(window.__karma__.files) 17 | .filter(onlySpecs) 18 | .map(pathToModule); 19 | } 20 | 21 | require.config({ 22 | // Karma serves files under `/base`, which is the `basePath` from `karma-conf.js` file. 23 | baseUrl: '/base', 24 | 25 | paths: { 26 | assert: './node_modules/rtts-assert/dist/amd/assert', 27 | angular: './bower_components/angular/angular', 28 | 'angular-mocks': './bower_components/angular-mocks/angular-mocks', 29 | 'angular-new-router': './node_modules/angular-new-router/dist/router.es5' 30 | }, 31 | 32 | shim: { 33 | 'angular': {'exports': 'angular'}, 34 | 'angular-mocks': {deps: ['angular'], 'exports': 'angular.mock'}, 35 | 'angular-new-router': {deps: ['angular']} 36 | }, 37 | 38 | // Dynamically load all test files. 39 | deps: getAllSpecs(), 40 | 41 | // Kickoff Jasmine, once all spec files are loaded. 42 | callback: window.__karma__.start 43 | }); 44 | -------------------------------------------------------------------------------- /test/AnnotationFinder_spec.js: -------------------------------------------------------------------------------- 1 | import {AnnotationFinder} from "../src/a1atscript/AnnotationFinder.js"; 2 | import {ToAnnotation} from "../src/a1atscript/ToAnnotation.js"; 3 | 4 | @ToAnnotation 5 | class Anno1 { 6 | 7 | } 8 | 9 | @ToAnnotation 10 | class Anno2 { 11 | 12 | } 13 | 14 | @Anno1() 15 | @Anno2() 16 | class Something { 17 | constructor() { 18 | 19 | } 20 | } 21 | 22 | describe("AnnotationFinder", function() { 23 | var anno1Class, anno2Class, annotationFinder; 24 | beforeEach(function() { 25 | anno1Class = Anno1.originalClass || Anno1; 26 | anno2Class = Anno2.originalClass || Anno2; 27 | annotationFinder = new AnnotationFinder(Something); 28 | }); 29 | 30 | it("should find annotations", function () { 31 | expect(annotationFinder.annotationFor(Anno1)).toEqual(jasmine.any(anno1Class)); 32 | expect(annotationFinder.annotationFor(Anno2)).toEqual(jasmine.any(anno2Class)); 33 | }); 34 | }); 35 | -------------------------------------------------------------------------------- /test/ComponentMapper_spec.js: -------------------------------------------------------------------------------- 1 | import {Controller} from '../src/a1atscript/annotations.js' 2 | import {Component, View} from '../src/a1atscript/ng2Directives/Component.js' 3 | import {ComponentMapper} from '../src/a1atscript/router/ComponentMapper.js' 4 | 5 | @Controller('AwesomeController', []) 6 | class AwesomeController { 7 | constructor() { 8 | 9 | } 10 | } 11 | 12 | @Controller('weirdName', []) 13 | class WeirdNameController { 14 | constructor() { 15 | 16 | } 17 | } 18 | 19 | @Component({ 20 | selector: 'awesome' 21 | }) 22 | @View({ 23 | templateUrl: "cheese.tpl.html" 24 | }) 25 | class AwesomeComponent { 26 | constructor() { 27 | 28 | } 29 | } 30 | 31 | @Component({ 32 | controllerAs: 'cac' 33 | }) 34 | @View({ 35 | templateUrl: "cheese.tpl.html" 36 | }) 37 | class ControllerAsComponent { 38 | constructor() { 39 | 40 | } 41 | } 42 | 43 | @Component({}) 44 | class UnNamedComponent { 45 | constructor() { 46 | 47 | } 48 | } 49 | 50 | class NonAnnotatedComponent { 51 | constructor() { 52 | 53 | } 54 | } 55 | 56 | @Component({ 57 | selector: "cheese" 58 | }) 59 | @View({ 60 | template: "

Awesome

" 61 | }) 62 | class InlineTemplateComponent { 63 | constructor() { 64 | 65 | } 66 | } 67 | 68 | describe("ComponentMapper", function() { 69 | var componentMapper, componentMapping; 70 | 71 | beforeEach(function() { 72 | componentMapper = new ComponentMapper(); 73 | }); 74 | 75 | describe("controllers", function() { 76 | it("should convert canonically named controllers to components", function() { 77 | componentMapping = componentMapper.register(AwesomeController); 78 | expect(componentMapping.componentName).toEqual("awesome"); 79 | expect(componentMapping.templateUrl).toEqual("./components/awesome/awesome.html"); 80 | expect(componentMapping.isController).toBe(true); 81 | expect(componentMapping.controllerName).toEqual("AwesomeController"); 82 | expect(componentMapper.controllerRegistry["AwesomeController"]).toEqual("awesome"); 83 | }); 84 | 85 | it("should convert oddly named controllers to components", function() { 86 | componentMapping = componentMapper.register(WeirdNameController); 87 | expect(componentMapping.componentName).toEqual("weirdName"); 88 | expect(componentMapping.templateUrl).toEqual("./components/weirdName/weirdName.html"); 89 | expect(componentMapping.isController).toBe(true); 90 | expect(componentMapping.controllerName).toEqual("weirdName"); 91 | expect(componentMapper.controllerRegistry["weirdName"]).toEqual("weirdName"); 92 | }); 93 | }); 94 | 95 | describe("components", function() { 96 | it("should convert components with controllerAs value to components with same name", function() { 97 | componentMapping = componentMapper.register(ControllerAsComponent); 98 | expect(componentMapping.componentName).toEqual("cac"); 99 | expect(componentMapping.controllerName).toEqual("A1AtScriptCacController"); 100 | expect(componentMapper.controllerRegistry["A1AtScriptCacController"]).toEqual("cac"); 101 | }); 102 | 103 | it("should convert components with selector names to components with same name", function() { 104 | componentMapping = componentMapper.register(AwesomeComponent); 105 | expect(componentMapping.componentName).toEqual("awesome"); 106 | expect(componentMapping.controllerName).toEqual("A1AtScriptAwesomeController"); 107 | expect(componentMapper.controllerRegistry["A1AtScriptAwesomeController"]).toEqual("awesome"); 108 | }); 109 | 110 | it("should not mark them as controllers", function() { 111 | expect(componentMapping.isController).toBe(false); 112 | }) 113 | 114 | 115 | it("should read templateUrls from View annotations", function() { 116 | componentMapping = componentMapper.register(AwesomeComponent); 117 | expect(componentMapping.templateUrl).toEqual("cheese.tpl.html"); 118 | }); 119 | 120 | it("should generate a name for components with no selector", function() { 121 | componentMapping = componentMapper.register(UnNamedComponent); 122 | expect(componentMapping.componentName).toEqual("a1atscriptComponent_0"); 123 | expect(componentMapping.templateUrl).toEqual("./components/a1atscriptComponent_0/a1atscriptComponent_0.html"); 124 | expect(componentMapping.controllerName).toEqual("A1AtScriptComponent_0Controller"); 125 | expect(componentMapper.controllerRegistry["A1AtScriptComponent_0Controller"]).toEqual("a1atscriptComponent_0"); 126 | 127 | // check idempotence 128 | componentMapping = componentMapper.register(UnNamedComponent); 129 | expect(componentMapping.componentName).toEqual("a1atscriptComponent_0"); 130 | expect(componentMapping.templateUrl).toEqual("./components/a1atscriptComponent_0/a1atscriptComponent_0.html"); 131 | expect(componentMapping.controllerName).toEqual("A1AtScriptComponent_0Controller"); 132 | expect(componentMapper.controllerRegistry["A1AtScriptComponent_0Controller"]).toEqual("a1atscriptComponent_0"); 133 | 134 | }); 135 | }); 136 | 137 | describe("non annotated classes", function() { 138 | it("should generate a name for classes with no annotation at all", function() { 139 | componentMapping = componentMapper.register(NonAnnotatedComponent); 140 | expect(componentMapping.componentName).toEqual("a1atscriptComponent_0"); 141 | expect(componentMapping.controllerName).toEqual("A1AtScriptComponent_0Controller"); 142 | expect(componentMapping.templateUrl).toEqual("./components/a1atscriptComponent_0/a1atscriptComponent_0.html"); 143 | expect(componentMapping.isController).toBe(false); 144 | expect(componentMapper.controllerRegistry["A1AtScriptComponent_0Controller"]).toEqual("a1atscriptComponent_0"); 145 | }); 146 | }); 147 | 148 | describe("inline template components", function() { 149 | it("should add the template to the inline template cache", function() { 150 | componentMapping = componentMapper.register(InlineTemplateComponent); 151 | expect(componentMapper.inlineTemplateCache["./components/cheese/cheese.html"]).toEqual("

Awesome

"); 152 | }); 153 | }) 154 | }); 155 | -------------------------------------------------------------------------------- /test/Component_spec.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import 'angular-mocks'; 3 | 4 | import {Component, View} from '../src/a1atscript/ng2Directives/Component' 5 | import "../src/a1atscript/ng2Directives/ComponentInjector"; 6 | 7 | import { 8 | Module, 9 | Service 10 | } from '../src/a1atscript/annotations'; 11 | 12 | import { 13 | bootstrap 14 | } from '../src/a1atscript/bootstrap'; 15 | 16 | import {getInjector} from '../src/a1atscript/Injector'; 17 | 18 | var mock = angular.mock; 19 | 20 | @Service('ExampleService') 21 | class ExampleService { 22 | constructor() { 23 | this.value = 'Set within controller'; 24 | } 25 | } 26 | 27 | class AwesomeBase { 28 | constructor() { 29 | this.test = "test"; 30 | } 31 | 32 | setValue() { 33 | this.value = this.exampleService.value; 34 | } 35 | } 36 | 37 | @Component({ 38 | selector: "awesome", 39 | properties: { 40 | apple: "apple" 41 | }, 42 | events: { 43 | click: "click" 44 | }, 45 | appInjector: ["ExampleService"] 46 | }) 47 | @View({ 48 | templateUrl: "awesome.tpl.html" 49 | }) 50 | class AwesomeComponent extends AwesomeBase { 51 | constructor(exampleService) { 52 | super(); 53 | this.exampleService = exampleService; 54 | } 55 | setValue() { 56 | super.setValue(); 57 | this.subValue = this.exampleService.value; 58 | } 59 | } 60 | 61 | angular.module("awesomeTemplate", []).run(["$templateCache", function($templateCache) { 62 | $templateCache.put("awesome.tpl.html", 63 | "

{{awesome.test}} {{awesome.apple}}

"); 64 | }]); 65 | 66 | var AppModule = new Module('AppModule', ['awesomeTemplate', ExampleService, AwesomeComponent]) 67 | 68 | describe("Component", function() { 69 | var scope, isolateScope, element, injector, $compile, saveSpy, 70 | componentInjector, beforeHook, hooks; 71 | 72 | beforeEach(function() { 73 | hooks = { 74 | before(module, ddo) { 75 | ddo._bind.foo = "@" 76 | }, 77 | after() {} 78 | }; 79 | 80 | componentInjector = getInjector('component'); 81 | spyOn(hooks, 'before').and.callThrough(); 82 | spyOn(hooks, 'after'); 83 | componentInjector.componentHooks.before.push(hooks.before); 84 | componentInjector.componentHooks.after.push(hooks.after); 85 | 86 | bootstrap(AppModule, "AppModule"); 87 | mock.module('AppModule'); 88 | mock.inject(function($rootScope, _$compile_) { 89 | scope = $rootScope.$new(); 90 | scope.apple = "cheese"; 91 | scope.save = function() { }; 92 | saveSpy = spyOn(scope, 'save'); 93 | $compile = _$compile_; 94 | element = ''; 95 | element = $compile(element)(scope); 96 | scope.$digest(); 97 | isolateScope = element.isolateScope(); 98 | }); 99 | }); 100 | 101 | it("should function as a directive definition object", function() { 102 | expect(element.find('p').length).toEqual(1); 103 | expect(element.find('p')[0].innerHTML).toEqual("test cheese") 104 | }); 105 | 106 | it("should setup the events", function() { 107 | isolateScope.awesome.click(); 108 | expect(saveSpy).toHaveBeenCalled(); 109 | }); 110 | 111 | it("should call 'before' hook and allow altering ddo", function() { 112 | let hookArgs = hooks.before.calls.argsFor(0); 113 | let module = hookArgs[0]; 114 | let ddo = hookArgs[1]; 115 | let ComponentClass = Component.originalClass || Component; 116 | expect(module).toEqual(angular.module(AppModule.token)); 117 | expect(ddo._annotation instanceof ComponentClass).toBeTruthy(); 118 | expect(ddo._controller).toEqual(AwesomeComponent); 119 | expect(isolateScope.awesome.foo).toEqual('bar'); 120 | }); 121 | 122 | it("should call 'after' hook", function() { 123 | let hookArgs = hooks.after.calls.argsFor(0); 124 | let module = hookArgs[0]; 125 | let ddo = hookArgs[1]; 126 | let ComponentClass = Component.originalClass || Component; 127 | expect(module).toEqual(angular.module(AppModule.token)); 128 | expect(ddo._annotation instanceof ComponentClass).toBeTruthy(); 129 | expect(ddo._controller).toEqual(AwesomeComponent); 130 | }); 131 | 132 | describe("this", function() { 133 | beforeEach(function() { 134 | isolateScope.awesome.setValue(); 135 | }); 136 | it("should be able to access this from within the link function", function() { 137 | expect(isolateScope.awesome.value).toEqual("Set within controller"); 138 | expect(isolateScope.awesome.subValue).toEqual("Set within controller"); 139 | }) 140 | }); 141 | 142 | }); 143 | -------------------------------------------------------------------------------- /test/DirectiveObject_spec.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import 'angular-mocks'; 3 | 4 | import {DirectiveObject} from '../src/a1atscript/DirectiveObject' 5 | 6 | import { 7 | Module, 8 | Service 9 | } from '../src/a1atscript/annotations'; 10 | 11 | import { 12 | bootstrap 13 | } from '../src/a1atscript/bootstrap'; 14 | 15 | var mock = angular.mock; 16 | 17 | @Service('ExampleService') 18 | class ExampleService { 19 | constructor() { 20 | this.value = 'Set within link'; 21 | this.value2 = "Set within callback"; 22 | } 23 | 24 | setValue(scope) { 25 | scope.value = this.exampleService.value; 26 | } 27 | 28 | } 29 | 30 | class ExampleBase { 31 | constructor() { 32 | this.restrict = "E"; 33 | } 34 | 35 | link(scope, element, attrs) { 36 | this.setValue(scope); 37 | scope.setFromService = () => { 38 | scope.value2 = this.exampleService.value2; 39 | } 40 | } 41 | 42 | setValue(scope) { 43 | scope.value = this.exampleService.value; 44 | } 45 | } 46 | 47 | @DirectiveObject('exampleDirective', ['ExampleService']) 48 | class ExampleDirective extends ExampleBase { 49 | constructor(exampleService) { 50 | super(); 51 | this.exampleService = exampleService; 52 | this.templateUrl = "template.tpl.html"; 53 | } 54 | setValue(scope) { 55 | super.setValue(scope); 56 | scope.subValue = this.exampleService.value; 57 | } 58 | } 59 | 60 | angular.module("simpleTemplate", []).run(["$templateCache", function($templateCache) { 61 | $templateCache.put("template.tpl.html", 62 | "

Hello

"); 63 | }]); 64 | 65 | var AppModule = new Module('AppModule', ['simpleTemplate', ExampleService, ExampleDirective]) 66 | 67 | describe("DirectiveObject", function() { 68 | var scope, element, injector, $compile; 69 | 70 | beforeEach(function() { 71 | bootstrap(AppModule, "AppModule"); 72 | mock.module('AppModule'); 73 | mock.inject(function($rootScope, _$compile_) { 74 | scope = $rootScope.$new(); 75 | $compile = _$compile_; 76 | element = ''; 77 | element = $compile(element)(scope); 78 | scope.$digest(); 79 | }); 80 | }); 81 | 82 | it("should function as a directive definition object", function() { 83 | expect(element.find('p').length).toEqual(1); 84 | }); 85 | 86 | describe("linking and this", function() { 87 | beforeEach(function() { 88 | scope.setFromService(); 89 | }); 90 | it("should be able to access this from within the link function", function() { 91 | expect(scope.value).toEqual("Set within link"); 92 | expect(scope.subValue).toEqual("Set within link"); 93 | expect(scope.value2).toEqual("Set within callback"); 94 | }) 95 | }); 96 | 97 | }); 98 | -------------------------------------------------------------------------------- /test/EventsBuilder_spec.js: -------------------------------------------------------------------------------- 1 | import EventsBuilder from "../src/a1atscript/ng2Directives/EventsBuilder.js" 2 | 3 | class Component { 4 | constructor() { 5 | 6 | } 7 | } 8 | 9 | describe("EventsBuilder", function() { 10 | var eventsObj, events; 11 | 12 | beforeEach(function() { 13 | eventsObj = [ "cheese: danish", "apple"]; 14 | events = (new EventsBuilder(eventsObj, Component)).build(); 15 | }); 16 | 17 | it("should setup the correct events", function() { 18 | expect(events).toEqual({ 19 | "cheese": "=?onDanish", 20 | "apple": "=?onApple" 21 | }); 22 | }); 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /test/Ng2DirectiveDefinitionObject_spec.js: -------------------------------------------------------------------------------- 1 | import Ng2Directive from '../src/a1atscript/ng2Directives/Ng2Directive.js'; 2 | import Ng2DirectiveDefinitionObject from '../src/a1atscript/ng2Directives/Ng2DirectiveDefinitionObject.js'; 3 | 4 | class Hello { 5 | constructor() { 6 | } 7 | } 8 | 9 | describe("DirectiveDefinitionObject", function() { 10 | var ng2DirectiveDefinitionObject, ng2Directive, ddoFactoryFn, templateProperties, bind; 11 | 12 | describe("regular behavior", function() { 13 | beforeEach(function() { 14 | ng2Directive = new Ng2Directive({ 15 | selector: "[attr]", 16 | bind: { 17 | 'something': "something" 18 | } 19 | }); 20 | angular.version.major = 1; 21 | angular.version.minor = 4; 22 | ng2DirectiveDefinitionObject = new Ng2DirectiveDefinitionObject(Hello, ng2Directive); 23 | }); 24 | 25 | it("should have the right properties", function() { 26 | expect(ng2DirectiveDefinitionObject.restrict).toEqual("A"); 27 | expect(ng2DirectiveDefinitionObject.name).toEqual("attr"); 28 | expect(ng2DirectiveDefinitionObject.controllerAs).toEqual("attr"); 29 | expect(ng2DirectiveDefinitionObject.bindToController).toEqual({ 30 | 'something': "something" 31 | }); 32 | expect(ng2DirectiveDefinitionObject.controller).toEqual(Hello); 33 | expect(ng2DirectiveDefinitionObject.scope).toEqual({}); 34 | expect(ng2DirectiveDefinitionObject.template).toBe(undefined); 35 | expect(ng2DirectiveDefinitionObject.templateUrl).toBe(undefined); 36 | expect(ng2DirectiveDefinitionObject.require).toBe(undefined); 37 | expect(ng2DirectiveDefinitionObject.transclude).toBe(undefined); 38 | }); 39 | 40 | describe("factoryFn", function() { 41 | beforeEach(function() { 42 | ddoFactoryFn = ng2DirectiveDefinitionObject.factoryFn; 43 | }); 44 | 45 | it("should build a factory function that returns the right DDO", function() { 46 | expect(ddoFactoryFn()).toEqual({ 47 | scope: {}, 48 | restrict: "A", 49 | controllerAs: "attr", 50 | bindToController: { 51 | 'something': "something" 52 | }, 53 | require: undefined, 54 | transclude: undefined, 55 | controller: Hello, 56 | template: undefined, 57 | templateUrl: undefined 58 | }); 59 | }); 60 | }); 61 | }); 62 | 63 | describe("with ng1 customizations", function() { 64 | beforeEach(function() { 65 | ng2Directive = new Ng2Directive({ 66 | selector: "[attr]", 67 | bind: { 68 | 'something': "something" 69 | }, 70 | controllerAs: "awesome", 71 | require: "power" 72 | }); 73 | angular.version.major = 1; 74 | angular.version.minor = 4; 75 | ng2DirectiveDefinitionObject = new Ng2DirectiveDefinitionObject(Hello, ng2Directive); 76 | }); 77 | 78 | it("should have the right properties", function() { 79 | expect(ng2DirectiveDefinitionObject.restrict).toEqual("A"); 80 | expect(ng2DirectiveDefinitionObject.name).toEqual("attr"); 81 | expect(ng2DirectiveDefinitionObject.controllerAs).toEqual("awesome"); 82 | expect(ng2DirectiveDefinitionObject.bindToController).toEqual({ 83 | 'something': "something" 84 | }); 85 | expect(ng2DirectiveDefinitionObject.controller).toEqual(Hello); 86 | expect(ng2DirectiveDefinitionObject.scope).toEqual({}); 87 | expect(ng2DirectiveDefinitionObject.template).toBe(undefined); 88 | expect(ng2DirectiveDefinitionObject.templateUrl).toBe(undefined); 89 | expect(ng2DirectiveDefinitionObject.require).toBe("power"); 90 | expect(ng2DirectiveDefinitionObject.transclude).toBe(undefined); 91 | 92 | }); 93 | 94 | describe("factoryFn", function() { 95 | beforeEach(function() { 96 | ddoFactoryFn = ng2DirectiveDefinitionObject.factoryFn; 97 | }); 98 | 99 | it("should build a factory function that returns the right DDO", function() { 100 | expect(ddoFactoryFn()).toEqual({ 101 | scope: {}, 102 | restrict: "A", 103 | controllerAs: "awesome", 104 | bindToController: { 105 | 'something': "something" 106 | }, 107 | require: "power", 108 | transclude: undefined, 109 | controller: Hello, 110 | template: undefined, 111 | templateUrl: undefined 112 | }); 113 | }); 114 | }); 115 | }); 116 | 117 | describe("with template", function() { 118 | beforeEach(function() { 119 | ng2Directive = new Ng2Directive({ 120 | selector: "[attr]", 121 | bind: { 122 | 'something': 'something' 123 | } 124 | }); 125 | templateProperties = { 126 | templateUrl: "attr.html" 127 | } 128 | angular.version.major = 1; 129 | angular.version.minor = 4; 130 | ng2DirectiveDefinitionObject = new Ng2DirectiveDefinitionObject(Hello, ng2Directive, templateProperties); 131 | }); 132 | 133 | it("should have the right properties", function() { 134 | expect(ng2DirectiveDefinitionObject.restrict).toEqual("A"); 135 | expect(ng2DirectiveDefinitionObject.name).toEqual("attr"); 136 | expect(ng2DirectiveDefinitionObject.controllerAs).toEqual("attr"); 137 | expect(ng2DirectiveDefinitionObject.bindToController).toEqual({ 138 | 'something': "something" 139 | }); 140 | expect(ng2DirectiveDefinitionObject.controller).toEqual(Hello); 141 | expect(ng2DirectiveDefinitionObject.scope).toEqual({}); 142 | expect(ng2DirectiveDefinitionObject.template).toBe(undefined); 143 | expect(ng2DirectiveDefinitionObject.templateUrl).toBe("attr.html"); 144 | expect(ng2DirectiveDefinitionObject.require).toBe(undefined); 145 | expect(ng2DirectiveDefinitionObject.transclude).toBe(undefined); 146 | }); 147 | 148 | describe("factoryFn", function() { 149 | beforeEach(function() { 150 | ddoFactoryFn = ng2DirectiveDefinitionObject.factoryFn; 151 | }); 152 | 153 | it("should build a factory function that returns the right DDO", function() { 154 | expect(ddoFactoryFn()).toEqual({ 155 | scope: {}, 156 | restrict: "A", 157 | controllerAs: "attr", 158 | bindToController: { 159 | 'something': "something" 160 | }, 161 | require: undefined, 162 | transclude: undefined, 163 | controller: Hello, 164 | template: undefined, 165 | templateUrl: "attr.html" 166 | }); 167 | }); 168 | }); 169 | }); 170 | 171 | describe("with bind", function() { 172 | beforeEach(function() { 173 | ng2Directive = new Ng2Directive({ 174 | selector: "[attr]", 175 | bind: { 176 | 'something': "something" 177 | } 178 | }); 179 | bind = { 180 | other: "awesome" 181 | } 182 | angular.version.major = 1; 183 | angular.version.minor = 4; 184 | ng2DirectiveDefinitionObject = new Ng2DirectiveDefinitionObject(Hello, ng2Directive, {}, bind); 185 | }); 186 | 187 | it("should have the right properties", function() { 188 | expect(ng2DirectiveDefinitionObject.restrict).toEqual("A"); 189 | expect(ng2DirectiveDefinitionObject.name).toEqual("attr"); 190 | expect(ng2DirectiveDefinitionObject.controllerAs).toEqual("attr"); 191 | expect(ng2DirectiveDefinitionObject.bindToController).toEqual({ 192 | other: "awesome" 193 | }); 194 | expect(ng2DirectiveDefinitionObject.controller).toEqual(Hello); 195 | expect(ng2DirectiveDefinitionObject.scope).toEqual({}); 196 | expect(ng2DirectiveDefinitionObject.template).toBe(undefined); 197 | expect(ng2DirectiveDefinitionObject.templateUrl).toBe(undefined); 198 | expect(ng2DirectiveDefinitionObject.require).toBe(undefined); 199 | expect(ng2DirectiveDefinitionObject.transclude).toBe(undefined); 200 | }); 201 | 202 | describe("factoryFn", function() { 203 | beforeEach(function() { 204 | ddoFactoryFn = ng2DirectiveDefinitionObject.factoryFn; 205 | }); 206 | 207 | it("should build a factory function that returns the right DDO", function() { 208 | expect(ddoFactoryFn()).toEqual({ 209 | scope: {}, 210 | restrict: "A", 211 | controllerAs: "attr", 212 | bindToController: { 213 | other: "awesome" 214 | }, 215 | require: undefined, 216 | transclude: undefined, 217 | controller: Hello, 218 | template: undefined, 219 | templateUrl: undefined 220 | }); 221 | }); 222 | }); 223 | }); 224 | 225 | describe("angular < 1.4", function() { 226 | beforeEach(function() { 227 | ng2Directive = new Ng2Directive({ 228 | selector: "[attr]", 229 | bind: { 230 | 'something': "something" 231 | } 232 | }); 233 | angular.version.major = 1; 234 | angular.version.minor = 3; 235 | ng2DirectiveDefinitionObject = new Ng2DirectiveDefinitionObject(Hello, ng2Directive); 236 | }); 237 | 238 | it("should have the right properties", function() { 239 | expect(ng2DirectiveDefinitionObject.restrict).toEqual("A"); 240 | expect(ng2DirectiveDefinitionObject.name).toEqual("attr"); 241 | expect(ng2DirectiveDefinitionObject.controllerAs).toEqual("attr"); 242 | expect(ng2DirectiveDefinitionObject.bindToController).toEqual(true); 243 | expect(ng2DirectiveDefinitionObject.controller).toEqual(Hello); 244 | expect(ng2DirectiveDefinitionObject.scope).toEqual({ 245 | 'something': "something" 246 | }); 247 | expect(ng2DirectiveDefinitionObject.template).toBe(undefined); 248 | expect(ng2DirectiveDefinitionObject.templateUrl).toBe(undefined); 249 | expect(ng2DirectiveDefinitionObject.require).toBe(undefined); 250 | expect(ng2DirectiveDefinitionObject.transclude).toBe(undefined); 251 | }); 252 | 253 | describe("factoryFn", function() { 254 | beforeEach(function() { 255 | ddoFactoryFn = ng2DirectiveDefinitionObject.factoryFn; 256 | }); 257 | 258 | it("should build a factory function that returns the right DDO", function() { 259 | expect(ddoFactoryFn()).toEqual({ 260 | scope: { 261 | 'something': "something" 262 | }, 263 | restrict: "A", 264 | controllerAs: "attr", 265 | bindToController: true, 266 | require: undefined, 267 | transclude: undefined, 268 | controller: Hello, 269 | template: undefined, 270 | templateUrl: undefined 271 | }); 272 | }); 273 | }); 274 | }); 275 | 276 | 277 | }); 278 | -------------------------------------------------------------------------------- /test/NoRouterPresent_spec.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import 'angular-mocks'; 3 | 4 | import {Component, View} from '../src/a1atscript/ng2Directives/Component'; 5 | import {RouteConfig} from '../src/a1atscript/router/RouteConfig'; 6 | import "../src/a1atscript/ng2Directives/ComponentInjector"; 7 | 8 | import { 9 | AsModule, 10 | Service 11 | } from '../src/a1atscript/annotations'; 12 | 13 | import { 14 | bootstrap 15 | } from '../src/a1atscript/bootstrap'; 16 | 17 | var mock = angular.mock; 18 | 19 | @Component({}) 20 | @View({ 21 | template: "

Sub

" 22 | }) 23 | class SubComponent { 24 | 25 | } 26 | 27 | @Component({}) 28 | @View({ 29 | template: "

Home

" 30 | }) 31 | @RouteConfig({ 32 | path: "/sub", component: SubComponent 33 | }) 34 | class HomeComponent { 35 | } 36 | 37 | @AsModule('NoRouterAppModule', ['templates', HomeComponent, SubComponent]) 38 | @Component({ 39 | selector: "awesome" 40 | }) 41 | @View({ 42 | templateUrl: "app.tpl.html" 43 | }) 44 | @RouteConfig({ 45 | path: "/home", component: HomeComponent 46 | }) 47 | class AppComponent { 48 | } 49 | 50 | angular.module("templates", []).run(["$templateCache", function($templateCache) { 51 | $templateCache.put("app.tpl.html", 52 | ""); 53 | }]); 54 | 55 | describe("Routable Component", function() { 56 | var scope, element, $compile; 57 | 58 | beforeEach(function() { 59 | bootstrap(AppComponent, "NoRouterAppModule"); 60 | mock.module('NoRouterAppModule'); 61 | mock.inject(function($rootScope, _$compile_) { 62 | scope = $rootScope.$new(); 63 | $compile = _$compile_; 64 | element = ''; 65 | element = $compile(element)(scope); 66 | $rootScope.$digest(); 67 | }); 68 | }); 69 | 70 | it("should not build routes but should compile with no issues despite lack of router", function() { 71 | expect(element.find('ng-viewport').length).toEqual(1); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /test/PropertiesBuilder_spec.js: -------------------------------------------------------------------------------- 1 | import PropertiesBuilder from "../src/a1atscript/ng2Directives/PropertiesBuilder.js" 2 | 3 | class Component { 4 | constructor() { 5 | 6 | } 7 | } 8 | 9 | describe("PropertiesBuilder", function() { 10 | var propertiesObj, properties; 11 | 12 | beforeEach(function() { 13 | propertiesObj = ["cheese:danish","apple"]; 14 | properties = (new PropertiesBuilder(propertiesObj, Component)).build(); 15 | }); 16 | 17 | it("should setup the correct properties", function() { 18 | expect(properties).toEqual({ 19 | "_@_cheese": "@danish", 20 | "_=_cheese": "=?bindDanish", 21 | "_@_apple": "@apple", 22 | "_=_apple": "=?bindApple" 23 | }); 24 | }); 25 | 26 | it("should setup the bind setter", function() { 27 | var component = new Component(); 28 | component["_=_apple"] = "bind"; 29 | expect(component.apple).toEqual("bind"); 30 | }); 31 | 32 | it("should setup the string setter", function() { 33 | var component = new Component(); 34 | component["_@_apple"] = "string"; 35 | expect(component.apple).toEqual("string"); 36 | }); 37 | 38 | it("should disable string if bind is used first", function() { 39 | var component = new Component(); 40 | component["_=_apple"] = "bind"; 41 | expect(() => component["_@_apple"] = "string").toThrow(new Error('Cannot use bind-apple and apple simultaneously')); 42 | expect(component.apple).toEqual('bind'); 43 | }); 44 | 45 | it("should disable bind if string is used first", function() { 46 | var component = new Component(); 47 | component["_@_apple"] = "string"; 48 | expect(() => component["_=_apple"] = "bind").toThrow(new Error('Cannot use bind-apple and apple simultaneously')); 49 | expect(component.apple).toEqual('string'); 50 | }); 51 | 52 | it("should generate getter for bind property that proxies to the bound object real property", function() { 53 | var component = new Component(); 54 | component.apple = 'bind'; 55 | expect(component["_=_apple"]).toEqual('bind'); 56 | }); 57 | 58 | it("should generate getter for string property that proxies to the bound object real property", function() { 59 | var component = new Component(); 60 | component.apple = 'string'; 61 | expect(component["_@_apple"]).toEqual('string'); 62 | }) 63 | 64 | it("should allow different component instances to use different property binding strategies (string and bind)", function() { 65 | var componentA = new Component(); 66 | var componentB = new Component(); 67 | 68 | componentA["_@_apple"] = "string"; 69 | expect(() => componentB["_=_apple"] = "bind").not.toThrow(); 70 | }) 71 | }); 72 | -------------------------------------------------------------------------------- /test/RoutableComponent_spec.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import 'angular-mocks'; 3 | import 'angular-new-router'; 4 | 5 | import {Component, View} from '../src/a1atscript/ng2Directives/Component'; 6 | import {RouteConfig} from '../src/a1atscript/router/RouteConfig'; 7 | import "../src/a1atscript/ng2Directives/ComponentInjector"; 8 | 9 | import { 10 | AsModule, 11 | Service 12 | } from '../src/a1atscript/annotations'; 13 | 14 | import { 15 | bootstrap 16 | } from '../src/a1atscript/bootstrap'; 17 | 18 | var mock = angular.mock; 19 | 20 | @Component({}) 21 | @View({ 22 | template: "

Sub

" 23 | }) 24 | class SubComponent { 25 | 26 | } 27 | 28 | @Component({}) 29 | @View({ 30 | template: "

Home

" 31 | }) 32 | @RouteConfig({ 33 | path: "/sub", component: SubComponent 34 | }) 35 | class HomeComponent { 36 | } 37 | 38 | @AsModule('AppModule', ['templates', 'ngNewRouter', HomeComponent, SubComponent]) 39 | @Component({ 40 | selector: "awesome" 41 | }) 42 | @View({ 43 | templateUrl: "app.tpl.html" 44 | }) 45 | @RouteConfig({ 46 | path: "/home", component: HomeComponent 47 | }) 48 | class AppComponent { 49 | } 50 | 51 | angular.module("templates", []).run(["$templateCache", function($templateCache) { 52 | $templateCache.put("app.tpl.html", 53 | ""); 54 | }]); 55 | 56 | describe("Routable Component", function() { 57 | var scope, element, $compile; 58 | 59 | beforeEach(function() { 60 | bootstrap(AppComponent, "AppModule"); 61 | mock.module('AppModule'); 62 | mock.inject(function($rootScope, $router, _$compile_) { 63 | scope = $rootScope.$new(); 64 | $compile = _$compile_; 65 | element = ''; 66 | element = $compile(element)(scope); 67 | $router.navigate("/home/sub") 68 | $rootScope.$digest(); 69 | }); 70 | }); 71 | 72 | it("should navigate correctly to the right route", function() { 73 | expect(element.find('p').length).toEqual(2); 74 | expect(element.find('p')[0].innerHTML).toEqual("Home") 75 | expect(element.find('p')[1].innerHTML).toEqual("Sub") 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /test/RouteInitializer_spec.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import 'angular-mocks'; 3 | import 'angular-new-router'; 4 | 5 | import {RouteInitializer} from "../src/a1atscript/router/RouteInitializer.js"; 6 | 7 | var mock = angular.mock; 8 | 9 | angular.module('testApp', ['ngNewRouter']); 10 | 11 | describe("RouteInitializer", function() { 12 | 13 | describe("initialize", function() { 14 | var componentMapper, routeInitializer, $templateCache, $componentLoader, TestComponent, TestController, controllerSpy, TopConfigComponent; 15 | beforeEach(function() { 16 | TestComponent = function() { 17 | }; 18 | TestController = function() { 19 | }; 20 | TopConfigComponent = function() { 21 | }; 22 | TopConfigComponent.$routeConfig = [{ 23 | path: "awesome", component: "awesome" 24 | }]; 25 | 26 | componentMapper = { 27 | registry: { 28 | "awesome": { 29 | 'templateUrl': 'awesome.tpl.html', 30 | 'component': TestComponent, 31 | 'controllerName': 'AwesomeController', 32 | 'isController': false, 33 | 'routeConfig': [{ 34 | path: "cheese", component: "cheese" 35 | }] 36 | }, 37 | "cheese": { 38 | 'templateUrl': './components/cheese/cheese.html', 39 | 'component': TestController, 40 | 'controllerName': "CheesetasticController", 41 | 'isController': true 42 | }, 43 | "topConfig": { 44 | 'templateUrl': 'topConfig.tpl.html', 45 | 'component': TopConfigComponent, 46 | 'controllerName': 'TopConfigController', 47 | 'isController': false, 48 | 'routeConfig': [{ 49 | path: "awesome", component: "awesome" 50 | }] 51 | } 52 | }, 53 | controllerRegistry: { 54 | "AwesomeController": "awesome", 55 | "CheesetasticController": "cheese" 56 | }, 57 | inlineTemplateCache: { 58 | 'awesome.tpl.html': "

FizzBuzz

" 59 | } 60 | }; 61 | 62 | routeInitializer = new RouteInitializer(componentMapper); 63 | controllerSpy = spyOn(angular.module('testApp'), 'controller'); 64 | routeInitializer.initialize('testApp', TopConfigComponent); 65 | mock.module("testApp", TopConfigComponent); 66 | mock.inject(function(_$componentLoader_, _$templateCache_) { 67 | $componentLoader = _$componentLoader_; 68 | $templateCache = _$templateCache_; 69 | }); 70 | }); 71 | 72 | it("should setup controller name mappings properly", function() { 73 | expect($componentLoader.controllerName("awesome")).toEqual("AwesomeController"); 74 | expect($componentLoader.controllerName("cheese")).toEqual("CheesetasticController"); 75 | }); 76 | 77 | it("should setup template mappings properly", function() { 78 | expect($componentLoader.template("awesome")).toEqual("awesome.tpl.html") 79 | expect($componentLoader.template("cheese")).toEqual("./components/cheese/cheese.html") 80 | }); 81 | 82 | it("should setup comopnent name mappings properly", function() { 83 | expect($componentLoader.component("AwesomeController")).toEqual("awesome"); 84 | expect($componentLoader.component("CheesetasticController")).toEqual("cheese"); 85 | }); 86 | 87 | it("should initialize controllers for all components", function() { 88 | expect(controllerSpy).toHaveBeenCalledWith("AwesomeController", TestComponent); 89 | expect(controllerSpy).not.toHaveBeenCalledWith("CheesetasticController", TestController); 90 | expect(controllerSpy).not.toHaveBeenCalledWith("TopConfigController", TopConfigComponent); 91 | }); 92 | 93 | it("should setup inline templates in the template cache", function() { 94 | expect($templateCache.get("awesome.tpl.html")).toEqual("

FizzBuzz

"); 95 | }); 96 | }); 97 | }); 98 | -------------------------------------------------------------------------------- /test/RouteReader_spec.js: -------------------------------------------------------------------------------- 1 | import {RouteReader} from '../src/a1atscript/router/RouteReader.js' 2 | import {RouteConfig} from '../src/a1atscript/router/RouteConfig'; 3 | 4 | 5 | class UserComponent { 6 | 7 | } 8 | 9 | class AwesomeComponent { 10 | 11 | } 12 | 13 | @RouteConfig({ 14 | path: 'cheese', component: 'awesome' 15 | }) 16 | class MyController { 17 | } 18 | 19 | @RouteConfig({ 20 | path: '/user', component: UserComponent 21 | }) 22 | @RouteConfig({ 23 | path: '/test', components: { 24 | test: AwesomeComponent, 25 | headline: MyController 26 | } 27 | }) 28 | class AppComponent { 29 | } 30 | 31 | describe("RouteReader", function() { 32 | var componentMapper, componentMapperSpy, routeReader, routeConfig; 33 | beforeEach(function() { 34 | componentMapper = { 35 | map: new Map(), 36 | 37 | register: function(component) { 38 | if (!this.map.get(component)) { 39 | this.map.set(component, 40 | { 41 | get componentName() { 42 | if (component === AppComponent) { 43 | return "app"; 44 | } else if (component === AwesomeComponent) { 45 | return "awesome"; 46 | } else if (component == UserComponent) { 47 | return "user"; 48 | } else if (component == MyController) { 49 | return "my"; 50 | } 51 | } 52 | }); 53 | }; 54 | return this.map.get(component); 55 | } 56 | } 57 | 58 | componentMapperSpy = spyOn(componentMapper, "register").and.callThrough(); 59 | 60 | routeReader = new RouteReader(componentMapper); 61 | }); 62 | 63 | it("should register components", function() { 64 | routeReader.read(AppComponent); 65 | expect(componentMapperSpy).toHaveBeenCalledWith(AppComponent); 66 | expect(componentMapperSpy).toHaveBeenCalledWith(AwesomeComponent); 67 | expect(componentMapperSpy).toHaveBeenCalledWith(UserComponent); 68 | expect(componentMapperSpy).toHaveBeenCalledWith(MyController); 69 | }); 70 | 71 | it("should set routes correctly", function() { 72 | routeReader.read(AppComponent); 73 | routeConfig = AppComponent.$routeConfig; 74 | expect(routeConfig).toEqual([ 75 | { 76 | path: '/user', component: "user" 77 | }, 78 | { 79 | path: '/test', components: { 80 | test: "awesome", 81 | headline: "my" 82 | } 83 | } 84 | ]); 85 | }); 86 | 87 | it("should handle existing string names", function() { 88 | routeReader.read(MyController); 89 | routeConfig = MyController.$routeConfig; 90 | expect(routeConfig).toEqual([ 91 | { 92 | path: 'cheese', component: 'awesome' 93 | } 94 | ]); 95 | }); 96 | }); 97 | -------------------------------------------------------------------------------- /test/SelectorMatcher_spec.js: -------------------------------------------------------------------------------- 1 | import SelectorMatcher from "../src/a1atscript/ng2Directives/SelectorMatcher.js" 2 | 3 | describe("SelectorMatcher", function() { 4 | var selectorMatcher; 5 | describe("element", function() { 6 | beforeEach(function() { 7 | selectorMatcher = new SelectorMatcher("hello-test"); 8 | }); 9 | 10 | it("should be restricted to an element", function() { 11 | expect(selectorMatcher.restrict).toEqual('E'); 12 | }); 13 | 14 | it("should have the right name", function() { 15 | expect(selectorMatcher.name).toEqual('helloTest'); 16 | }); 17 | }); 18 | describe("attribute", function() { 19 | beforeEach(function() { 20 | selectorMatcher = new SelectorMatcher("[hello-test]"); 21 | }); 22 | 23 | it("should be restricted to an element", function() { 24 | expect(selectorMatcher.restrict).toEqual('A'); 25 | }); 26 | 27 | it("should have the right name", function() { 28 | expect(selectorMatcher.name).toEqual('helloTest'); 29 | }); 30 | }); 31 | describe("class", function() { 32 | beforeEach(function() { 33 | selectorMatcher = new SelectorMatcher(".hello-test"); 34 | }); 35 | 36 | it("should be restricted to an element", function() { 37 | expect(selectorMatcher.restrict).toEqual('C'); 38 | }); 39 | 40 | it("should have the right name", function() { 41 | expect(selectorMatcher.name).toEqual('helloTest'); 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /test/ToAnnotation_spec.js: -------------------------------------------------------------------------------- 1 | import {ToAnnotation} from '../src/a1atscript/ToAnnotation.js'; 2 | 3 | class AnnoClass { 4 | 5 | } 6 | 7 | class Anno2Class { 8 | constructor(awesome, awesomeness) { 9 | this.awesome = awesome; 10 | this.awesomeness = awesomeness; 11 | } 12 | } 13 | 14 | class TargetClass { 15 | method() { 16 | 17 | } 18 | } 19 | 20 | describe("ToAnnotation decorator", function() { 21 | var annoDecorator, anno2Decorator; 22 | beforeEach(function() { 23 | annoDecorator = ToAnnotation(AnnoClass); 24 | anno2Decorator = ToAnnotation(Anno2Class); 25 | }); 26 | 27 | it("on first annotation", function() { 28 | @annoDecorator() 29 | class MyTargetAnnoClass { 30 | 31 | } 32 | expect(MyTargetAnnoClass.annotations).toEqual([new AnnoClass()]); 33 | }); 34 | 35 | it("on second annotation", function() { 36 | @annoDecorator() 37 | @anno2Decorator("cheese", "grater") 38 | class MyTargetAnno2Class { 39 | 40 | } 41 | expect(MyTargetAnno2Class.annotations).toContain(new Anno2Class("cheese", "grater"), new AnnoClass()); 42 | }); 43 | 44 | it("operating on method", function() { 45 | annoDecorator()(TargetClass.prototype, 'method', Object.getOwnPropertyDescriptor(TargetClass.prototype, 'method')); 46 | expect(TargetClass.prototype.method.annotations).toEqual([new AnnoClass()]); 47 | }); 48 | }); 49 | -------------------------------------------------------------------------------- /test/annotations_spec.js: -------------------------------------------------------------------------------- 1 | import { 2 | Config, 3 | Run, 4 | Controller, 5 | Directive, 6 | Service, 7 | Factory, 8 | Provider, 9 | Value, 10 | Constant, 11 | Animation, 12 | Filter, 13 | AsModule 14 | } from '../src/a1atscript/annotations.js'; 15 | 16 | var OriginalConfig = Config.originalClass || Config; 17 | var OriginalRun = Run.originalClass || Run; 18 | var OriginalController = Controller.originalClass || Controller; 19 | var OriginalDirective = Directive.originalClass || Directive; 20 | var OriginalService = Service.originalClass || Service; 21 | var OriginalFactory = Factory.originalClass || Factory; 22 | var OriginalProvider = Provider.originalClass || Provider; 23 | var OriginalValue = Value.originalClass || Value; 24 | var OriginalConstant = Constant.originalClass || Constant; 25 | var OriginalAnimation = Animation.originalClass || Animation; 26 | var OriginalFilter = Filter.originalClass || Filter; 27 | var OriginalAsModule = AsModule.originalClass || AsModule; 28 | 29 | describe("annotations", function() { 30 | 31 | describe("config", function() { 32 | 33 | @Config('dep1', 'dep2') 34 | class ExampleConfig { 35 | constructor(dep1, dep2) { 36 | 37 | } 38 | }; 39 | 40 | it("should annotate the config", function() { 41 | expect(ExampleConfig.annotations[0]).toEqual( 42 | new OriginalConfig('dep1', 'dep2')); 43 | expect(ExampleConfig.annotations[0].dependencies).toEqual(['dep1', 'dep2']) 44 | }); 45 | 46 | }); 47 | 48 | describe("run", function() { 49 | 50 | @Run('dep1', 'dep2') 51 | class ExampleRun { 52 | constructor(dep1, dep2) { 53 | 54 | } 55 | }; 56 | 57 | it("should annotate the run", function() { 58 | expect(ExampleRun.annotations[0]).toEqual( 59 | new OriginalRun('dep1', 'dep2')); 60 | expect(ExampleRun.annotations[0].dependencies).toEqual(['dep1', 'dep2']) 61 | }); 62 | 63 | }); 64 | 65 | describe("controller", function() { 66 | 67 | @Controller('ExampleController', ['dep1', 'dep2']) 68 | class ExampleController { 69 | constructor(dep1, dep2) { 70 | 71 | } 72 | }; 73 | 74 | it("should annotate the controller", function() { 75 | expect(ExampleController.annotations[0]).toEqual( 76 | new OriginalController('ExampleController', ['dep1', 'dep2'])); 77 | }); 78 | 79 | }); 80 | 81 | describe("directive", function() { 82 | 83 | @Directive('ExampleDirective', ['dep1', 'dep2']) 84 | class ExampleDirective { 85 | constructor(dep1, dep2) { 86 | 87 | } 88 | }; 89 | 90 | it("should annotate the directive", function() { 91 | expect(ExampleDirective.annotations[0]).toEqual( 92 | new OriginalDirective('ExampleDirective', ['dep1', 'dep2'])); 93 | }); 94 | 95 | }); 96 | 97 | describe("service", function() { 98 | 99 | @Service('ExampleService', ['dep1', 'dep2']) 100 | class ExampleService { 101 | constructor(dep1, dep2) { 102 | 103 | } 104 | }; 105 | 106 | it("should annotate the service", function() { 107 | expect(ExampleService.annotations[0]).toEqual( 108 | new OriginalService('ExampleService', ['dep1', 'dep2'])); 109 | }); 110 | 111 | }); 112 | 113 | describe("factory", function() { 114 | 115 | @Factory('ExampleFactory', ['dep1', 'dep2']) 116 | class ExampleFactory { 117 | constructor(dep1, dep2) { 118 | 119 | } 120 | }; 121 | 122 | it("should annotate the factory", function() { 123 | expect(ExampleFactory.annotations[0]).toEqual( 124 | new OriginalFactory('ExampleFactory', ['dep1', 'dep2'])); 125 | }); 126 | 127 | }); 128 | 129 | describe("provider", function() { 130 | 131 | @Provider('ExampleProvider', ['dep1', 'dep2']) 132 | class ExampleProvider { 133 | constructor(dep1, dep2) { 134 | 135 | } 136 | }; 137 | 138 | it("should annotate the provider", function() { 139 | expect(ExampleProvider.annotations[0]).toEqual( 140 | new OriginalProvider('ExampleProvider', ['dep1', 'dep2'])); 141 | }); 142 | 143 | }); 144 | 145 | describe("value", function() { 146 | 147 | @Value('ExampleValue', ['dep1', 'dep2']) 148 | class ExampleValue { 149 | constructor(dep1, dep2) { 150 | 151 | } 152 | }; 153 | 154 | it("should annotate the value", function() { 155 | expect(ExampleValue.annotations[0]).toEqual( 156 | new OriginalValue('ExampleValue', ['dep1', 'dep2'])); 157 | }); 158 | 159 | }); 160 | 161 | describe("constant", function() { 162 | 163 | @Constant('ExampleConstant', ['dep1', 'dep2']) 164 | class ExampleConstant { 165 | constructor(dep1, dep2) { 166 | 167 | } 168 | }; 169 | 170 | it("should annotate the constant", function() { 171 | expect(ExampleConstant.annotations[0]).toEqual( 172 | new OriginalConstant('ExampleConstant', ['dep1', 'dep2'])); 173 | }); 174 | 175 | }); 176 | 177 | describe("animation", function() { 178 | 179 | @Animation('ExampleAnimation', ['dep1', 'dep2']) 180 | class ExampleAnimation { 181 | constructor(dep1, dep2) { 182 | 183 | } 184 | }; 185 | 186 | it("should annotate the animation", function() { 187 | expect(ExampleAnimation.annotations[0]).toEqual( 188 | new OriginalAnimation('ExampleAnimation', ['dep1', 'dep2'])); 189 | }); 190 | 191 | }); 192 | 193 | describe("filter", function() { 194 | 195 | @Filter('ExampleFilter', ['dep1', 'dep2']) 196 | class ExampleFilter { 197 | constructor(dep1, dep2) { 198 | 199 | } 200 | }; 201 | 202 | it("should annotate the filter", function() { 203 | expect(ExampleFilter.annotations[0]).toEqual( 204 | new OriginalFilter('ExampleFilter', ['dep1', 'dep2'])); 205 | }); 206 | 207 | }); 208 | 209 | 210 | describe("asModule", function() { 211 | 212 | @AsModule('ExampleModule', ['dep1', 'dep2']) 213 | class ExampleModule { 214 | constructor(dep1, dep2) { 215 | 216 | } 217 | }; 218 | 219 | it("should annotate the module", function() { 220 | expect(ExampleModule.annotations[0]).toEqual( 221 | new OriginalAsModule('ExampleModule', ['dep1', 'dep2'])); 222 | }); 223 | 224 | }); 225 | 226 | }); 227 | -------------------------------------------------------------------------------- /test/injector_spec.js: -------------------------------------------------------------------------------- 1 | import angular from 'angular'; 2 | import 'angular-mocks'; 3 | 4 | import { 5 | Module, 6 | AsModule, 7 | Controller, 8 | Directive, 9 | Service 10 | } from '../src/a1atscript/annotations'; 11 | 12 | import { 13 | Injector, 14 | registerInjector, 15 | getInjector 16 | } from '../src/a1atscript/Injector'; 17 | 18 | import { 19 | applyAnnotation 20 | } from "../src/a1atscript/applyAnnotation.js"; 21 | var mock = angular.mock; 22 | 23 | @Controller('ExampleController', ['$scope', 'ExampleService']) 24 | class ExampleController { 25 | constructor($scope, ExampleService) { 26 | $scope.value = ExampleService.value 27 | } 28 | } 29 | 30 | @AsModule('ServiceModule') 31 | @Service('ExampleService') 32 | class ExampleService { 33 | constructor() { 34 | this.value = 'Test Value'; 35 | } 36 | } 37 | 38 | function testDirective() { 39 | return { 40 | restrict: 'E', 41 | template: "

Hello"); 125 | element = element(scope); 126 | })) 127 | 128 | it("should be able to use annotations on functions using apply annotation", function() { 129 | expect(element.find("p").length).toEqual(1); 130 | }) 131 | }) 132 | }); 133 | 134 | }); 135 | 136 | describe("Registering an injector", function() { 137 | it("should store an instance of the class", function() { 138 | class Bar { 139 | 140 | } 141 | class Foo { 142 | get annotationClass() { 143 | return Bar; 144 | } 145 | } 146 | registerInjector('foo', Foo); 147 | expect(getInjector('foo') instanceof Foo).toBeTruthy(); 148 | }) 149 | }) 150 | }); 151 | -------------------------------------------------------------------------------- /wait_for_watcher.js: -------------------------------------------------------------------------------- 1 | // Wait for any outstanding Traceur watchers. 2 | // Hack to work-around https://youtrack.jetbrains.com/issue/WEB-14104 3 | 4 | // How it works? 5 | // WebStorm Traceur watcher writes LOCK_FILE when running and delete LOCK_FILE once all watchers are finished. 6 | // WebStorm Karma configuration waits for this process to finish (i.e. till the LOCK_FILE is removed). 7 | 8 | var fs = require('fs'); 9 | var LOCK_FILE = '.atscriptwatcher'; 10 | var START_DELAY = 500; 11 | 12 | setTimeout(function() { 13 | if (!fs.existsSync(LOCK_FILE)) { 14 | // Watcher was not running. 15 | process.exit(0); 16 | } 17 | 18 | fs.watch(LOCK_FILE, function() { 19 | if (!fs.existsSync(LOCK_FILE)) { 20 | // All watchers have finished. 21 | process.exit(0); 22 | } 23 | }); 24 | }, START_DELAY); 25 | 26 | 27 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = { 4 | entry: { 5 | app: './src/a1atscript.js' 6 | }, 7 | output: { 8 | path: path.join(__dirname, 'dist'), 9 | filename: 'a1atscript.bundle.js', 10 | libraryTarget: 'commonjs' 11 | }, 12 | module: { 13 | loaders: [ 14 | { 15 | test: /\.js$/, 16 | exclude: 'node_modules', 17 | loader: 'babel', 18 | query: { 19 | optional: ['es7.decorators'], 20 | stage: 0 21 | } 22 | } 23 | ] 24 | }, 25 | devtool: 'source-map' 26 | } 27 | -------------------------------------------------------------------------------- /webstorm_traceur.js: -------------------------------------------------------------------------------- 1 | var inputFilename = process.argv[2]; 2 | var outputFilename = process.argv[3] || inputFilename.replace(/\.ats$/, '.js'); 3 | 4 | var path = require('path'); 5 | var sourceRoot = path.relative(path.dirname(outputFilename), ''); 6 | 7 | var TraceurNodeCompiler = require('traceur/src/node/NodeCompiler').NodeCompiler; 8 | var options = require('./config.json').traceur; 9 | var compiler = new TraceurNodeCompiler(options); 10 | 11 | 12 | // Increment the lock to delay Karma unit tests until all watchers are finished. 13 | var LOCK_FILE = '.atscriptwatcher'; 14 | var fs = require('fs'); 15 | 16 | if (fs.existsSync(LOCK_FILE)) { 17 | var lockCount = parseInt(fs.readFileSync(LOCK_FILE).toString(), 10); 18 | lockCount++; 19 | fs.writeFileSync(LOCK_FILE, lockCount.toString()); 20 | } else { 21 | fs.writeFileSync(LOCK_FILE, '1'); 22 | } 23 | 24 | 25 | // TODO(vojta): Fix this in Traceur instead. 26 | // Traceur generates source map file in the CWD. 27 | // This hacks Traceur to generate source map file in the output file directory, respecting the `sourceRoot` option. 28 | var writeFile = require('traceur/src/node/file-util').writeFile; 29 | compiler.writeTreeToFile = function(tree, filename) { 30 | filename = this.normalize(filename); 31 | // This is changed. 32 | // Pass sourceRoot to `this.write`. Traceur does not pass it through. 33 | var compiledCode = this.write(tree, filename, sourceRoot); 34 | if (this.options_.sourceMaps === 'file') { 35 | var sourcemap = this.getSourceMap(); 36 | if (sourcemap) { 37 | // This is changed. 38 | // Generate the source map in the same folder as the output JS file. 39 | writeFile(filename.replace(/\.js$/, '.map'), sourcemap); 40 | } 41 | } 42 | 43 | writeFile(filename, compiledCode); 44 | }; 45 | 46 | 47 | compiler.compileSingleFile(inputFilename, outputFilename, function(err) { 48 | console.error(err); 49 | }); 50 | 51 | // Release/decrement the lock. 52 | var lockCount = parseInt(fs.readFileSync(LOCK_FILE).toString(), 10); 53 | lockCount--; 54 | 55 | if (lockCount === 0) { 56 | fs.unlinkSync(LOCK_FILE); 57 | } else { 58 | fs.writeFileSync(LOCK_FILE, lockCount.toString()); 59 | } 60 | --------------------------------------------------------------------------------