I think the reason this is so complicated is because there is no typed library there. I was able to get an approximate equivalent of this work by adding a few things. My version has a rather old configuration, but you can improve it.
system-config needs this:
const map:any = { 'brace': 'vendor/brace', 'w3c-blob': 'vendor/w3c-blob', 'buffer': 'vendor/buffer-shims' };
may also be required:
const packages:any = { 'w3c-blob': { format: 'cjs', defaultExtension: 'js', main: 'index.js' }, 'brace': { format: 'cjs', defaultExtension: 'js', main: 'index.js' }, 'buffer': { format: 'cjs', defaultExtension: 'js', main: 'index.js' } };
Then you also need to add these things as npm dependencies in angular-cli-build.js:
module.exports = function(defaults) { return new Angular2App(defaults, { vendorNpmFiles: [ 'brace/**/*.js', 'w3c-blob/index.js', 'buffer-shims/index.js' ] });
To a large extent, you get everything you need, depending on the dependencies. At the moment, I have added my own directive. The important parts are here:
import { Directive, ElementRef, EventEmitter } from '@angular/core';
Now import the brackets and all the modes and themes that you will use:
import 'brace'; declare let ace; import 'vendor/brace/mode/javascript'; import 'vendor/brace/theme/monokai';
"declare let ace" allows you to access brackets even if there are no typings, and this is not a true typescript module.
I called my js-editor directive, and you attach it to a tag of the appropriate height and width. Documents for brackets are said to apply the "block" style to a div. Then declare the directive:
@Directive({ selector: '[js-editor]', inputs: ['text'], outputs: ['textChanged', 'editorRef'] }) export class JsEditor { editor : any; textChanged : EventEmitter<any>; editorRef : EventEmitter<any>; value : string; set text(value) { // if(value === this.oldVal) return; // this.editor.setValue(value); // this.editor.clearSelection(); this.editor.focus(); } constructor(elementRef : ElementRef) { this.textChanged = new EventEmitter(); this.editorRef = new EventEmitter(); const el = elementRef.nativeElement; el.classList.add('editor');
Setting the base path is a key element in finding modes and themes. This is really the wrong place to install it - it needs to be done globally, and ONLY ONCE ... but it was just an experiment to see if it would work, so I did it here:
ace.config.set('basePath', 'vendor/brace');
Finally, create an editor:
this.editor = ace.edit(el);
and then set your mode and theme. Note that these LOOK modes / themes are similar along the way, but in reality this is not the case. The ace (or maybe Brace) will use these lines to generate the path using basePath above:
this.editor.getSession().setMode('ace/mode/javascript'); this.editor.setTheme('ace/theme/monokai'); setTimeout(() => { this.editorRef.next(this.editor); }); this.editor.on('change', () => { }); } }
This is a general idea. It really needs to be wrapped in a nice custom directive along the ng2-ace lines, but I'm not the guy who did it, I just wanted you to head in the right direction.
- Chris