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); }); }