├── .gitattributes
├── .gitignore
├── .travis.yml
├── Angular2-Haxe.hxproj
├── LICENSE
├── README.md
├── bin
├── css
│ ├── style.css
│ └── style.min.css
├── img
│ └── haxe-logo.png
├── index.html
└── templates
│ └── dependency.tpl.html
├── build.bat
├── build.sh
├── haxelib.json
├── package.json
├── spec
├── CompiledComponents.test.js
├── ComponentMetadata.spec.js
├── DirectiveMetadata.spec.js
├── ViewMetadata.spec.js
└── runTests.js
└── src
├── BuildRegistry.hx
├── Main.hx
├── angular2haxe
├── AngularExtension.hx
├── Annotation.hx
├── AnnotationExtension.hx
├── AnnotationPair.hx
├── Application.hx
├── ComponentAnnotationExtension.hx
├── DirectiveAnnotationExtension.hx
├── KeyboardEvent.hx
├── LifecycleEventExtension.hx
├── Trace.hx
├── ViewAnnotationExtension.hx
├── ViewEncapsulationExtension.hx
├── buildplugin
│ └── BuildPlugin.hx
└── ng
│ ├── Angular.hx
│ ├── ComponentConstructorData.hx
│ ├── ComponentMetadata.hx
│ ├── DirectiveConstructorData.hx
│ ├── DirectiveMetadata.hx
│ ├── EventEmitter.hx
│ ├── LifecycleEvent.hx
│ ├── NgFor.hx
│ ├── NgIf.hx
│ ├── ViewConstructorData.hx
│ ├── ViewEncapsulation.hx
│ └── ViewMetadata.hx
├── test
├── ChildComponent.hx
├── Dependency.hx
├── DependencyDisplayComponent.hx
├── DisplayComponent.hx
├── FriendsService.hx
├── HelloWorld.hx
├── InputDirective.hx
├── ParentComponent.hx
└── TodoList.hx
└── testcompile
├── ChildComponent.hx
├── Dependency.hx
├── DependencyDisplayComponent.hx
├── DisplayComponent.hx
├── FriendsService.hx
├── Greeter.hx
├── HelloWorld.hx
├── InputDirective.hx
├── MyDirective.hx
├── NeedsGreeter.hx
├── NgModelDirective.hx
├── ParentComponent.hx
└── TodoList.hx
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.zip
2 | node_modules/
3 | bin/angular.sfx.dev.js
4 | bin/http.sfx.dev.js
5 | bin/angular2haxe.js
6 | bin/Angular2-Haxe.js
7 | bin/angular2haxe.js.map
8 | bin/Angular2-Haxe.js.map
9 |
10 | # Windows image file caches
11 | Thumbs.db
12 | ehthumbs.db
13 |
14 | # Folder config file
15 | Desktop.ini
16 |
17 | # Recycle Bin used on file shares
18 | $RECYCLE.BIN/
19 |
20 | # Windows Installer files
21 | *.cab
22 | *.msi
23 | *.msm
24 | *.msp
25 |
26 | # Windows shortcuts
27 | *.lnk
28 |
29 | # =========================
30 | # Operating System Files
31 | # =========================
32 |
33 | # OSX
34 | # =========================
35 |
36 | .DS_Store
37 | .AppleDouble
38 | .LSOverride
39 |
40 | # Thumbnails
41 | ._*
42 |
43 | # Files that might appear on external disk
44 | .Spotlight-V100
45 | .Trashes
46 |
47 | # Directories potentially created on remote AFP share
48 | .AppleDB
49 | .AppleDesktop
50 | Network Trash Folder
51 | Temporary Items
52 | .apdisk
53 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "iojs"
4 | before_install:
5 | - "npm install mocha -g"
6 | - curl http://haxe.org/website-content/downloads/3.2.0/downloads/haxe-3.2.0-linux64.tar.gz > haxe.tar.gz
7 | - tar -xzf haxe.tar.gz -C ~
8 | - export HAXE_STD_PATH=~/haxe-3.2.0/std
9 | - export HAXE_HOME=~/haxe-3.2.0
10 | - chmod +x ./build.sh
11 | - chmod +x ~/haxe-3.2.0/haxe
12 | script: ./build.sh
--------------------------------------------------------------------------------
/Angular2-Haxe.hxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Haxe Language Bindings for Angular 2
2 | ===
3 | [](https://travis-ci.org/nweedon/angular2haxe)
4 | [](http://lib.haxe.org/p/angular2haxe/)
5 |
6 | * Supported Angular 2 version: alpha.35
7 | * Heavily work-in-progress, API is subject to change as the Angular 2 API goes through development.
8 |
9 | ### Haxelib Installation
10 | * Stable: ```haxelib install angular2haxe 0.3.2```
11 |
12 | Also, add ```-lib angular2haxe``` to the build command of your project.
13 |
14 | ### Building the demo project
15 | Run ```build.bat``` on Windows or ```./build.sh``` on Linux. This will build a demo project and run
16 | the current suite of tests. You can then launch a webserver targetting the build folder and visit
17 | the servers' configured address to view a selection of demo components.
18 |
19 | *Note:* Currently, you must have an active internet connection for the tests to run correctly,
20 | as the demo webpage accesses the Angular 2 library files.
21 |
22 | ### Building components at build-time *(as of 0.3.0)*
23 | Use the ```@:build``` component metadata to build the component
24 | at build-time. All classes (except for Angular externs) will be resolved
25 | at build-time so that the component does not have to be fully resolved when
26 | the web page loads.
27 |
28 | *Change from 0.3.0-alpha*: All components can now be bootstrapped via the
29 | main class (see example below). The old way of compiling components will still work.
30 |
31 | *Note:* for class names to resolve at build-time, the class needs to be imported. To
32 | solve this, the library utilises a build registry, which holds all imports you want to
33 | resolve. This doesn't come with the library by default, you must provide this yourself; if
34 | you don't know how to do this, I recommend looking at BuildRegistry.hx.
35 |
36 | Finally, to use the build registry, include the following on the command line:
37 | ```-D using_registry```
38 |
39 | Example:
40 | ```haxe
41 | @:build(angular2haxe.buildplugin.BuildPlugin.app([
42 | testcompile.DisplayComponent,
43 | testcompile.TodoList,
44 | // ... other class names (as strings or class names, fully qualified)
45 | ]))
46 | class Main
47 | {
48 | static function main()
49 | {
50 | ...
51 | }
52 | }
53 | ```
54 |
55 | ### Creating an application
56 | Creating an application this way allows you to import and bootstrap all of your components with ease. All data transformation (from Haxe metadata to Angular annotations) is done under the hood! (See 'src/Main.hx').
57 | ```haxe
58 | import angular2haxe.Application;
59 |
60 | class Main
61 | {
62 | static function main()
63 | {
64 | new Application([
65 |
66 | // List of class names which are Angular 2 components
67 |
68 | ]);
69 | }
70 | }
71 | ```
72 |
73 | ### Creating a component (@Component and @View annotations)
74 | Creating components is pretty much the same as it is in ES6/TypeScript, with a few slight changes due to limitations with Haxe metadata.
75 |
76 | **Currently tested metadata for @Component annotation:**
77 | * selector
78 | * lifecycle ("onInit", "onCheck", "onAllChangesDone")
79 | * hostInjector *(Note: class names must be surrounded in double-quotes)*
80 | * compileChildren
81 |
82 | **Implemented but untested metadata for @Component annotation:**
83 | * lifecycle (onChange, onDestroy)
84 |
85 | *Make sure to use the @:expose metadata tag on classes you wish to import!*
86 |
87 | **Currently tested metadata for @View annotation:**
88 | * directives *(Note: class names must be surrounded in double-quotes)*
89 | * template
90 | * templateUrl
91 |
92 | ```haxe
93 | @Component({
94 | selector: 'display',
95 | viewBindings: ["test.FriendsService"]
96 | })
97 | @View({
98 | directives: ["angular.NgFor", "angular.NgIf"],
99 | template: '
--------------------------------------------------------------------------------
/build.bat:
--------------------------------------------------------------------------------
1 | @echo OFF
2 |
3 | haxe -debug --each -cp src -js ./bin/angular2haxe.js -D using_registry -D debug_level=ERROR -main Main -dce full
4 | mocha spec/runTests.js -t 5000
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #/usr/bin/env sh
2 | ~/haxe-3.2.0/haxe -debug --each -cp src -js ./bin/angular2haxe.js -D using_registry -D debug_level=ERROR -main Main -dce full
3 | mocha spec/runTests.js -t 5000
--------------------------------------------------------------------------------
/haxelib.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "angular2haxe",
3 | "url" : "https://github.com/nweedon/angular2haxe",
4 | "license" : "Apache",
5 | "tags" : ["angular", "web", "language bindings"],
6 | "description" : "Haxe language bindings for Angular 2",
7 | "version" : "0.3.2",
8 | "classpath" : "angular2haxe/",
9 | "releasenote" : "Improve code block modification at build-time for app compilation.",
10 | "contributors" : ["nweedon"],
11 | "dependencies" : { }
12 | }
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "connect": "^3.4.0",
4 | "expect.js": "^0.3.1",
5 | "serve-static": "^1.10.0",
6 | "zombie": "^4.0.13"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/spec/CompiledComponents.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | "use strict"
17 | module.exports = { };
18 |
19 | module.exports.spec = function(browser, expect, compiled) {
20 | let desc = 'Bootstrapped Component Testing';
21 |
22 | if(compiled) {
23 | desc += " (Compiled)";
24 | }
25 |
26 | describe(desc, function() {
27 | before(function(done) {
28 | browser.visit('/index.html', { debug: false }, function() {
29 | done();
30 | });
31 | });
32 |
33 | let ns = 'test';
34 | let componentSuffixes = [
35 | "ChildComponent",
36 | "DependencyDisplayComponent",
37 | "DisplayComponent",
38 | "HelloWorld",
39 | "ParentComponent",
40 | "TodoList"
41 | ];
42 |
43 | if(compiled) {
44 | ns += 'compile';
45 | }
46 |
47 | for(var suffix of componentSuffixes) {
48 | it(`${suffix}`, function() {
49 | expect(browser.window[ns][suffix].__bootstrapped).not.to.be(null);
50 | expect(browser.window[ns][suffix].__bootstrapped).not.to.be(undefined);
51 | expect(browser.window[ns][suffix].__bootstrapped).to.be.a('boolean');
52 | expect(browser.window[ns][suffix].__bootstrapped).to.eql(true);
53 | });
54 | }
55 | });
56 | };
--------------------------------------------------------------------------------
/spec/ComponentMetadata.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | "use strict"
17 | module.exports = { };
18 |
19 | module.exports.spec = function(browser, expect, compiled) {
20 | let desc = 'ComponentMetadata parsing';
21 |
22 | if(compiled) {
23 | desc += ' (Compiled)';
24 | }
25 |
26 | describe(desc, function() {
27 | let meta = { };
28 | let anno = { };
29 | let params = { };
30 | let alreadyConstructed = { };
31 |
32 | before(function(done) {
33 | browser.visit('/index.html', { debug: false }, function() {
34 | let ns = 'test';
35 | let packs = ["HelloWorld", "TodoList"];
36 |
37 | if(compiled) {
38 | ns += 'compile';
39 | }
40 |
41 | for(var pack of packs) {
42 | anno[pack] = browser.window[ns][pack].annotations;
43 | params[pack] = browser.window[ns][pack].parameters;
44 | alreadyConstructed[pack] = browser.window[ns][pack].__alreadyConstructed;
45 |
46 | if(!compiled) {
47 | meta[pack] = browser.window[ns][pack].__meta__.obj;
48 | }
49 | }
50 |
51 | done();
52 | });
53 | });
54 |
55 | // Selector conversion.
56 | // Should be one-to-one mapping (String -> String)
57 | it('selector', function() {
58 | var expectedSelector;
59 |
60 | if(!compiled) {
61 | expect(meta["HelloWorld"].Component.length).to.eql(1);
62 | expectedSelector = 'greet';
63 | } else {
64 | expect(alreadyConstructed["HelloWorld"]).to.be.a('boolean');
65 | expect(alreadyConstructed["HelloWorld"]).to.eql(true);
66 | expectedSelector = 'c-greet';
67 | }
68 |
69 | expect(anno["HelloWorld"].length).to.eql(2);
70 | expect(anno["HelloWorld"][0]).not.to.be(null);
71 | expect(anno["HelloWorld"][0].selector).not.to.be(null);
72 | expect(anno["HelloWorld"][0].selector).to.eql(expectedSelector);
73 | });
74 |
75 | // Properties conversion.
76 | // Should be Array -> Array mapping
77 | it('properties', function() {
78 | if(!compiled) {
79 | expect(meta["TodoList"].Component[0].properties).not.to.be(null);
80 | expect(meta["TodoList"].Component[0].properties).to.be.an('array');
81 | expect(meta["TodoList"].Component[0].properties).to.eql([ "lastValue", "todos" ]);
82 | } else {
83 | expect(alreadyConstructed["TodoList"]).to.be.a('boolean');
84 | expect(alreadyConstructed["TodoList"]).to.eql(true);
85 | }
86 |
87 | expect(anno["TodoList"][0].properties).not.to.be(null);
88 | expect(anno["TodoList"][0].properties).to.be.an('array');
89 | expect(anno["TodoList"][0].properties).to.eql([ "lastValue", "todos" ]);
90 | });
91 |
92 | it('events');
93 |
94 | // Host conversion.
95 | // Should be Map -> Map
96 | // angular2haxe removes prefixed $__hx__ from keys that are strings.
97 | it('host');
98 |
99 | // Lifecycle conversion.
100 | // Should be Array -> Array
101 | it('lifecycle', function() {
102 | // Meta checks
103 | if(!compiled) {
104 | expect(meta["TodoList"].Component[0].lifecycle).not.to.be(null);
105 | expect(meta["TodoList"].Component[0].lifecycle.length).to.eql(4);
106 | expect(meta["TodoList"].Component[0].lifecycle).to.eql([
107 | "onInit",
108 | "onChange",
109 | "onAllChangesDone",
110 | "onCheck"
111 | ]);
112 | } else {
113 | expect(alreadyConstructed["TodoList"]).to.be.a('boolean');
114 | expect(alreadyConstructed["TodoList"]).to.eql(true);
115 | }
116 |
117 | // Annotation checks
118 | expect(anno["TodoList"]).not.to.be(null);
119 | expect(anno["TodoList"].length).to.eql(2);
120 | expect(anno["TodoList"][0]).not.to.be(null);
121 | expect(anno["TodoList"][0].lifecycle).not.to.be(null);
122 | expect(anno["TodoList"][0].lifecycle.length).to.eql(4);
123 | expect(anno["TodoList"][0].lifecycle).to.eql([
124 | browser.window.ng.LifecycleEvent.onInit,
125 | browser.window.ng.LifecycleEvent.onChange,
126 | browser.window.ng.LifecycleEvent.onAllChangesDone,
127 | browser.window.ng.LifecycleEvent.onCheck
128 | ]);
129 | });
130 |
131 | // Bindings conversion.
132 | // Should be String -> Function mapping
133 | it('bindings');
134 |
135 | // ExportAs conversion.
136 | // Should be String -> String mapping
137 | it('exportAs', function() {
138 | if(!compiled) {
139 | expect(meta["HelloWorld"].Component[0].exportAs).not.to.be(null);
140 | expect(meta["HelloWorld"].Component[0].exportAs).to.be.a('string');
141 | expect(meta["HelloWorld"].Component[0].exportAs).to.eql('componentGreet');
142 | } else {
143 | expect(alreadyConstructed["HelloWorld"]).to.be.a('boolean');
144 | expect(alreadyConstructed["HelloWorld"]).to.eql(true);
145 | }
146 |
147 | expect(anno["HelloWorld"][0].exportAs).not.to.be(null);
148 | expect(anno["HelloWorld"][0].exportAs).to.be.a('string');
149 | expect(anno["HelloWorld"][0].exportAs).to.eql('componentGreet');
150 | });
151 |
152 | // CompileChildren conversion. (Defaults to true)
153 | // Should be Bool -> Bool mapping
154 | it('compileChildren', function() {
155 | expect(anno["HelloWorld"][0].compileChildren).not.to.be(null);
156 | expect(anno["HelloWorld"][0].compileChildren).to.be.a('boolean');
157 | expect(anno["HelloWorld"][0].compileChildren).to.eql(true);
158 | });
159 |
160 | it('viewBindings', function() {
161 | var expectedName;
162 |
163 | // Original Metadata
164 | if(!compiled) {
165 | expect(meta["HelloWorld"].Component.length).to.eql(1);
166 | expect(meta["HelloWorld"].Component[0].viewBindings.length).to.eql(1);
167 | expect(meta["HelloWorld"].Component[0].viewBindings[0]).to.be.a('string');
168 | expect(meta["HelloWorld"].Component[0].viewBindings[0]).to.eql('test.Greeter');
169 | expectedName = ["test", "Greeter"];
170 | } else {
171 | expect(alreadyConstructed["HelloWorld"]).to.be.a('boolean');
172 | expect(alreadyConstructed["HelloWorld"]).to.eql(true);
173 | expectedName = ["testcompile", "Greeter"];
174 | }
175 |
176 | expect(anno["HelloWorld"].length).to.eql(2);
177 | expect(anno["HelloWorld"][0]).not.to.be(null);
178 | expect(anno["HelloWorld"][0].viewBindings).not.to.be(null);
179 | expect(anno["HelloWorld"][0].viewBindings.length).to.eql(1);
180 | expect(anno["HelloWorld"][0].viewBindings[0]).to.be.a('function');
181 | expect(anno["HelloWorld"][0].viewBindings[0].__name__).to.eql(expectedName);
182 | });
183 |
184 | // CompileChildren conversion. (Defaults to "DEFAULT")
185 | // Should be String -> String mapping
186 | it('changeDetection', function() {
187 | if(!compiled) {
188 | expect(meta["TodoList"].Component.length).to.eql(1);
189 | expect(meta["TodoList"].Component[0].changeDetection).not.to.be(null);
190 | expect(meta["TodoList"].Component[0].changeDetection).to.be.a('string');
191 | expect(meta["TodoList"].Component[0].changeDetection).to.eql('CHECK_ALWAYS');
192 | } else {
193 | expect(alreadyConstructed["TodoList"]).to.be.a('boolean');
194 | expect(alreadyConstructed["TodoList"]).to.eql(true);
195 | }
196 |
197 | expect(anno["HelloWorld"][0].changeDetection).not.to.be(null);
198 | expect(anno["HelloWorld"][0].changeDetection).to.be.a('string');
199 | expect(anno["HelloWorld"][0].changeDetection).to.eql('DEFAULT');
200 | expect(anno["TodoList"][0].changeDetection).not.to.be(null);
201 | expect(anno["TodoList"][0].changeDetection).to.be.a('string');
202 | expect(anno["TodoList"][0].changeDetection).to.eql('CHECK_ALWAYS');
203 | });
204 | });
205 |
206 | };
--------------------------------------------------------------------------------
/spec/DirectiveMetadata.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | "use strict"
17 | module.exports = { };
18 |
19 | module.exports.spec = function(browser, expect, compiled) {
20 | let desc = 'DirectiveMetadata parsing';
21 |
22 | if(compiled) {
23 | desc += ' (Compiled)';
24 | }
25 |
26 | describe(desc, function() {
27 | let meta = { };
28 | let anno = { };
29 | let params = { };
30 | let alreadyConstructed = { };
31 |
32 | before(function(done) {
33 | browser.visit('/index.html', { debug: false }, function() {
34 | let ns = 'test';
35 | let packs = ["NeedsGreeter", "InputDirective", "Dependency"];
36 |
37 | if(compiled) {
38 | ns += 'compile';
39 | }
40 |
41 | for(var pack of packs) {
42 | anno[pack] = browser.window[ns][pack].annotations;
43 | params[pack] = browser.window[ns][pack].parameters;
44 | alreadyConstructed[pack] = browser.window[ns][pack].__alreadyConstructed;
45 |
46 | if(!compiled) {
47 | meta[pack] = browser.window[ns][pack].__meta__.obj;
48 | }
49 | }
50 |
51 | done();
52 | });
53 | });
54 |
55 | // Selector conversion.
56 | // Should be one-to-one mapping (String -> String)
57 | it('selector', function() {
58 | if(!compiled) {
59 | expect(meta["NeedsGreeter"].Directive.length).to.eql(1);
60 | } else {
61 | // Check the component actually built properly at run-time.
62 | expect(alreadyConstructed["NeedsGreeter"]).to.be.a('boolean');
63 | expect(alreadyConstructed["NeedsGreeter"]).to.eql(true);
64 | }
65 |
66 | expect(anno["NeedsGreeter"].length).to.eql(1);
67 | expect(anno["NeedsGreeter"][0]).not.to.be(null);
68 | expect(anno["NeedsGreeter"][0].selector).not.to.be(null);
69 |
70 | if(!compiled) {
71 | expect(anno["NeedsGreeter"][0].selector).to.eql('needs-greeter');
72 | } else {
73 | expect(anno["NeedsGreeter"][0].selector).to.eql('c-needs-greeter');
74 | }
75 | });
76 |
77 | // Properties conversion.
78 | // Should be Array -> Array mapping
79 | it('properties', function() {
80 | if(!compiled) {
81 | expect(meta["Dependency"].Directive[0].properties).not.to.be(null);
82 | expect(meta["Dependency"].Directive[0].properties).to.be.an('array');
83 | expect(meta["Dependency"].Directive[0].properties).to.eql([ "id: dependency" ]);
84 | } else {
85 | expect(alreadyConstructed["Dependency"]).to.be.a('boolean');
86 | expect(alreadyConstructed["Dependency"]).to.eql(true);
87 | }
88 |
89 | expect(anno["Dependency"][0].properties).not.to.be(null);
90 | expect(anno["Dependency"][0].properties).to.be.an('array');
91 |
92 | if(compiled) {
93 | expect(anno["Dependency"][0].properties).to.eql([ "id: c-dependency" ]);
94 | } else {
95 | expect(anno["Dependency"][0].properties).to.eql([ "id: dependency" ]);
96 | }
97 | });
98 |
99 | it('events');
100 |
101 | // Host conversion.
102 | // Should be Map -> Map
103 | // angular2haxe removes prefixed $__hx__ from keys that are strings.
104 | it('host', function() {
105 | if(!compiled) {
106 | expect(meta["InputDirective"].Directive[0].host).not.to.be(null);
107 | expect(meta["InputDirective"].Directive[0].host['(keyup)']).not.to.be(null);
108 | expect(meta["InputDirective"].Directive[0].host['(keyup)']).to.eql('onKeyUp($event)');
109 | } else {
110 | expect(alreadyConstructed["InputDirective"]).to.be.a('boolean');
111 | expect(alreadyConstructed["InputDirective"]).to.eql(true);
112 | }
113 |
114 | expect(anno["InputDirective"]).not.to.be(null);
115 | expect(anno["InputDirective"].length).to.eql(1);
116 | expect(anno["InputDirective"][0]).not.to.be(null);
117 | expect(anno["InputDirective"][0].host).not.to.be(null);
118 | expect(anno["InputDirective"][0].host['(keyup)']).not.to.be(null);
119 | expect(anno["InputDirective"][0].host['(keyup)']).to.eql('onKeyUp($event)');
120 | });
121 |
122 | // Lifecycle conversion.
123 | // Should be Array -> Array
124 | it('lifecycle', function() {
125 | // Meta checks
126 | if(!compiled) {
127 | expect(meta["InputDirective"].Directive[0].lifecycle).not.to.be(null);
128 | expect(meta["InputDirective"].Directive[0].lifecycle.length).to.eql(4);
129 | expect(meta["InputDirective"].Directive[0].lifecycle).to.eql([
130 | "onInit",
131 | "onChange",
132 | "onAllChangesDone",
133 | "onCheck"
134 | ]);
135 | } else {
136 | expect(alreadyConstructed["InputDirective"]).to.be.a('boolean');
137 | expect(alreadyConstructed["InputDirective"]).to.eql(true);
138 | }
139 |
140 | // Annotation checks
141 | expect(anno["InputDirective"]).not.to.be(null);
142 | expect(anno["InputDirective"].length).to.eql(1);
143 | expect(anno["InputDirective"][0]).not.to.be(null);
144 | expect(anno["InputDirective"][0].lifecycle).not.to.be(null);
145 | expect(anno["InputDirective"][0].lifecycle.length).to.eql(4);
146 | expect(anno["InputDirective"][0].lifecycle).to.eql([
147 | browser.window.ng.LifecycleEvent.onInit,
148 | browser.window.ng.LifecycleEvent.onChange,
149 | browser.window.ng.LifecycleEvent.onAllChangesDone,
150 | browser.window.ng.LifecycleEvent.onCheck
151 | ]);
152 | });
153 |
154 | // Bindings conversion.
155 | // Should be String -> Function mapping
156 | it('bindings', function() {
157 | var expectedName;
158 | // Original Metadata
159 | if(!compiled) {
160 | expect(meta["NeedsGreeter"].Directive.length).to.eql(1);
161 | expect(meta["NeedsGreeter"].Directive[0].bindings.length).to.eql(1);
162 | expect(meta["NeedsGreeter"].Directive[0].bindings[0]).to.be.a('string');
163 | expect(meta["NeedsGreeter"].Directive[0].bindings[0]).to.eql('test.Greeter');
164 | expectedName = ["test", "Greeter"];
165 | } else {
166 | expect(alreadyConstructed["NeedsGreeter"]).to.be.a('boolean');
167 | expect(alreadyConstructed["NeedsGreeter"]).to.eql(true);
168 | expectedName = ["testcompile", "Greeter"];
169 | }
170 |
171 | expect(anno["NeedsGreeter"].length).to.eql(1);
172 | expect(anno["NeedsGreeter"][0]).not.to.be(null);
173 | expect(anno["NeedsGreeter"][0].bindings).not.to.be(null);
174 | expect(anno["NeedsGreeter"][0].bindings.length).to.eql(1);
175 | expect(anno["NeedsGreeter"][0].bindings[0]).to.be.a('function');
176 | expect(anno["NeedsGreeter"][0].bindings[0].__name__).to.eql(expectedName);
177 | });
178 |
179 | // ExportAs conversion.
180 | // Should be String -> String mapping
181 | it('exportAs', function() {
182 | if(!compiled) {
183 | expect(meta["InputDirective"].Directive[0].exportAs).not.to.be(null);
184 | expect(meta["InputDirective"].Directive[0].exportAs).to.be.a('string');
185 | expect(meta["InputDirective"].Directive[0].exportAs).to.eql('input-directive');
186 | } else {
187 | expect(alreadyConstructed["InputDirective"]).to.be.a('boolean');
188 | expect(alreadyConstructed["InputDirective"]).to.eql(true);
189 | }
190 |
191 | expect(anno["InputDirective"][0].exportAs).not.to.be(null);
192 | expect(anno["InputDirective"][0].exportAs).to.be.a('string');
193 | expect(anno["InputDirective"][0].exportAs).to.eql('input-directive');
194 | });
195 |
196 | // CompileChildren conversion. (Defaults to true)
197 | // Should be Bool -> Bool mapping
198 | it('compileChildren', function() {
199 | expect(anno["InputDirective"][0].compileChildren).not.to.be(null);
200 | expect(anno["InputDirective"][0].compileChildren).to.be.a('boolean');
201 | expect(anno["InputDirective"][0].compileChildren).to.eql(true);
202 | });
203 | });
204 |
205 | };
--------------------------------------------------------------------------------
/spec/ViewMetadata.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | "use strict"
17 | module.exports = { };
18 |
19 | module.exports.spec = function(browser, expect, compiled) {
20 | let desc = 'ViewMetadata parsing';
21 |
22 | if(compiled) {
23 | desc += ' (Compiled)';
24 | }
25 |
26 | describe(desc, function() {
27 | let meta = { };
28 | let anno = { };
29 | let params = { };
30 | let alreadyConstructed = { };
31 |
32 | before(function(done) {
33 | browser.visit('/index.html', { debug: false }, function() {
34 | let ns = 'test';
35 | let packs = ["HelloWorld", "TodoList", "DependencyDisplayComponent"];
36 |
37 | if(compiled) {
38 | ns += 'compile';
39 | }
40 |
41 | for(var pack of packs) {
42 | anno[pack] = browser.window[ns][pack].annotations;
43 | params[pack] = browser.window[ns][pack].parameters;
44 | alreadyConstructed[pack] = browser.window[ns][pack].__alreadyConstructed;
45 |
46 | if(!compiled) {
47 | meta[pack] = browser.window[ns][pack].__meta__.obj;
48 | }
49 | }
50 |
51 | done();
52 | });
53 | });
54 |
55 | // TemplateUrl conversion.
56 | // Should be String -> String mapping
57 | it('templateUrl', function() {
58 | if(!compiled) {
59 | expect(meta["DependencyDisplayComponent"].View.length).to.eql(1);
60 | expect(meta["DependencyDisplayComponent"].View[0].templateUrl).not.to.be(null);
61 | expect(meta["DependencyDisplayComponent"].View[0].templateUrl).to.be.a('string');
62 | expect(meta["DependencyDisplayComponent"].View[0].templateUrl).to.eql("templates/dependency.tpl.html");
63 | } else {
64 | expect(alreadyConstructed["DependencyDisplayComponent"]).to.be.a('boolean');
65 | expect(alreadyConstructed["DependencyDisplayComponent"]).to.eql(true);
66 | }
67 |
68 | expect(anno["DependencyDisplayComponent"].length).to.eql(2);
69 | expect(anno["DependencyDisplayComponent"][1]).not.to.be(null);
70 | expect(anno["DependencyDisplayComponent"][1].templateUrl).not.to.be(null);
71 | expect(anno["DependencyDisplayComponent"][1].templateUrl).to.be.a('string');
72 | expect(anno["DependencyDisplayComponent"][1].templateUrl).to.eql("templates/dependency.tpl.html");
73 | });
74 |
75 | // Template conversion.
76 | // Should be one-to-one mapping (String -> String)
77 | it('template', function() {
78 | if(!compiled) {
79 | expect(meta["HelloWorld"].View.length).to.eql(1);
80 | expect(meta["HelloWorld"].View[0].template).not.to.be(null);
81 | expect(meta["HelloWorld"].View[0].template).to.be.a('string');
82 | expect(meta["HelloWorld"].View[0].template).to.eql("{{ greeter.greet('World') }}");
83 | } else {
84 | expect(alreadyConstructed["HelloWorld"]).to.be.a('boolean');
85 | expect(alreadyConstructed["HelloWorld"]).to.eql(true);
86 | }
87 |
88 | expect(anno["HelloWorld"].length).to.eql(2);
89 | expect(anno["HelloWorld"][1]).not.to.be(null);
90 | expect(anno["HelloWorld"][1].template).not.to.be(null);
91 | expect(anno["HelloWorld"][1].template).to.be.a('string');
92 |
93 | if(compiled) {
94 | expect(anno["HelloWorld"][1].template).to.eql("{{ greeter.greet('World') }}");
95 | } else {
96 | expect(anno["HelloWorld"][1].template).to.eql("{{ greeter.greet('World') }}");
97 | }
98 | });
99 |
100 | // Directives conversion.
101 | it('directives', function() {
102 | var expectedNames = null;
103 |
104 | if(!compiled) {
105 | expectedNames = ["test.Dependency", "test.MyDirective", "test.NgModelDirective"];
106 | expect(meta["DependencyDisplayComponent"].View.length).to.eql(1);
107 | expect(meta["DependencyDisplayComponent"].View[0].directives).not.to.be(null);
108 | expect(meta["DependencyDisplayComponent"].View[0].directives).to.be.an('array');
109 | expect(meta["DependencyDisplayComponent"].View[0].directives).to.eql(expectedNames);
110 | } else {
111 | expectedNames = ["testcompile.Dependency", "testcompile.MyDirective", "testcompile.NgModelDirective"];
112 | expect(alreadyConstructed["DependencyDisplayComponent"]).to.be.a('boolean');
113 | expect(alreadyConstructed["DependencyDisplayComponent"]).to.eql(true);
114 | }
115 |
116 | for(var name in expectedNames) {
117 | expectedNames[name] = expectedNames[name].split('.');
118 | }
119 |
120 | expect(anno["DependencyDisplayComponent"].length).to.eql(2);
121 | expect(anno["DependencyDisplayComponent"][1].directives).not.to.be(null);
122 | expect(anno["DependencyDisplayComponent"][1].directives).to.be.an('array');
123 |
124 | for(var i in expectedNames) {
125 | expect(anno["DependencyDisplayComponent"][1].directives[i]).to.be.a('function');
126 | expect(anno["DependencyDisplayComponent"][1].directives[i].__name__).to.eql(expectedNames[i]);
127 | }
128 | });
129 |
130 | // Encapsulation conversion.
131 | it('encapsulation', function() {
132 | if(!compiled) {
133 | expect(meta["DependencyDisplayComponent"].View.length).to.eql(1);
134 | expect(meta["DependencyDisplayComponent"].View[0].encapsulation).to.be(undefined);
135 | expect(meta["HelloWorld"].View.length).to.eql(1);
136 | expect(meta["HelloWorld"].View[0].encapsulation).not.to.be(null);
137 | expect(meta["HelloWorld"].View[0].encapsulation).to.be.a('string');
138 | expect(meta["HelloWorld"].View[0].encapsulation).to.eql("NONE");
139 | } else {
140 | expect(alreadyConstructed["DependencyDisplayComponent"]).to.be.a('boolean');
141 | expect(alreadyConstructed["DependencyDisplayComponent"]).to.eql(true);
142 | expect(alreadyConstructed["HelloWorld"]).to.be.a('boolean');
143 | expect(alreadyConstructed["HelloWorld"]).to.eql(true);
144 | }
145 |
146 | expect(anno["DependencyDisplayComponent"].length).to.eql(2);
147 | expect(anno["DependencyDisplayComponent"][1].encapsulation).not.to.be(null);
148 | expect(anno["DependencyDisplayComponent"][1].encapsulation).to.be.a('number');
149 | expect(anno["DependencyDisplayComponent"][1].encapsulation).to.be(browser.window.ng.ViewEncapsulation.NONE);
150 | expect(anno["HelloWorld"].length).to.eql(2);
151 | expect(anno["HelloWorld"][1].encapsulation).not.to.be(null);
152 | expect(anno["HelloWorld"][1].encapsulation).to.be.a('number');
153 | expect(anno["HelloWorld"][1].encapsulation).to.eql(browser.window.ng.ViewEncapsulation.NONE);
154 | });
155 |
156 | // Styles conversion.
157 | it('styles');
158 |
159 | // StyleUrls conversion.
160 | it('styleUrls');
161 | });
162 | };
--------------------------------------------------------------------------------
/spec/runTests.js:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | /*
17 | > IO.JS version 3.0.0
18 | Basic webserver to serve files during tests
19 | Reference: http://stackoverflow.com/questions/6084360/using-node-js-as-a-simple-web-server
20 |
21 | > Run with:
22 | mocha runTests.js -t 5000
23 |
24 | > Requires:
25 | - connect
26 | - serve-static
27 | - zombie@4.0.13
28 | - mocha
29 | - expect.js
30 | */
31 | "use strict"
32 | const zombie = require('zombie');
33 | const expect = require('expect.js');
34 | const connect = require('connect');
35 | const serveStatic = require('serve-static');
36 | const port = 8080;
37 | const specs = ['CompiledComponents.test.js', 'DirectiveMetadata.spec.js', 'ComponentMetadata.spec.js', 'ViewMetadata.spec.js'];
38 |
39 | // Launch webserver. Will be shut down automatically
40 | // once mocha has finished.
41 | connect().use(serveStatic(__dirname + "/../bin/")).listen(port);
42 |
43 | // As of Angular 2.0.0-alpha.35, the following message is displayed:
44 | // TypeError: Array.prototype.slice called on null or undefined
45 | // This is due to ZombieJS not refreshing its own DOM structure. Once
46 | // Angular compiles its' children, it expects that they should be present
47 | // in the DOM, however, as ZombieJS doesn't refresh the DOM, they
48 | // don't exist.
49 | zombie.silent = true;
50 | zombie.localhost('localhost', port);
51 |
52 | // Run spec tests.
53 | for(var spec of specs) {
54 | // Test compiled and non-compiled.
55 | for(var b of [false, true]) {
56 | const browser = new zombie({
57 | waitFor: 2000,
58 | loadCSS: false,
59 | runScripts: true
60 | });
61 |
62 | require('./' + spec).spec(browser, expect, b);
63 | }
64 | }
--------------------------------------------------------------------------------
/src/BuildRegistry.hx:
--------------------------------------------------------------------------------
1 | package;
2 |
3 | import test.ChildComponent;
4 | import test.Dependency;
5 | import test.DependencyDisplayComponent;
6 | import test.FriendsService;
7 | import test.HelloWorld;
8 | import test.InputDirective;
9 | import test.ParentComponent;
10 | import test.TodoList;
11 |
12 | import testcompile.ChildComponent;
13 | import testcompile.Dependency;
14 | import testcompile.DependencyDisplayComponent;
15 | import testcompile.DisplayComponent;
16 | import testcompile.FriendsService;
17 | import testcompile.HelloWorld;
18 | import testcompile.InputDirective;
19 | import testcompile.ParentComponent;
20 | import testcompile.TodoList;
21 | import testcompile.MyDirective;
22 | import testcompile.NgModelDirective;
23 | import testcompile.NeedsGreeter;
24 | import testcompile.Greeter;
25 |
26 | /**
27 | * Dummy build registry to demonstrate
28 | * compile-time builds. It's main use is
29 | * to be a hub for all imports which will be
30 | * resolved as part of the build process.
31 | */
32 | class BuildRegistry
33 | {
34 | private function new()
35 | {
36 |
37 | }
38 | }
--------------------------------------------------------------------------------
/src/Main.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package;
17 |
18 | import angular2haxe.ng.Angular;
19 | import angular2haxe.Application;
20 |
21 | import test.ChildComponent;
22 | import test.Dependency;
23 | import test.DependencyDisplayComponent;
24 | import test.DisplayComponent;
25 | import test.ParentComponent;
26 | import test.TodoList;
27 | import test.HelloWorld;
28 | import test.InputDirective;
29 |
30 | @:build(angular2haxe.buildplugin.BuildPlugin.app([
31 | testcompile.DisplayComponent,
32 | testcompile.TodoList,
33 | testcompile.ParentComponent,
34 | testcompile.ChildComponent,
35 | testcompile.MyDirective,
36 | testcompile.NgModelDirective,
37 | testcompile.Dependency,
38 | testcompile.DependencyDisplayComponent,
39 | testcompile.Greeter,
40 | testcompile.NeedsGreeter,
41 | testcompile.HelloWorld,
42 | testcompile.InputDirective
43 | ]))
44 | class Main
45 | {
46 | static function main()
47 | {
48 | // Create a new application, bootstrapping the
49 | // listed classes in the process.
50 | new Application([
51 |
52 | test.DisplayComponent,
53 | test.TodoList,
54 | test.ParentComponent,
55 | test.ChildComponent,
56 |
57 | // --- Dependency.hx ---
58 | test.MyDirective,
59 | test.NgModelDirective,
60 | test.Dependency,
61 |
62 | // --- DependencyDisplayComponent.hx --
63 | test.DependencyDisplayComponent,
64 |
65 | // --- HelloWorld.hx ---
66 | test.Greeter,
67 | test.NeedsGreeter,
68 | test.HelloWorld,
69 |
70 | test.InputDirective
71 |
72 | ]);
73 | }
74 | }
--------------------------------------------------------------------------------
/src/angular2haxe/AngularExtension.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | import angular2haxe.ng.NgFor;
19 | import angular2haxe.ng.NgIf;
20 |
21 | class AngularExtension
22 | {
23 | private static var angularClasses : Map> = [
24 | "NgFor" => NgFor,
25 | "NgIf" => NgIf
26 | ];
27 |
28 | private function new() { }
29 |
30 | public static function getAngularClasses() : Map>
31 | {
32 | return angularClasses;
33 | }
34 |
35 | public static function getAngularClass(name : String) : Class
36 | {
37 | if (angularClasses.exists(name))
38 | {
39 | return angularClasses[name];
40 | }
41 |
42 | return null;
43 | }
44 |
45 | public static function isAngularClass(name : String) : Bool
46 | {
47 | if (name.substr(0, 3) == "ng." || name.substr(0, 8) == "angular.")
48 | {
49 | name = getFullyQualifiedName(name);
50 | }
51 |
52 | return angularClasses.exists(name);
53 | }
54 |
55 | public static function getBareName(name : String) : String
56 | {
57 | if (name.substr(0, 3) == "ng.")
58 | {
59 | return name;
60 | }
61 | else if (name.substr(0, 8) == "angular.")
62 | {
63 | return name.substr(8);
64 | }
65 |
66 | return name;
67 | }
68 |
69 | public static function getFullyQualifiedName(name : String) : String
70 | {
71 | if (isAngularClass(name))
72 | {
73 | return name;
74 | }
75 |
76 | return "ng." + getBareName(name);
77 | }
78 | }
--------------------------------------------------------------------------------
/src/angular2haxe/Annotation.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | class Annotation
19 | {
20 | private function new(data : Dynamic) { }
21 | }
--------------------------------------------------------------------------------
/src/angular2haxe/AnnotationExtension.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | import angular2haxe.buildplugin.BuildPlugin;
19 | import angular2haxe.ng.ComponentMetadata;
20 | import angular2haxe.ng.DirectiveMetadata;
21 | import angular2haxe.ng.ViewMetadata;
22 |
23 | // Type.resolveClass in macro works if type is imported
24 | //import test.HelloWorld;
25 |
26 | class AnnotationExtension
27 | {
28 | private function new() { }
29 |
30 | // Intended to be overridden in child class
31 | public static function transform(input : Dynamic, annotations : Array, parameters : Array) : Dynamic
32 | {
33 | return input;
34 | }
35 |
36 | /**
37 | * Resolve Haxe metadata input to the form Angular
38 | * expects, checking that the fields are of the
39 | * correct type.
40 | */
41 | public static function resolveInputAnnotation(input : Dynamic, outputType : Class) : T
42 | {
43 | var output : T;
44 |
45 | output = Type.createInstance(outputType, []);
46 |
47 | for (field in Reflect.fields(input))
48 | {
49 | if (Reflect.hasField(output, field))
50 | {
51 | var inputField = Reflect.field(input, field);
52 | var outputClass = Type.getClass(Reflect.field(output, field));
53 |
54 | // If outputClass is null, the output class is most likely Dynamic
55 | if (Std.is(inputField, outputClass) || outputClass == null)
56 | {
57 | var result = null;
58 | #if !macro
59 | // Deep copy array objects, so original meta is
60 | // preserved.
61 | // Reference: https://gist.github.com/Asmageddon/4013485
62 | if (Std.is(inputField, Array))
63 | {
64 | result = Type.createInstance(outputClass, []);
65 |
66 | untyped
67 | {
68 | for (i in 0...inputField.length)
69 | {
70 | result.push(inputField[i]);
71 | }
72 | }
73 | }
74 | else
75 | {
76 | result = inputField;
77 | }
78 | #else
79 | result = inputField;
80 | #end
81 |
82 | Reflect.setField(output, field, result);
83 | }
84 | else
85 | {
86 | var inputClassName : String = Type.getClassName(Type.getClass(inputField));
87 | var outputClassName : String = Type.getClassName(outputClass);
88 | Trace.error('Input type of field "${field}" (${inputClassName}) does not match type of output field (${outputClassName}).');
89 | }
90 | }
91 | else
92 | {
93 | Trace.error('${Type.getClassName(outputType)} does not have field "${field}" and as such this field will be ignored.');
94 | }
95 | }
96 |
97 | return output;
98 | }
99 |
100 | /**
101 | * Parse annotation injectors to be used in the Angular, resolving
102 | * strings to their respective class/type.
103 | * service parameters.
104 | * @param injector Annotation injector variable (i.e. hostInjector).
105 | * @return
106 | */
107 | private static function parseServiceParameters(injector : Array) : Array
108 | {
109 | var serviceParams : Array = [];
110 | var index : Int = 0;
111 |
112 | for (app in injector)
113 | {
114 | if (app != null && app.length > 0)
115 | {
116 | var cl = Type.resolveClass(app);
117 | serviceParams.push(cl);
118 | injector[index] = cl;
119 | }
120 |
121 | index++;
122 | }
123 | return serviceParams;
124 | }
125 |
126 | /**
127 | * Parses an annotation injector variable. Most of the work in this instance is
128 | * deferred to AnnotationExtension.parseServiceParameters.
129 | * @param parameters Static variable of the same name located in an Angular class.
130 | * @param injector The injector variable to parse.
131 | */
132 | private static function parseInjector(parameters : Array, injector : Array)
133 | {
134 | var serviceParameter : Array = parseServiceParameters(injector);
135 |
136 | if (serviceParameter != null && serviceParameter.length > 0)
137 | {
138 | parameters.push(serviceParameter);
139 | }
140 | }
141 |
142 | /**
143 | * Transform lifecycle variable names (String) to Angular
144 | * lifecycle variables (JS Object).
145 | * @param lifecycle
146 | */
147 | private static function transformLifecycle(lifecycle : Array)
148 | {
149 | // Transform lifecycle values
150 | var index : Int = 0;
151 |
152 | while (index < lifecycle.length)
153 | {
154 | lifecycle[index] = LifecycleEventExtension.toAngular(cast(lifecycle[index], String));
155 | index++;
156 | }
157 | }
158 | }
--------------------------------------------------------------------------------
/src/angular2haxe/AnnotationPair.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | typedef AnnotationPair = {
19 | annotation : Class,
20 | extension : Class
21 | };
--------------------------------------------------------------------------------
/src/angular2haxe/Application.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | import haxe.rtti.Meta;
19 | import angular2haxe.ng.Angular;
20 | import angular2haxe.ng.ComponentMetadata;
21 | import angular2haxe.ng.DirectiveMetadata;
22 | import angular2haxe.ng.ViewMetadata;
23 |
24 | #if !macro
25 | import js.Lib;
26 | #end
27 |
28 | class Application
29 | {
30 | public function new(components : Array>)
31 | {
32 | // Patch for Angular 2 issue #3890:
33 | // https://github.com/angular/angular/issues/3890
34 | // angular2haxe issue #6:
35 | // https://github.com/nweedon/angular2haxe/issues/6
36 | untyped window.assert = function() { return true; };
37 |
38 | // Bootstrap all components
39 | bootstrap(components);
40 | }
41 |
42 | /**
43 | * Bootstrap the application, which currently sets up component
44 | * classes and their respective annotations ready for Angular 2.
45 | * Once this is complete, angular.bootstrap is called for each
46 | * component supplied.
47 | * @param components - An array of valid component classes
48 | */
49 | private function bootstrap(components : Array>)
50 | {
51 | var showDataInTrace : Bool = false;
52 | var validAnnotations : Map = [
53 | "Component" => { annotation: ComponentMetadata, extension: ComponentAnnotationExtension },
54 | "Directive" => { annotation: DirectiveMetadata, extension: DirectiveAnnotationExtension },
55 | "View" => { annotation: ViewMetadata, extension: ViewAnnotationExtension },
56 | ];
57 |
58 | for (component in components)
59 | {
60 | var anno = Meta.getType(component);
61 | var className = Type.getClassName(component);
62 | var hasComponentAnnotation = false;
63 |
64 | if (Reflect.fields(component).indexOf('__alreadyConstructed') > -1)
65 | {
66 | // Parse Angular Object in annotations field. This has to be done
67 | // at runtime as all Angular Objects are external and do not resolve
68 | // at compile-time.
69 | var annotations : Array = Reflect.field(component, "annotations");
70 |
71 | if (annotations != null)
72 | {
73 | // Annotations are built in the order:
74 | // Component, View, Directive (see BuildPlugin.hx)
75 | var metaNames : Array = ["Component", "View", "Directive"];
76 | var index : Int = 0;
77 |
78 | for (data in annotations)
79 | {
80 | if (data != null)
81 | {
82 | // Set hasComponentAnnotation to true to
83 | // trigger Angular bootstrap process.
84 | if (index == 0)
85 | {
86 | hasComponentAnnotation = true;
87 | }
88 |
89 | // Call Annotation extension function to
90 | // transform all string representations
91 | // to Angular Object data
92 | Reflect.callMethod( validAnnotations[metaNames[index]].extension,
93 | Reflect.field(validAnnotations[metaNames[index]].extension, "postCompileTransform"),
94 | [data]);
95 | }
96 |
97 | index++;
98 | }
99 |
100 | index = 0;
101 |
102 | // Filter out all null entries.
103 | for (index in 0...annotations.length)
104 | {
105 | if (annotations[index] == null)
106 | {
107 | annotations.remove(null);
108 | }
109 | }
110 | }
111 | }
112 | else
113 | {
114 | // Create 'annotations' and 'parameters' fields, so they don't have
115 | // to be added by a developer every time a new class is created.
116 | Reflect.setField(component, "annotations", []);
117 | Reflect.setField(component, "parameters", []);
118 |
119 | // Get the annotation and parameters fields from the component class.
120 | var annotations : Array = Reflect.field(component, "annotations");
121 | var parameters : Array = Reflect.field(component, "parameters");
122 |
123 | // Only bootstrap once.
124 | if (annotations != null && annotations.length == 0)
125 | {
126 | Trace.log('=> Bootstrapping ${className}');
127 |
128 | for(name in Reflect.fields(anno))
129 | {
130 | if (validAnnotations.exists(name))
131 | {
132 | var field = Reflect.field(anno, name);
133 |
134 | // Call AnnotationExtension transform function. This transform
135 | // function takes Haxe metadata input and transforms it into the
136 | // data that Angular 2 expects.
137 | // For example, Haxe metadata only handles constants (no class names),
138 | // so the string representations of the class names must be transformed into
139 | // JavaScript classes/functions at runtime.
140 | var input = field[0];
141 |
142 | var result = Reflect.callMethod(validAnnotations[name].extension,
143 | Reflect.field(validAnnotations[name].extension, "transform"),
144 | [input, annotations, parameters]);
145 |
146 | annotations.push(Type.createInstance(validAnnotations[name].annotation, [result]));
147 | }
148 | else
149 | {
150 | Trace.error(name + " is not a valid annotation.");
151 | }
152 | }
153 |
154 | hasComponentAnnotation = Reflect.fields(anno).indexOf("Component") >= 0;
155 |
156 | if (showDataInTrace)
157 | {
158 | Trace.log('Annotations:\n${annotations}');
159 | Trace.log('Parameters:\n${parameters}');
160 | }
161 | }
162 | else
163 | {
164 | Trace.error('${className} does not have an "annotations" static variable in its class definition!');
165 | }
166 | }
167 |
168 | // Add event listener for Angular Bootstrap
169 | #if !macro
170 | js.Browser.document.addEventListener("DOMContentLoaded", function()
171 | {
172 | if (hasComponentAnnotation)
173 | {
174 | Angular.bootstrap(component);
175 | Reflect.setField(component, "__bootstrapped", true);
176 | }
177 |
178 | Trace.log('=> Finished bootstrapping ${className}');
179 | });
180 | #end
181 | }
182 | }
183 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ComponentAnnotationExtension.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | import angular2haxe.ng.ComponentConstructorData;
19 | import angular2haxe.ng.LifecycleEvent;
20 |
21 | class ComponentAnnotationExtension extends AnnotationExtension
22 | {
23 | public function new()
24 | {
25 | super();
26 | }
27 |
28 | /**
29 | * Transforms Haxe metadata input into valid Angular 2 annotation data.
30 | * @param input - Haxe metadata
31 | * @param annotations - annotations static field present in angular component
32 | * @param parameters - parameters static field present in angular component
33 | * @return Angular 2 component annotation constructor
34 | */
35 | @:keep
36 | public static function transform(input : Dynamic, annotations : Array, parameters : Array) : ComponentConstructorData
37 | {
38 | var output : ComponentConstructorData = AnnotationExtension.resolveInputAnnotation(input, ComponentConstructorData);
39 |
40 | // Transform appInjector to resolve to the
41 | // correct JavaScript classes.
42 | if (parameters != null && output.viewBindings != null)
43 | {
44 | AnnotationExtension.parseInjector(parameters, output.viewBindings);
45 | }
46 |
47 | if (parameters != null && output.bindings != null)
48 | {
49 | AnnotationExtension.parseInjector(parameters, output.bindings);
50 | }
51 |
52 | if (output.lifecycle != null)
53 | {
54 | AnnotationExtension.transformLifecycle(output.lifecycle);
55 | }
56 |
57 | return output;
58 | }
59 |
60 | @:keep
61 | public static function postCompileTransform(data : ComponentConstructorData)
62 | {
63 | if (data != null)
64 | {
65 | var bindings : Array> = [data.viewBindings, data.bindings];
66 |
67 | for (binding in bindings)
68 | {
69 | if (binding != null)
70 | {
71 | var index : Int = 0;
72 |
73 | for (element in binding)
74 | {
75 | if (Std.is(element, String))
76 | {
77 | binding[index] = AngularExtension.getAngularClass(element);
78 | }
79 |
80 | index++;
81 | }
82 | }
83 | }
84 | }
85 |
86 | if (data.lifecycle != null)
87 | {
88 | AnnotationExtension.transformLifecycle(data.lifecycle);
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/src/angular2haxe/DirectiveAnnotationExtension.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | import angular2haxe.ng.DirectiveConstructorData;
19 | import haxe.ds.StringMap;
20 | import haxe.Json;
21 | import haxe.macro.Expr;
22 |
23 | class DirectiveAnnotationExtension extends AnnotationExtension
24 | {
25 | public function new()
26 | {
27 | super();
28 | }
29 |
30 | /**
31 | * Transforms Haxe metadata input into valid Angular 2 annotation data.
32 | * @param input - Haxe metadata
33 | * @param annotations - annotations static field present in angular component
34 | * @param parameters - parameters static field present in angular component
35 | * @return Angular 2 directive annotation constructor
36 | */
37 | @:keep
38 | public static function transform(input : Dynamic, annotations : Array, parameters : Array) : DirectiveConstructorData
39 | {
40 | #if !macro
41 | // Update host events. Metadata objects with a string as their
42 | // key have '@$__hx__' prefixed to them, so it needs to be removed.
43 | if (input.host != null)
44 | {
45 | var outputHost : Dynamic = { };
46 | // Iterate through input.host and strip prefixed
47 | // tag from all variables that have it.
48 | for (field in Reflect.fields(input.host))
49 | {
50 | var index : Int = field.indexOf("@$__hx__");
51 |
52 | if (index > -1)
53 | {
54 | // Remove the prepended @$__hx__ and add
55 | // it to the new object.
56 | var key = field.substring(8);
57 | Reflect.setField(outputHost, key, Reflect.field(input.host, field));
58 | }
59 | }
60 |
61 | input.host = outputHost;
62 | }
63 | #end
64 |
65 | // Resolve final input.
66 | var output : DirectiveConstructorData = AnnotationExtension.resolveInputAnnotation(input, DirectiveConstructorData);
67 |
68 | if (parameters != null && output.bindings != null)
69 | {
70 | AnnotationExtension.parseInjector(parameters, output.bindings);
71 | }
72 |
73 | if (output.lifecycle != null)
74 | {
75 | AnnotationExtension.transformLifecycle(output.lifecycle);
76 | }
77 |
78 | return output;
79 | }
80 |
81 | @:keep
82 | public static function postCompileTransform(data : DirectiveConstructorData)
83 | {
84 | if (data != null)
85 | {
86 | if (data.bindings != null)
87 | {
88 | var index : Int = 0;
89 |
90 | for (element in data.bindings)
91 | {
92 | if (Std.is(element, String))
93 | {
94 | data.bindings[index] = AngularExtension.getAngularClass(element);
95 | }
96 |
97 | index++;
98 | }
99 | }
100 |
101 | if (data.lifecycle != null)
102 | {
103 | AnnotationExtension.transformLifecycle(data.lifecycle);
104 | }
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/src/angular2haxe/KeyboardEvent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | #if !macro
19 | import js.html.KeyboardEventInit;
20 |
21 | class KeyboardEvent extends js.html.KeyboardEvent
22 | {
23 | @:native("target")
24 | public var _target : Dynamic;
25 |
26 | public function new(typeArg:String, ?keyboardEventInitDict:KeyboardEventInit)
27 | {
28 | super(typeArg, keyboardEventInitDict);
29 | }
30 | }
31 | #else
32 | class KeyboardEvent
33 | {
34 |
35 | }
36 | #end
37 |
--------------------------------------------------------------------------------
/src/angular2haxe/LifecycleEventExtension.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | import angular2haxe.ng.LifecycleEvent;
19 |
20 | #if macro
21 | import haxe.macro.Context;
22 | #end
23 |
24 | class LifecycleEventExtension
25 | {
26 | private static var supportedLifecycleEvents : Map;
27 | private static var initialised : Bool = false;
28 |
29 | private function new() { }
30 |
31 | private static function init()
32 | {
33 | if (!initialised)
34 | {
35 | supportedLifecycleEvents = [
36 | "onChange" => LifecycleEvent.onChange,
37 | "onInit" => LifecycleEvent.onInit,
38 | "onCheck" => LifecycleEvent.onCheck,
39 | "onAllChangesDone" => LifecycleEvent.onAllChangesDone,
40 | "onDestroy" => LifecycleEvent.onDestroy
41 | ];
42 |
43 | initialised = true;
44 | }
45 | }
46 |
47 | /**
48 | * Convert string to an Angular Lifecycle object. If the
49 | * object does not exist, null is returned.
50 | * @param lifecycleEvent String representing an Angular Lifecycle event (i.e. onInit).
51 | * @return
52 | */
53 | public static function toAngular(lifecycleEvent : String) : Dynamic
54 | {
55 | #if !macro
56 | init();
57 |
58 | if (supportedLifecycleEvents.exists(lifecycleEvent))
59 | {
60 | return supportedLifecycleEvents[lifecycleEvent];
61 | }
62 | else
63 | {
64 | Trace.error('Angular does not have LifecycleEvent "${lifecycleEvent}"');
65 | return lifecycleEvent;
66 | }
67 | #else
68 | return lifecycleEvent;
69 | #end
70 | }
71 | }
--------------------------------------------------------------------------------
/src/angular2haxe/Trace.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | #if macro
19 | import haxe.macro.Context;
20 | #end
21 |
22 | /**
23 | * Debug Level:
24 | *
25 | * ALL: Show all log messages (trace, warning, error)
26 | * WARN: Show warning and error messages
27 | * ERROR: Show just error messages
28 | */
29 | class Trace
30 | {
31 | #if (debug_level=="WARN")
32 | private static var logLevel : String = "WARN";
33 | #elseif (debug_level == "ERROR")
34 | private static var logLevel : String = "ERROR";
35 | #else
36 | private static var logLevel : String = "ALL";
37 | #end
38 |
39 | private function new()
40 | {
41 | }
42 |
43 | /**
44 | * Feed string to console.error
45 | * @param info String to display as an error.
46 | */
47 | public static inline function error(info : String)
48 | {
49 | #if macro
50 | Context.error(info, Context.currentPos());
51 | #else
52 | untyped
53 | {
54 | console.error(info);
55 | }
56 | #end
57 | }
58 |
59 | public static inline function warning(info : String)
60 | {
61 | #if macro
62 | Context.warning(info, Context.currentPos());
63 | #else
64 | if (logLevel == "WARN" || logLevel == "ALL")
65 | {
66 | untyped
67 | {
68 | console.warn(info);
69 | }
70 | }
71 | #end
72 | }
73 |
74 | /**
75 | * Feed string to console.log
76 | * @param info String to display as a log message.
77 | */
78 | public static inline function log(info : String)
79 | {
80 | if (logLevel == "ALL")
81 | {
82 | trace(info);
83 | }
84 | }
85 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ViewAnnotationExtension.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 |
18 | import angular2haxe.ng.ViewConstructorData;
19 | import angular2haxe.AngularExtension;
20 | import angular2haxe.ng.ViewEncapsulation;
21 |
22 | #if macro
23 | import angular2haxe.buildplugin.BuildPlugin;
24 | #end
25 |
26 | class ViewAnnotationExtension extends AnnotationExtension
27 | {
28 | private function new()
29 | {
30 | super();
31 | }
32 |
33 | /**
34 | * Transforms Haxe metadata input into valid Angular 2 annotation data.
35 | * @param input - Haxe metadata
36 | * @param annotations - annotations static field present in angular component
37 | * @param parameters - parameters static field present in angular component
38 | * @return Angular 2 view annotation constructor
39 | */
40 | @:keep
41 | public static function transform(input : Dynamic, annotations : Array, parameters : Array) : ViewConstructorData
42 | {
43 | var output : ViewConstructorData = AnnotationExtension.resolveInputAnnotation(input, ViewConstructorData);
44 | var index : Int = 0;
45 |
46 | #if !macro
47 | output.encapsulation = ViewEncapsulationExtension.toAngular(output.encapsulation);
48 | #end
49 |
50 | // Transform directive names was field[0]
51 | if (output.directives != null)
52 | {
53 | for (directive in output.directives)
54 | {
55 | if (directive != null && directive.length > 0)
56 | {
57 | // Possible issue using eval here? The field has to exist using
58 | // valid field characters, so is there even a possibility that a
59 | // vulnerability exists?
60 | directive = StringTools.htmlEscape(directive);
61 |
62 | // extern classes won't resolve
63 | #if macro
64 | var resolvedClass;
65 | // Can't resolve angular classes at build-time (as they
66 | // are extenal), so they have to be converted at run-time.
67 | if (!AngularExtension.isAngularClass(directive))
68 | {
69 | resolvedClass = BuildPlugin.resolveClass(directive);
70 | }
71 | else
72 | {
73 | // Angular classes have to be resolved at run-time
74 | // due to them being external to the build.
75 | resolvedClass = directive;
76 | }
77 | #else
78 | var resolvedClass = Type.resolveClass(directive);
79 | #end
80 |
81 | if (resolvedClass != null)
82 | {
83 | output.directives[index] = resolvedClass;
84 | }
85 | else
86 | {
87 | var angularClass = AngularExtension.getAngularClass(directive);
88 |
89 | if (angularClass != null)
90 | {
91 | output.directives[index] = angularClass;
92 | }
93 | else
94 | {
95 | Trace.error('The definition for ${directive} does not exist!');
96 | }
97 | }
98 | }
99 |
100 | index++;
101 | }
102 | }
103 |
104 | return output;
105 | }
106 |
107 | @:keep
108 | public static function postCompileTransform(data : ViewConstructorData)
109 | {
110 | if (data != null)
111 | {
112 | if (data.directives != null)
113 | {
114 | var index : Int = 0;
115 |
116 | for (element in data.directives)
117 | {
118 | if (Std.is(element, String))
119 | {
120 | data.directives[index] = AngularExtension.getAngularClass(element);
121 | }
122 |
123 | index++;
124 | }
125 | }
126 |
127 | data.encapsulation = ViewEncapsulationExtension.toAngular(data.encapsulation);
128 | }
129 | }
130 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ViewEncapsulationExtension.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe;
17 | import angular2haxe.ng.ViewEncapsulation;
18 |
19 | class ViewEncapsulationExtension
20 | {
21 | private function new()
22 | {
23 |
24 | }
25 |
26 | public static function toAngular(name : String) : Int
27 | {
28 | return switch(name) {
29 | case "EMULATED" : ViewEncapsulation.EMULATED;
30 | case "NATIVE" : ViewEncapsulation.NATIVE;
31 | case "NONE" : ViewEncapsulation.NONE;
32 | default : ViewEncapsulation.NONE;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/src/angular2haxe/buildplugin/BuildPlugin.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.buildplugin;
17 |
18 | #if macro
19 | import haxe.macro.Compiler;
20 | import haxe.macro.Context;
21 | import haxe.macro.Expr;
22 | import haxe.macro.ExprTools;
23 | import haxe.macro.Type in MType;
24 | import haxe.macro.Type.ClassType;
25 | import haxe.macro.MacroStringTools;
26 | #end
27 |
28 | import angular2haxe.Application;
29 | import angular2haxe.Trace;
30 | import angular2haxe.AngularExtension;
31 |
32 | // Command line: -D using_registry
33 | #if using_registry
34 | /* Import a build registry. The registry
35 | * holds all imports that need to be resolved
36 | * at build-time.
37 | * If you don't have one, follow the link for a
38 | * reference implementation:
39 | *
40 | * https://github.com/nweedon/Angular2-Haxe/blob/master/src/BuildRegistry.hx
41 | */
42 | import BuildRegistry;
43 | #end
44 | /* --- */
45 |
46 | class BuildPlugin
47 | {
48 | private function new()
49 | {
50 |
51 | }
52 |
53 | #if macro
54 | private static var QUOTED_FIELD_PREFIX = "@$__hx__";
55 |
56 | /**
57 | * Resolve class by name at build time. Classes will resolve if
58 | * they are imported explicitly in this file.
59 | * @param name Fully-qualified name of the class to resolve (including package names).
60 | * @return Class representation of the name provided. If the class doesn't resolve, an error is thrown.
61 | */
62 | public static function resolveClass(name : String) : Class
63 | {
64 | var cl : Class;
65 |
66 | if (AngularExtension.isAngularClass(name))
67 | {
68 | name = AngularExtension.getFullyQualifiedName(name);
69 | }
70 |
71 | cl = Type.resolveClass(name);
72 |
73 | if (cl == null)
74 | {
75 | // Skip compiling Angular classes.
76 | if (!AngularExtension.isAngularClass(name))
77 | {
78 | Trace.error('${name} has not resolved to a class. Make sure it is imported in the BuildPlugin file.');
79 | }
80 | }
81 |
82 | return cl;
83 | }
84 |
85 | /**
86 | * Extract value from expression. Credit to nadako:
87 | * https://gist.github.com/nadako/9081608
88 | * @param e
89 | * @return
90 | */
91 | private static function extractValue(e : Expr) : Dynamic
92 | {
93 | switch (e.expr)
94 | {
95 | case EConst(c):
96 | switch (c)
97 | {
98 | case CInt(s):
99 | var i = Std.parseInt(s);
100 | return (i != null) ? i : Std.parseFloat(s); // if the number exceeds standard int return as float
101 | case CFloat(s):
102 | return Std.parseFloat(s);
103 | case CString(s):
104 | return s;
105 | case CIdent("null"):
106 | return null;
107 | case CIdent("true"):
108 | return true;
109 | case CIdent("false"):
110 | return false;
111 | case CIdent(s):
112 | return s;
113 | default:
114 | }
115 | case EBlock([]):
116 | return {};
117 | case EObjectDecl(fields):
118 | var object = {};
119 | for (field in fields)
120 | Reflect.setField(object, unquoteField(field.field), extractValue(field.expr));
121 | return object;
122 | case EArrayDecl(exprs):
123 | return [for (e in exprs) extractValue(e)];
124 | case EField(e, f):
125 | var pack = extractValue(e);
126 | return '${pack}.${f}';
127 | default:
128 | }
129 | throw new Error("Invalid JSON expression", e.pos);
130 | }
131 |
132 | /**
133 | * Strips "@$__hx__" from all object declarations.
134 | * see https://github.com/HaxeFoundation/haxe/issues/2642
135 | * @param name
136 | * @return
137 | */
138 | private static function unquoteField(name:String):String
139 | {
140 | return (name.indexOf(QUOTED_FIELD_PREFIX) == 0) ? name.substr(QUOTED_FIELD_PREFIX.length) : name;
141 | }
142 |
143 | /**
144 | * Compile the modules in modulesExpr by adding
145 | * '@:build' metadata to them, which in turn triggers
146 | * BuildPlugin.build(). This function also updates the
147 | * main method so that the components are bootstrapped
148 | * at run-time.
149 | * @param modulesExpr
150 | * @return
151 | */
152 | macro public static function app(modulesExpr : Expr) : Array
153 | {
154 | var modules : Array = extractValue(modulesExpr);
155 | var moduleClasses : Array> = [];
156 | var originalBlock : Array;
157 | var fields : Array = Context.getBuildFields();
158 | var mainFieldName : String = "main";
159 | var blockModified : Bool = false;
160 |
161 | for (module in modules)
162 | {
163 | Trace.log('Adding build metadata for ${module}');
164 | Compiler.addMetadata("@:build(angular2haxe.buildplugin.BuildPlugin.build())", module);
165 | Compiler.addMetadata("@:keep", module);
166 | moduleClasses.push(resolveClass(module));
167 | }
168 |
169 | var mainExists : Bool = Lambda.exists(fields, function(field : Field) : Bool
170 | {
171 | return field.name == mainFieldName;
172 | });
173 |
174 | if (mainExists)
175 | {
176 | // Remove the main function, it will be replaced with a new one.
177 | for (i in 0...fields.length)
178 | {
179 | if (fields[i].name == mainFieldName)
180 | {
181 | // Retrieve main function.
182 | var func : haxe.macro.Expr.Function = switch(fields[i].kind)
183 | {
184 | case FFun(f): f;
185 | default: null;
186 | };
187 |
188 | // Retrieve original code block. If an original
189 | // doesn't exist, create an empty block.
190 | originalBlock = switch(func.expr.expr)
191 | {
192 | case EBlock(b): b;
193 | default: [];
194 | }
195 |
196 | // If we don't have an empty block, search through it
197 | // for an application statement and update the array of
198 | // components to be bootstrapped.
199 | if (originalBlock.length > 0)
200 | {
201 | for (expr in originalBlock)
202 | {
203 | // Only search for ENew expressions, as an application is created
204 | // as such:
205 | // new angular2haxe.Application([ ... ]);
206 | // Retrieve the type and params used in the ENew expression.
207 | var appInitParams = switch(expr.expr)
208 | {
209 | case ENew(tp, params): { type: tp, params: params };
210 | default: null;
211 | }
212 |
213 | if (appInitParams != null)
214 | {
215 | // Search for ENew({ name => Application, pack => [], params => [] }, ... )
216 | // or pack == [angular2haxe]
217 | if (appInitParams.type.name == "Application" && (appInitParams.type.pack.length == 0 || appInitParams.type.pack == ["angular2haxe"]))
218 | {
219 | // Strip out the EArrayDecl values so the resulting
220 | // array can be added to.
221 | var arrayDecl = switch(appInitParams.params[0].expr)
222 | {
223 | case EArrayDecl(v): v;
224 | default: null;
225 | }
226 |
227 | if (arrayDecl != null)
228 | {
229 | // Add module classes to current declaration. As arrayDecl
230 | // etc. are references and not values, there is no need to
231 | // reconstruct the block.
232 | for (cl in moduleClasses)
233 | {
234 | arrayDecl.push(Context.makeExpr(cl, Context.currentPos()));
235 | }
236 |
237 | blockModified = true;
238 | }
239 | }
240 | }
241 | }
242 | }
243 |
244 | // If the original block was not modified, update the
245 | // current block which creates a new application.
246 | if (!blockModified)
247 | {
248 | // Remove original code block.
249 | fields.splice(i, 1);
250 |
251 | // Add the new main function, with the new call to
252 | // bootstrap all provided modules / classes.
253 | fields.push({
254 | name: mainFieldName,
255 | doc: null,
256 | meta: [],
257 | access: [AStatic, APublic],
258 | kind: FieldType.FFun({
259 | ret: macro : Void,
260 | params: [],
261 | expr: macro {
262 | $b{originalBlock};
263 | new angular2haxe.Application($v{moduleClasses});
264 | },
265 | args: []
266 | }),
267 | pos: Context.currentPos()
268 | });
269 | }
270 | }
271 | }
272 | }
273 |
274 | return fields;
275 | }
276 |
277 | /**
278 | * Compile data at build-time rather than run-time.
279 | * @return
280 | */
281 | macro public static function build() : Array
282 | {
283 | var attachedClass : ClassType = Context.getLocalClass().get();
284 | var attachedMetadata : Metadata = attachedClass.meta.get();
285 | var fields : Array = Context.getBuildFields();
286 |
287 | // Exit if already built.
288 | for (i in 0...fields.length)
289 | {
290 | if (fields[i].name == '__alreadyConstructed')
291 | {
292 | return null;
293 | }
294 | }
295 |
296 | // Use template strings to build final output code / macro
297 | var validAnnotations : Map> = [
298 | "Component" => ComponentAnnotationExtension,
299 | "Directive" => DirectiveAnnotationExtension,
300 | "View" => ViewAnnotationExtension
301 | ];
302 |
303 | // Set default values for annotations and parameters fields.
304 | var annotationData : Array = [];
305 | var annotationKeys : Array = [];
306 | var parameters : Array = [];
307 |
308 | Trace.log('=> Started compiling "${attachedClass.name}"');
309 |
310 | for (meta in attachedMetadata)
311 | {
312 | if (["Component", "Directive", "View"].indexOf(meta.name) > -1)
313 | {
314 | var data : Dynamic = { };
315 | var annotationName : String = meta.name;
316 |
317 | Trace.log('\t-> Parsing ${meta.name} annotation');
318 |
319 | for (param in meta.params)
320 | {
321 | var params : Array = param.expr.getParameters()[0];
322 | var i : Int = 0;
323 |
324 | // Cast all annotation values at build-time into values
325 | // we can work with.
326 | for (paramNames in params)
327 | {
328 | var e : Expr = params[i].expr;
329 | var fieldValue : Dynamic;
330 |
331 | // Extract value from expression.
332 | fieldValue = extractValue(e);
333 |
334 | Reflect.setField(data, paramNames.field, fieldValue);
335 | i++;
336 | }
337 | }
338 |
339 | Reflect.callMethod(validAnnotations[annotationName],
340 | Reflect.field(validAnnotations[annotationName], "transform"),
341 | [data, annotationData, parameters]);
342 |
343 | annotationData.push(data);
344 | annotationKeys.push(annotationName);
345 | // Clear annotation as it is not needed.
346 | attachedClass.meta.remove(annotationName);
347 | }
348 | }
349 |
350 | var keepMeta : MetadataEntry = {
351 | pos: Context.currentPos(),
352 | params: [],
353 | name: ':keep'
354 | };
355 |
356 | // Create annotations and parameters fields
357 | fields.push({
358 | name: 'annotations',
359 | doc: null,
360 | meta: [keepMeta],
361 | access: [AStatic, APublic],
362 | kind: FVar(macro : Array, macro [
363 | untyped __js__("{1} ? new ng.ComponentMetadata({0}) : null", $v{ annotationData[annotationKeys.indexOf("Component")] }, $v{ annotationKeys.indexOf("Component") > -1 }),
364 | untyped __js__("{1} ? new ng.ViewMetadata({0}) : null", $v{ annotationData[annotationKeys.indexOf("View")] }, $v{ annotationKeys.indexOf("View") > -1 } ),
365 | untyped __js__("{1} ? new ng.DirectiveMetadata({0}) : null", $v{ annotationData[annotationKeys.indexOf("Directive")] }, $v{ annotationKeys.indexOf("Directive") > -1 }),
366 | ]),
367 | pos: Context.currentPos()
368 | });
369 |
370 | fields.push({
371 | name: 'parameters',
372 | doc: null,
373 | meta: [keepMeta],
374 | access: [AStatic, APublic],
375 | kind: FVar(macro : Array, Context.makeExpr(parameters, Context.currentPos())),
376 | pos: Context.currentPos()
377 | });
378 |
379 | // Create field to note that the class has been
380 | // constructed at build-time.
381 | fields.push({
382 | name: '__alreadyConstructed',
383 | doc: null,
384 | meta: [keepMeta],
385 | access: [AStatic, APublic],
386 | kind: FVar(macro : Bool, macro true),
387 | pos: Context.currentPos()
388 | });
389 |
390 | Trace.log('=> Finished compiling "${attachedClass.name}"');
391 | return fields;
392 | }
393 | #end
394 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/Angular.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | /**
19 | * Haxe representation of Angular 2.0
20 | */
21 | @:native('ng')
22 | extern class Angular
23 | {
24 | function new();
25 |
26 | static function bootstrap(cl : Class) : Angular;
27 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/ComponentConstructorData.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | /**
19 | * Reference:
20 | * https://github.com/angular/angular/blob/master/modules/angular2/src/core/annotations_impl/annotations.ts
21 | *
22 | * Notes:
23 | * - 'exportAs' is included in the constructor, but according to the source (25 July 2015),
24 | * doesn't do anything yet.
25 | */
26 | @:keep
27 | class ComponentConstructorData
28 | {
29 | public var selector : String = null;
30 | public var properties : Array = [];
31 | public var events : Array = [];
32 | public var host : Map = new Map();
33 | public var lifecycle : Array = [];
34 | public var bindings : Array = [];
35 | public var exportAs : String = null;
36 | public var compileChildren : Bool = true;
37 | public var viewBindings : Array = [];
38 | public var changeDetection : String = "DEFAULT";
39 |
40 | public function new()
41 | {
42 | }
43 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/ComponentMetadata.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | import angular2haxe.ng.ComponentConstructorData;
19 | import angular2haxe.Annotation;
20 |
21 | @:native('ng.ComponentMetadata')
22 | extern class ComponentMetadata extends Annotation
23 | {
24 | function new(data : ComponentConstructorData);
25 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/DirectiveConstructorData.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 | import haxe.ds.StringMap;
18 |
19 | /**
20 | * Reference:
21 | * https://angular.io/docs/js/latest/api/annotations/DirectiveAnnotation-class.html
22 | * https://github.com/angular/angular/blob/master/modules/angular2/src/core/annotations_impl/annotations.ts
23 | */
24 | @:keep
25 | class DirectiveConstructorData
26 | {
27 | public var selector : String = null;
28 | public var properties : Array = [];
29 | public var events : Array = [];
30 | public var host : Dynamic = null;
31 | public var lifecycle : Array = [];
32 | public var bindings : Array = [];
33 | public var exportAs : String = null;
34 | public var compileChildren : Bool = true;
35 |
36 | public function new()
37 | {
38 | }
39 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/DirectiveMetadata.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 | import angular2haxe.Annotation;
18 |
19 | @:native('ng.DirectiveMetadata')
20 | extern class DirectiveMetadata extends Annotation
21 | {
22 | function new(data : DirectiveConstructorData);
23 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/EventEmitter.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | @:native('angular.EventEmitter')
19 | extern class EventEmitter
20 | {
21 | function new();
22 | public function next(event : Dynamic) : EventEmitter;
23 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/LifecycleEvent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | @:native('ng.LifecycleEvent')
19 | extern class LifecycleEvent
20 | {
21 | @:native('onChange')
22 | public static var onChange : Dynamic;
23 |
24 | @:native('onInit')
25 | public static var onInit : Dynamic;
26 |
27 | @:native('onCheck')
28 | public static var onCheck : Dynamic;
29 |
30 | @:native('onAllChangesDone')
31 | public static var onAllChangesDone : Dynamic;
32 |
33 | @:native('onDestroy')
34 | public static var onDestroy : Dynamic;
35 |
36 | private function new() { }
37 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/NgFor.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | @:native('ng.NgFor')
19 | extern class NgFor
20 | {
21 | // TODO: Original Constructor
22 | // viewContainer: ViewContainerRef, templateRef: TemplateRef, pipes: Pipes, cdr: ChangeDetectorRef
23 | public function new(viewContainer : Dynamic, templateRef : Dynamic, pipes : Dynamic, cdr : Dynamic)
24 | {
25 |
26 | }
27 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/NgIf.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | @:native('ng.NgIf')
19 | extern class NgIf
20 | {
21 | // TODO: Original Constructor
22 | // viewContainer: ViewContainerRef, templateRef: TemplateRef
23 | public function new(viewContainer : Dynamic, templateRef : Dynamic)
24 | {
25 |
26 | }
27 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/ViewConstructorData.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | /**
19 | * Reference:
20 | * https://angular.io/docs/js/latest/api/annotations/ViewAnnotation-class.html
21 | */
22 | @:keep
23 | class ViewConstructorData
24 | {
25 | public var templateUrl : String = null;
26 | public var template : String = null;
27 | public var directives : Array = [];
28 | public var encapsulation : Dynamic = null;
29 | public var styles : Array = [];
30 | public var styleUrls : Array = [];
31 |
32 | public function new()
33 | {
34 | }
35 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/ViewEncapsulation.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 |
18 | @:native('ng.ViewEncapsulation')
19 | extern class ViewEncapsulation
20 | {
21 | @:native('EMULATED')
22 | public static var EMULATED : Int;
23 | @:native('NATIVE')
24 | public static var NATIVE : Int;
25 | @:native('NONE')
26 | public static var NONE : Int;
27 |
28 | private function new() { }
29 | }
--------------------------------------------------------------------------------
/src/angular2haxe/ng/ViewMetadata.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package angular2haxe.ng;
17 | import angular2haxe.Annotation;
18 | import angular2haxe.ng.ViewConstructorData;
19 |
20 | @:native('ng.ViewMetadata')
21 | extern class ViewMetadata extends Annotation
22 | {
23 | function new(data : ViewConstructorData);
24 | }
--------------------------------------------------------------------------------
/src/test/ChildComponent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 |
18 | import angular2haxe.ng.Angular;
19 |
20 | /*
21 | * Reference:
22 | * https://angular.io/docs/js/latest/guide/making-components.html
23 | */
24 |
25 | @Component({
26 | selector: 'child'
27 | })
28 | @View({
29 | template: '
{{ message }}
'
30 | })
31 | @:expose
32 | @:keep
33 | class ChildComponent
34 | {
35 | private var message = "I am the child.";
36 |
37 | public function new()
38 | {
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/Dependency.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 |
18 | import angular2haxe.ng.Angular;
19 | import angular2haxe.ng.EventEmitter;
20 | import angular2haxe.Trace;
21 |
22 | /*
23 | * Reference:
24 | * https://angular.io/docs/js/latest/api/annotations/DirectiveAnnotation-class.html
25 | * http://victorsavkin.com/post/119943127151/angular-2-template-syntax
26 | *
27 | * Note: Events on Dependency and NgModelDirective classes are work-in-progress.
28 | */
29 |
30 | @Directive({
31 | selector: '[dependency]',
32 | properties: [
33 | "id: dependency"
34 | ],
35 | lifecycle: ["onInit"]
36 | })
37 | @:expose
38 | @:keep
39 | class Dependency
40 | {
41 | public var id : String;
42 |
43 | public function new()
44 | {
45 | }
46 |
47 | public function onInit()
48 | {
49 | Trace.log('Dependency.hx result:\n${this}');
50 | }
51 |
52 | public function onMouseEnter(event : Dynamic)
53 | {
54 | trace('onMouseEnter: ${id}');
55 | }
56 |
57 | public function onMouseLeave()
58 | {
59 | trace('onMouseLeave: ${id}');
60 | }
61 |
62 | public function onResize(event : Dynamic)
63 | {
64 | trace('resize ${event}');
65 | }
66 | }
67 |
68 | /**
69 | * Injecting dependency with hostInjector
70 | */
71 | @Directive({
72 | selector: '[my-directive]',
73 | lifecycle: ["onInit"],
74 | bindings: ["test.Dependency"]
75 | })
76 | @:expose
77 | @:keep
78 | class MyDirective
79 | {
80 | private var dependency : Dependency;
81 |
82 | public function new(?dependency : Dependency)
83 | {
84 | if (dependency != null)
85 | {
86 | this.dependency = dependency;
87 | }
88 | }
89 |
90 | public function onInit()
91 | {
92 | Trace.log('MyDirective Dependency:\n${dependency}');
93 | }
94 | }
95 |
96 | @Directive({
97 | selector: '[ng-model]',
98 | properties: ['ngModel']
99 | })
100 | @:expose
101 | @:keep
102 | class NgModelDirective
103 | {
104 | private var ngModel : String = "";
105 | private var ngModelChanged : EventEmitter = new EventEmitter();
106 |
107 | public function new()
108 | {
109 | }
110 |
111 | public function modelChanged(event : Dynamic)
112 | {
113 | Trace.log(event);
114 | ngModelChanged.next(event.target.value);
115 | }
116 | }
--------------------------------------------------------------------------------
/src/test/DependencyDisplayComponent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 |
18 | import angular2haxe.ng.Angular;
19 | import angular2haxe.ng.LifecycleEvent;
20 | import test.Dependency.MyDirective;
21 |
22 | /*
23 | * Reference:
24 | * https://angular.io/docs/js/latest/guide/displaying-data.html
25 | */
26 |
27 | @Component({
28 | selector: 'dependency-display',
29 | compileChildren: true
30 | })
31 | @View({
32 | directives: ["test.Dependency", "test.MyDirective", "test.NgModelDirective"],
33 | templateUrl: "templates/dependency.tpl.html"
34 | })
35 | @:expose
36 | @:keep
37 | class DependencyDisplayComponent
38 | {
39 | public function new()
40 | {
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/DisplayComponent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 |
18 | import angular2haxe.ng.Angular;
19 |
20 | /*
21 | * Reference:
22 | * https://angular.io/docs/js/latest/guide/displaying-data.html
23 | */
24 |
25 | @Component({
26 | selector: 'display',
27 | viewBindings: ["test.FriendsService"]
28 | })
29 | @View({
30 | directives: ["NgFor", "NgIf"],
31 | template: '
My name: {{ myName }}
Friends:
{{ name }}
3">You have many friends!
'
32 | })
33 | @:keep
34 | @:expose
35 | class DisplayComponent
36 | {
37 | private var myName : String;
38 | private var names : Array;
39 |
40 | public function new(?friends : FriendsService)
41 | {
42 | myName = "Alice";
43 |
44 | if (friends != null)
45 | {
46 | names = friends.names;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/test/FriendsService.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 |
18 | @:expose
19 | class FriendsService
20 | {
21 | public var names : Array;
22 |
23 | @:keep
24 | public function new()
25 | {
26 | names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];
27 | }
28 | }
--------------------------------------------------------------------------------
/src/test/HelloWorld.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 |
18 | import angular2haxe.buildplugin.BuildPlugin;
19 |
20 | /**
21 | * Reference(s):
22 | * https://angular.io/docs/js/latest/api/annotations/DirectiveAnnotation-class.html
23 | *
24 | * Uses:
25 | * Directive => hostInjector
26 | * Component => hostInjector
27 | */
28 |
29 | @:expose
30 | @:keep
31 | class Greeter
32 | {
33 | public function new() { }
34 | public function greet(name : String)
35 | {
36 | return 'Hello ${name}!';
37 | }
38 | }
39 |
40 | @Directive({
41 | selector: 'needs-greeter',
42 | bindings: [
43 | "test.Greeter"
44 | ]
45 | })
46 | @:expose
47 | @:keep
48 | class NeedsGreeter
49 | {
50 | private var greeter : Greeter;
51 |
52 | public function new(greeter : Greeter)
53 | {
54 | this.greeter = greeter;
55 | }
56 | }
57 |
58 | @Component({
59 | selector: 'greet',
60 | viewBindings: [
61 | "test.Greeter"
62 | ],
63 | exportAs: 'componentGreet'
64 | })
65 | @View({
66 | template: "{{ greeter.greet('World') }}",
67 | directives: ["test.NeedsGreeter"],
68 | encapsulation: "NONE"
69 | })
70 | @:expose
71 | @:keep
72 | class HelloWorld
73 | {
74 | private var greeter : Greeter;
75 |
76 | public function new(greeter : Greeter)
77 | {
78 | this.greeter = greeter;
79 | }
80 | }
--------------------------------------------------------------------------------
/src/test/InputDirective.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 | import angular2haxe.KeyboardEvent;
18 |
19 | @Directive({
20 | selector: 'input',
21 | lifecycle: ["onInit", "onChange", "onAllChangesDone", "onCheck"],
22 | host: {
23 | '(keyup)' : 'onKeyUp($event)'
24 | },
25 | exportAs: 'input-directive'
26 | })
27 | @:expose
28 | @:keep
29 | class InputDirective
30 | {
31 | public function new()
32 | {
33 |
34 | }
35 |
36 | #if !macro
37 | public function onInit()
38 | {
39 | trace('InputDirective.onInit: ${this}');
40 | }
41 |
42 | public function onChange()
43 | {
44 |
45 | }
46 |
47 | public function onAllChangesDone()
48 | {
49 |
50 | }
51 |
52 | public function onCheck()
53 | {
54 |
55 | }
56 |
57 | public function onKeyUp(event : KeyboardEvent)
58 | {
59 | trace('You just pressed a key with key code: ${event.keyCode}!');
60 | }
61 | #end
62 | }
--------------------------------------------------------------------------------
/src/test/ParentComponent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 |
18 | import angular2haxe.ng.Angular;
19 |
20 | /*
21 | * Reference:
22 | * https://angular.io/docs/js/latest/guide/making-components.html
23 | */
24 |
25 | @Component({
26 | selector: 'parent'
27 | })
28 | @View({
29 | directives: ["test.ChildComponent"],
30 | template: '
{{ message }}
'
31 | })
32 | @:keep
33 | class ParentComponent
34 | {
35 | private var message = "I am the parent.";
36 |
37 | public function new()
38 | {
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/TodoList.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package test;
17 |
18 | import angular2haxe.KeyboardEvent;
19 | import angular2haxe.Trace;
20 | import test.InputDirective;
21 |
22 | /*
23 | * Reference:
24 | * https://angular.io/docs/js/latest/guide/user-input.html
25 | */
26 |
27 | @Component({
28 | selector: 'todo-list',
29 | properties: ["lastValue", "todos"],
30 | lifecycle: ["onInit", "onChange", "onAllChangesDone", "onCheck"],
31 | changeDetection: "CHECK_ALWAYS"
32 | })
33 | @View({
34 | directives: ["NgFor", "NgIf", "test.InputDirective"],
35 | template: 'Last value: {{lastValue}}
{{ todo }}
',
36 | })
37 | @:expose
38 | @:keep
39 | class TodoList
40 | {
41 | private var todos : Array;
42 | public var lastValue : String = "";
43 |
44 | public function new()
45 | {
46 | todos = ["Eat Breakfast", "Walk Dog", "Breathe"];
47 | lastValue = todos[todos.length - 1];
48 | }
49 | #if !macro
50 | public function doneTyping(event : KeyboardEvent)
51 | {
52 | if (event.which == 13)
53 | {
54 | addTodo(event._target.value);
55 | event._target.value = "";
56 | }
57 | }
58 | #end
59 | public function addTodo(todo : String)
60 | {
61 | lastValue = todo;
62 | todos.push(todo);
63 | }
64 |
65 | public function onInit()
66 | {
67 | Trace.log('Lifecycle onInit:\n${this}');
68 | }
69 |
70 | public function onCheck()
71 | {
72 | Trace.log('Lifecycle onCheck');
73 | }
74 |
75 | public function onChange(changes : Dynamic)
76 | {
77 | Trace.log('Lifecycle onChange: ${changes}');
78 | }
79 |
80 | public function onAllChangesDone()
81 | {
82 | Trace.log('Lifecycle onAllChangesDone');
83 | }
84 | }
--------------------------------------------------------------------------------
/src/testcompile/ChildComponent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.ng.Angular;
19 |
20 | /*
21 | * Reference:
22 | * https://angular.io/docs/js/latest/guide/making-components.html
23 | */
24 |
25 | @Component({
26 | selector: 'c-child'
27 | })
28 | @View({
29 | template: '
{{ message }}
'
30 | })
31 | @:expose
32 | class ChildComponent
33 | {
34 | private var message = "I am the child.";
35 |
36 | public function new()
37 | {
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/testcompile/Dependency.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.ng.Angular;
19 | import angular2haxe.ng.EventEmitter;
20 | import angular2haxe.Trace;
21 |
22 | /*
23 | * Reference:
24 | * https://angular.io/docs/js/latest/api/annotations/DirectiveAnnotation-class.html
25 | * http://victorsavkin.com/post/119943127151/angular-2-template-syntax
26 | *
27 | * Note: Events on Dependency and NgModelDirective classes are work-in-progress.
28 | */
29 |
30 | @Directive({
31 | selector: '[c-dependency]',
32 | properties: [
33 | "id: c-dependency"
34 | ],
35 | lifecycle: ["onInit"]
36 | })
37 | @:expose
38 | class Dependency
39 | {
40 | public var id : String;
41 |
42 | public function new()
43 | {
44 | }
45 |
46 | public function onInit()
47 | {
48 | Trace.log('Dependency.hx result:\n${this}');
49 | }
50 |
51 | public function onMouseEnter(event : Dynamic)
52 | {
53 | trace('onMouseEnter: ${id}');
54 | }
55 |
56 | public function onMouseLeave()
57 | {
58 | trace('onMouseLeave: ${id}');
59 | }
60 |
61 | public function onResize(event : Dynamic)
62 | {
63 | trace('resize ${event}');
64 | }
65 | }
--------------------------------------------------------------------------------
/src/testcompile/DependencyDisplayComponent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.ng.Angular;
19 | import angular2haxe.ng.LifecycleEvent;
20 | import test.Dependency.MyDirective;
21 |
22 | /*
23 | * Reference:
24 | * https://angular.io/docs/js/latest/guide/displaying-data.html
25 | */
26 |
27 | @Component({
28 | selector: 'c-dependency-display',
29 | compileChildren: true
30 | })
31 | @View({
32 | directives: ["testcompile.Dependency", "testcompile.MyDirective", "testcompile.NgModelDirective"],
33 | templateUrl: "templates/dependency.tpl.html"
34 | })
35 | @:expose
36 | class DependencyDisplayComponent
37 | {
38 | public function new()
39 | {
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/testcompile/DisplayComponent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.ng.Angular;
19 |
20 | /*
21 | * Reference:
22 | * https://angular.io/docs/js/latest/guide/displaying-data.html
23 | */
24 |
25 | @Component({
26 | selector: 'c-display',
27 | viewBindings: ["testcompile.FriendsService"]
28 | })
29 | @View({
30 | directives: ["NgFor", "NgIf"],
31 | template: '
My name: {{ myName }}
Friends:
{{ name }}
3">You have many friends!
'
32 | })
33 | @:expose
34 | class DisplayComponent
35 | {
36 | private var myName : String;
37 | private var names : Array;
38 |
39 | public function new(?friends : FriendsService)
40 | {
41 | myName = "Alice";
42 |
43 | if (friends != null)
44 | {
45 | names = friends.names;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/testcompile/FriendsService.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | @:expose
19 | class FriendsService
20 | {
21 | public var names : Array;
22 |
23 | @:keep
24 | public function new()
25 | {
26 | names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];
27 | }
28 | }
--------------------------------------------------------------------------------
/src/testcompile/Greeter.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | @:expose
19 | class Greeter
20 | {
21 | public function new() { }
22 | public function greet(name : String)
23 | {
24 | return 'Hello ${name}!';
25 | }
26 | }
--------------------------------------------------------------------------------
/src/testcompile/HelloWorld.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.buildplugin.BuildPlugin;
19 |
20 | /**
21 | * Reference(s):
22 | * https://angular.io/docs/js/latest/api/annotations/DirectiveAnnotation-class.html
23 | *
24 | * Uses:
25 | * Directive => hostInjector
26 | * Component => hostInjector
27 | */
28 |
29 | @Component({
30 | selector: 'c-greet',
31 | viewBindings: [
32 | "testcompile.Greeter"
33 | ],
34 | exportAs: 'componentGreet'
35 | })
36 | @View({
37 | template: "{{ greeter.greet('World') }}",
38 | directives: ["testcompile.NeedsGreeter"],
39 | encapsulation: "NONE"
40 | })
41 | @:expose
42 | class HelloWorld
43 | {
44 | private var greeter : Greeter;
45 |
46 | public function new(greeter : Greeter)
47 | {
48 | this.greeter = greeter;
49 | }
50 | }
--------------------------------------------------------------------------------
/src/testcompile/InputDirective.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.KeyboardEvent;
19 |
20 | @Directive({
21 | selector: 'input',
22 | lifecycle: ["onInit", "onChange", "onAllChangesDone", "onCheck"],
23 | host: {
24 | '(keyup)' : 'onKeyUp($event)'
25 | },
26 | exportAs: 'input-directive'
27 | })
28 | @:expose
29 | class InputDirective
30 | {
31 | public function new()
32 | {
33 |
34 | }
35 |
36 | #if !macro
37 | public function onInit()
38 | {
39 | trace('InputDirective.onInit: ${this}');
40 | }
41 |
42 | public function onChange()
43 | {
44 |
45 | }
46 |
47 | public function onAllChangesDone()
48 | {
49 |
50 | }
51 |
52 | public function onCheck()
53 | {
54 |
55 | }
56 |
57 | public function onKeyUp(event : KeyboardEvent)
58 | {
59 | trace('You just pressed a key with key code: ${event.keyCode}!');
60 | }
61 | #end
62 | }
--------------------------------------------------------------------------------
/src/testcompile/MyDirective.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.Trace;
19 |
20 | @Directive({
21 | selector: '[my-directive]',
22 | lifecycle: ["onInit"],
23 | bindings: ["testcompile.Dependency"]
24 | })
25 | @:expose
26 | class MyDirective
27 | {
28 | private var dependency : Dependency;
29 |
30 | public function new(?dependency : Dependency)
31 | {
32 | if (dependency != null)
33 | {
34 | this.dependency = dependency;
35 | }
36 | }
37 |
38 | public function onInit()
39 | {
40 | Trace.log('MyDirective Dependency:\n${dependency}');
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/testcompile/NeedsGreeter.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | @Directive({
19 | selector: 'c-needs-greeter',
20 | bindings: [
21 | "testcompile.Greeter"
22 | ]
23 | })
24 | @:expose
25 | class NeedsGreeter
26 | {
27 | private var greeter : Greeter;
28 |
29 | public function new(greeter : Greeter)
30 | {
31 | this.greeter = greeter;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/testcompile/NgModelDirective.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.ng.EventEmitter;
19 | import angular2haxe.Trace;
20 |
21 | @Directive({
22 | selector: '[ng-model]',
23 | properties: ['ngModel']
24 | })
25 | @:expose
26 | class NgModelDirective
27 | {
28 | private var ngModel : String = "";
29 | private var ngModelChanged : EventEmitter = new EventEmitter();
30 |
31 | public function new()
32 | {
33 | }
34 |
35 | public function modelChanged(event : Dynamic)
36 | {
37 | Trace.log(event);
38 | ngModelChanged.next(event.target.value);
39 | }
40 | }
--------------------------------------------------------------------------------
/src/testcompile/ParentComponent.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.ng.Angular;
19 |
20 | /*
21 | * Reference:
22 | * https://angular.io/docs/js/latest/guide/making-components.html
23 | */
24 |
25 | @Component({
26 | selector: 'c-parent'
27 | })
28 | @View({
29 | directives: ["testcompile.ChildComponent"],
30 | template: '
{{ message }}
'
31 | })
32 | class ParentComponent
33 | {
34 | private var message = "I am the parent.";
35 |
36 | public function new()
37 | {
38 |
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/testcompile/TodoList.hx:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2015 Niall Frederick Weedon
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 | */
16 | package testcompile;
17 |
18 | import angular2haxe.KeyboardEvent;
19 | import angular2haxe.Trace;
20 | import test.InputDirective;
21 |
22 | /*
23 | * Reference:
24 | * https://angular.io/docs/js/latest/guide/user-input.html
25 | */
26 |
27 | @Component({
28 | selector: 'c-todo-list',
29 | properties: ["lastValue", "todos"],
30 | lifecycle: ["onInit", "onChange", "onAllChangesDone", "onCheck"],
31 | changeDetection: "CHECK_ALWAYS"
32 | })
33 | @View({
34 | directives: ["NgFor", "NgIf", "testcompile.InputDirective"],
35 | template: 'Last value: {{lastValue}}
{{ todo }}
',
36 | })
37 | @:expose
38 | class TodoList
39 | {
40 | private var todos : Array;
41 | public var lastValue : String = "";
42 |
43 | public function new()
44 | {
45 | todos = ["Eat Breakfast", "Walk Dog", "Breathe"];
46 | lastValue = todos[todos.length - 1];
47 | }
48 |
49 | #if !macro
50 | public function doneTyping(event : KeyboardEvent)
51 | {
52 | if (event.which == 13)
53 | {
54 | addTodo(event._target.value);
55 | event._target.value = "";
56 | }
57 | }
58 | #end
59 |
60 | public function addTodo(todo : String)
61 | {
62 | lastValue = todo;
63 | todos.push(todo);
64 | }
65 |
66 | public function onInit()
67 | {
68 | Trace.log('Lifecycle onInit:\n${this}');
69 | }
70 |
71 | public function onCheck()
72 | {
73 | Trace.log('Lifecycle onCheck');
74 | }
75 |
76 | public function onChange(changes : Dynamic)
77 | {
78 | Trace.log('Lifecycle onChange: ${changes}');
79 | }
80 |
81 | public function onAllChangesDone()
82 | {
83 | Trace.log('Lifecycle onAllChangesDone');
84 | }
85 | }
--------------------------------------------------------------------------------