├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── src
└── index.js
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 |
29 | # Optional npm cache directory
30 | .npm
31 |
32 | # Optional REPL history
33 | .node_repl_history
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Kyle J. Kemp
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ng2-ace
2 | A basic ace editor directive for angular 2.
3 |
4 | # Install
5 | `npm i -s ng2-ace`
6 |
7 | # Sample Usage
8 |
9 | ```js
10 | import { Component } from 'angular2/core';
11 |
12 | import { AceEditorDirective } from 'ng2-ace';
13 |
14 | import 'brace/theme/clouds';
15 | import 'brace/mode/sql';
16 |
17 | @Component({
18 | directives: [AceEditorDirective],
19 | template: `
20 |
28 | `
29 | })
30 | export class MyComponent {
31 | constructor() {
32 | this.text = 'test';
33 | this.options = { printMargin: false };
34 | this.onChange = (data) => {
35 | console.log(data);
36 | }
37 | }
38 | }
39 | ```
40 | Important pieces to note in the HTML template: `[ace-editor]` attribute, `[text]`, `[theme]`, `[mode]`, `[readOnly]`, `[options]` inputs, `(textChanged)` output. As per Ace, you must also make it a `display: block;` and give it a width and height.
41 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ng2-ace",
3 | "version": "0.0.15",
4 | "description": "An ace editor directive for angular2.",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/seiyria/ng2-ace.git"
12 | },
13 | "keywords": [
14 | "ng2",
15 | "angular2",
16 | "ace",
17 | "ace",
18 | "editor",
19 | "ng2-ace",
20 | "angular2-ace"
21 | ],
22 | "author": "Kyle Kemp ",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/seiyria/ng2-ace/issues"
26 | },
27 | "scripts": {
28 | "compile": "babel src/index.js -o index.js --plugins transform-decorators-legacy,transform-class-properties --presets es2015"
29 | },
30 | "homepage": "https://github.com/seiyria/ng2-ace#readme",
31 | "dependencies": {
32 | "brace": "^0.8.0"
33 | },
34 | "peerDependencies": {
35 | "@angular/core": "^2.0.0-rc.4"
36 | },
37 | "devDependencies": {
38 | "babel-plugin-transform-class-properties": "^6.9.0",
39 | "babel-plugin-transform-decorators-legacy": "^1.3.4",
40 | "babel-preset-es2015": "^6.9.0"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 |
2 | import { Directive, ElementRef, EventEmitter } from '@angular/core';
3 | import ace from 'brace';
4 |
5 | @Directive({
6 | selector: '[ace-editor]',
7 | inputs: ['text', 'mode', 'theme', 'readOnly', 'options'],
8 | outputs: ['textChanged', 'editorRef']
9 | })
10 | export class AceEditorDirective {
11 | static get parameters() {
12 | return [[ElementRef]];
13 | }
14 |
15 | set options(value) {
16 | this.editor.setOptions(value || {});
17 | }
18 |
19 | set readOnly(value) {
20 | this._readOnly = value;
21 | this.editor.setReadOnly(value);
22 | }
23 |
24 | set theme(value) {
25 | this._theme = value;
26 | this.editor.setTheme(`ace/theme/${value}`);
27 | }
28 |
29 | set mode(value) {
30 | this._mode = value;
31 | this.editor.getSession().setMode(`ace/mode/${value}`);
32 | }
33 |
34 | set text(value) {
35 | if(value === this.oldVal) return;
36 | this.editor.setValue(value);
37 | this.editor.clearSelection();
38 | this.editor.focus();
39 | }
40 |
41 | constructor(elementRef) {
42 | this.textChanged = new EventEmitter();
43 | this.editorRef = new EventEmitter();
44 |
45 | const el = elementRef.nativeElement;
46 | el.classList.add('editor');
47 |
48 | this.editor = ace.edit(el);
49 |
50 | setTimeout(() => {
51 | this.editorRef.next(this.editor);
52 | });
53 |
54 | this.editor.on('change', () => {
55 | const newVal = this.editor.getValue();
56 | if(newVal === this.oldVal) return;
57 | if(typeof this.oldVal !== 'undefined') {
58 | this.textChanged.next(newVal);
59 | }
60 | this.oldVal = newVal;
61 | });
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.AceEditorDirective = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _dec, _class;
11 |
12 | var _core = require('@angular/core');
13 |
14 | var _brace = require('brace');
15 |
16 | var _brace2 = _interopRequireDefault(_brace);
17 |
18 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19 |
20 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21 |
22 | var AceEditorDirective = exports.AceEditorDirective = (_dec = (0, _core.Directive)({
23 | selector: '[ace-editor]',
24 | inputs: ['text', 'mode', 'theme', 'readOnly', 'options'],
25 | outputs: ['textChanged', 'editorRef']
26 | }), _dec(_class = function () {
27 | _createClass(AceEditorDirective, [{
28 | key: 'options',
29 | set: function set(value) {
30 | this.editor.setOptions(value || {});
31 | }
32 | }, {
33 | key: 'readOnly',
34 | set: function set(value) {
35 | this._readOnly = value;
36 | this.editor.setReadOnly(value);
37 | }
38 | }, {
39 | key: 'theme',
40 | set: function set(value) {
41 | this._theme = value;
42 | this.editor.setTheme('ace/theme/' + value);
43 | }
44 | }, {
45 | key: 'mode',
46 | set: function set(value) {
47 | this._mode = value;
48 | this.editor.getSession().setMode('ace/mode/' + value);
49 | }
50 | }, {
51 | key: 'text',
52 | set: function set(value) {
53 | if (value === this.oldVal) return;
54 | this.editor.setValue(value);
55 | this.editor.clearSelection();
56 | this.editor.focus();
57 | }
58 | }], [{
59 | key: 'parameters',
60 | get: function get() {
61 | return [[_core.ElementRef]];
62 | }
63 | }]);
64 |
65 | function AceEditorDirective(elementRef) {
66 | var _this = this;
67 |
68 | _classCallCheck(this, AceEditorDirective);
69 |
70 | this.textChanged = new _core.EventEmitter();
71 | this.editorRef = new _core.EventEmitter();
72 |
73 | var el = elementRef.nativeElement;
74 | el.classList.add('editor');
75 |
76 | this.editor = _brace2.default.edit(el);
77 |
78 | setTimeout(function () {
79 | _this.editorRef.next(_this.editor);
80 | });
81 |
82 | this.editor.on('change', function () {
83 | var newVal = _this.editor.getValue();
84 | if (newVal === _this.oldVal) return;
85 | if (typeof _this.oldVal !== 'undefined') {
86 | _this.textChanged.next(newVal);
87 | }
88 | _this.oldVal = newVal;
89 | });
90 | }
91 |
92 | return AceEditorDirective;
93 | }()) || _class);
94 |
--------------------------------------------------------------------------------