Skip to content

Instantly share code, notes, and snippets.

@velara3
Last active August 29, 2015 14:27
Show Gist options
  • Save velara3/96794b56b836ecedaa9f to your computer and use it in GitHub Desktop.
Save velara3/96794b56b836ecedaa9f to your computer and use it in GitHub Desktop.
Ace Editor for Flex desktop AIR with MXML Property Inspector
/**
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
**/
package com.flexcapacitor.controls {
import com.flexcapacitor.controls.IAceEditor;
import flash.events.Event;
import flash.utils.getTimer;
import mx.controls.HTML;
import mx.events.FlexEvent;
import spark.events.TextOperationEvent;
import flashx.textLayout.operations.FlowOperation;
/**
* Dispached as the mouse moves over the editor.
*
* @eventType flash.events.Event
*/
[Event(name="mouseMoveOverEditor", type="flash.events.Event")]
/**
* Dispached after the cursor changes positions.
*
* @eventType flash.events.Event
*/
[Event(name="cursorChange", type="flash.events.Event")]
/**
* Dispached after the session has changed
*
* @eventType flash.events.Event
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="sessionChange", type="flash.events.Event")]
/**
* Dispached after the selection anchor position and/or
* selection active or lead position properties have changed
* for any reason.
*
* @eventType flash.events.Event
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="selectionChange", type="flash.events.Event")]
/**
* Dispached after the <code>selectionAnchorPosition</code> and/or
* <code>selectionActivePosition</code> properties have changed
* for any reason.
*
* @eventType mx.events.FlexEvent.SELECTION_CHANGE
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="selectionChange", type="flash.events.Event")]
/**
* Dispatched after a user editing operation is complete.
*
* @eventType spark.events.TextOperationEvent.CHANGE
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
[Event(name="change", type="spark.events.TextOperationEvent")]
/**
* Ace editor for AIR apps. If you do not need to listen to change events it's takes a third as long to
* render. It automatically loads unless you set loadOnCreationComplete to false. If that is false then
* call initializeEditor() when you want to load the editor.
*
* Only about half of the API is supported at this time.
*
* Listening and dispatching events duration: Average:4ms with debug build.
* Not listening or dispatching events duration: Average:1ms with debug build.
*
* You need to copy the ace source code (src-min-noconflict) and ace.html page into your project.
*
<pre>
&lt;local:AceEditor id="ace" height="100%" width="100%"
top="60" left="0" right="0" bottom="30"
complete="ace_completeHandler(event)"
selectionChange="ace_selectionChangeHandler(event)"
cursorChange="ace_cursorChangeHandler(event)"
mouseMoveOverEditor="ace_mouseMoveOverChangeHandler(event)"
pathToTemplate="app:/ace.html"/>
public function selectionChangeHandler(event:Object, editor:Object):void {
var type:String = event.type; // changeSelection
anchor = editor.anchor;
lead = editor.lead;
}
protected function ace_cursorChangeHandler(event:Event):void {
var cursorPositionLabel:String = ace.row + ":" + ace.column;
var token:Object = ace.getTokenAt(ace.row, ace.column);
var tokenLabel:String = token ? token.type : "";
}
protected function ace_mouseMoveOverEditorHandler(event:Event):void {
var position:Object = ace.mouseMoveEvent.getDocumentPosition();
var mousePositionLabel:String = position.row + ":" + position.column;
var token:Object = ace.getTokenAt(position.row, position.column);
var tokenLabel:String = token ? token.type : "";
}
protected function ace_completeHandler(event:Event):void {
ace.setMode("ace/mode/html");
ace.setValue(myHTMLContent);
}
</pre>
*
* http://ace.c9.io/
*
* @see http://ace.c9.io/#nav=howto
* */
public class AceEditor extends HTML implements IAceEditor {
public function AceEditor() {
super();
htmlText = "<h1>loading</h1>";
addEventListener(FlexEvent.INITIALIZE, initializedHandler);
addEventListener(Event.COMPLETE, completeHandler);
addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
}
protected function creationCompleteHandler(event:FlexEvent):void
{
//trace("creationComplete");
}
public function initializedHandler(event:Event):void {
//trace("initialized");
if (loadOnCreationComplete) {
location = pathToTemplate;
}
}
public var loadOnCreationComplete:Boolean = true;
public static const INSERT_ACTION:String = "insert";
public static const INSERT_TEXT_ACTION:String = "insertText";
public static const INSERT_LINES_ACTION:String = "insertLines";
public static const REMOVE_LINES_ACTION:String = "removeLines";
public static const SESSION_CHANGE:String = "sessionChange";
public static const SELECTION_CHANGE:String = "selectionChange";
public static const CURSOR_CHANGE:String = "cursorChange";
public static const MOUSE_MOVE_OVER_EDITOR:String = "mouseMoveOverEditor";
public static const EDITOR_CHANGE:String = "change";
// ACE uses event names such as changeSession instead of sessionChange
// this is different than ActionScript3 conventions which is sessionChange
private static const SESSION_CHANGE_SESSION:String = "changeSession";
private static const SESSION_CHANGE_SELECTION:String = "changeSelection";
private static const SESSION_CHANGE_CURSOR:String = "changeCursor";
private static const SESSION_MOUSE_MOVE:String = "mousemove";
private var callBackAdded:Boolean;
/**
* Path to HTML page that has the Ace editor in it
* */
public var pathToTemplate:String = "app:/ace.html";
/**
* Reference to the HTML document
* */
public var pageDocument:Object;
/**
* Reference to the HTML document
* */
public var pagePlugins:Object;
/**
* Reference to the HTML document
* */
public var pageScripts:Object;
/**
* Reference to the ace editor instance
* */
public var editor:Object;
/**
* Reference to the ace editor container element instance
* */
public var element:Object;
/**
* Reference to the ace session instance.
* Not sure if this changes throughout the life of the editor.
* */
public var session:Object;
/**
* Reference to the ace selection instance
* Not sure if this changes throughout the life of the editor.
* */
public var selection:Object;
/**
* Reference to the ace editor manager
* */
public var aceManager:Object;
/**
* Reference to the page stylesheets
* */
public var pageStyleSheets:Object;
/**
* Reference to the ace language tools
* */
public var languageTools:Object;
/**
* Reference to the ace beautify extension
* */
public var beautify:Object;
/**
* Identity of editor on the page. <br/><br/>
*
* You should have a div on your page with an identity like this:
<pre>
&lt;div id='editor'>&lt;/div>
</pre>
* */
public var editorIdentity:String = "editor";
private var _theme:String = "ace/theme/crimson_editor";
/**
* Theme of the editor as a path to the theme files.
* Default is "ace/theme/crimson_editor"
* */
public function get theme():String {
return _theme;
}
/**
* @private
*/
public function set theme(value:String):void {
if (_theme!=value) themeChanged = true;
_theme = value;
invalidateProperties();
}
private var _showInvisibles:Boolean;
public function get showInvisibles():Boolean {
return _showInvisibles;
}
public function set showInvisibles(value:Boolean):void {
if (_showInvisibles!=value) showInvisiblesChanged = true;
_showInvisibles = value;
invalidateProperties();
}
private var _enableBehaviors:Boolean;
public function get enableBehaviors():Boolean {
return _enableBehaviors;
}
/**
* Specifies whether to use behaviors or not.
* "Behaviors" in this case is the auto-pairing of special characters,
* like quotation marks, parenthesis, or brackets.
* */
public function set enableBehaviors(value:Boolean):void {
if (_enableBehaviors!=value) enableBehaviorsChanged = true;
_enableBehaviors = value;
invalidateProperties();
}
public var _mode:String = "ace/mode/html";
/**
* Mode of the editor as a path to the mode files.
* Default is "ace/mode/html"
* */
public function get mode():String {
return _mode;
}
/**
* @private
*/
public function set mode(value:String):void {
if (_mode!=value) modeChanged = true;
_mode = value;
invalidateProperties();
}
private var _showFoldWidgets:Boolean = true;
/**
* Shows fold widgeths if true.
* Default is true.
* */
public function get showFoldWidgets():Boolean {
return _showFoldWidgets;
}
/**
* @private
*/
public function set showFoldWidgets(value:Boolean):void {
if (_showFoldWidgets!=value) showFoldWidgetsChanged = true;
_showFoldWidgets = value;
invalidateProperties();
}
private var _showPrintMargin:Boolean;
/**
* Show.
* Default is true.
* */
public function get showPrintMargin():Boolean {
return _showPrintMargin;
}
/**
* @private
*/
public function set showPrintMargin(value:Boolean):void {
if (_showPrintMargin!=value) showPrintMarginsChanged = true;
_showPrintMargin = value;
invalidateProperties();
}
/**
* Shows the gutter if true
* Default is true.
* */
public function get showGutter():Boolean {
return _showGutter;
}
/**
* @private
*/
public function set showGutter(value:Boolean):void {
if (_showGutter!=value) showGutterChanged = true;
_showGutter = value;
invalidateProperties();
}
private var _showGutter:Boolean = true;
private var _useWordWrap:Boolean;
/**
* Uses word wrap if true
* Default is true.
* */
public function get useWordWrap():Boolean {
return _useWordWrap;
}
/**
* @private
*/
public function set useWordWrap(value:Boolean):void {
if (_useWordWrap!=value) useWordWrapChanged = true;
_useWordWrap = value;
invalidateProperties();
}
private var _highlightActiveLine:Boolean;
public function get highlightActiveLine():Boolean {
return _highlightActiveLine;
}
public function set highlightActiveLine(value:Boolean):void {
if (_highlightActiveLine!=value) {
highlightActiveLineChanged = true;
invalidateProperties();
}
_highlightActiveLine = value;
}
private var _highlightGutterLine:Boolean;
public function get highlightGutterLine():Boolean {
return _highlightGutterLine;
}
public function set highlightGutterLine(value:Boolean):void {
if (_highlightGutterLine!=value) {
highlightGutterLineChanged = true;
invalidateProperties();
}
_highlightGutterLine = value;
}
private var _highlightSelectedWord:Boolean;
public function get highlightSelectedWord():Boolean {
return _highlightSelectedWord;
}
public function set highlightSelectedWord(value:Boolean):void {
if (_highlightSelectedWord!=value) {
highlightSelectedWordChanged = true;
invalidateProperties();
}
_highlightSelectedWord = value;
}
private var _tabSize:int = 4;
public function get tabSize():int {
return _tabSize;
}
public function set tabSize(value:int):void {
if (_tabSize!=value) {
tabSizeChanged = true;
invalidateProperties();
}
_tabSize = value;
}
private var _useSoftTabs:Boolean;
public function get useSoftTabs():Boolean {
return _useSoftTabs;
}
public function set useSoftTabs(value:Boolean):void {
if (_useSoftTabs!=value) {
useSoftTabsChanged = true;
invalidateProperties();
}
_useSoftTabs = value;
}
private var _useWorker:Boolean;
public function get useWorker():Boolean {
return _useWorker;
}
public function set useWorker(value:Boolean):void {
if (_useWorker!=value) {
useWorkerChanged = true;
invalidateProperties();
}
_useWorker = value;
}
private var _enableWrapBehaviors:Boolean;
public function get enableWrapBehaviors():Boolean {
return _enableWrapBehaviors;
}
/**
* Specifies whether to automatically wrap the selection with
* characters like brackets when the character is typed in.
* For example, select a word and then press the open curly brace key.
* The selection would be enclosed with open and close curly braces
* with this option enabled.
*
* Before: "text". After: "{test}".
* */
public function set enableWrapBehaviors(value:Boolean):void {
if (_enableWrapBehaviors!=value) {
enableWrapBehaviorsChanged = true;
invalidateProperties();
}
_enableWrapBehaviors = value;
}
private var _enableBasicAutoCompletion:Boolean = true;
public function get enableBasicAutoCompletion():Boolean {
return _enableBasicAutoCompletion;
}
public function set enableBasicAutoCompletion(value:Boolean):void {
if (_enableBasicAutoCompletion!=value) {
enableBasicAutoCompletionChanged = true;
invalidateProperties();
}
_enableBasicAutoCompletion = value;
}
private var _enableSnippets:Boolean;
public function get enableSnippets():Boolean {
return _enableSnippets;
}
public function set enableSnippets(value:Boolean):void {
if (_enableSnippets!=value) {
enableSnippetsChanged = true;
invalidateProperties();
}
_enableSnippets = value;
}
private var _enableLiveAutoCompletion:Boolean;
public function get enableLiveAutoCompletion():Boolean {
return _enableLiveAutoCompletion;
}
public function set enableLiveAutoCompletion(value:Boolean):void {
if (_enableLiveAutoCompletion!=value) {
enableLiveAutoCompletionChanged = true;
invalidateProperties();
}
_enableLiveAutoCompletion = value;
}
private var _keyBinding:String;
public function get keyBinding():String {
return _keyBinding;
}
public function set keyBinding(value:String):void {
if (_keyBinding!=value) {
keyBindingChanged = true;
invalidateProperties();
}
_keyBinding = value;
}
public function getFirstVisibleRow():int {return 0;};
public function getLastVisibleRow():int {return 0;};
public function getOptions():Object {return {};};
public function getSelection():Object {return {};};
/**
* Get selected text
* */
public function getTextRange():String {
var text:String = session.getTextRange(getSelectionRange());
return text;
}
/**
* Get selection range
* */
public function getSelectionRange():Object {
return editor.getSelectionRange();
}
/**
* Go to line
* */
public function gotoLine(line:uint):void {
editor.gotoLine(line);
}
public function gotoPageDown():void{};
public function gotoPageUp():void{};
/**
* Indents the current line
* */
public function indent():void {
editor.indent();
};
/**
* Returns true if the text input is currently focused
* */
public function isFocused():Boolean {
return editor.isFocused();
}
/**
* Indicates if the entire row is fully visible
* */
public function isRowFullyVisible(row:uint):Boolean {
return editor.isRowFullyVisible(row);
}
/**
* Is row visible
* */
public function isRowVisible(row:uint):Boolean {
return editor.isRowVisible(row);
}
/**
* Jumps to the matching brace or tag.
* */
public function jumpToMatching(select:Object):void {
editor.jumpToMatching(select);
}
public function modifyNumber():void{};
public function moveLinesDown():void{};
public function moveLinesUp():void{};
public function moveText():void{};
public function navigateDown():void{};
public function navigateFileEnd():void{};
public function navigateFileStart():void{};
public function navigateLeft():void{};
public function navigateLineEnd():void{};
public function navigateLineStart():void{};
public function navigateRight():void{};
public function navigateTo():void{};
public function navigateUp():void{};
public function navigateWordLeft():void{};
public function navigateWordRight():void{};
public function off():void{};
public function on():void{};
public function once():void{};
/**
* Redos the last operation
* */
public function redo():void {
session.redo();
}
/**
* Undo the last operation
* */
public function undo():void {
session.undo();
}
/**
* Removes the range from the document
* */
public function remove(range:Object):void {
session.remove(range);
}
/**
* Performs a replace on a previous call to find(). <br/><br/>
*
* To perform a replace:
<pre>
ace.find("needle");
ace.replace("bar");
</pre>
*
* @see #find()
* @see #replaceAll()
* */
public function replace(value:String = ""):void {
editor.replace(value);
}
/**
* Performs a replace all occurances on a previous call to find(). <br/><br/>
*
* To perform a replace:
<pre>
ace.find("needle");
ace.replaceAll("bar");
</pre>
*
* @see #replace()
* @see #find()
* */
public function replaceAll(value:String = ""):void {
editor.replaceAll(value);
}
/**
* Ace resizes itself on window events. If you resize the editor
* div in another manner use may need to call resize().
* */
public function resize():void{
editor.resize();
}
public function revealRange():void{};
/**
* Selects all the text in the document
* */
public function selectAll():void{
editor.selectAll();
}
public function selectMore():void{};
public function selectMoreLines():void{};
public function selectPageDown():void{};
public function selectPageUp():void{};
/**
* Set the highlight of the active line
* */
public function setHighlightActiveLine(value:Boolean):void{
editor.setHighlightActiveLine(value);
}
/**
* Set the highlight of the gutter line
* */
public function setHighlightGutterLine(value:Boolean):void{
editor.setHighlightGutterLine(value);
}
/**
* Set the highlight of the selected word
* */
public function setHighlightSelectedWord(value:Boolean):void{
editor.setHighlightSelectedWord(value);
}
/**
* Set the mode of the editor
* @see #mode
* */
public function setMode(value:String):void{
editor.getSession().setMode(value);
_mode = value;
}
/**
* Set theme of the editor
* @see #theme
* */
public function setTheme(value:String):void{
editor.setTheme(value);
_theme = value;
}
private var _isReadOnly:Boolean;
/**
* Uses word wrap if true
* Default is true.
* */
public function get isReadOnly():Boolean {
return _isReadOnly;
}
/**
* @private
*/
public function set isReadOnly(value:Boolean):void {
if (_isReadOnly!=value) isReadOnlyChanged = true;
_isReadOnly = value;
invalidateProperties();
}
private var _enableFind:Boolean = true;
/**
* Enable find
* Default is true.
* */
public function get enableFind():Boolean {
return _enableFind;
}
/**
* @private
*/
public function set enableFind(value:Boolean):void {
if (_enableFind!=value) enableFindChanged = true;
_enableFind = value;
invalidateProperties();
}
private var _enableReplace:Boolean = true;
/**
* Enable replace
* Default is true.
* */
public function get enableReplace():Boolean {
return _enableReplace;
}
/**
* @private
*/
public function set enableReplace(value:Boolean):void {
if (_enableFind!=value) enableFindChanged = true;
_enableReplace = value;
invalidateProperties();
}
/**
* Listen for change events. The editor may be faster if we
* aren't listening for change events and transporting values back and forth.
* Setting this to false is good for situations like read only mode.
* Default is true.
* */
public function get listenForChanges():Boolean {
return _listenForChanges;
}
/**
* @private
*/
public function set listenForChanges(value:Boolean):void {
if (_listenForChanges!=value) listenForChangesChanged = true;
_listenForChanges = value;
invalidateProperties();
}
private var _listenForChanges:Boolean = true;
private var listenForChangesChanged:Boolean;
override protected function commitProperties():void {
super.commitProperties();
if (!editor) return; // come back later?
const FIND:String = "find";
const REPLACE:String = "replace";
// this is good to turn off listeners for read only mode as it will save CPU cycles
if (listenForChangesChanged) {
// should we use session here instead of getSession() - not unless handler is always added
if (listenForChanges && !callBackAdded) {
editor.on(SESSION_MOUSE_MOVE, mouseMoveHandler);
editor.getSession().on(EDITOR_CHANGE, changeHandler);
editor.getSession().on(SESSION_CHANGE_SESSION, sessionChangeHandler);
editor.getSession().selection.on(SESSION_CHANGE_SELECTION, selectionChangeHandler);
editor.getSession().selection.on(SESSION_CHANGE_CURSOR, cursorChangeHandler);
/* ...too busy
editor.getSession().on("changeSelectionStyle", changeHandler);
editor.getSession().on("copy", changeHandler);
editor.getSession().on("paste", changeHandler);
editor.getSession().on("blur", changeHandler);
editor.getSession().on("focus", changeHandler);
*/
callBackAdded = true;
}
else if (!listenForChanges) {
editor.off(SESSION_MOUSE_MOVE, mouseMoveHandler);
editor.getSession().off(EDITOR_CHANGE, changeHandler);
editor.getSession().off(SESSION_CHANGE_SESSION, sessionChangeHandler);
editor.getSession().selection.off(SESSION_CHANGE_SELECTION, selectionChangeHandler);
editor.getSession().selection.off(SESSION_CHANGE_CURSOR, cursorChangeHandler);
callBackAdded = false;
}
listenForChangesChanged = false;
}
if (marginChanged) {
element.style.margin = margin;
marginChanged = false;
}
if (themeChanged) {
editor.setTheme(theme);
themeChanged = false;
}
// there might be a bug where the snippets are not for the correct language if we enable
// snippets at a later time than at startup so we mark mode as changed
if (enableSnippetsChanged) {
editor.setOption("enableSnippets", enableSnippets);
//options = aceEditor.getOptions();
enableSnippetsChanged = false;
}
if (modeChanged) {
editor.getSession().setMode(_mode);
modeChanged = false;
}
if (keyBindingChanged) {
editor.setKeyboardHandler(keyBinding);
keyBindingChanged = false;
}
if (showFoldWidgetsChanged) {
editor.setShowFoldWidgets(showFoldWidgets);
showFoldWidgetsChanged = false;
}
if (showPrintMarginsChanged) {
editor.setShowPrintMargin(showPrintMargin);
showPrintMarginsChanged = false;
}
if (showGutterChanged) {
editor.renderer.setShowGutter(showGutter);
showGutterChanged = false;
}
if (useWordWrapChanged) {
editor.getSession().setUseWrapMode(useWordWrap);
useWordWrapChanged = false;
}
if (isReadOnlyChanged) {
editor.setReadOnly(isReadOnly);
isReadOnlyChanged = false;
}
if (showInvisiblesChanged) {
editor.setShowInvisibles(showInvisibles);
showInvisiblesChanged = false;
}
if (fontSizeChanged) {
var fontSize:Number = getStyle("fontSize");
editor.setFontSize(fontSize);
fontSizeChanged = false;
}
if (showIndentGuidesChanged) {
editor.setDisplayIndentGuides(showIndentGuides);
showIndentGuidesChanged = false;
}
if (enableFindChanged) {
if (enableFind) {
editor.commands.removeCommand(FIND);
}
else {
editor.commands.addCommand(FIND);
}
enableFindChanged = false;
}
if (enableReplaceChanged) {
if (enableReplace) {
editor.commands.removeCommand(REPLACE);
}
else {
editor.commands.addCommand(REPLACE);
}
enableReplaceChanged = false;
}
var options:Object;
if (enableBasicAutoCompletionChanged) {
editor.setOption("enableBasicAutocompletion", enableBasicAutoCompletion);
enableBasicAutoCompletionChanged = false;
}
if (enableLiveAutoCompletionChanged) {
editor.setOption("enableLiveAutocompletion", enableLiveAutoCompletion);
enableLiveAutoCompletionChanged = false;
}
if (highlightActiveLineChanged) {
editor.setHighlightActiveLine(highlightActiveLine);
highlightActiveLineChanged = false;
}
if (highlightGutterLineChanged) {
editor.setHighlightGutterLine(highlightGutterLine);
highlightGutterLineChanged = false;
}
if (highlightSelectedWordChanged) {
editor.setHighlightSelectedWord(highlightSelectedWord);
highlightSelectedWordChanged = false;
}
if (tabSizeChanged || useSoftTabsChanged) {
editor.getSession().setUseSoftTabs(useSoftTabs);
editor.getSession().setTabSize(tabSize);
tabSizeChanged = false;
useSoftTabsChanged = false;
}
if (useWorkerChanged) {
editor.getSession().setUseWorker(useWorker);
useWorkerChanged = false;
}
if (enableBehaviorsChanged) {
editor.setBehavioursEnabled(enableBehaviors);
enableBehaviorsChanged = false;
}
if (enableWrapBehaviorsChanged) {
editor.setWrapBehavioursEnabled(enableWrapBehaviors);
enableWrapBehaviorsChanged = false;
}
if (textChanged) {
setValue(_text); // use _text not text // causes selectionChange changeSelection events
textChanged = false;
}
}
/**
* Set focus to the editor. Not really working now. Problem with AIR?
* */
override public function setFocus():void {
super.setFocus();
if (editor) {
var textInput:Object = editor.textInput;
var container:Object = editor.container;
var textAreas:Object = container.getElementsByTagName("textarea");
var textArea:Object = textAreas[0];
textInput.focus(); // doesn't seem to work
textArea.focus();
}
}
/**
* @private
*/
override public function styleChanged(styleProp:String):void {
var allStyles:Boolean = (styleProp == null || styleProp == "styleName");
super.styleChanged(styleProp);
if (allStyles || styleProp == "fontSize") {
fontSizeChanged = true;
invalidateProperties();
}
}
/**
* Maps to the session reset cache method
* */
public function resetCaches():void {
session.resetCaches();
}
/**
* Resets the cache
* */
public function resetCache():void {
session.bgTokenizer.lines.length = session.bgTokenizer.states.length = 0;
}
/**
* Maps to the session beautify method. Doesn't work well.
* */
public function beautifyMarkup():void {
if (beautify) {
beautify.beautify(session);
}
else {
throw new Error("Beautify extension is not installed. Add an include on the page template");
}
}
/**
* Inserts a block of text and the indicated position.
* */
public function insert(position:Object, text:String):Object {
return editor.insert(position, text);
}
/**
* Set the selection range
* */
public function setSelectionRange(range:Object, reverse:Boolean = false):void {
editor.setSelectionRange(range, reverse);
}
/**
* Moves the selection cursor to the indicated row and column.
* */
public function selectTo(row:Number, column:Number):void {
editor.setSelectionTo(row, column);
}
/**
* Moves the selection cursor to the row and column indicated
* */
public function selectToPosition(position:Object):void {
editor.selectToPosition(position);
}
/**
* Adds a range to a selection by entering multiselect mode, if necessary.
* */
public function addRange(range:Object, blockChangeEvents:Boolean):void {
editor.addRange(range, blockChangeEvents);
}
/**
* Gets the selection anchor
* */
public function getSelectionAnchor():Object {
return editor.getSelectionAnchor();
}
/**
* Gets the selection lead
* */
public function getSelectionLead():Object {
return editor.getSelectionLead();
}
/**
* Gets the cursor
* */
public function getCursor():Number {
return editor.selection.getCursor();
}
/**
* Gets the range
* */
public function getRange():Object {
return editor.getRange();
}
/**
* Gets the cursor
* */
public function getTotalLines():int {
return editor.session.getLength();
}
/**
* Gets the token at the row and column specified
* */
public function getTokenAt(row:uint, column:uint):Object {
return editor.session.getTokenAt(row, column);
}
/**
* Moves the cursor to the position provided.
* */
public function moveCursorToPosition(position:Object):void {
editor.moveCursorToPosition(position);
}
/**
* Moves the cursor to the row and column provided. If preventUpdateDesiredColumn
* is true, then the cursor stays in the same column position as its original point.
* */
public function moveCursorTo(row:Number, column:Number, keepDesiredColumn:Boolean = false):void {
editor.moveCursorTo(row, column, keepDesiredColumn);
}
/**
* Moves the cursor to the row and column provided. If preventUpdateDesiredColumn
* is true, then the cursor stays in the same column position as its original point.
* */
public function moveCursorToScreen(row:Number, column:Number, keepDesiredColumn:Boolean = false):void {
editor.moveCursorToScreen(row, column, keepDesiredColumn);
}
/**
* Reference to the range
* */
public var range:Object;
public function get showIndentGuides():Boolean {
return _showIndentGuides;
}
/**
* Shows indent guides
* */
public function set showIndentGuides(value:Boolean):void {
if (_showIndentGuides!=value) showIndentGuidesChanged = true;
_showIndentGuides = value;
invalidateProperties();
}
private var _showIndentGuides:Boolean;
/**
* Text to show or is shown in the editor.
* Use _text to get the value that was set programmatically.
* */
public function get text():String {
if (editor) {
return editor.getValue();
}
return _text;
}
/**
* @private
*/
public function set text(value:String):void {
if (_text!=value) textChanged = true;
_text = value;
invalidateProperties();
}
public var _text:String = "";
private var _margin:String;
public function get margin():String {
return _margin;
}
/**
* Sets the margin around the editor. This is useful for scrolling
* beyond the boundries of the editor. Also works around some mouse issues
* Set to values such as "20px 0". This will add 20px of space around the
* top and bottom of the editor. Default is 0.
* */
public function set margin(value:String):void {
if (_margin!=value) marginChanged = true;
_margin = value;
invalidateProperties();
}
public var errorMessage:String;
/**
* Returns an editor that has an id. This will error out here if the div
* cannot be found on the page template.
*
* You should have a div on your page with an identity like this:
<pre>
&lt;div id='editor'>&lt;/div>
</pre>
* @see #editorIdentity
* */
public function getEditor(id:String):Object {
return domWindow.ace.edit(id);
}
/**
* Handles when editor is loaded. Happens earlier if it's a Friday night.
* */
protected function completeHandler(event:Event):void {
//var isPrimaryApplication:Boolean = SystemManagerGlobals.topLevelSystemManagers[0] == systemManager;
if (validateSources) {
aceFound = domWindow.ace ? true : false;
try {
if (aceFound) {
// can't seem to catch this error!
// the folling line always throws an error if div is not found:
// domWindow.ace.edit(id);
// would have hoped it returned null
// using old fashioned method
var element:Object = domWindow.document.getElementById(editorIdentity);
var localName:String = element ? element.nodeName : null;
aceEditorFound = (element && localName && localName.toLowerCase()=="div");
}
}
catch (e:Error) {
aceEditorFound = false;
}
if (!aceFound) {
errorMessage = "The ace JavaScript variable was not found. Make sure to copy the directory, ";
errorMessage += "'src-min-noconflict' to your project src directory and include a reference ";
errorMessage += "to it in the template page.";
throw new Error(errorMessage);
}
else if (!aceEditorFound) {
errorMessage = "The ace editor div was not found. Make sure the template page ";
errorMessage += "has a div with an id of '" + editorIdentity + "'.";
throw new Error(errorMessage);
}
}
createHTMLReferences();
setEditorProperties();
commitProperties();
setValue(text);
clearSelection();
}
/**
* Creates references we will use to reference the ace editor
* */
private function createHTMLReferences():void {
pageDocument = domWindow.document;
pagePlugins = pageDocument.plugins;
pageScripts = pageDocument.scripts;
pageStyleSheets = pageDocument.styleSheets;
aceManager = domWindow.ace;
editor = aceManager.edit(editorIdentity);
element = editor.container;
languageTools = aceManager.require("ace/ext/language_tools");
beautify = aceManager.require("ace/ext/beautify");
session = editor.getSession();
selection = session.selection;
// this is a hack because somewhere in ace javascript someone is calling console.log
// and there is no console in the AIR HTML component dom window
// however you can create your own and assign it to the console property
if (console==null) {
console = {};
console.log = trace;
console.error = trace;
}
if (domWindow.console==null) {
domWindow.console = console;
//domWindow.console.log("hello");
//domWindow.console.error("hello error");
}
editor.commands.addCommand({
name: 'save',
bindKey: {win: "Ctrl-S", "mac": "Cmd-S"},
exec: saveKeyboardHandler});
editor.commands.addCommand({
name: 'blockComment',
bindKey: {win: "Ctrl-Shift-c", "mac": "Cmd-Shift-C"},
exec: blockCommentHandler});
}
/**
* Handler for save keyboard shortcut
* */
public function blockCommentHandler(editor:Object, event:Object):void {
editor.toggleBlockComment();
}
/**
* Handler for save keyboard shortcut
* */
public function saveKeyboardHandler(editor:Object, event:Object):void {
//console.log("saving", editor.session.getValue())
}
/**
* Sets the ace editor properties. We might want to use
* Flex commit properties to handle changes
* */
public function setEditorProperties():void {
invalidateProperties();
// set values from editor
//var options:Object = editor.getOptions();
enableBehaviorsChanged = true;
enableFindChanged = true;
enableReplaceChanged = true;
enableSnippetsChanged = true;
showInvisiblesChanged = true;
showIndentGuidesChanged = true;
fontSizeChanged = true;
enableBasicAutoCompletionChanged = true;
enableLiveAutoCompletionChanged = true;
highlightActiveLineChanged = true;
highlightGutterLineChanged = true;
highlightSelectedWordChanged = true;
isReadOnlyChanged = true;
keyBindingChanged = true;
listenForChangesChanged = true;
modeChanged = true;
showFoldWidgetsChanged = true;
showPrintMarginsChanged = true;
showGutterChanged = true;
tabSizeChanged = true;
textChanged = true;
themeChanged = true;
useSoftTabsChanged = true;
useWordWrapChanged = true;
useWorkerChanged = true;
enableWrapBehaviorsChanged = true;
marginChanged = true;
}
/**
* Sets the text of the editor. You can also set the text property.
* Required. If position is 0 then all text is selected and cursor is at the end of the document,
* if -1 then the cursor is placed at the start of the document and
* if 1 then the cursor is placed at the end.
* Default is -1.
* */
public function setValue(text:String, position:int = -1):void {
isValueCommit = true;
editor.setValue(text, position);
isValueCommit = false;
}
/**
* Indicates that the changes being dispatched from the ace editor
* are not changes from the user typing but from us setting the
* contents programmatically.
* */
public var isValueCommit:Boolean;
private var themeChanged:Boolean;
private var modeChanged:Boolean;
private var showFoldWidgetsChanged:Boolean;
private var showPrintMarginsChanged:Boolean;
private var showGutterChanged:Boolean;
private var useWordWrapChanged:Boolean;
private var isReadOnlyChanged:Boolean;
private var enableFindChanged:Boolean;
private var enableReplaceChanged:Boolean;
private var showInvisiblesChanged:Boolean;
private var fontSizeChanged:Boolean;
private var textChanged:Boolean;
private var showIndentGuidesChanged:Boolean;
private var enableBasicAutoCompletionChanged:Boolean;
private var enableLiveAutoCompletionChanged:Boolean;
private var highlightActiveLineChanged:Boolean;
private var highlightGutterLineChanged:Boolean;
private var highlightSelectedWordChanged:Boolean;
private var tabSizeChanged:Boolean;
private var useSoftTabsChanged:Boolean;
private var useWorkerChanged:Boolean;
private var enableWrapBehaviorsChanged:Boolean;
private var enableSnippetsChanged:Boolean;
private var marginChanged:Boolean;
/**
* Reference to the anchor of the last changeSelection event
* */
public var anchor:Object;
/**
* Reference to the lead of the last changeSelection event
* */
public var lead:Object;
/**
* Reference to current row. Must have listenForChanges enabled
* */
public var row:int;
/**
* Reference to current column.
* */
public var column:int;
private var enableBehaviorsChanged:Boolean;
private var keyBindingChanged:Boolean;
public var mouseMoveEvent:Object;
/**
* Console object.
* This is a workaround because somewhere in the ace javascript someone is calling console.log
* and there is no console in the AIR HTML component dom window
* however you can create your own and assign it to the console property.
* Add at least log and error methods.
*/
public var console:Object;
/**
* Set this to true to report errors to the console
* such as missing template file and missing JavaScript ace global variable
*/
public var validateSources:Boolean = true;
/**
* Indicates if the window.ace instance is found. If it's false and the complete event
* has been dispatched check that you have a script on the page template and that
* it is pointing to the location of the ace editor src files.
*
* It should look like this:
<pre>
&lt;script src="src-min-noconflict/ace.js" type="text/javascript" charset="utf-8">&lt;/script>
</pre>
* */
public var aceFound:Boolean;
/**
* Indicates if the window.ace editor instance is found. If it's false, the complete event
* has been dispatched and the property aceFound is true then check that you have a div
* on the page template that has an id that matches the value in editorIdentity
* (default is "editor").
*
* It should look like this:
<pre>
&lt;div id='editor'>&lt;/div>
</pre>
* */
public var aceEditorFound:Boolean;
/**
* Handles session change events from the editor. Not tested.
* */
public function sessionChangeHandler(event:Object, editor:Object):void {
var type:String = event.type; // changeSelection
session = editor.getSession();
if (hasEventListener(SESSION_CHANGE)) {
dispatchEvent(new Event(SESSION_CHANGE));
}
}
/**
* Handles selection change events from the editor
* */
public function selectionChangeHandler(event:Object, editor:Object):void {
var type:String = event.type; // changeSelection
anchor = editor.anchor;
lead = editor.lead;
if (hasEventListener(SELECTION_CHANGE)) {
dispatchEvent(new Event(SELECTION_CHANGE));
}
}
/**
* Handles cursor change events from the editor
* */
public function cursorChangeHandler(event:Object, editor:Object):void {
var type:String = event.type; // changeCursor
anchor = editor.anchor;
lead = editor.lead;
//var leadPosition:Object = lead.getPosition();
row = lead.row;
column = lead.column;
if (hasEventListener(CURSOR_CHANGE)) {
dispatchEvent(new Event(CURSOR_CHANGE));
}
}
/**
* Handles mouse move events from the editor. Named as it is because UIComponent already
* has a mouseMove event.
*
* You can use this event to get token info:
<pre>
var position = ace.mouseMoveEvent.getDocumentPosition();
var token:Object = session.getTokenAt(position.row, position.column);
trace(token);
token = {
type: "paren.paren",
value: "}",
index: 0,
start: 0
}
</pre>
* */
public function mouseMoveHandler(event:Object, editor:Object):void {
//var token:Object = session.getTokenAt(position.row, position.column);
if (hasEventListener(MOUSE_MOVE_OVER_EDITOR)) {
mouseMoveEvent = event;
dispatchEvent(new Event(MOUSE_MOVE_OVER_EDITOR));
}
}
/**
* Handles change events from the editor
* */
public function changeHandler(event:Object, editor:Object):void {
var action:String = event.action;
var operation:FlowOperation;
//trace("action:" + action);
if (hasEventListener(Event.CHANGE)) {
operation = new FlowOperation(null); // thought I could use this but doesn't look like I can set certain properties
operation.userData = event;
if (action==INSERT_ACTION) {
}
else if (action==INSERT_TEXT_ACTION) {
//dispatchEvent(new TextOperationEvent(TextOperationEvent.CHANGE, false, false, operation));
}
else if (action==INSERT_LINES_ACTION) {
//dispatchEvent(new TextOperationEvent(TextOperationEvent.CHANGE, false, false, operation));
}
else if (action==REMOVE_LINES_ACTION) {
//dispatchEvent(new TextOperationEvent(TextOperationEvent.CHANGE, false, false, operation));
}
dispatchEvent(new TextOperationEvent(TextOperationEvent.CHANGE, false, false, operation));
}
}
/**
* Performs another search for the word previously specified.
* */
public function findPrevious(options:Object = null, animate:Boolean = false):void {
editor.findPrevious(options, animate);
}
/**
* Performs another search for the word previously specified.
* */
public function findNext(options:Object = null, animate:Boolean = false):void {
editor.findNext(options, animate);
}
/**
* Performs a search for the word specified.<br/><br/>
*
* To peform a find:
<pre>
ace.find("needle",{
backwards: false,
wrap: false,
caseSensitive: false,
wholeWord: false,
regExp: false
});
ace.findNext();
ace.findPrevious();
</pre>
* To perform a replace:
<pre>
ace.find("needle");
ace.replace('bar');
</pre>
* @param needle: The string or regular expression you're looking for
* @param backwards: Whether to search backwards from where cursor currently is. Defaults to false.
* @param wrap: Whether to wrap the search back to the beginning when it hits the end. Defaults to false.
* @param caseSensitive: Whether the search ought to be case-sensitive. Defaults to false.
* @param wholeWord: Whether the search matches only on whole words. Defaults to false.
* @param range: The Range to search within. Set this to null for the whole document
* @param regExp: Whether the search is a regular expression or not. Defaults to false.
* @param start: The starting Range or cursor position to begin the search
* @param skipCurrent: Whether or not to include the current line in the search. Default to false
* @param animate: Whether or not to animate. Default to false
* */
public function find(value:String, options:Object = null, animate:Boolean = false):void {
editor.find(value, options, animate);
}
/**
* Performs a search for the word specified.
* */
public function findAll(value:String, options:Object = null, keeps:Boolean = false):Number {
var result:Number = editor.findAll(value, options, keeps);
return result;
}
/**
* Clears the selection highlight
* */
public function clearSelection():void {
editor.clearSelection();
}
/**
* Attempts to center the selection on the screen
* */
public function centerSelection():void {
editor.centerSelection();
}
/**
* Measures the performance of the editor.
* Returns how fast a mode can tokenize the whole document.
* */
public function measureTokenizePerformance():int {
// reset cache
var linesCount:uint = session.getLength();
var time:uint = getTimer();
for (var i:int; i < linesCount; i++) {
session.getTokens(i);
}
/*
if (editor.$highlightTagPending == true) {
editor.$highlightTagPending = false;
editor.$highlightPending = false;
}
else {
session.removeMarker(session.$tagHighlight);
session.$tagHighlight = null;
session.removeMarker(session.$bracketHighlight);
session.$bracketHighlight = null;
editor.$highlightTagPending = true;
editor.$highlightPending = true;
}*/
return getTimer() - time;
}
/**
* Sets the location to the html page that has ace editor in it.
* You should include this file in your application
* @see loadOnCreationComplete
* @see pathToTemplate
* */
public function initializeEditor():void {
location = pathToTemplate;
}
}
}
package com.flexcapacitor.controls
{
import mx.core.IDeferredInstantiationUIComponent;
import mx.core.IFlexDisplayObject;
import mx.core.IInvalidating;
import mx.core.ILayoutDirectionElement;
import mx.core.ILayoutElement;
import mx.core.IUIComponent;
import mx.core.IVisualElement;
import mx.managers.ILayoutManagerClient;
public interface IAceEditor extends IVisualElement, IUIComponent, IInvalidating, IFlexDisplayObject,
ILayoutManagerClient, IDeferredInstantiationUIComponent, ILayoutElement,
ILayoutDirectionElement
{
function get text():String;
function set text(value:String):void;
function get mode():String;
function set mode(value:String):void;
function get isReadOnly():Boolean;
function set isReadOnly(value:Boolean):void;
function get showFoldWidgets():Boolean;
function set showFoldWidgets(value:Boolean):void;
function get showGutter():Boolean;
function set showGutter(value:Boolean):void;
function get margin():String;
function set margin(value:String):void;
}
}
package com.flexcapacitor.utils
{
import com.flexcapacitor.controls.AceEditor;
public class AceEditorUtils {
public var editor:AceEditor;
public function AceEditorUtils()
{
}
/**
* Creates an instance of the Ace Editor and returns it
* Used for cases where browser and desktop application
* uses the same view. By placing the definition in another
* class we prevent errors in the browser
*/
public static function createInstance():AceEditor {
var editor:AceEditor = new AceEditor();
return editor;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:window="com.flexcapacitor.effects.window.*"
xmlns:handlers="com.flexcapacitor.handlers.*"
xmlns:utils="com.flexcapacitor.utils.*"
xmlns:local="*"
width="1100"
height="600"
>
<fx:Script>
<![CDATA[
import com.flexcapacitor.performance.PerformanceMeter;
import com.flexcapacitor.utils.ArrayUtils;
import spark.events.IndexChangeEvent;
import spark.events.TextOperationEvent;
private var lastSearchValue:String;
protected function ace_completeHandler(event:Event):void {
setEditorMode("html");
updateUI();
}
public function updateUI():void {
listeningButton.selected = ace.listenForChanges;
useWordWrapButton.selected = ace.useWordWrap;
showFoldWidgetsButton.selected = ace.showFoldWidgets;
showPrintMarginsButton.selected = ace.showPrintMargin;
showGutterButton.selected = ace.showGutter;
highlightActiveLineButton.selected = ace.highlightActiveLine;
highlightGutterLineButton.selected = ace.highlightGutterLine;
highlightSelectedWordButton.selected = ace.highlightSelectedWord;
//enableFindButton.selected = ace.enableFind;
//enableReplaceButton.selected = ace.enableReplace;
isReadOnlyButton.selected = ace.isReadOnly;
showInvisiblesButton.selected = ace.showInvisibles;
showIndentGuidesButton.selected = ace.showIndentGuides;
//var selectedTheme:Object = ArrayUtils.find((themesList.dataProvider as ArrayList).source, "value", ace.theme.replace("ace/theme/",""));
themesList.selectedItem = ace.theme;
var mode:String = ace.mode.replace("ace/mode/","");
var selectedMode:Object = ArrayUtils.find((modesList.dataProvider as ArrayCollection).source, "value", mode);
modesList.selectedItem = selectedMode;
fontSizeStepper.value = ace.getStyle("fontSize");
useSoftTabsButton.selected = ace.useSoftTabs;
enableSnippetsButton.selected = ace.enableSnippets;
enableBasicAutoCompletionButton.selected = ace.enableBasicAutoCompletion;
enableLiveAutoCompletionButton.selected = ace.enableLiveAutoCompletion;
useWorkerButton.selected = ace.useWorker;
enableBehaviorsButton.selected = ace.enableBehaviors;
}
protected function setContentsButton_clickHandler(event:MouseEvent):void {
setEditorMode(event.currentTarget.label);
}
public function setEditorMode(mode:String):void {
var length:int = 1;
var code:String = "";
mode = mode.toLowerCase();
if (!ace.aceFound) {
trace("The Ace editor was not initialized correctly. \nMake sure the page template is loading and that it points to the ace javascript.");
return;
}
if (!ace.aceEditorFound) {
trace("The Ace editor was not found in the page template. \nMake sure you have a div on the page with an id that matches the value in the ace.editorIdentity property.");
return;
}
if (mode=="html") {
code = html;
ace.setMode("ace/mode/html");
}
if (mode=="actionscript") {
code = actionscript;
ace.setMode("ace/mode/actionscript");
}
if (mode=="css") {
code = css;
ace.setMode("ace/mode/css");
}
if (mode=="javascript") {
code = javascript;
ace.setMode("ace/mode/javascript");
}
if (mode=="php") {
code = php;
ace.setMode("ace/mode/php");
}
if (mode=="mxml") {
code = mxml;
ace.setMode("ace/mode/html"); // no support for mxml yet
}
const SET_EDITOR_LISTENING:String = "Set editor value";
for (var i:int;i<length;i++) {
PerformanceMeter.start(SET_EDITOR_LISTENING, true, true);
//ace.text = "";
//ace.text = code + i;
ace.setValue(code);
ace.validateNow();
PerformanceMeter.stop(SET_EDITOR_LISTENING, false);
}
//PerformanceMeter.traceMultitest(SET_EDITOR_LISTENING);
PerformanceMeter.clear(SET_EDITOR_LISTENING);
//ace.clearSelection();
//ace.moveCursorTo(0,0);
updateUI();
}
protected function listeningButton_clickHandler(event:MouseEvent):void {
ace.listenForChanges = listeningButton.selected;
}
protected function setFocusButton_clickHandler(event:MouseEvent):void {
ace.setFocus();
}
protected function wordWrapButton_clickHandler(event:MouseEvent):void {
ace.useWordWrap = useWordWrapButton.selected;
}
protected function showFoldingWidgetsButton_clickHandler(event:MouseEvent):void {
ace.showFoldWidgets = showFoldWidgetsButton.selected;
}
protected function showPrintMarginsButton_clickHandler(event:MouseEvent):void {
ace.showPrintMargin = showPrintMarginsButton.selected;
}
protected function highlightLineButton_clickHandler(event:MouseEvent):void {
ace.highlightActiveLine = highlightActiveLineButton.selected;
}
protected function highlightGutterButton_clickHandler(event:MouseEvent):void {
ace.highlightGutterLine = highlightGutterLineButton.selected;
}
protected function highlightSelectedWordButton_clickHandler(event:MouseEvent):void {
ace.highlightSelectedWord = highlightSelectedWordButton.selected;
}
protected function showGutterButton_clickHandler(event:MouseEvent):void {
ace.showGutter = showGutterButton.selected;
}
protected function isReadOnlyButton_clickHandler(event:MouseEvent):void {
ace.isReadOnly = isReadOnlyButton.selected;
}
protected function enableFindButton_clickHandler(event:MouseEvent):void {
//ace.enableFind = enableFindButton.selected;
}
protected function enableReplaceButton_clickHandler(event:MouseEvent):void {
//ace.enableReplace = enableReplaceButton.selected;
}
protected function modesList_changeHandler(event:IndexChangeEvent):void {
ace.mode = "ace/mode/" + modesList.selectedItem.value;
}
protected function themesList_changeHandler(event:IndexChangeEvent):void {
ace.theme = "ace/theme/" + themesList.selectedItem;
}
protected function showInvisiblesButton_clickHandler(event:MouseEvent):void {
ace.showInvisibles = showInvisiblesButton.selected;
}
protected function fontSize_changeHandler(event:Event):void {
ace.setStyle("fontSize", fontSizeStepper.value);
}
protected function showIndentGuidesButton_clickHandler(event:MouseEvent):void {
ace.showIndentGuides = showIndentGuidesButton.selected;
}
protected function findInput_changeHandler(event:TextOperationEvent=null):void {
var searchText:String = findInput.text;
if (lastSearchValue==searchText) {
// if shift key is down go back otherwise go forward
ace.findNext(searchText);
}
else {
ace.find(findInput.text);
}
lastSearchValue = searchText;
}
protected function clearSelectionButton_clickHandler(event:MouseEvent):void {
ace.clearSelection();
}
protected function measurePerformanceButton_clickHandler(event:MouseEvent):void {
tokenLabel.text = ace.measureTokenizePerformance() + "ms";
}
protected function useSoftTabsButton_clickHandler(event:MouseEvent):void {
ace.useSoftTabs = useSoftTabsButton.selected;
}
protected function enableSnippetsButton_clickHandler(event:MouseEvent):void {
ace.enableSnippets = enableSnippetsButton.selected;
ace.resetCaches();
}
protected function enableBasicAutoCompletionButton_clickHandler(event:MouseEvent):void {
ace.enableBasicAutoCompletion = enableBasicAutoCompletionButton.selected;
}
protected function enableLiveAutoCompletionButton_clickHandler(event:MouseEvent):void {
ace.enableLiveAutoCompletion = enableLiveAutoCompletionButton.selected;
}
protected function ace_cursorChangeHandler(event:Event):void {
var token:Object = ace.getTokenAt(ace.row, ace.column);
tokenLabel.text = token ? token.type : "";
cursorPositionLabel.text = ace.row + ":" + ace.column;
}
protected function ace_mouseMoveOverEditorHandler(event:Event):void {
var position:Object = ace.mouseMoveEvent.getDocumentPosition();
//mousePositionLabel.text = position.row + ":" + position.column;
var token:Object = ace.getTokenAt(position.row, position.column);
tokenLabel.text = token ? token.type : "";
}
protected function useWorkerButton_clickHandler(event:MouseEvent):void {
ace.useWorker = useWorkerButton.selected;
}
protected function enableBehaviorsButton_clickHandler(event:MouseEvent):void {
ace.enableBehaviors = enableBehaviorsButton.selected;
}
protected function enableWrapBehaviorsButton_clickHandler(event:MouseEvent):void {
ace.enableWrapBehaviors = enableWrapBehaviorsButton.selected;
}
protected function keyBindingList_changeHandler(event:IndexChangeEvent):void {
ace.keyBinding = keyBindingList.selectedItem.value;
}
protected function formatSourceButton_clickHandler(event:MouseEvent):void {
ace.beautifyMarkup();
}
protected function ace_selectionChangeHandler(event:Event):void {
var anchor:String = ace.anchor.row + ":" + ace.anchor.column;
var lead:String = ace.lead.row + ":" + ace.lead.column;
if (anchor==lead) {
selectionPositionLabel.text = "none";
}
else {
selectionPositionLabel.text = anchor + " - " + lead;
}
}
protected function ace_uncaughtScriptExceptionHandler(event:Event):void {
//
//trace("uncaught script exception");
}
protected function ace_locationChangeHandler(event:Event):void {
//
//trace("location change");
}
]]>
</fx:Script>
<fx:Declarations>
<handlers:EventHandler eventName="initialize">
<window:CenterWindow target="{this}" />
</handlers:EventHandler>
<s:ArrayCollection id="modes">
<fx:Object value="abap" label="ABAP"/>
<fx:Object value="abc" label="ABC"/>
<fx:Object value="actionscript" label="ActionScript"/>
<fx:Object value="ada" label="ADA"/>
<fx:Object value="apache_conf" label="Apache Conf"/>
<fx:Object value="asciidoc" label="AsciiDoc"/>
<fx:Object value="assembly_x86" label="Assembly x86"/>
<fx:Object value="autohotkey" label="AutoHotKey"/>
<fx:Object value="batchfile" label="BatchFile"/>
<fx:Object value="c_cpp" label="C and C++"/>
<fx:Object value="c9search" label="C9Search"/>
<fx:Object value="cirru" label="Cirru"/>
<fx:Object value="clojure" label="Clojure"/>
<fx:Object value="cobol" label="Cobol"/>
<fx:Object value="coffee" label="CoffeeScript"/>
<fx:Object value="coldfusion" label="ColdFusion"/>
<fx:Object value="csharp" label="C#"/>
<fx:Object value="css" label="CSS"/>
<fx:Object value="curly" label="Curly"/>
<fx:Object value="d" label="D"/>
<fx:Object value="dart" label="Dart"/>
<fx:Object value="diff" label="Diff"/>
<fx:Object value="dockerfile" label="Dockerfile"/>
<fx:Object value="dot" label="Dot"/>
<fx:Object value="dummy" label="Dummy"/>
<fx:Object value="dummysyntax" label="DummySyntax"/>
<fx:Object value="eiffel" label="Eiffel"/>
<fx:Object value="ejs" label="EJS"/>
<fx:Object value="elixir" label="Elixir"/>
<fx:Object value="elm" label="Elm"/>
<fx:Object value="erlang" label="Erlang"/>
<fx:Object value="forth" label="Forth"/>
<fx:Object value="ftl" label="FreeMarker"/>
<fx:Object value="gcode" label="Gcode"/>
<fx:Object value="gherkin" label="Gherkin"/>
<fx:Object value="gitignore" label="Gitignore"/>
<fx:Object value="glsl" label="Glsl"/>
<fx:Object value="golang" label="Go"/>
<fx:Object value="groovy" label="Groovy"/>
<fx:Object value="haml" label="HAML"/>
<fx:Object value="handlebars" label="Handlebars"/>
<fx:Object value="haskell" label="Haskell"/>
<fx:Object value="haxe" label="haXe"/>
<fx:Object value="html" label="HTML"/>
<fx:Object value="html_ruby" label="HTML (Ruby)"/>
<fx:Object value="ini" label="INI"/>
<fx:Object value="io" label="Io"/>
<fx:Object value="jack" label="Jack"/>
<fx:Object value="jade" label="Jade"/>
<fx:Object value="java" label="Java"/>
<fx:Object value="javascript" label="JavaScript"/>
<fx:Object value="json" label="JSON"/>
<fx:Object value="jsoniq" label="JSONiq"/>
<fx:Object value="jsp" label="JSP"/>
<fx:Object value="jsx" label="JSX"/>
<fx:Object value="julia" label="Julia"/>
<fx:Object value="latex" label="LaTeX"/>
<fx:Object value="lean" label="Lean"/>
<fx:Object value="less" label="LESS"/>
<fx:Object value="liquid" label="Liquid"/>
<fx:Object value="lisp" label="Lisp"/>
<fx:Object value="livescript" label="LiveScript"/>
<fx:Object value="logiql" label="LogiQL"/>
<fx:Object value="lsl" label="LSL"/>
<fx:Object value="lua" label="Lua"/>
<fx:Object value="luapage" label="LuaPage"/>
<fx:Object value="lucene" label="Lucene"/>
<fx:Object value="makefile" label="Makefile"/>
<fx:Object value="markdown" label="Markdown"/>
<fx:Object value="mask" label="Mask"/>
<fx:Object value="matlab" label="MATLAB"/>
<fx:Object value="maze" label="Maze"/>
<fx:Object value="mel" label="MEL"/>
<fx:Object value="mushcode" label="MUSHCode"/>
<fx:Object value="mysql" label="MySQL"/>
<fx:Object value="nix" label="Nix"/>
<fx:Object value="objectivec" label="Objective-C"/>
<fx:Object value="ocaml" label="OCaml"/>
<fx:Object value="pascal" label="Pascal"/>
<fx:Object value="perl" label="Perl"/>
<fx:Object value="pgsql" label="pgSQL"/>
<fx:Object value="php" label="PHP"/>
<fx:Object value="powershell" label="Powershell"/>
<fx:Object value="praat" label="Praat"/>
<fx:Object value="prolog" label="Prolog"/>
<fx:Object value="properties" label="Properties"/>
<fx:Object value="protobuf" label="Protobuf"/>
<fx:Object value="python" label="Python"/>
<fx:Object value="r" label="R"/>
<fx:Object value="rdoc" label="RDoc"/>
<fx:Object value="rhtml" label="RHTML"/>
<fx:Object value="ruby" label="Ruby"/>
<fx:Object value="rust" label="Rust"/>
<fx:Object value="sass" label="SASS"/>
<fx:Object value="scad" label="SCAD"/>
<fx:Object value="scala" label="Scala"/>
<fx:Object value="scheme" label="Scheme"/>
<fx:Object value="scss" label="SCSS"/>
<fx:Object value="sh" label="SH"/>
<fx:Object value="sjs" label="SJS"/>
<fx:Object value="smarty" label="Smarty"/>
<fx:Object value="snippets" label="snippets"/>
<fx:Object value="soy_template" label="Soy Template"/>
<fx:Object value="space" label="Space"/>
<fx:Object value="sql" label="SQL"/>
<fx:Object value="sqlserver" label="SQLServer"/>
<fx:Object value="stylus" label="Stylus"/>
<fx:Object value="svg" label="SVG"/>
<fx:Object value="tcl" label="Tcl"/>
<fx:Object value="tex" label="Tex"/>
<fx:Object value="text" label="Text"/>
<fx:Object value="textile" label="Textile"/>
<fx:Object value="toml" label="Toml"/>
<fx:Object value="twig" label="Twig"/>
<fx:Object value="typescript" label="Typescript"/>
<fx:Object value="vala" label="Vala"/>
<fx:Object value="vbscript" label="VBScript"/>
<fx:Object value="velocity" label="Velocity"/>
<fx:Object value="verilog" label="Verilog"/>
<fx:Object value="vhdl" label="VHDL"/>
<fx:Object value="xml" label="XML"/>
<fx:Object value="xquery" label="XQuery"/>
<fx:Object value="yaml" label="YAML"/>
<fx:Object value="django" label="Django"/>
</s:ArrayCollection>
<s:ArrayCollection id="themes">
<fx:String >--Light--</fx:String>
<fx:String>chrome</fx:String>
<fx:String>clouds</fx:String>
<fx:String>crimson_editor</fx:String>
<fx:String>dawn</fx:String>
<fx:String>dreamweaver</fx:String>
<fx:String>eclipse</fx:String>
<fx:String>github</fx:String>
<fx:String>chrome</fx:String>
<fx:String>clouds</fx:String>
<fx:String>crimson_editor</fx:String>
<fx:String>dawn</fx:String>
<fx:String>dreamweaver</fx:String>
<fx:String>eclipse</fx:String>
<fx:String>github</fx:String>
<fx:String>iplastic</fx:String>
<fx:String>solarized_light</fx:String>
<fx:String>textmate</fx:String>
<fx:String>tomorrow</fx:String>
<fx:String>xcode</fx:String>
<fx:String>kuroir</fx:String>
<fx:String>katzenmilch</fx:String>
<fx:String>sqlserver</fx:String>
<fx:String >--Dark--</fx:String>
<fx:String>ambiance</fx:String>
<fx:String>chaos</fx:String>
<fx:String>clouds_midnight</fx:String>
<fx:String>cobalt</fx:String>
<fx:String>idle_fingers</fx:String>
<fx:String>kr_theme</fx:String>
<fx:String>merbivore</fx:String>
<fx:String>merbivore_soft</fx:String>
<fx:String>mono_industrial</fx:String>
<fx:String>monokai</fx:String>
<fx:String>pastel_on_dark</fx:String>
<fx:String>solarized_dark</fx:String>
<fx:String>terminal</fx:String>
<fx:String>tomorrow_night</fx:String>
<fx:String>tomorrow_night_blue</fx:String>
<fx:String>tomorrow_night_bright</fx:String>
<fx:String>tomorrow_night_eighties</fx:String>
<fx:String>twilight</fx:String>
<fx:String>vibrant_ink</fx:String>
</s:ArrayCollection>
<s:ArrayCollection id="keyBindings">
<fx:Object value="ace" label="Ace"/>
<fx:Object value="vim" label="Vim"/>
<fx:Object value="emacs" label="Emacs"/>
<fx:Object value="custom" label="Custom"/>
</s:ArrayCollection>
<utils:MiniInspector />
<fx:String id="html" source="examples/html.txt" />
<fx:String id="css" source="./examples/css.txt"/>
<fx:String id="actionscript" source="./examples/actionscript.txt"/>
<fx:String id="javascript" source="/examples/javascript.txt"/>
<fx:String id="php" source="./examples/php.txt"/>
<fx:String id="mxml" source="./examples/mxml.txt"/>
</fx:Declarations>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:HGroup>
<s:Label text="Ace Editor" paddingTop="5" paddingLeft="5" fontSize="24"/>
</s:HGroup>
<s:HGroup>
<s:Label text="Text:" paddingTop="5" paddingLeft="5" minWidth="100"/>
<s:Button id="setContentsButton" label="HTML" click="setContentsButton_clickHandler(event)"/>
<s:Button label="JavaScript" click="setContentsButton_clickHandler(event)"/>
<s:Button label="CSS" click="setContentsButton_clickHandler(event)"/>
<s:Button label="ActionScript" click="setContentsButton_clickHandler(event)"/>
<s:Button label="MXML" click="setContentsButton_clickHandler(event)"/>
</s:HGroup>
<s:HGroup>
<s:Label text="Visuals:" paddingTop="5" paddingLeft="5" minWidth="100"/>
<s:ToggleButton id="showInvisiblesButton" label="Show Invisibles" click="showInvisiblesButton_clickHandler(event)"/>
<s:ToggleButton id="showIndentGuidesButton" label="Show Indent Guides" click="showIndentGuidesButton_clickHandler(event)"/>
<s:ToggleButton id="highlightActiveLineButton" label="Highlight Line" click="highlightLineButton_clickHandler(event)"/>
<s:ToggleButton id="highlightGutterLineButton" label="Highlight Gutter" click="highlightGutterButton_clickHandler(event)"/>
<s:ToggleButton id="highlightSelectedWordButton" label="Highlight Selected Word" click="highlightSelectedWordButton_clickHandler(event)"/>
<s:ToggleButton id="showPrintMarginsButton" label="Print Margins" click="showPrintMarginsButton_clickHandler(event)"/>
</s:HGroup>
<s:HGroup>
<s:Label text="Theme:" paddingTop="5" paddingLeft="5" minWidth="100"/>
<s:DropDownList id="themesList"
minWidth="180"
change="themesList_changeHandler(event)"
requireSelection="true"
selectedIndex="3"
dataProvider="{themes}">
</s:DropDownList>
<s:Label text="Font Size:" paddingTop="5"/>
<s:NumericStepper id="fontSizeStepper"
value="12"
stepSize=".1"
snapInterval="0"
change="fontSize_changeHandler(event)"
maximum="72" minimum="6"/>
<s:Spacer width="100%"/>
</s:HGroup>
<s:HGroup>
<s:Label text="Options:" paddingTop="5" paddingLeft="5" minWidth="100"/>
<s:ToggleButton id="useWordWrapButton" label="Word wrap" click="wordWrapButton_clickHandler(event)"/>
<s:ToggleButton id="showFoldWidgetsButton" label="Folding" click="showFoldingWidgetsButton_clickHandler(event)"/>
<s:ToggleButton id="showGutterButton" label="Gutter" click="showGutterButton_clickHandler(event)"/>
<s:ToggleButton id="useSoftTabsButton" label="Soft Tabs" click="useSoftTabsButton_clickHandler(event)"/>
<s:ToggleButton id="useWorkerButton" label="Use Workers" click="useWorkerButton_clickHandler(event)"/>
<s:ToggleButton id="isReadOnlyButton" label="Read only" click="isReadOnlyButton_clickHandler(event)"/>
<s:Label text="Mode:" paddingTop="5"/>
<s:DropDownList id="modesList"
minWidth="180"
change="modesList_changeHandler(event)"
requireSelection="true"
selectedIndex="2" dataProvider="{modes}">
</s:DropDownList>
<s:Label text="Key Bindings:" paddingTop="5"/>
<s:DropDownList id="keyBindingList"
change="keyBindingList_changeHandler(event)"
requireSelection="true"
selectedIndex="0"
dataProvider="{keyBindings}">
</s:DropDownList>
</s:HGroup>
<s:HGroup >
<s:Label text="Language Tools:" paddingTop="5" paddingLeft="5" minWidth="100"/>
<s:ToggleButton id="enableBasicAutoCompletionButton" label="Basic AutoComplete" click="enableBasicAutoCompletionButton_clickHandler(event)"/>
<s:ToggleButton id="enableLiveAutoCompletionButton" label="Live AutoComplete" click="enableLiveAutoCompletionButton_clickHandler(event)"/>
<s:ToggleButton id="enableBehaviorsButton" label="Behaviors" click="enableBehaviorsButton_clickHandler(event)"/>
<s:ToggleButton id="enableWrapBehaviorsButton" label="Wrap Behaviors" click="enableWrapBehaviorsButton_clickHandler(event)"/>
<s:ToggleButton id="enableSnippetsButton" label="Snippets" click="enableSnippetsButton_clickHandler(event)"/>
<s:ToggleButton id="listeningButton" label="Listen for changes" click="listeningButton_clickHandler(event)"/>
<!--Doesn't seem to prevent or enable anything
<s:ToggleButton id="enableFindButton" label="Enable Find" click="enableFindButton_clickHandler(event)"/>
<s:ToggleButton id="enableReplaceButton" label="Enable Replace" click="enableReplaceButton_clickHandler(event)"/>-->
</s:HGroup>
<local:AceEditor id="ace" height="100%" width="100%"
top="40" left="0" right="0" bottom="10"
margin="20px 0"
complete="ace_completeHandler(event)"
selectionChange="ace_selectionChangeHandler(event)"
cursorChange="ace_cursorChangeHandler(event)"
loadOnCreationComplete="true"
uncaughtScriptException="ace_uncaughtScriptExceptionHandler(event)"
locationChange="ace_locationChangeHandler(event)"/>
<s:HGroup bottom="4" left="1" paddingBottom="5" paddingLeft="5" paddingRight="5" width="100%">
<s:Label text="Find:" paddingTop="5" />
<s:TextInput id="findInput" change="findInput_changeHandler(event)" enter="findInput_changeHandler()"/>
<s:Button id="clearSelectionButton" label="Clear Selection" click="clearSelectionButton_clickHandler(event)"/>
<s:Button id="measurePerformanceButton" label="Measure Tokenizing" click="measurePerformanceButton_clickHandler(event)"/>
<!--<s:Button id="setFocusButton" label="Set Focus" click="setFocusButton_clickHandler(event)"/>
<s:Button id="formatSourceButton" label="Format Source" click="formatSourceButton_clickHandler(event)"/>-->
<s:Spacer width="100%"/>
<s:Label text="Token:" paddingTop="5" />
<s:Label id="tokenLabel" paddingTop="5" minWidth="250"/>
<!--<s:Label text="Mouse Position:" paddingTop="5" />
<s:Label id="mousePositionLabel" paddingTop="5" minWidth="80"/>-->
<s:Label text="Selection:" paddingTop="5" />
<s:Label id="selectionPositionLabel" paddingTop="5" minWidth="80"/>
<s:Label text="Cursor:" paddingTop="5" />
<s:Label id="cursorPositionLabel" paddingTop="5" minWidth="50"/>
</s:HGroup>
</s:WindowedApplication>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- saved from url=(0014)about:internet -->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Ace Editor</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- Include CSS to eliminate any default margins/padding and set the height of the html element and
the body element to 100%, because Firefox, or any Gecko based browser, interprets percentage as
the percentage of the height of its parent container, which has to be set explicitly. Fix for
Firefox 3.6 focus border issues.
-->
<style type="text/css" media="screen">
html, body {
height:100%;
}
body {
margin:0;
padding:0;
overflow:auto;
text-align:left;
background-color: transparent;
}
object:focus {
outline:none;
}
#editor {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
</style>
</head>
<body>
<div id='editor'></div>
<!-- ACE editor -->
<script src="src-min-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script src="src-min-noconflict/ext-language_tools.js" type="text/javascript" charset="utf-8"></script>
<script src="src-min-noconflict/ext-beautify.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment