Dart DocumentationiceEditor

Editor class

class Editor {
 bool edit_only, autoupdate, enable_javascript_mode;
 String title;

 var _el;
 Element __el, __editor_el, __preview_el;

 var _ace;
 Completer _waitForAce, _waitForPreview;

 Editor(this._el, {this.edit_only:false, this.autoupdate:true, this.title, this.enable_javascript_mode:true}) {
   this._startAce();
   this._applyStyles();
 }

 set content(String data) {
   if (!_waitForAce.isCompleted) {
     editorReady.then((_) => this.content = data);
     return;
   }

   var original_autoupdate = autoupdate;
   autoupdate = false;
   _ace.value = data;
   _ace.focus();
   updatePreview();
   autoupdate = original_autoupdate;
 }

 Timer _update_timer;
 void delayedUpdatePreview() {
   if (!this.autoupdate) return;
   if (_update_timer != null) _update_timer.cancel();

   var wait = new Duration(seconds: 2);
   _update_timer = new Timer(wait, (){
     this.updatePreview();
     _update_timer = null;
   });
 }

 void _extendDelayedUpdatePreview() {
   if (_update_timer == null) return;
   delayedUpdatePreview();
 }

 // worry about waitForAce?
 String get content => _ace.value;
 Future get editorReady => _waitForAce.future;

 /// Update the preview layer with the current contents of the editor
 /// layer.
 // worry about waitForAce?
 updatePreview() {
   if (this.edit_only) return;

   this.removePreview();
   var iframe = this.createPreviewIframe();

   var wait = new Duration(milliseconds: 900);
   new Timer(wait, (){
     if (iframe.contentWindow == null) return;
     iframe.contentWindow.postMessage(_ace.value, window.location.href);
   });
 }

 removePreview() {
   while (this._preview_el.children.length > 0) {
     	  this._preview_el.children.first.remove();
   }
 }

 createPreviewIframe() {
   var iframe = new IFrameElement();
   iframe
     ..width = "${this._preview_el.clientWidth}"
     ..height = "${this._preview_el.clientHeight}"
     ..style.border = '0'
     ..src = 'packages/ice_code_editor/html/preview_frame.html';

   this._preview_el.children.add( iframe );

   return iframe;
 }


 /// Show the code layer, calling the ACE resize methods to ensure that
 /// the display is correct.
 // worry about waitForAce?
 showCode() {
   _editor_el.style.display = '';
   _ace.renderer.onResize();
   _ace.focus();
 }

 /// Hide the code layer
 hideCode() {
   _editor_el.style.display = 'none';
   if (this.edit_only) return;

   _preview_el.children[0].focus();
 }

 Element get el {
   if (__el != null) return __el;

   if (this._el.runtimeType == Element) {
     __el = _el;
   }
   else {
     __el = document.query(_el);
   }
   return __el;
 }

 Element get _editor_el {
   if (__editor_el != null) return __editor_el;

   __editor_el = new DivElement()
     ..classes.add('ice-code-editor-editor');
   this.el.children.add(__editor_el);
   return __editor_el;
 }

 Element get _preview_el {
   if (__preview_el != null) return __preview_el;

   __preview_el = new DivElement()
     ..classes.add('ice-code-editor-preview');

   if (!this.edit_only) {
     this.el.children.add(__preview_el);
   }

   return __preview_el;
 }

 static List _scripts;
 static get _isAceJsAttached => (_scripts != null);
 static _attachScripts() {
   if (_scripts != null) return;

   var script_paths = [
     "packages/ice_code_editor/js/ace/ace.js",
     "packages/ice_code_editor/js/ace/keybinding-emacs.js",
     "packages/ice_code_editor/js/deflate/rawdeflate.js",
     "packages/ice_code_editor/js/deflate/rawinflate.js"
   ];

   var scripts = script_paths.
     map((path) {
       var script = new ScriptElement()
         ..async = false
         ..src = path;
       document.head.nodes.add(script);
       return script;
     }).
     toList();

   return _scripts = scripts;
 }

 _startAce() {
   this._waitForAce = new Completer();

   if (_isAceJsAttached) {
     _startJsAce();
   }
   else {
     var scripts = _attachScripts();
     scripts.first.onLoad.listen((_)=> _startJsAce());
   }

   _attachKeyHandlersForAce();
 }

 _startJsAce() {
   js.context.ace.config.set("workerPath", "packages/ice_code_editor/js/ace");

   _ace = Ace.edit(_editor_el);
   js.retain(_ace);

   _ace
     ..theme = "ace/theme/chrome"
     ..fontSize = '18px'
     ..printMarginColumn = false
     ..displayIndentGuides = false;

   if (enable_javascript_mode) {
     _ace.session
       ..mode = "ace/mode/javascript"
       ..useWrapMode = true
       ..useSoftTabs = true
       ..tabSize = 2;
   }

   _ace.session.onChange.listen((e)=> this.delayedUpdatePreview());

   _waitForAce.complete();
 }

 _attachKeyHandlersForAce() {
   // Using keyup b/c ACE swallows keydown events
   document.onKeyUp.listen((e) {
     // only handling arrow keys
     if (e.keyCode < 37) return;
     if (e.keyCode > 40) return;
     _extendDelayedUpdatePreview();
   });

   document.onKeyPress.listen((event) {
     if (event.keyCode == 9829) {
       event.preventDefault();
       _ace.toggleEmacs();
     }
   });
 }

 _applyStyles() {
   var style = new LinkElement()
     ..type = "text/css"
     ..rel = "stylesheet"
     ..href = "packages/ice_code_editor/css/ice.css";
   document.head.nodes.add(style);

   this.el.style
     ..position = 'relative';

   this._editor_el.style
     ..position = 'absolute'
     ..zIndex = '20';

   this._preview_el.style
     ..position = 'absolute'
     ..zIndex = '10';
 }
}

Constructors

new Editor(_el, {bool edit_only: false, bool autoupdate: true, String title, bool enable_javascript_mode: true}) #

Editor(this._el, {this.edit_only:false, this.autoupdate:true, this.title, this.enable_javascript_mode:true}) {
 this._startAce();
 this._applyStyles();
}

Properties

bool autoupdate #

bool edit_only, autoupdate

String content #

String get content => _ace.value;
set content(String data) {
 if (!_waitForAce.isCompleted) {
   editorReady.then((_) => this.content = data);
   return;
 }

 var original_autoupdate = autoupdate;
 autoupdate = false;
 _ace.value = data;
 _ace.focus();
 updatePreview();
 autoupdate = original_autoupdate;
}

bool edit_only #

bool edit_only

final Future editorReady #

Future get editorReady => _waitForAce.future;

final Element el #

Element get el {
 if (__el != null) return __el;

 if (this._el.runtimeType == Element) {
   __el = _el;
 }
 else {
   __el = document.query(_el);
 }
 return __el;
}

bool enable_javascript_mode #

bool edit_only, autoupdate, enable_javascript_mode

String title #

String title

Methods

dynamic createPreviewIframe() #

createPreviewIframe() {
 var iframe = new IFrameElement();
 iframe
   ..width = "${this._preview_el.clientWidth}"
   ..height = "${this._preview_el.clientHeight}"
   ..style.border = '0'
   ..src = 'packages/ice_code_editor/html/preview_frame.html';

 this._preview_el.children.add( iframe );

 return iframe;
}

void delayedUpdatePreview() #

void delayedUpdatePreview() {
 if (!this.autoupdate) return;
 if (_update_timer != null) _update_timer.cancel();

 var wait = new Duration(seconds: 2);
 _update_timer = new Timer(wait, (){
   this.updatePreview();
   _update_timer = null;
 });
}

dynamic hideCode() #

Hide the code layer

hideCode() {
 _editor_el.style.display = 'none';
 if (this.edit_only) return;

 _preview_el.children[0].focus();
}

dynamic removePreview() #

removePreview() {
 while (this._preview_el.children.length > 0) {
   	  this._preview_el.children.first.remove();
 }
}

dynamic showCode() #

Show the code layer, calling the ACE resize methods to ensure that the display is correct.

showCode() {
 _editor_el.style.display = '';
 _ace.renderer.onResize();
 _ace.focus();
}

dynamic updatePreview() #

Update the preview layer with the current contents of the editor layer.

updatePreview() {
 if (this.edit_only) return;

 this.removePreview();
 var iframe = this.createPreviewIframe();

 var wait = new Duration(milliseconds: 900);
 new Timer(wait, (){
   if (iframe.contentWindow == null) return;
   iframe.contentWindow.postMessage(_ace.value, window.location.href);
 });
}