Fires whenever the anchor position changes. Events that can trigger this function include 'includeText', `'insertL...
+
+
+
Fires whenever the anchor position changes. Events that can trigger this function include 'includeText', 'insertLines', 'removeText', and 'removeLines'.
Tokenizes the current Document in the background, and caches the tokenized rows for future use. If a certain row is changed, everything below that row is re-tokenized.
Contains the text of the document. Documents are controlled by a single EditSession. At its core, Documents are just an array of strings, with each row in the document matching up to the array index.
The position of the last line of text. If the length of text is 0, this function simply returns position. Inserts a block of text and the indicated position.
Returns an object containing the final row and column, like this: {row: endRow, column: 0} If lines is empty, this function returns an object containing the current row, and column, like this: {row: row, column: 0}
Returns the new start property of the range, which contains startRow and startColumn. If range is empty, this function returns the unmodified value of range.start.
+
+
+
+
+
+
+
+
+
+
+
+
+
Document.removeInLine(Number row, Number startColumn, Number endColumn)
+
Returns an object containing startRow and startColumn, indicating the new row and column values. If startColumn is equal to endColumn, this function returns nothing.
+
+
+
+
+
+
+
+
+
+
+
+
+
Document.removeLines(Number firstRow, Number lastRow)
+
Returns an object containing the final row and column, like this: {row: endRow, column: 0} If the text and range are empty, this function returns an object containing the current range.start value. If the text is the exact same as what currently exists, this function returns an object containing the current range.end value.
+
+
+
+
+
+
+
+
+
+
+
+
+
Document.revertDeltas(deltas)
+
+
+
Void
+
+
+
+
+
+
+
+
+
+
Reverts any changes previously applied. These can be either 'includeText', 'insertLines', 'removeText', and `'...
+
+
+
Reverts any changes previously applied. These can be either 'includeText', 'insertLines', 'removeText', and 'removeLines'.
Required. The inital language mode to use for the document
+
+
+
+
+
+
Events
+
+
+
+
+
+
+
+
EditSession.on("onChange", function(e))
+
+
+
+
+
+
+
+
Emitted when the document changes. ...
+
+
+
Emitted when the document changes.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
EditSession.on("onChangeFold", function(e))
+
+
+
+
+
+
+
+
Emitted when a code fold changes its state. ...
+
+
+
Emitted when a code fold changes its state.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
EditSession.on("onReloadTokenizer", function(e))
+
+
+
+
+
+
+
+
Reloads all the tokens on the current session. This function calls [[BackgroundTokenizer.start `BackgroundTokenizer....
+
+
+
Reloads all the tokens on the current session. This function calls BackgroundTokenizer.start () to all the rows; it also emits the 'tokenizerUpdate' event.
Adds a new marker to the given Range. If inFront is true, a front marker is defined, and the `'changeFrontMark...
+
+
+
Adds a new marker to the given Range. If inFront is true, a front marker is defined, and the 'changeFrontMarker' event fires; otherwise, the 'changeBackMarker' event fires.
Converts document coordinates to screen coordinates. This takes into account code folding, word wrap, tab size, and any other visual modifications. ...
+
+
+
Converts document coordinates to screen coordinates. This takes into account code folding, word wrap, tab size, and any other visual modifications.
Returns the current value for tabs. If the user is using soft tabs, this will be a series of spaces (defined by [[Ed...
+
+
+
Returns the current value for tabs. If the user is using soft tabs, this will be a series of spaces (defined by getTabSize); otherwise it's simply '\t'.
The new range where the text was moved to. Moves a range of text from the given range to the given position. toPosition is an object that looks like this:
The new start property of the range, which contains startRow and startColumn. If range is empty, this function returns the unmodified value of range.start.
Removes the marker with the specified ID. If this marker was in front, the 'changeFrontMarker' event is emitted. I...
+
+
+
Removes the marker with the specified ID. If this marker was in front, the 'changeFrontMarker' event is emitted. If the marker was in the back, the 'changeBackMarker' event is emitted.
Returns an object containing the final row and column, like this: {row: endRow, column: 0} If the text and range are empty, this function returns an object containing the current range.start value. If the text is the exact same as what currently exists, this function returns an object containing the current range.end value.
+
+
+
+
+
+
+
+
+
+
+
+
+
EditSession.screenToDocumentPosition(Number screenRow, Number screenColumn)
+
Sets a new text mode for the EditSession. This method also emits the 'changeMode' event. If a [[BackgroundTokeni...
+
+
+
Sets a new text mode for the EditSession. This method also emits the 'changeMode' event. If a BackgroundTokenizer is set, the 'tokenizerUpdate' event is also emitted.
Pass in true to enable overwrites in your session, or false to disable. If overwrites is enabled, any text you e...
+
+
+
Pass in true to enable overwrites in your session, or false to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of overwrite changes, this function also emites the changeOverwrite event.
Set the number of spaces that define a soft tab; for example, passing in 4 transforms the soft tabs to be equivale...
+
+
+
Set the number of spaces that define a soft tab; for example, passing in 4 transforms the soft tabs to be equivalent to four spaces. This function also emits the changeTabSize event.
EditSession.setWrapLimitRange(Number min, Number max)
+
+
+
+
+
+
+
+
Sets the boundaries of wrap. Either value can be null to have an unconstrained wrap, or, they can be the same numb...
+
+
+
Sets the boundaries of wrap. Either value can be null to have an unconstrained wrap, or, they can be the same number to pin the limit. If the wrap limits for min or max are different, this method also emits the 'changeWrapMode' event.
The main entry point into the Ace functionality. The Editor manages the EditSession (which manages Documents), as well as the VirtualRenderer, which draws everything to the screen. Event sessions dealing with the mouse and keyboard are bubbled up from Document to the Editor, which decides what to do with them.
Returns true if the behaviors are currently enabled. "Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets. ...
+
+
+
Returns true if the behaviors are currently enabled. "Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.
Pass in true to enable overwrites in your session, or false to disable. If overwrites is enabled, any text you e...
+
+
+
Pass in true to enable overwrites in your session, or false to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of overwrite changes, this function also emites the changeOverwrite event.
Welcome to the Ace API Reference Guide. Ace is a standalone code editor written in JavaScript that you can embed onto any website. We're used in a bunch of places already, like GitHub, Google, and Facebook.
+
+
+
On the left, you'll find a list of all of our currently documented classes. There are plenty more to do, but these represent the "core" set. For more information on how to work with Ace, check out the main Ace website.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api/multi_select.html b/api/multi_select.html
new file mode 100644
index 00000000..b280767b
--- /dev/null
+++ b/api/multi_select.html
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+ Ace API - multi_select
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
This method returns one of the following numbers: 0 if the two points are exactly equal -1 if p.row is less then the calling range 1 if p.row is greater than the calling range
If the starting row of the calling range is equal to p.row, and: p.column is greater than or equal to the calling range's starting column, this returns 0 Otherwise, it returns -1
If the ending row of the calling range is equal to p.row, and: p.column is less than or equal to the calling range's ending column, this returns 0 Otherwise, it returns 1
This method returns one of the following numbers: 0 if the two points are exactly equal -1 if p.row is less then the calling range 1 if p.row is greater than the calling range, or if isEnd is true.<br/> <br/> If the starting row of the calling range is equal to p.row, and:<br/> p.column is greater than or equal to the calling range's starting column, this returns 0<br/> Otherwise, it returns -1<br/> <br/> If the ending row of the calling range is equal to p.row, and:<br/> p.column is less than or equal to the calling range's ending column, this returns 0` Otherwise, it returns 1
This method returns one of the following numbers: 1 if the ending row of the calling range is equal to row, and the ending column of the calling range is equal to column -1 if the starting row of the calling range is equal to row, and the starting column of the calling range is equal to column
Otherwise, it returns the value after calling compare.
This method returns one of the following numbers: 0 if the two points are exactly equal -1 if p.row is less then the calling range 1 if p.row is greater than the calling range
If the starting row of the calling range is equal to p.row, and: p.column is greater than or equal to the calling range's starting column, this returns 0 Otherwise, it returns -1
If the ending row of the calling range is equal to p.row, and: p.column is less than or equal to the calling range's ending column, this returns 0 Otherwise, it returns 1
-2: (B) is in front of (A), and doesn't intersect with (A) -1: (B) begins before (A) but ends inside of (A) 0: (B) is completely inside of (A) OR (A) is completely inside of (B) +1: (B) begins inside of (A) but ends outside of (A) +2: (B) is after (A) and doesn't intersect with (A) 42: FTW state: (B) ends in (A) but starts outside of (A)
0 if the two points are exactly equal -1 if p.row is less then the calling range 1 if p.row is greater than the calling range, or if isStart is true.
If the starting row of the calling range is equal to p.row, and: p.column is greater than or equal to the calling range's starting column, this returns 0 Otherwise, it returns -1
If the ending row of the calling range is equal to p.row, and: p.column is less than or equal to the calling range's ending column, this returns 0 Otherwise, it returns 1
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,unknownElems:!!a.getElementsByTagName("nav").length,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",enctype:!!c.createElement("form").enctype,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.lastChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-999px",top:"-999px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;f(function(){var a,b,d,e,g,h,i=1,j="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",l="visibility:hidden;border:0;",n="style='"+j+"border:5px solid #000;padding:0;'",p="
Searches for options.needle. If found, this method returns the Range where the text first occurs. If `...
+
+
+
Searches for options.needle. If found, this method returns the Range where the text first occurs. If options.backwards is true, the search goes backwards in the session.
Searches for all occurances options.needle. If found, this method returns an array of Ranges where the...
+
+
+
Searches for all occurances options.needle. If found, this method returns an array of Ranges where the text first occurs. If options.backwards is true, the search goes backwards in the session.
If options.regExp is true, this function returns input with the replacement already made. Otherwise, this function just returns replacement. If options.needle was not found, this function returns null.
Contains the cursor position and the text selection of an edit session.
+
+
+
The row/columns used in the selection are in document coordinates representing ths coordinates as thez appear in the document before applying soft wrap and folding.
Selection.moveCursorToScreen(Number row, Number column, Boolean keepDesiredColumn)
+
+
+
+
+
+
+
+
Moves the cursor to the screen position indicated by row and column. If preventUpdateDesiredColumn is true, then the cursor stays in the same column position as its original point. ...
+
+
+
Moves the cursor to the screen position indicated by row and column. If preventUpdateDesiredColumn is true, then the cursor stays in the same column position as its original point.
Tokenizes all the items from the current point until the next row in the document. If the current point is at the en...
+
+
+
Tokenizes all the items from the current point until the next row in the document. If the current point is at the end of the file, this function returns null. Otherwise, it returns the tokenized string.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/api/tokenizer.html b/api/tokenizer.html
new file mode 100644
index 00000000..44059cfc
--- /dev/null
+++ b/api/tokenizer.html
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+ Ace API - tokenizer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Provides a means for implementing your own undo manager. options has one property, args, an undefined, w...
+
+
+
Provides a means for implementing your own undo manager. options has one property, args, an undefined, with two elements:
+args[0] is an array of deltas
+args[1] is the document to associate with
Returns the index of the first fully visible row. "Fully" here means that the characters in the row are not truncate...
+
+
+
Returns the index of the first fully visible row. "Fully" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.
Returns the index of the last fully visible row. "Fully" here means that the characters in the row are not truncated...
+
+
+
Returns the index of the last fully visible row. "Fully" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.
Triggers a full update of the text, for all the rows. ...
+
+
+
Triggers a full update of the text, for all the rows.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
VirtualRenderer.visualizeBlur()
+
+
+
Void
+
+
+
+
+
+
+
+
+
+
Blurs the current container. ...
+
+
+
Blurs the current container.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
VirtualRenderer.visualizeFocus()
+
+
+
Void
+
+
+
+
+
+
+
+
+
+
Focuses the current container. ...
+
+
+
Focuses the current container.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/build/demo/kitchen-sink/kitchen-sink-uncompressed.js b/build/demo/kitchen-sink/kitchen-sink-uncompressed.js
index bc804e57..8501f93b 100644
--- a/build/demo/kitchen-sink/kitchen-sink-uncompressed.js
+++ b/build/demo/kitchen-sink/kitchen-sink-uncompressed.js
@@ -507,7 +507,8 @@ split.on("focus", function(editor) {
});
env.split = split;
window.env = env;
-window.ace = env.editor;
+window.editor = window.ace = env.editor;
+env.editor.setAnimatedScroll(true);
var docEl = document.getElementById("doc");
var modeEl = document.getElementById("mode");
@@ -601,10 +602,28 @@ function saveOption(el, val) {
}
}
+event.addListener(themeEl, "mouseover", function(e){
+ this.desiredValue = e.target.value;
+ if (!this.$timer)
+ this.$timer = setTimeout(this.updateTheme);
+})
+
+event.addListener(themeEl, "mouseout", function(e){
+ this.desiredValue = null;
+ if (!this.$timer)
+ this.$timer = setTimeout(this.updateTheme, 20);
+})
+
+themeEl.updateTheme = function(){
+ env.split.setTheme(themeEl.desiredValue || themeEl.selectedValue);
+ themeEl.$timer = null;
+}
+
bindDropdown("theme", function(value) {
if (!value)
return;
env.editor.setTheme(value);
+ themeEl.selectedValue = value;
});
bindDropdown("keybinding", function(value) {
@@ -686,6 +705,9 @@ bindCheckbox("enable_behaviours", function(checked) {
env.editor.setBehavioursEnabled(checked);
});
+bindCheckbox("fade_fold_widgets", function(checked) {
+ env.editor.setFadeFoldWidgets(checked);
+});
var secondSession = null;
bindDropdown("split", function(value) {
@@ -847,7 +869,8 @@ define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/rege
require("./regexp");
require("./es5-shim");
-});/**
+});
+/*
* Based on code from:
*
* XRegExp 1.5.0
@@ -985,7 +1008,7 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
-/**
+/*
* Brings an environment as close to ECMAScript 5 compliance
* as is possible with the facilities of erstwhile engines.
*
@@ -2015,7 +2038,8 @@ var prepareString = "a"[0] != "a",
}
return Object(o);
};
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -2142,7 +2166,8 @@ function deHyphenate(str) {
return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
}
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2245,7 +2270,7 @@ exports.arrayToMap = function(arr) {
};
-/**
+/*
* splice out of 'array' anything that === 'value'
*/
exports.arrayRemove = function(array, value) {
@@ -2358,7 +2383,7 @@ exports.removeListener = function(elem, type, callback) {
}
};
-/**
+/*
* Prevents propagation and clobbers the default action of the passed event
*/
exports.stopEvent = function(e) {
@@ -2381,23 +2406,7 @@ exports.preventDefault = function(e) {
e.returnValue = false;
};
-exports.getDocumentX = function(e) {
- if (e.clientX) {
- return e.clientX + dom.getPageScrollLeft();
- } else {
- return e.pageX;
- }
-};
-
-exports.getDocumentY = function(e) {
- if (e.clientY) {
- return e.clientY + dom.getPageScrollTop();
- } else {
- return e.pageY;
- }
-};
-
-/**
+/*
* @return {Number} 0 for left button, 1 for middle button, 2 for right button
*/
exports.getButton = function(e) {
@@ -2654,7 +2663,7 @@ define('ace/lib/keys', ['require', 'exports', 'module' , 'ace/lib/oop'], functio
var oop = require("./oop");
-/**
+/*
* Helper functions and hashes for key handling.
*/
var Keys = (function() {
@@ -2744,7 +2753,8 @@ exports.keyCodeToString = function(keyCode) {
return (Keys[keyCode] || String.fromCharCode(keyCode)).toLowerCase();
}
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2848,13 +2858,13 @@ define('ace/lib/useragent', ['require', 'exports', 'module' ], function(require,
var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
var ua = navigator.userAgent;
-/** Is the user using a browser that identifies itself as Windows */
+// Is the user using a browser that identifies itself as Windows
exports.isWin = (os == "win");
-/** Is the user using a browser that identifies itself as Mac OS */
+// Is the user using a browser that identifies itself as Mac OS
exports.isMac = (os == "mac");
-/** Is the user using a browser that identifies itself as Linux */
+// Is the user using a browser that identifies itself as Linux
exports.isLinux = (os == "linux");
exports.isIE =
@@ -2863,16 +2873,16 @@ exports.isIE =
exports.isOldIE = exports.isIE && exports.isIE < 9;
-/** Is this Firefox or related? */
+// Is this Firefox or related?
exports.isGecko = exports.isMozilla = window.controllers && window.navigator.product === "Gecko";
-/** oldGecko == rev < 2.0 **/
+// oldGecko == rev < 2.0
exports.isOldGecko = exports.isGecko && parseInt((navigator.userAgent.match(/rv\:(\d+)/)||[])[1], 10) < 4;
-/** Is this Opera */
+// Is this Opera
exports.isOpera = window.opera && Object.prototype.toString.call(window.opera) == "[object Opera]";
-/** Is the user using a browser that identifies itself as WebKit */
+// Is the user using a browser that identifies itself as WebKit
exports.isWebKit = parseFloat(ua.split("WebKit/")[1]) || undefined;
exports.isChrome = parseFloat(ua.split(" Chrome/")[1]) || undefined;
@@ -2883,7 +2893,7 @@ exports.isIPad = ua.indexOf("iPad") >= 0;
exports.isTouchPad = ua.indexOf("TouchPad") >= 0;
-/**
+/*
* I hate doing this, but we need some way to determine if the user is on a Mac
* The reason is that users have different expectations of their key combinations.
*
@@ -2896,7 +2906,7 @@ exports.OS = {
WINDOWS: "WINDOWS"
};
-/**
+/*
* Return an exports.OS constant
*/
exports.getOS = function() {
@@ -2975,7 +2985,7 @@ exports.hasCssClass = function(el, name) {
return classes.indexOf(name) !== -1;
};
-/**
+/*
* Add a CSS class to the list of classes on the given node
*/
exports.addCssClass = function(el, name) {
@@ -2984,7 +2994,7 @@ exports.addCssClass = function(el, name) {
}
};
-/**
+/*
* Remove a CSS class from the list of classes on the given node
*/
exports.removeCssClass = function(el, name) {
@@ -3016,7 +3026,7 @@ exports.toggleCssClass = function(el, name) {
return add;
};
-/**
+/*
* Add or remove a CSS class from the list of classes on the given node
* depending on the value of include
*/
@@ -3167,7 +3177,7 @@ exports.scrollbarWidth = function(document) {
return noScrollbar-withScrollbar;
};
-/**
+/*
* Optimized set innerHTML. This is faster than plain innerHTML if the element
* already contains a lot of child elements.
*
@@ -3201,7 +3211,8 @@ exports.getParentWindow = function(document) {
return document.defaultView || document.parentWindow;
};
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -3304,8 +3315,8 @@ exports.cssText = ".ace-tm .ace_editor {\
}\
\
.ace-tm .ace_line .ace_invalid {\
- background-color: rgb(153, 0, 0);\
- color: white;\
+ background-color: rgba(255, 0, 0, 0.1);\
+ color: red;\
}\
\
.ace-tm .ace_line .ace_support.ace_function {\
@@ -3392,6 +3403,9 @@ exports.cssText = ".ace-tm .ace_editor {\
.ace-tm .ace_marker-layer .ace_active_line {\
background: rgba(0, 0, 0, 0.07);\
}\
+.ace-tm .ace_gutter_active_line{\
+ background-color : #dcdcdc;\
+}\
\
.ace-tm .ace_marker-layer .ace_selected_word {\
background: rgb(250, 250, 255);\
@@ -3463,6 +3477,22 @@ var Range = require("./range").Range;
var Document = require("./document").Document;
var BackgroundTokenizer = require("./background_tokenizer").BackgroundTokenizer;
+/**
+ * class EditSession
+ *
+ * Stores various states related to a [[Document `Document`]]. A single `EditSession` can be in charge of several `Document`s.
+ *
+ **/
+
+/**
+ * new EditSession(text, mode)
+ * - text (Document | String): If `text` is a `Document`, it associates the `EditSession` with it. Otherwise, a new `Document` is created, with the initial text
+ * - mode (TextMode): The inital language mode to use for the document
+ *
+ * Sets up a new `EditSession` and associates it with the given `Document` and `TextMode`.
+ *
+ **/
+
var EditSession = function(text, mode) {
this.$modified = true;
this.$breakpoints = [];
@@ -3488,10 +3518,7 @@ var EditSession = function(text, mode) {
}
this.selection = new Selection(this);
- if (mode)
- this.setMode(mode);
- else
- this.setMode(new TextMode());
+ this.setMode(mode);
};
@@ -3499,6 +3526,13 @@ var EditSession = function(text, mode) {
oop.implement(this, EventEmitter);
+ /**
+ * EditSession.setDocument(doc)
+ * - doc (Document): The new `Document` to use
+ *
+ * Sets the `EditSession` to point to a new `Document`. If a `BackgroundTokenizer` exists, it also points to `doc`.
+ *
+ **/
this.setDocument = function(doc) {
if (this.doc)
throw new Error("Document is already set");
@@ -3513,10 +3547,23 @@ var EditSession = function(text, mode) {
}
};
+ /**
+ * EditSession.getDocument() -> Document
+ *
+ * Returns the `Document` associated with this session.
+ *
+ **/
this.getDocument = function() {
return this.doc;
};
+ /** internal, hide
+ * EditSession.$resetRowCache(row)
+ * - row (Number): The row to work with
+ *
+ *
+ *
+ **/
this.$resetRowCache = function(row) {
if (row == 0) {
this.$rowCache = [];
@@ -3531,11 +3578,22 @@ var EditSession = function(text, mode) {
}
};
+ /**
+ * EditSession@onChangeFold(e)
+ *
+ * Emitted when a code fold changes its state.
+ *
+ **/
this.onChangeFold = function(e) {
var fold = e.data;
this.$resetRowCache(fold.start.row);
};
+ /**
+ * EditSession@onChange(e)
+ *
+ * Emitted when the document changes.
+ **/
this.onChange = function(e) {
var delta = e.data;
this.$modified = true;
@@ -3559,6 +3617,13 @@ var EditSession = function(text, mode) {
this._emit("change", e);
};
+ /**
+ * EditSession.setValue(text)
+ * - text (String): The new text to place
+ *
+ * Sets the session text.
+ *
+ **/
this.setValue = function(text) {
this.doc.setValue(text);
this.selection.moveCursorTo(0, 0);
@@ -3571,23 +3636,62 @@ var EditSession = function(text, mode) {
this.getUndoManager().reset();
};
+ /** alias of: EditSession.toString
+ * EditSession.getValue() -> String
+ *
+ * Returns the current [[Document `Document`]] as a string.
+ *
+ **/
+ /** alias of: EditSession.getValue
+ * EditSession.toString() -> String
+ *
+ * Returns the current [[Document `Document`]] as a string.
+ *
+ **/
this.getValue =
this.toString = function() {
return this.doc.getValue();
};
+ /**
+ * EditSession.getSelection() -> String
+ *
+ * Returns the string of the current selection.
+ **/
this.getSelection = function() {
return this.selection;
};
+ /** related to: BackgroundTokenizer.getState
+ * EditSession.getState(row) -> Array
+ * - row (Number): The row to start at
+ *
+ * {:BackgroundTokenizer.getState}
+ *
+ **/
this.getState = function(row) {
return this.bgTokenizer.getState(row);
};
+ /** related to: BackgroundTokenizer.getTokens
+ * EditSession.getTokens(firstRow, lastRow) -> Array
+ * - firstRow (Number): The row to start at
+ * - lastRow (Number): The row to finish at
+ *
+ * Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.
+ *
+ **/
this.getTokens = function(firstRow, lastRow) {
return this.bgTokenizer.getTokens(firstRow, lastRow);
};
+ /**
+ * EditSession.getTokenAt(row, column) -> Array
+ * - row (Number): The row number to retrieve from
+ * - column (Number): The column number to retrieve from
+ *
+ * Returns an array of tokens at the indicated row and column.
+ **/
this.getTokenAt = function(row, column) {
var tokens = this.bgTokenizer.getTokens(row, row)[0].tokens;
var token, c = 0;
@@ -3609,6 +3713,12 @@ var EditSession = function(text, mode) {
return token;
};
+ /**
+ * EditSession.setUndoManager(undoManager)
+ * - undoManager (UndoManager): The new undo manager
+ *
+ * Sets the undo manager.
+ **/
this.setUndoManager = function(undoManager) {
this.$undoManager = undoManager;
this.$resetRowCache(0);
@@ -3621,6 +3731,11 @@ var EditSession = function(text, mode) {
if (undoManager) {
var self = this;
+ /** internal, hide
+ * EditSession.$syncInformUndoManager()
+ *
+ *
+ **/
this.$syncInformUndoManager = function() {
self.$informUndoManager.cancel();
@@ -3660,10 +3775,20 @@ var EditSession = function(text, mode) {
reset: function() {}
};
+ /**
+ * EditSession.getUndoManager() -> UndoManager
+ *
+ * Returns the current undo manager.
+ **/
this.getUndoManager = function() {
return this.$undoManager || this.$defaultUndoManager;
},
+ /**
+ * EditSession.getTabString() -> String
+ *
+ * Returns the current value for tabs. If the user is using soft tabs, this will be a series of spaces (defined by [[EditSession.getTabSize `getTabSize()`]]); otherwise it's simply `'\t'`.
+ **/
this.getTabString = function() {
if (this.getUseSoftTabs()) {
return lang.stringRepeat(" ", this.getTabSize());
@@ -3673,17 +3798,36 @@ var EditSession = function(text, mode) {
};
this.$useSoftTabs = true;
+ /**
+ * EditSession.setUseSoftTabs(useSoftTabs)
+ * - useSoftTabs (Boolean): Value indicating whether or not to use soft tabs
+ *
+ * Pass `true` to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character (`'\t'`).
+ *
+ **/
this.setUseSoftTabs = function(useSoftTabs) {
if (this.$useSoftTabs === useSoftTabs) return;
this.$useSoftTabs = useSoftTabs;
};
+ /**
+ * EditSession.getUseSoftTabs() -> Boolean
+ *
+ * Returns `true` if soft tabs are being used, `false` otherwise.
+ *
+ **/
this.getUseSoftTabs = function() {
return this.$useSoftTabs;
};
this.$tabSize = 4;
+ /**
+ * EditSession.setTabSize(tabSize)
+ * - tabSize (Number): The new tab size
+ *
+ * Set the number of spaces that define a soft tab; for example, passing in `4` transforms the soft tabs to be equivalent to four spaces. This function also emits the `changeTabSize` event.
+ **/
this.setTabSize = function(tabSize) {
if (isNaN(tabSize) || this.$tabSize === tabSize) return;
@@ -3692,15 +3836,33 @@ var EditSession = function(text, mode) {
this._emit("changeTabSize");
};
+ /**
+ * EditSession.getTabSize() -> Number
+ *
+ * Returns the current tab size.
+ **/
this.getTabSize = function() {
return this.$tabSize;
};
+ /**
+ * EditSession.isTabStop(position) -> Boolean
+ * - position (Object): The position to check
+ *
+ * Returns `true` if the character at the position is a soft tab.
+ **/
this.isTabStop = function(position) {
return this.$useSoftTabs && (position.column % this.$tabSize == 0);
};
this.$overwrite = false;
+ /**
+ * EditSession.setOverwrite(overwrite)
+ * - overwrite (Boolean): Defines wheter or not to set overwrites
+ *
+ * Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emites the `changeOverwrite` event.
+ *
+ **/
this.setOverwrite = function(overwrite) {
if (this.$overwrite == overwrite) return;
@@ -3708,18 +3870,40 @@ var EditSession = function(text, mode) {
this._emit("changeOverwrite");
};
+ /**
+ * EditSession.getOverwrite() -> Boolean
+ *
+ * Returns `true` if overwrites are enabled; `false` otherwise.
+ **/
this.getOverwrite = function() {
return this.$overwrite;
};
+ /**
+ * EditSession.toggleOverwrite()
+ *
+ * Sets the value of overwrite to the opposite of whatever it currently is.
+ **/
this.toggleOverwrite = function() {
this.setOverwrite(!this.$overwrite);
};
+ /**
+ * EditSession.getBreakpoints() -> Array
+ *
+ * Returns an array of numbers, indicating which rows have breakpoints.
+ **/
this.getBreakpoints = function() {
return this.$breakpoints;
};
+ /**
+ * EditSession.setBreakpoints(rows)
+ * - rows (Array): An array of row indicies
+ *
+ * Sets a breakpoint on every row number given by `rows`. This function also emites the `'changeBreakpoint'` event.
+ *
+ **/
this.setBreakpoints = function(rows) {
this.$breakpoints = [];
for (var i=0; i Number
+ * - range (Range): Define the range of the marker
+ * - clazz (String): Set the CSS class for the marker
+ * - type (Function | String): Identify the type of the marker
+ * - inFront (Boolean): Set to `true` to establish a front marker
+ *
+ * Adds a new marker to the given `Range`. If `inFront` is `true`, a front marker is defined, and the `'changeFrontMarker'` event fires; otherwise, the `'changeBackMarker'` event fires.
+ *
+ **/
this.addMarker = function(range, clazz, type, inFront) {
var id = this.$markerId++;
@@ -3769,6 +3976,13 @@ var EditSession = function(text, mode) {
return id;
};
+ /**
+ * EditSession.removeMarker(markerId)
+ * - markerId (Number): A number representing a marker
+ *
+ * Removes the marker with the specified ID. If this marker was in front, the `'changeFrontMarker'` event is emitted. If the marker was in the back, the `'changeBackMarker'` event is emitted.
+ *
+ **/
this.removeMarker = function(markerId) {
var marker = this.$frontMarkers[markerId] || this.$backMarkers[markerId];
if (!marker)
@@ -3781,11 +3995,18 @@ var EditSession = function(text, mode) {
}
};
+ /**
+ * EditSession.getMarkers(inFront) -> Array
+ * - inFront (Boolean): If `true`, indicates you only want front markers; `false` indicates only back markers
+ *
+ * Returns an array containing the IDs of all the markers, either front or back.
+ *
+ **/
this.getMarkers = function(inFront) {
return inFront ? this.$frontMarkers : this.$backMarkers;
};
- /**
+ /*
* Error:
* {
* row: 12,
@@ -3794,6 +4015,12 @@ var EditSession = function(text, mode) {
* type: "error" // or "warning" or "info"
* }
*/
+ /**
+ * EditSession.setAnnotations(annotations)
+ * - annotations (Array): A list of annotations
+ *
+ * Sets annotations for the `EditSession`. This functions emits the `'changeAnnotation'` event.
+ **/
this.setAnnotations = function(annotations) {
this.$annotations = {};
for (var i=0; i Object
+ *
+ * Returns the annotations for the `EditSession`.
+ **/
this.getAnnotations = function() {
return this.$annotations || {};
};
+ /**
+ * EditSession.clearAnnotations()
+ *
+ * Clears all the annotations for this session. This function also triggers the `'changeAnnotation'` event.
+ **/
this.clearAnnotations = function() {
this.$annotations = {};
this._emit("changeAnnotation", {});
};
+ /** internal, hide
+ * EditSession.$detectNewLine(text)
+ * - text (String): A block of text
+ *
+ * If `text` contains either the newline (`\n`) or carriage-return ('\r') characters, `$autoNewLine` stores that value.
+ *
+ **/
this.$detectNewLine = function(text) {
var match = text.match(/^.*?(\r?\n)/m);
if (match) {
@@ -3825,6 +4069,14 @@ var EditSession = function(text, mode) {
}
};
+ /**
+ * EditSession.getWordRange(row, column) -> Range
+ * - row (Number): The row to start at
+ * - column (Number): The column to start at
+ *
+ * Given a starting row and column, this method returns the `Range` of the first word boundary it finds.
+ *
+ **/
this.getWordRange = function(row, column) {
var line = this.getLine(row);
@@ -3856,7 +4108,13 @@ var EditSession = function(text, mode) {
return new Range(row, start, row, end);
};
- // Gets the range of a word including its right whitespace
+ /**
+ * EditSession.getAWordRange(row, column) -> Range
+ * - row (Number): The row number to start from
+ * - column (Number): The column number to start from
+ *
+ * Gets the range of a word, including its right whitespace.
+ **/
this.getAWordRange = function(row, column) {
var wordRange = this.getWordRange(row, column);
var line = this.getLine(wordRange.end.row);
@@ -3867,15 +4125,34 @@ var EditSession = function(text, mode) {
return wordRange;
};
+ /** related to: Document.setNewLineMode
+ * EditSession.setNewLineMode(newLineMode)
+ * - newLineMode (String): {:Document.setNewLineMode.param}
+ *
+ * {:Document.setNewLineMode.desc}
+ **/
this.setNewLineMode = function(newLineMode) {
this.doc.setNewLineMode(newLineMode);
};
+ /** related to: Document.getNewLineMode
+ * EditSession.getNewLineMode() -> String
+ *
+ * Returns the current new line mode.
+ **/
this.getNewLineMode = function() {
return this.doc.getNewLineMode();
};
this.$useWorker = true;
+
+ /**
+ * EditSession.setUseWorker(useWorker)
+ * - useWorker (Boolean): Set to `true` to use a worker
+ *
+ * Identifies if you want to use a worker for the `EditSession`.
+ *
+ **/
this.setUseWorker = function(useWorker) {
if (this.$useWorker == useWorker)
return;
@@ -3887,10 +4164,20 @@ var EditSession = function(text, mode) {
this.$startWorker();
};
+ /**
+ * EditSession.getUseWorker() -> Boolean
+ *
+ * Returns `true` if workers are being used.
+ **/
this.getUseWorker = function() {
return this.$useWorker;
};
+ /**
+ * EditSession@onReloadTokenizer(e)
+ *
+ * Reloads all the tokens on the current session. This function calls [[BackgroundTokenizer.start `BackgroundTokenizer.start ()`]] to all the rows; it also emits the `'tokenizerUpdate'` event.
+ **/
this.onReloadTokenizer = function(e) {
var rows = e.data;
this.bgTokenizer.start(rows.first);
@@ -3901,7 +4188,7 @@ var EditSession = function(text, mode) {
this._loadMode = function(mode, callback) {
if (this.$modes[mode])
return callback(this.$modes[mode]);
-
+
var _self = this;
var module;
try {
@@ -3909,16 +4196,17 @@ var EditSession = function(text, mode) {
} catch (e) {};
if (module)
return done(module);
-
+
fetch(function() {
require([mode], done);
});
-
+
function done(module) {
if (_self.$modes[mode])
return callback(_self.$modes[mode]);
-
+
_self.$modes[mode] = new module.Mode();
+ _self.$modes[mode].$id = mode;
_self._emit("loadmode", {
name: mode,
mode: _self.$modes[mode]
@@ -3929,33 +4217,48 @@ var EditSession = function(text, mode) {
function fetch(callback) {
if (!config.get("packaged"))
return callback();
-
+
var base = mode.split("/").pop();
var filename = config.get("modePath") + "/mode-" + base + config.get("suffix");
net.loadScript(filename, callback);
}
};
+ /**
+ * EditSession.setMode(mode)
+ * - mode (TextMode): Set a new text mode
+ *
+ * Sets a new text mode for the `EditSession`. This method also emits the `'changeMode'` event. If a [[BackgroundTokenizer `BackgroundTokenizer`]] is set, the `'tokenizerUpdate'` event is also emitted.
+ *
+ **/
this.$mode = null;
- this.$origMode = null;
+ this.$modeId = null;
this.setMode = function(mode) {
- this.$origMode = mode;
-
// load on demand
if (typeof mode === "string") {
+ if (this.$modeId == mode)
+ return;
+
+ this.$modeId = mode;
var _self = this;
this._loadMode(mode, function(module) {
- if (_self.$origMode !== mode)
+ if (_self.$modeId !== mode)
return;
-
+
_self.setMode(module);
});
return;
+ } else if (mode == null) {
+ mode = "ace/mode/text"
+ this.$modeId = mode;
+ this.$modes[mode] = this.$modes[mode] || (new TextMode());
+ this.setMode(this.$modes[mode]);
+ return;
}
-
+
if (this.$mode === mode) return;
this.$mode = mode;
-
+ this.$modeId = mode.$id;
this.$stopWorker();
@@ -3990,6 +4293,11 @@ var EditSession = function(text, mode) {
this._emit("changeMode");
};
+ /** internal, hide
+ * EditSession.stopWorker()
+ *
+ *
+ **/
this.$stopWorker = function() {
if (this.$worker)
this.$worker.terminate();
@@ -3997,6 +4305,11 @@ var EditSession = function(text, mode) {
this.$worker = null;
};
+ /** internal, hide
+ * EditSession.$startWorker()
+ *
+ *
+ **/
this.$startWorker = function() {
if (typeof Worker !== "undefined" && !require.noWorker) {
try {
@@ -4011,11 +4324,22 @@ var EditSession = function(text, mode) {
this.$worker = null;
};
+ /**
+ * EditSession.getMode() -> TextMode
+ *
+ * Returns the current text mode.
+ **/
this.getMode = function() {
return this.$mode;
};
-
+
this.$scrollTop = 0;
+ /**
+ * EditSession.setScrollTop(scrollTop)
+ * - scrollTop (Number): The new scroll top value
+ *
+ * This function sets the scroll top value. It also emits the `'changeScrollTop'` event.
+ **/
this.setScrollTop = function(scrollTop) {
scrollTop = Math.round(Math.max(0, scrollTop));
if (this.$scrollTop === scrollTop)
@@ -4025,11 +4349,21 @@ var EditSession = function(text, mode) {
this._emit("changeScrollTop", scrollTop);
};
+ /**
+ * EditSession.getScrollTop() -> Number
+ *
+ * [Returns the value of the distance between the top of the editor and the topmost part of the visible content.]{: #EditSession.getScrollTop}
+ **/
this.getScrollTop = function() {
return this.$scrollTop;
};
-
+
this.$scrollLeft = 0;
+ /**
+ * EditSession.setScrollLeft(scrollLeft)
+ *
+ * [Sets the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.setScrollLeft}
+ **/
this.setScrollLeft = function(scrollLeft) {
scrollLeft = Math.round(Math.max(0, scrollLeft));
if (this.$scrollLeft === scrollLeft)
@@ -4039,15 +4373,30 @@ var EditSession = function(text, mode) {
this._emit("changeScrollLeft", scrollLeft);
};
+ /**
+ * EditSession.getScrollLeft() -> Number
+ *
+ * [Returns the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #EditSession.getScrollLeft}
+ **/
this.getScrollLeft = function() {
return this.$scrollLeft;
};
+ /**
+ * EditSession.getWidth() -> Number
+ *
+ * Returns the width of the document.
+ **/
this.getWidth = function() {
this.$computeWidth();
return this.width;
};
+ /**
+ * EditSession.getScreenWidth() -> Number
+ *
+ * Returns the width of the screen.
+ **/
this.getScreenWidth = function() {
this.$computeWidth();
return this.screenWidth;
@@ -4092,33 +4441,82 @@ var EditSession = function(text, mode) {
}
};
- /**
- * Get a verbatim copy of the given line as it is in the document
- */
+ /** related to: Document.getLine
+ * EditSession.getLine(row) -> String
+ * - row (Number): The row to retrieve from
+ *
+ * Returns a verbatim copy of the given line as it is in the document
+ *
+ **/
this.getLine = function(row) {
return this.doc.getLine(row);
};
+ /** related to: Document.getLines
+ * EditSession.getLines(firstRow, lastRow) -> Array
+ * - firstRow (Number): The first row index to retrieve
+ * - lastRow (Number): The final row index to retrieve
+ *
+ * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
+ *
+ **/
this.getLines = function(firstRow, lastRow) {
return this.doc.getLines(firstRow, lastRow);
};
+ /** related to: Document.getLength
+ * EditSession.getLength()-> Number
+ *
+ * Returns the number of rows in the document.
+ **/
this.getLength = function() {
return this.doc.getLength();
};
+ /** related to: Document.getTextRange
+ * EditSession.getTextRange(range) -> Array
+ * - range (String): The range to work with
+ *
+ * {:Document.getTextRange.desc}
+ **/
this.getTextRange = function(range) {
return this.doc.getTextRange(range);
};
+ /** related to: Document.insert
+ * EditSession.insert(position, text) -> Number
+ * - position (Number): The position to start inserting at
+ * - text (String): A chunk of text to insert
+ * + (Number): The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.
+ *
+ * Inserts a block of `text` and the indicated `position`.
+ *
+ *
+ **/
this.insert = function(position, text) {
return this.doc.insert(position, text);
};
+ /** related to: Document.remove
+ * EditSession.remove(range) -> Object
+ * - range (Range): A specified Range to remove
+ * + (Object): The new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
+ *
+ * Removes the `range` from the document.
+ *
+ *
+ **/
this.remove = function(range) {
return this.doc.remove(range);
};
+ /**
+ * EditSession.undoChanges(deltas, dontSelect) -> Range
+ * - deltas (Array): An array of previous changes
+ * - dontSelect (Boolean): [If `true`, doesn't select the range of where the change occured]{: #dontSelect}
+ *
+ * Reverts previous changes to your document.
+ **/
this.undoChanges = function(deltas, dontSelect) {
if (!deltas.length)
return;
@@ -4145,6 +4543,13 @@ var EditSession = function(text, mode) {
return lastUndoRange;
};
+ /**
+ * EditSession.redoChanges(deltas, dontSelect) -> Range
+ * - deltas (Array): An array of previous changes
+ * - dontSelect (Boolean): {:dontSelect}
+ *
+ * Re-implements a previously undone change to your document.
+ **/
this.redoChanges = function(deltas, dontSelect) {
if (!deltas.length)
return;
@@ -4167,10 +4572,21 @@ var EditSession = function(text, mode) {
return lastUndoRange;
};
+ /**
+ * EditSession.setUndoSelect(enable)
+ * - enable (Boolean): If `true`, selects the range of the reinserted change
+ *
+ * ENables or disables highlighting of the range where an undo occured.
+ **/
this.setUndoSelect = function(enable) {
this.$undoSelect = enable;
};
+ /** internal, hide
+ * EditSession.$getUndoSelection(deltas, isUndo, lastUndoRange) -> Range
+ *
+ *
+ **/
this.$getUndoSelection = function(deltas, isUndo, lastUndoRange) {
function isInsert(delta) {
var insert =
@@ -4225,19 +4641,36 @@ var EditSession = function(text, mode) {
return range;
},
+ /** related to: Document.replace
+ * EditSession.replace(range, text) -> Object
+ * - range (Range): A specified Range to replace
+ * - text (String): The new text to use as a replacement
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * If the text and range are empty, this function returns an object containing the current `range.start` value.
+ * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
+ *
+ * Replaces a range in the document with the new `text`.
+ *
+ *
+ *
+ **/
this.replace = function(range, text) {
return this.doc.replace(range, text);
};
/**
- * Move a range of text from the given range to the given position.
- *
- * @param fromRange {Range} The range of text you want moved within the
- * document.
- * @param toPosition {Object} The location (row and column) where you want
- * to move the text to.
- * @return {Range} The new range where the text was moved to.
- */
+ * EditSession.moveText(fromRange, toPosition) -> Range
+ * - fromRange (Range): The range of text you want moved within the document
+ * - toPosition (Object): The location (row and column) where you want to move the text to
+ * + (Range): The new range where the text was moved to.
+ * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:
+ *
+ * { row: newRowLocation, column: newColumnLocation }
+ *
+ *
+ *
+ **/
this.moveText = function(fromRange, toPosition) {
var text = this.getTextRange(fromRange);
this.remove(fromRange);
@@ -4268,12 +4701,30 @@ var EditSession = function(text, mode) {
return toRange;
};
+ /**
+ * EditSession.indentRows(startRow, endRow, indentString)
+ * - startRow (Number): Starting row
+ * - endRow (Number): Ending row
+ * - indentString (String): The indent token
+ *
+ * Indents all the rows, from `startRow` to `endRow` (inclusive), by prefixing each row with the token in `indentString`.
+ *
+ * If `indentString` contains the `'\t'` character, it's replaced by whatever is defined by [[EditSession.getTabString `getTabString()`]].
+ *
+ **/
this.indentRows = function(startRow, endRow, indentString) {
indentString = indentString.replace(/\t/g, this.getTabString());
for (var row=startRow; row<=endRow; row++)
this.insert({row: row, column:0}, indentString);
};
+ /**
+ * EditSession.outdentRows(range)
+ * - range (Range): A range of rows
+ *
+ * Outdents all the rows defined by the `start` and `end` properties of `range`.
+ *
+ **/
this.outdentRows = function (range) {
var rowRange = range.collapseRows();
var deleteRange = new Range(0, 0, 0, 0);
@@ -4298,6 +4749,16 @@ var EditSession = function(text, mode) {
}
};
+ /** related to: Document.insertLines
+ * EditSession.moveLinesUp(firstRow, lastRow) -> Number
+ * - firstRow (Number): The starting row to move up
+ * - lastRow (Number): The final row to move up
+ * + (Number): If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.
+ *
+ * Shifts all the lines in the document up one, starting from `firstRow` and ending at `lastRow`.
+ *
+ *
+ **/
this.moveLinesUp = function(firstRow, lastRow) {
if (firstRow <= 0) return 0;
@@ -4306,6 +4767,15 @@ var EditSession = function(text, mode) {
return -1;
};
+ /** related to: Document.insertLines
+ * EditSession.moveLinesDown(firstRow, lastRow) -> Number
+ * - firstRow (Number): The starting row to move down
+ * - lastRow (Number): The final row to move down
+ * + (Number): If `firstRow` is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.
+ *
+ *
+ *
+ **/
this.moveLinesDown = function(firstRow, lastRow) {
if (lastRow >= this.doc.getLength()-1) return 0;
@@ -4314,6 +4784,17 @@ var EditSession = function(text, mode) {
return 1;
};
+ /**
+ * EditSession.duplicateLines(firstRow, lastRow) -> Number
+ * - firstRow (Number): The starting row to duplicate
+ * - lastRow (Number): The final row to duplicate
+ * + (Number): Returns the number of new rows added; in other words, `lastRow - firstRow + 1`.
+ *
+ * Duplicates all the text between `firstRow` and `lastRow`.
+ *
+ *
+ *
+ **/
this.duplicateLines = function(firstRow, lastRow) {
var firstRow = this.$clipRowToDocument(firstRow);
var lastRow = this.$clipRowToDocument(lastRow);
@@ -4325,6 +4806,7 @@ var EditSession = function(text, mode) {
return addedRows;
};
+
this.$clipRowToDocument = function(row) {
return Math.max(0, Math.min(row, this.doc.getLength()-1));
};
@@ -4335,6 +4817,7 @@ var EditSession = function(text, mode) {
return Math.min(this.doc.getLine(row).length, column);
};
+
this.$clipPositionToDocument = function(row, column) {
column = Math.max(0, column);
@@ -4367,7 +4850,7 @@ var EditSession = function(text, mode) {
range.start.column
);
}
-
+
var len = this.doc.getLength() - 1;
if (range.end.row > len) {
range.end.row = len;
@@ -4389,6 +4872,12 @@ var EditSession = function(text, mode) {
max : null
};
+ /**
+ * EditSession.setUseWrapMode(useWrapMode)
+ * - useWrapMode (Boolean): Enable (or disable) wrap mode
+ *
+ * Sets whether or not line wrapping is enabled. If `useWrapMode` is different than the current value, the `'changeWrapMode'` event is emitted.
+ **/
this.setUseWrapMode = function(useWrapMode) {
if (useWrapMode != this.$useWrapMode) {
this.$useWrapMode = useWrapMode;
@@ -4409,6 +4898,11 @@ var EditSession = function(text, mode) {
}
};
+ /**
+ * EditSession.getUseWrapMode() -> Boolean
+ *
+ * Returns `true` if wrap mode is being used; `false` otherwise.
+ **/
this.getUseWrapMode = function() {
return this.$useWrapMode;
};
@@ -4417,6 +4911,13 @@ var EditSession = function(text, mode) {
// parameter can be null to allow the wrap limit to be unconstrained
// in that direction. Or set both parameters to the same number to pin
// the limit to that value.
+ /**
+ * EditSession.setWrapLimitRange(min, max)
+ * - min (Number): The minimum wrap value (the left side wrap)
+ * - max (Number): The maximum wrap value (the right side wrap)
+ *
+ * Sets the boundaries of wrap. Either value can be `null` to have an unconstrained wrap, or, they can be the same number to pin the limit. If the wrap limits for `min` or `max` are different, this method also emits the `'changeWrapMode'` event.
+ **/
this.setWrapLimitRange = function(min, max) {
if (this.$wrapLimitRange.min !== min || this.$wrapLimitRange.max !== max) {
this.$wrapLimitRange.min = min;
@@ -4427,8 +4928,12 @@ var EditSession = function(text, mode) {
}
};
- // This should generally only be called by the renderer when a resize
- // is detected.
+ /** internal, hide
+ * EditSession.adjustWrapLimit(desiredLimit) -> Boolean
+ * - desiredLimit (Number): The new wrap limit
+ *
+ * This should generally only be called by the renderer when a resize is detected.
+ **/
this.adjustWrapLimit = function(desiredLimit) {
var wrapLimit = this.$constrainWrapLimit(desiredLimit);
if (wrapLimit != this.$wrapLimit && wrapLimit > 0) {
@@ -4444,6 +4949,11 @@ var EditSession = function(text, mode) {
return false;
};
+ /** internal, hide
+ * EditSession.$constrainWrapLimit(wrapLimit)
+ *
+ *
+ **/
this.$constrainWrapLimit = function(wrapLimit) {
var min = this.$wrapLimitRange.min;
if (min)
@@ -4457,10 +4967,23 @@ var EditSession = function(text, mode) {
return Math.max(1, wrapLimit);
};
+ /**
+ * EditSession.getWrapLimit() -> Number
+ *
+ * Returns the value of wrap limit.
+ **/
this.getWrapLimit = function() {
return this.$wrapLimit;
};
+ /**
+ * EditSession.getWrapLimitRange() -> Object
+ *
+ * Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this:
+ *
+ * { min: wrapLimitRange_min, max: wrapLimitRange_max }
+ *
+ **/
this.getWrapLimitRange = function() {
// Avoid unexpected mutation by returning a copy
return {
@@ -4469,6 +4992,11 @@ var EditSession = function(text, mode) {
};
};
+ /** internal, hide
+ * EditSession.$updateInternalDataOnChange()
+ *
+ *
+ **/
this.$updateInternalDataOnChange = function(e) {
var useWrapMode = this.$useWrapMode;
var len;
@@ -4584,6 +5112,11 @@ var EditSession = function(text, mode) {
return removedFolds;
};
+ /** internal, hide
+ * EditSession.$updateWrapData(firstRow, lastRow)
+ *
+ *
+ **/
this.$updateWrapData = function(firstRow, lastRow) {
var lines = this.doc.getAllLines();
var tabSize = this.getTabSize();
@@ -4643,6 +5176,11 @@ var EditSession = function(text, mode) {
TAB = 11,
TAB_SPACE = 12;
+ /** internal, hide
+ * EditSession.$computeWrapSplits(tokens, wrapLimit) -> Array
+ *
+ *
+ **/
this.$computeWrapSplits = function(tokens, wrapLimit) {
if (tokens.length == 0) {
return [];
@@ -4759,11 +5297,13 @@ var EditSession = function(text, mode) {
return splits;
}
- /**
- * @param
- * offset: The offset in screenColumn at which position str starts.
- * Important for calculating the realTabSize.
- */
+ /** internal, hide
+ * EditSession.$getDisplayTokens(str, offset) -> Array
+ * - str (String): The string to check
+ * - offset (Number): The value to start at
+ *
+ * Given a string, returns an array of the display characters, including tabs and spaces.
+ **/
this.$getDisplayTokens = function(str, offset) {
var arr = [];
var tabSize;
@@ -4795,15 +5335,19 @@ var EditSession = function(text, mode) {
return arr;
}
- /**
- * Calculates the width of the a string on the screen while assuming that
- * the string starts at the first column on the screen.
- *
- * @param string str String to calculate the screen width of
- * @return array
- * [0]: number of columns for str on screen.
- * [1]: docColumn position that was read until (useful with screenColumn)
- */
+ /** internal, hide
+ * EditSession.$getStringScreenWidth(str, maxScreenColumn, screenColumn) -> [Number]
+ * - str (String): The string to calculate the screen width of
+ * - maxScreenColumn (Number):
+ * - screenColumn (Number):
+ * + ([Number]): Returns an `int[]` array with two elements:
+ * The first position indicates the number of columns for `str` on screen.
+ * The second value contains the position of the document column that this function read until.
+ *
+ * Calculates the width of the string `str` on the screen while assuming that the string starts at the first column on the screen.
+ *
+ *
+ **/
this.$getStringScreenWidth = function(str, maxScreenColumn, screenColumn) {
if (maxScreenColumn == 0) {
return [0, 0];
@@ -4836,8 +5380,12 @@ var EditSession = function(text, mode) {
}
/**
- * Returns the number of rows required to render this row on the screen
- */
+ * EditSession.getRowLength(row) -> Number
+ * - row (Number): The row number to check
+ *
+ *
+ * Returns the length of the indicated row.
+ **/
this.getRowLength = function(row) {
if (!this.$useWrapMode || !this.$wrapData[row]) {
return 1;
@@ -4847,27 +5395,52 @@ var EditSession = function(text, mode) {
}
/**
- * Returns the height in pixels required to render this row on the screen
+ * EditSession.getRowHeight(config, row) -> Number
+ * - config (Object): An object containing a parameter indicating the `lineHeight`.
+ * - row (Number): The row number to check
+ *
+ * Returns the height of the indicated row. This is mostly relevant for situations where wrapping occurs, and a single line spans across multiple rows.
+ *
**/
this.getRowHeight = function(config, row) {
return this.getRowLength(row) * config.lineHeight;
}
+ /** internal, hide, related to: EditSession.documentToScreenColumn
+ * EditSession.getScreenLastRowColumn(screenRow) -> Number
+ * - screenRow (Number): The screen row to check
+ *
+ * Returns the column position (on screen) for the last character in the provided row.
+ **/
this.getScreenLastRowColumn = function(screenRow) {
var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE)
return this.documentToScreenColumn(pos.row, pos.column);
};
+ /** internal, hide
+ * EditSession.getDocumentLastRowColumn(docRow, docColumn) -> Number
+ * - docRow (Number):
+ * - docColumn (Number):
+ *
+ **/
this.getDocumentLastRowColumn = function(docRow, docColumn) {
var screenRow = this.documentToScreenRow(docRow, docColumn);
return this.getScreenLastRowColumn(screenRow);
};
+ /** internal, hide
+ * EditSession.getDocumentLastRowColumnPosition(docRow, docColumn) -> Number
+ *
+ **/
this.getDocumentLastRowColumnPosition = function(docRow, docColumn) {
var screenRow = this.documentToScreenRow(docRow, docColumn);
return this.screenToDocumentPosition(screenRow, Number.MAX_VALUE / 10);
};
+ /** internal, hide
+ * EditSession.getRowSplitData(row) -> undefined | String
+ *
+ **/
this.getRowSplitData = function(row) {
if (!this.$useWrapMode) {
return undefined;
@@ -4877,20 +5450,43 @@ var EditSession = function(text, mode) {
};
/**
- * Returns the width of a tab character at screenColumn.
- */
+ * EditSession.getScreenTabSize(screenColumn) -> Number
+ * - screenColumn (Number): The screen column to check
+ *
+ * The distance to the next tab stop at the specified screen column.
+ **/
this.getScreenTabSize = function(screenColumn) {
return this.$tabSize - screenColumn % this.$tabSize;
};
+ /** internal, hide
+ * EditSession.screenToDocumentRow(screenRow, screenColumn) -> Number
+ *
+ *
+ **/
this.screenToDocumentRow = function(screenRow, screenColumn) {
return this.screenToDocumentPosition(screenRow, screenColumn).row;
};
+ /** internal, hide
+ * EditSession.screenToDocumentColumn(screenRow, screenColumn) -> Number
+ *
+ *
+ **/
this.screenToDocumentColumn = function(screenRow, screenColumn) {
return this.screenToDocumentPosition(screenRow, screenColumn).column;
};
+ /** related to: EditSession.documentToScreenPosition
+ * EditSession.screenToDocumentPosition(screenRow, screenColumn) -> Object
+ * - screenRow (Number): The screen row to check
+ * - screenColumn (Number): The screen column to check
+ * + (Object): The object returned has two properties: `row` and `column`.
+ *
+ * Converts characters coordinates on the screen to characters coordinates within the document. [This takes into account code folding, word wrap, tab size, and any other visual modifications.]{: #conversionConsiderations}
+ *
+ *
+ **/
this.screenToDocumentPosition = function(screenRow, screenColumn) {
if (screenRow < 0) {
return {
@@ -4986,6 +5582,17 @@ var EditSession = function(text, mode) {
}
};
+ /** related to: EditSession.screenToDocumentPosition
+ * EditSession.documentToScreenPosition(docRow, docColumn) -> Object
+ * - docRow (Number): The document row to check
+ * - docColumn (Number): The document column to check
+ * + (Object): The object returned by this method has two properties: `row` and `column`.
+ *
+ * Converts document coordinates to screen coordinates. {:conversionConsiderations}
+ *
+ *
+ *
+ **/
this.documentToScreenPosition = function(docRow, docColumn) {
// Normalize the passed in arguments.
if (typeof docColumn === "undefined")
@@ -5089,14 +5696,29 @@ var EditSession = function(text, mode) {
};
};
+ /** internal, hide
+ * EditSession.documentToScreenColumn(row, docColumn) -> Number
+ *
+ *
+ **/
this.documentToScreenColumn = function(row, docColumn) {
return this.documentToScreenPosition(row, docColumn).column;
};
+ /** internal, hide
+ * EditSession.documentToScreenRow(docRow, docColumn) -> Number
+ *
+ *
+ **/
this.documentToScreenRow = function(docRow, docColumn) {
return this.documentToScreenPosition(docRow, docColumn).row;
};
+ /**
+ * EditSession.getScreenLength() -> Number
+ *
+ * Returns the length of the screen.
+ **/
this.getScreenLength = function() {
var screenRows = 0;
var fold = null;
@@ -5175,7 +5797,7 @@ require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype)
exports.EditSession = EditSession;
});
-/**
+/*
* based on code from:
*
* @license RequireJS text 0.25.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
@@ -5236,7 +5858,8 @@ exports.loadScript = function(path, callback) {
s.onload = callback;
};
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -5313,7 +5936,7 @@ EventEmitter._dispatchEvent = function(eventName, e) {
}
if (defaultHandler && !e.defaultPrevented)
- defaultHandler(e);
+ return defaultHandler(e);
};
EventEmitter.setDefaultHandler = function(eventName, callback) {
@@ -5356,7 +5979,8 @@ EventEmitter.removeAllListeners = function(eventName) {
exports.EventEmitter = EventEmitter;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -5403,22 +6027,30 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
/**
- * Keeps cursor position and the text selection of an edit session.
+ * class Selection
*
- * The row/columns used in the selection are in document coordinates
- * representing ths coordinates as thez appear in the document
- * before applying soft wrap and folding.
- */
+ * Contains the cursor position and the text selection of an edit session.
+ *
+ * The row/columns used in the selection are in document coordinates representing ths coordinates as thez appear in the document before applying soft wrap and folding.
+ **/
+
+/**
+ * new Selection(session)
+ * - session (EditSession): The session to use
+ *
+ * Creates a new `Selection` object.
+ *
+**/
var Selection = function(session) {
this.session = session;
this.doc = session.getDocument();
this.clearSelection();
- this.selectionLead = this.doc.createAnchor(0, 0);
- this.selectionAnchor = this.doc.createAnchor(0, 0);
+ this.lead = this.selectionLead = this.doc.createAnchor(0, 0);
+ this.anchor = this.selectionAnchor = this.doc.createAnchor(0, 0);
var self = this;
- this.selectionLead.on("change", function(e) {
+ this.lead.on("change", function(e) {
self._emit("changeCursor");
if (!self.$isEmpty)
self._emit("changeSelection");
@@ -5436,13 +6068,23 @@ var Selection = function(session) {
oop.implement(this, EventEmitter);
+ /**
+ * Selection.isEmpty() -> Boolean
+ *
+ * Returns `true` if the selection is empty.
+ **/
this.isEmpty = function() {
return (this.$isEmpty || (
- this.selectionAnchor.row == this.selectionLead.row &&
- this.selectionAnchor.column == this.selectionLead.column
+ this.anchor.row == this.lead.row &&
+ this.anchor.column == this.lead.column
));
};
+ /**
+ * Selection.isMultiLine() -> Boolean
+ *
+ * Returns `true` if the selection is a multi-line.
+ **/
this.isMultiLine = function() {
if (this.isEmpty()) {
return false;
@@ -5451,12 +6093,24 @@ var Selection = function(session) {
return this.getRange().isMultiLine();
};
+ /**
+ * Selection.getCursor() -> Number
+ *
+ * Gets the current position of the cursor.
+ **/
this.getCursor = function() {
- return this.selectionLead.getPosition();
+ return this.lead.getPosition();
};
+ /**
+ * Selection.setSelectionAnchor(row, column)
+ * - row (Number): The new row
+ * - column (Number): The new column
+ *
+ * Sets the row and column position of the anchor. This function also emits the `'changeSelection'` event.
+ **/
this.setSelectionAnchor = function(row, column) {
- this.selectionAnchor.setPosition(row, column);
+ this.anchor.setPosition(row, column);
if (this.$isEmpty) {
this.$isEmpty = false;
@@ -5464,20 +6118,38 @@ var Selection = function(session) {
}
};
+ /** related to: Anchor.getPosition
+ * Selection.getSelectionAnchor() -> Object
+ *
+ * Returns an object containing the `row` and `column` of the calling selection anchor.
+ *
+ **/
this.getSelectionAnchor = function() {
if (this.$isEmpty)
return this.getSelectionLead()
else
- return this.selectionAnchor.getPosition();
+ return this.anchor.getPosition();
};
+ /**
+ * Selection.getSelectionLead() -> Object
+ *
+ * Returns an object containing the `row` and `column` of the calling selection lead.
+ **/
this.getSelectionLead = function() {
- return this.selectionLead.getPosition();
+ return this.lead.getPosition();
};
+ /**
+ * Selection.shiftSelection(columns)
+ * - columns (Number): The number of columns to shift by
+ *
+ * Shifts the selection up (or down, if [[Selection.isBackwards `isBackwards()`]] is true) the given number of columns.
+ *
+ **/
this.shiftSelection = function(columns) {
if (this.$isEmpty) {
- this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns);
+ this.moveCursorTo(this.lead.row, this.lead.column + columns);
return;
};
@@ -5496,15 +6168,25 @@ var Selection = function(session) {
}
};
+ /**
+ * Selection.isBackwards() -> Boolean
+ *
+ * Returns `true` if the selection is going backwards in the document.
+ **/
this.isBackwards = function() {
- var anchor = this.selectionAnchor;
- var lead = this.selectionLead;
+ var anchor = this.anchor;
+ var lead = this.lead;
return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
};
+ /**
+ * Selection.getRange() -> Range
+ *
+ * [Returns the [[Range `Range`]] for the selected text.]{: #Selection.getRange}
+ **/
this.getRange = function() {
- var anchor = this.selectionAnchor;
- var lead = this.selectionLead;
+ var anchor = this.anchor;
+ var lead = this.lead;
if (this.isEmpty())
return Range.fromPoints(lead, lead);
@@ -5517,6 +6199,11 @@ var Selection = function(session) {
}
};
+ /**
+ * Selection.clearSelection()
+ *
+ * [Empties the selection (by de-selecting it). This function also emits the `'changeSelection'` event.]{: #Selection.clearSelection}
+ **/
this.clearSelection = function() {
if (!this.$isEmpty) {
this.$isEmpty = true;
@@ -5524,12 +6211,25 @@ var Selection = function(session) {
}
};
+ /**
+ * Selection.selectAll()
+ *
+ * Selects all the text in the document.
+ **/
this.selectAll = function() {
var lastRow = this.doc.getLength() - 1;
this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length);
this.moveCursorTo(0, 0);
};
+ /**
+ * Selection.setSelectionRange(range, reverse)
+ * - range (Range): The range of text to select
+ * - reverse (Boolean): Indicates if the range should go backwards (`true`) or not
+ *
+ * Sets the selection to the provided range.
+ *
+ **/
this.setSelectionRange = function(range, reverse) {
if (reverse) {
this.setSelectionAnchor(range.end.row, range.end.column);
@@ -5542,80 +6242,161 @@ var Selection = function(session) {
};
this.$moveSelection = function(mover) {
- var lead = this.selectionLead;
+ var lead = this.lead;
if (this.$isEmpty)
this.setSelectionAnchor(lead.row, lead.column);
mover.call(this);
};
+ /**
+ * Selection.selectTo(row, column)
+ * - row (Number): The row to select to
+ * - column (Number): The column to select to
+ *
+ * Moves the selection cursor to the indicated row and column.
+ *
+ **/
this.selectTo = function(row, column) {
this.$moveSelection(function() {
this.moveCursorTo(row, column);
});
};
+ /**
+ * Selection.selectToPosition(pos)
+ * - pos (Object): An object containing the row and column
+ *
+ * Moves the selection cursor to the row and column indicated by `pos`.
+ *
+ **/
this.selectToPosition = function(pos) {
this.$moveSelection(function() {
this.moveCursorToPosition(pos);
});
};
+ /**
+ * Selection.selectUp()
+ *
+ * Moves the selection up one row.
+ **/
this.selectUp = function() {
this.$moveSelection(this.moveCursorUp);
};
+ /**
+ * Selection.selectDown()
+ *
+ * Moves the selection down one row.
+ **/
this.selectDown = function() {
this.$moveSelection(this.moveCursorDown);
};
+ /**
+ * Selection.selectRight()
+ *
+ * Moves the selection right one column.
+ **/
this.selectRight = function() {
this.$moveSelection(this.moveCursorRight);
};
+ /**
+ * Selection.selectLeft()
+ *
+ * Moves the selection left one column.
+ **/
this.selectLeft = function() {
this.$moveSelection(this.moveCursorLeft);
};
+ /**
+ * Selection.selectLineStart()
+ *
+ * Moves the selection to the beginning of the current line.
+ **/
this.selectLineStart = function() {
this.$moveSelection(this.moveCursorLineStart);
};
+ /**
+ * Selection.selectLineEnd()
+ *
+ * Moves the selection to the end of the current line.
+ **/
this.selectLineEnd = function() {
this.$moveSelection(this.moveCursorLineEnd);
};
+ /**
+ * Selection.selectFileEnd()
+ *
+ * Moves the selection to the end of the file.
+ **/
this.selectFileEnd = function() {
this.$moveSelection(this.moveCursorFileEnd);
};
+ /**
+ * Selection.selectFileStart()
+ *
+ * Moves the selection to the start of the file.
+ **/
this.selectFileStart = function() {
this.$moveSelection(this.moveCursorFileStart);
};
+ /**
+ * Selection.selectWordRight()
+ *
+ * Moves the selection to the first word on the right.
+ **/
this.selectWordRight = function() {
this.$moveSelection(this.moveCursorWordRight);
};
+ /**
+ * Selection.selectWordLeft()
+ *
+ * Moves the selection to the first word on the left.
+ **/
this.selectWordLeft = function() {
this.$moveSelection(this.moveCursorWordLeft);
};
- this.selectWord = function() {
- var cursor = this.getCursor();
- var range = this.session.getWordRange(cursor.row, cursor.column);
- this.setSelectionRange(range);
+ /** related to: EditSession.getWordRange
+ * Selection.selectWord()
+ *
+ * Moves the selection to highlight the entire word.
+ **/
+ this.getWordRange = function(row, column) {
+ if (typeof column == "undefined") {
+ var cursor = row || this.lead;
+ row = cursor.row;
+ column = cursor.column;
+ }
+ return this.session.getWordRange(row, column);
};
- // Selects a word including its right whitespace
+ this.selectWord = function() {
+ this.setSelectionRange(this.getWordRange());
+ };
+
+ /** related to: EditSession.getAWordRange
+ * Selection.selectAWord()
+ *
+ * Selects a word, including its right whitespace.
+ **/
this.selectAWord = function() {
var cursor = this.getCursor();
var range = this.session.getAWordRange(cursor.row, cursor.column);
this.setSelectionRange(range);
};
- this.selectLine = function() {
- var rowStart = this.selectionLead.row;
+ this.getLineRange = function(row, excludeLastChar) {
+ var rowStart = typeof row == "number" ? row : this.lead.row;
var rowEnd;
var foldLine = this.session.getFoldLine(rowStart);
@@ -5625,22 +6406,46 @@ var Selection = function(session) {
} else {
rowEnd = rowStart;
}
- this.setSelectionAnchor(rowStart, 0);
- this.$moveSelection(function() {
- this.moveCursorTo(rowEnd + 1, 0);
- });
+ if (excludeLastChar)
+ return new Range(rowStart, 0, rowEnd, this.session.getLine(rowEnd).length);
+ else
+ return new Range(rowStart, 0, rowEnd + 1, 0);
};
+ /**
+ * Selection.selectLine()
+ *
+ * Selects the entire line.
+ **/
+ this.selectLine = function() {
+ this.setSelectionRange(this.getLineRange());
+ };
+
+ /**
+ * Selection.moveCursorUp()
+ *
+ * Moves the cursor up one row.
+ **/
this.moveCursorUp = function() {
this.moveCursorBy(-1, 0);
};
+ /**
+ * Selection.moveCursorDown()
+ *
+ * Moves the cursor down one row.
+ **/
this.moveCursorDown = function() {
this.moveCursorBy(1, 0);
};
+ /**
+ * Selection.moveCursorLeft()
+ *
+ * Moves the cursor left one column.
+ **/
this.moveCursorLeft = function() {
- var cursor = this.selectionLead.getPosition(),
+ var cursor = this.lead.getPosition(),
fold;
if (fold = this.session.getFoldAt(cursor.row, cursor.column, -1)) {
@@ -5660,20 +6465,25 @@ var Selection = function(session) {
}
};
+ /**
+ * Selection.moveCursorRight()
+ *
+ * Moves the cursor right one column.
+ **/
this.moveCursorRight = function() {
- var cursor = this.selectionLead.getPosition(),
+ var cursor = this.lead.getPosition(),
fold;
if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) {
this.moveCursorTo(fold.end.row, fold.end.column);
}
- else if (this.selectionLead.column == this.doc.getLine(this.selectionLead.row).length) {
- if (this.selectionLead.row < this.doc.getLength() - 1) {
- this.moveCursorTo(this.selectionLead.row + 1, 0);
+ else if (this.lead.column == this.doc.getLine(this.lead.row).length) {
+ if (this.lead.row < this.doc.getLength() - 1) {
+ this.moveCursorTo(this.lead.row + 1, 0);
}
}
else {
var tabSize = this.session.getTabSize();
- var cursor = this.selectionLead;
+ var cursor = this.lead;
if (this.session.isTabStop(cursor) && this.doc.getLine(cursor.row).slice(cursor.column, cursor.column+tabSize).split(" ").length-1 == tabSize)
this.moveCursorBy(0, tabSize);
else
@@ -5681,9 +6491,14 @@ var Selection = function(session) {
}
};
+ /**
+ * Selection.moveCursorLineStart()
+ *
+ * Moves the cursor to the start of the line.
+ **/
this.moveCursorLineStart = function() {
- var row = this.selectionLead.row;
- var column = this.selectionLead.column;
+ var row = this.lead.row;
+ var column = this.lead.column;
var screenRow = this.session.documentToScreenRow(row, column);
// Determ the doc-position of the first character at the screen line.
@@ -5709,8 +6524,13 @@ var Selection = function(session) {
}
};
+ /**
+ * Selection.moveCursorLineEnd()
+ *
+ * Moves the cursor to the end of the line.
+ **/
this.moveCursorLineEnd = function() {
- var lead = this.selectionLead;
+ var lead = this.lead;
var lastRowColumnPosition =
this.session.getDocumentLastRowColumnPosition(lead.row, lead.column);
this.moveCursorTo(
@@ -5719,19 +6539,34 @@ var Selection = function(session) {
);
};
+ /**
+ * Selection.moveCursorFileEnd()
+ *
+ * Moves the cursor to the end of the file.
+ **/
this.moveCursorFileEnd = function() {
var row = this.doc.getLength() - 1;
var column = this.doc.getLine(row).length;
this.moveCursorTo(row, column);
};
+ /**
+ * Selection.moveCursorFileStart()
+ *
+ * Moves the cursor to the start of the file.
+ **/
this.moveCursorFileStart = function() {
this.moveCursorTo(0, 0);
};
- this.moveCursorWordRight = function() {
- var row = this.selectionLead.row;
- var column = this.selectionLead.column;
+ /**
+ * Selection.moveCursorLongWordRight()
+ *
+ * Moves the cursor to the word on the right.
+ **/
+ this.moveCursorLongWordRight = function() {
+ var row = this.lead.row;
+ var column = this.lead.column;
var line = this.doc.getLine(row);
var rightOfCursor = line.substring(column);
@@ -5745,14 +6580,14 @@ var Selection = function(session) {
this.moveCursorTo(fold.end.row, fold.end.column);
return;
}
-
+
// first skip space
if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
column += this.session.nonTokenRe.lastIndex;
this.session.nonTokenRe.lastIndex = 0;
rightOfCursor = line.substring(column);
}
-
+
// if at line end proceed with next line
if (column >= line.length) {
this.moveCursorTo(row, line.length);
@@ -5761,7 +6596,7 @@ var Selection = function(session) {
this.moveCursorWordRight();
return;
}
-
+
// advance to the end of the next token
if (match = this.session.tokenRe.exec(rightOfCursor)) {
column += this.session.tokenRe.lastIndex;
@@ -5771,9 +6606,14 @@ var Selection = function(session) {
this.moveCursorTo(row, column);
};
- this.moveCursorWordLeft = function() {
- var row = this.selectionLead.row;
- var column = this.selectionLead.column;
+ /**
+ * Selection.moveCursorLongWordLeft()
+ *
+ * Moves the cursor to the word on the left.
+ **/
+ this.moveCursorLongWordLeft = function() {
+ var row = this.lead.row;
+ var column = this.lead.column;
// skip folds
var fold;
@@ -5786,19 +6626,19 @@ var Selection = function(session) {
if (str == null) {
str = this.doc.getLine(row).substring(0, column)
}
-
+
var leftOfCursor = lang.stringReverse(str);
var match;
this.session.nonTokenRe.lastIndex = 0;
this.session.tokenRe.lastIndex = 0;
-
+
// skip whitespace
if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
column -= this.session.nonTokenRe.lastIndex;
leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
this.session.nonTokenRe.lastIndex = 0;
}
-
+
// if at begin of the line proceed in line above
if (column <= 0) {
this.moveCursorTo(row, 0);
@@ -5817,10 +6657,103 @@ var Selection = function(session) {
this.moveCursorTo(row, column);
};
+ this.$shortWordEndIndex = function(rightOfCursor) {
+ var match, index = 0, ch;
+ var whitespaceRe = /\s/;
+ var tokenRe = this.session.tokenRe;
+
+ tokenRe.lastIndex = 0;
+ if (match = this.session.tokenRe.exec(rightOfCursor)) {
+ index = this.session.tokenRe.lastIndex;
+ } else {
+ while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
+ index ++;
+
+ if (index <= 1) {
+ tokenRe.lastIndex = 0;
+ while ((ch = rightOfCursor[index]) && !tokenRe.test(ch)) {
+ tokenRe.lastIndex = 0;
+ index ++;
+ if (whitespaceRe.test(ch)) {
+ if (index > 2) {
+ index--
+ break;
+ } else {
+ while ((ch = rightOfCursor[index]) && whitespaceRe.test(ch))
+ index ++;
+ if (index > 2)
+ break
+ }
+ }
+ }
+ }
+ }
+ tokenRe.lastIndex = 0;
+
+ return index;
+ };
+
+ this.moveCursorShortWordRight = function() {
+ var row = this.lead.row;
+ var column = this.lead.column;
+ var line = this.doc.getLine(row);
+ var rightOfCursor = line.substring(column);
+
+ var fold = this.session.getFoldAt(row, column, 1);
+ if (fold)
+ return this.moveCursorTo(fold.end.row, fold.end.column);
+
+ if (column == line.length)
+ return this.moveCursorRight();
+
+ var index = this.$shortWordEndIndex(rightOfCursor);
+
+ this.moveCursorTo(row, column + index);
+ };
+
+ this.moveCursorShortWordLeft = function() {
+ var row = this.lead.row;
+ var column = this.lead.column;
+
+ var fold;
+ if (fold = this.session.getFoldAt(row, column, -1))
+ return this.moveCursorTo(fold.start.row, fold.start.column);
+
+ if (column == 0)
+ return this.moveCursorLeft();
+
+ var str = this.session.getLine(row).substring(0, column);
+ var leftOfCursor = lang.stringReverse(str);
+ var index = this.$shortWordEndIndex(leftOfCursor);
+
+ return this.moveCursorTo(row, column - index);
+ };
+
+ this.moveCursorWordRight = function() {
+ if (this.session.$selectLongWords)
+ this.moveCursorLongWordRight();
+ else
+ this.moveCursorShortWordRight();
+ };
+
+ this.moveCursorWordLeft = function() {
+ if (this.session.$selectLongWords)
+ this.moveCursorLongWordLeft();
+ else
+ this.moveCursorShortWordLeft();
+ };
+
+ /** related to: EditSession.documentToScreenPosition
+ * Selection.moveCursorBy(rows, chars)
+ * - rows (Number): The number of rows to move by
+ * - chars (Number): The number of characters to move by
+ *
+ * Moves the cursor to position indicated by the parameters. Negative numbers move the cursor backwards in the document.
+ **/
this.moveCursorBy = function(rows, chars) {
var screenPos = this.session.documentToScreenPosition(
- this.selectionLead.row,
- this.selectionLead.column
+ this.lead.row,
+ this.lead.column
);
if (chars === 0) {
@@ -5836,10 +6769,24 @@ var Selection = function(session) {
this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0);
};
+ /**
+ * Selection.moveCursorToPosition(position)
+ * - position (Object): The position to move to
+ *
+ * Moves the selection to the position indicated by its `row` and `column`.
+ **/
this.moveCursorToPosition = function(position) {
this.moveCursorTo(position.row, position.column);
};
+ /**
+ * Selection.moveCursorTo(row, column, keepDesiredColumn)
+ * - row (Number): The row to move to
+ * - column (Number): The column to move to
+ * - keepDesiredColumn (Boolean): [If `true`, the cursor move does not respect the previous column]{: #preventUpdateBool}
+ *
+ * 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.]{: #preventUpdateBoolDesc}
+ **/
this.moveCursorTo = function(row, column, keepDesiredColumn) {
// Ensure the row/column is not inside of a fold.
var fold = this.session.getFoldAt(row, column, 1);
@@ -5849,13 +6796,21 @@ var Selection = function(session) {
}
this.$keepDesiredColumnOnChange = true;
- this.selectionLead.setPosition(row, column);
+ this.lead.setPosition(row, column);
this.$keepDesiredColumnOnChange = false;
if (!keepDesiredColumn)
this.$desiredColumn = null;
};
+ /**
+ * Selection.moveCursorToScreen(row, column, keepDesiredColumn)
+ * - row (Number): The row to move to
+ * - column (Number): The column to move to
+ * - keepDesiredColumn (Boolean): {:preventUpdateBool}
+ *
+ * Moves the cursor to the screen position indicated by row and column. {:preventUpdateBoolDesc}
+ **/
this.moveCursorToScreen = function(row, column, keepDesiredColumn) {
var pos = this.session.screenToDocumentPosition(row, column);
this.moveCursorTo(pos.row, pos.column, keepDesiredColumn);
@@ -5863,8 +6818,8 @@ var Selection = function(session) {
// remove listeners from document
this.detach = function() {
- this.selectionLead.detach();
- this.selectionAnchor.detach();
+ this.lead.detach();
+ this.anchor.detach();
this.session = this.doc = null;
}
@@ -5933,6 +6888,23 @@ exports.Selection = Selection;
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class Range
+ *
+ * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
+ *
+ **/
+
+/**
+ * new Range(startRow, startColumn, endRow, endColumn)
+ * - startRow (Number): The starting row
+ * - startColumn (Number): The starting column
+ * - endRow (Number): The ending row
+ * - endColumn (Number): The ending column
+ *
+ * Creates a new `Range` object with the given starting and ending row and column points.
+ *
+ **/
var Range = function(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
@@ -5946,6 +6918,13 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
(function() {
+ /**
+ * Range.isEqual(range) -> Boolean
+ * - range (Range): A range to check against
+ *
+ * Returns `true` if and only if the starting row and column, and ending tow and column, are equivalent to those given by `range`.
+ *
+ **/
this.isEqual = function(range) {
return this.start.row == range.start.row &&
this.end.row == range.end.row &&
@@ -5953,28 +6932,51 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
this.end.column == range.end.column
};
+ /**
+ * Range.toString() -> String
+ *
+ * Returns a string containing the range's row and column information, given like this:
+ *
+ * [start.row/start.column] -> [end.row/end.column]
+ *
+ **/
+
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
};
+ /** related to: Range.compare
+ * Range.contains(row, column) -> Boolean
+ * - row (Number): A row to check for
+ * - column (Number): A column to check for
+ *
+ * Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:
+ *
+ * this.start.row <= row <= this.end.row &&
+ * this.start.column <= column <= this.end.column
+ *
+ **/
+
this.contains = function(row, column) {
return this.compare(row, column) == 0;
};
- /**
- * Compares this range (A) with another range (B), where B is the passed in
- * range.
+ /** related to: Range.compare
+ * Range.compareRange(range) -> Number
+ * - range (Range): A range to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `-2`: (B) is in front of (A), and doesn't intersect with (A)
+ * * `-1`: (B) begins before (A) but ends inside of (A)
+ * * `0`: (B) is completely inside of (A) OR (A) is completely inside of (B)
+ * * `+1`: (B) begins inside of (A) but ends outside of (A)
+ * * `+2`: (B) is after (A) and doesn't intersect with (A)
+ * * `42`: FTW state: (B) ends in (A) but starts outside of (A)
+ *
+ * Compares `this` range (A) with another range (B).
*
- * Return values:
- * -2: (B) is infront of (A) and doesn't intersect with (A)
- * -1: (B) begins before (A) but ends inside of (A)
- * 0: (B) is completly inside of (A) OR (A) is complety inside of (B)
- * +1: (B) begins inside of (A) but ends outside of (A)
- * +2: (B) is after (A) and doesn't intersect with (A)
- *
- * 42: FTW state: (B) ends in (A) but starts outside of (A)
- */
+ **/
this.compareRange = function(range) {
var cmp,
end = range.end,
@@ -6004,27 +7006,86 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.comparePoint(p) -> Number
+ * - p (Range): A point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points of `p` with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.comparePoint = function(p) {
return this.compare(p.row, p.column);
}
+ /** related to: Range.comparePoint
+ * Range.containsRange(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
+ *
+ **/
this.containsRange = function(range) {
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
}
+ /**
+ * Range.intersects(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Returns `true` if passed in `range` intersects with the one calling this method.
+ *
+ **/
this.intersects = function(range) {
var cmp = this.compareRange(range);
return (cmp == -1 || cmp == 0 || cmp == 1);
}
+ /**
+ * Range.isEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's ending row point is the same as `row`, and if the caller's ending column is the same as `column`.
+ *
+ **/
this.isEnd = function(row, column) {
return this.end.row == row && this.end.column == column;
}
+ /**
+ * Range.isStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's starting row point is the same as `row`, and if the caller's starting column is the same as `column`.
+ *
+ **/
this.isStart = function(row, column) {
return this.start.row == row && this.start.column == column;
}
+ /**
+ * Range.setStart(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setStart = function(row, column) {
if (typeof row == "object") {
this.start.column = row.column;
@@ -6035,6 +7096,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.setEnd(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setEnd = function(row, column) {
if (typeof row == "object") {
this.end.column = row.column;
@@ -6045,6 +7114,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.inside(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range.
+ *
+ **/
this.inside = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column) || this.isStart(row, column)) {
@@ -6056,6 +7133,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's starting points.
+ *
+ **/
this.insideStart = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column)) {
@@ -6067,6 +7152,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's ending points.
+ *
+ **/
this.insideEnd = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isStart(row, column)) {
@@ -6078,6 +7171,27 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /**
+ * Range.compare(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compare = function(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
@@ -6101,8 +7215,28 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
/**
- * Like .compare(), but if isStart is true, return -1;
- */
+ * Range.compareStart(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isStart` is `true`.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareStart = function(row, column) {
if (this.start.row == row && this.start.column == column) {
return -1;
@@ -6112,8 +7246,26 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
/**
- * Like .compare(), but if isEnd is true, return 1;
- */
+ * Range.compareEnd(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isEnd` is `true.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compareEnd = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -6122,6 +7274,21 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.compareInside(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`
+ * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`
+ *
+ * Otherwise, it returns the value after calling [[Range.compare `compare()`]].
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareInside = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -6132,6 +7299,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.clipRows(firstRow, lastRow) -> Range
+ * - firstRow (Number): The starting row
+ * - lastRow (Number): The ending row
+ *
+ * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
+ *
+ **/
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
var end = {
@@ -6163,6 +7338,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
+ /**
+ * Range.extend(row, column) -> Range
+ * - row (Number): A new row to extend to
+ * - column (Number): A new column to extend to
+ *
+ * Changes the row and column points for the calling range for both the starting and ending points. This method returns that range with a new row.
+ *
+ **/
this.extend = function(row, column) {
var cmp = this.compare(row, column);
@@ -6176,33 +7359,36 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
- this.fixOrientation = function() {
- if (
- this.start.row < this.end.row
- || (this.start.row == this.end.row && this.start.column < this.end.column)
- ) {
- return false;
- }
-
- var temp = this.start;
- this.end = this.start;
- this.start = temp;
- return true;
- };
-
-
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
+ /**
+ * Range.isMultiLine() -> Boolean
+ *
+ * Returns true if the range spans across multiple lines.
+ *
+ **/
this.isMultiLine = function() {
return (this.start.row !== this.end.row);
};
+ /**
+ * Range.clone() -> Range
+ *
+ * Returns a duplicate of the calling range.
+ *
+ **/
this.clone = function() {
return Range.fromPoints(this.start, this.end);
};
+ /**
+ * Range.collapseRows() -> Range
+ *
+ * Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
+ *
+ **/
this.collapseRows = function() {
if (this.end.column == 0)
return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
@@ -6210,6 +7396,12 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return new Range(this.start.row, 0, this.end.row, 0)
};
+ /**
+ * Range.toScreenRange(session) -> Range
+ * - session (EditSession): The `EditSession` to retrieve coordinates from
+ *
+ * Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
+ **/
this.toScreenRange = function(session) {
var screenPosStart =
session.documentToScreenPosition(this.start);
@@ -6224,7 +7416,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}).call(Range.prototype);
-
+/**
+ * Range.fromPoints(start, end) -> Range
+ * - start (Range): A starting point to use
+ * - end (Range): An ending point to use
+ *
+ * Creates and returns a new `Range` based on the row and column of the given parameters.
+ *
+**/
Range.fromPoints = function(start, end) {
return new Range(start.row, start.column, end.row, end.column);
};
@@ -6492,6 +7691,21 @@ exports.Mode = Mode;
define('ace/tokenizer', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class Tokenizer
+ *
+ * This class takes a set of highlighting rules, and creates a tokenizer out of them. For more information, see [the wiki on extending highlighters](https://github.com/ajaxorg/ace/wiki/Creating-or-Extending-an-Edit-Mode#wiki-extendingTheHighlighter).
+ *
+ **/
+
+/**
+ * new Tokenizer(rules, flag)
+ * - rules (Object): The highlighting rules
+ * - flag (String): Any additional regular expression flags to pass (like "i" for case insensitive)
+ *
+ * Constructs a new tokenizer based on the given rules and flags.
+ *
+ **/
var Tokenizer = function(rules, flag) {
flag = flag ? "g" + flag : "g";
this.rules = rules;
@@ -6537,6 +7751,11 @@ var Tokenizer = function(rules, flag) {
(function() {
+ /**
+ * Tokenizer.getLineTokens() -> Object
+ *
+ * Returns an object containing two properties: `tokens`, which contains all the tokens; and `state`, the current state.
+ **/
this.getLineTokens = function(line, startState) {
var currentState = startState;
var state = this.rules[currentState];
@@ -6833,7 +8052,8 @@ var Behaviour = function() {
}).call(Behaviour.prototype);
exports.Behaviour = Behaviour;
-});define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) {
+});
+define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
/*
@@ -6939,7 +8159,8 @@ function addUnicodePackage (pack) {
exports.packages[name] = pack[name].replace(codePoint, "\\u$&");
};
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -6984,6 +8205,21 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
var Anchor = require("./anchor").Anchor;
+/**
+ * class Document
+ *
+ * Contains the text of the document. Documents are controlled by a single [[EditSession `EditSession`]]. At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.
+ *
+ *
+ **/
+
+ /**
+ * new Document([text])
+ * - text (String | Array): The starting text
+ *
+ * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.
+ *
+ **/
var Document = function(text) {
this.$lines = [];
@@ -7003,20 +8239,48 @@ var Document = function(text) {
oop.implement(this, EventEmitter);
+ /**
+ * Document.setValue(text) -> Void
+ * - text (String): The text to use
+ *
+ * Replaces all the lines in the current `Document` with the value of `text`.
+ **/
this.setValue = function(text) {
var len = this.getLength();
this.remove(new Range(0, 0, len, this.getLine(len-1).length));
this.insert({row: 0, column:0}, text);
};
+ /**
+ * Document.getValue() -> String
+ *
+ * Returns all the lines in the document as a single string, split by the new line character.
+ **/
this.getValue = function() {
return this.getAllLines().join(this.getNewLineCharacter());
};
+ /**
+ * Document.createAnchor(row, column) -> Anchor
+ * - row (Number): The row number to use
+ * - column (Number): The column number to use
+ *
+ * Creates a new `Anchor` to define a floating point in the document.
+ **/
this.createAnchor = function(row, column) {
return new Anchor(this, row, column);
};
+ /** internal, hide
+ * Document.$split(text) -> [String]
+ * - text (String): The text to work with
+ * + ([String]): A String array, with each index containing a piece of the original `text` string.
+ *
+ * Splits a string of text on any newline (`\n`) or carriage-return ('\r') characters.
+ *
+ *
+ **/
+
// check for IE split bug
if ("aaa".split(/a/).length == 0)
this.$split = function(text) {
@@ -7028,6 +8292,11 @@ var Document = function(text) {
};
+ /** internal, hide
+ * Document.$detectNewLine(text) -> Void
+ *
+ *
+ **/
this.$detectNewLine = function(text) {
var match = text.match(/^.*?(\r\n|\r|\n)/m);
if (match) {
@@ -7037,6 +8306,17 @@ var Document = function(text) {
}
};
+ /**
+ * Document.getNewLineCharacter() -> String
+ * + (String): If `newLineMode == windows`, `\r\n` is returned.
+ * If `newLineMode == unix`, `\n` is returned.
+ * If `newLineMode == auto`, the value of `autoNewLine` is returned.
+ *
+ * Returns the newline character that's being used, depending on the value of `newLineMode`.
+ *
+ *
+ *
+ **/
this.getNewLineCharacter = function() {
switch (this.$newLineMode) {
case "windows":
@@ -7052,6 +8332,12 @@ var Document = function(text) {
this.$autoNewLine = "\n";
this.$newLineMode = "auto";
+ /**
+ * Document.setNewLineMode(newLineMode) -> Void
+ * - newLineMode(String): [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param}
+ *
+ * [Sets the new line mode.]{: #Document.setNewLineMode.desc}
+ **/
this.setNewLineMode = function(newLineMode) {
if (this.$newLineMode === newLineMode)
return;
@@ -7059,51 +8345,92 @@ var Document = function(text) {
this.$newLineMode = newLineMode;
};
+ /**
+ * Document.getNewLineMode() -> String
+ *
+ * [Returns the type of newlines being used; either `windows`, `unix`, or `auto`]{: #Document.getNewLineMode}
+ *
+ **/
this.getNewLineMode = function() {
return this.$newLineMode;
};
+ /**
+ * Document.isNewLine(text) -> Boolean
+ * - text (String): The text to check
+ *
+ * Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`).
+ *
+ **/
this.isNewLine = function(text) {
return (text == "\r\n" || text == "\r" || text == "\n");
};
/**
- * Get a verbatim copy of the given line as it is in the document
- */
+ * Document.getLine(row) -> String
+ * - row (Number): The row index to retrieve
+ *
+ * Returns a verbatim copy of the given line as it is in the document
+ *
+ **/
this.getLine = function(row) {
return this.$lines[row] || "";
};
+ /**
+ * Document.getLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row index to retrieve
+ * - lastRow (Number): The final row index to retrieve
+ *
+ * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
+ *
+ **/
this.getLines = function(firstRow, lastRow) {
return this.$lines.slice(firstRow, lastRow + 1);
};
/**
- * Returns all lines in the document as string array. Warning: The caller
- * should not modify this array!
- */
+ * Document.getAllLines() -> [String]
+ *
+ * Returns all lines in the document as string array. Warning: The caller should not modify this array!
+ **/
this.getAllLines = function() {
return this.getLines(0, this.getLength());
};
+ /**
+ * Document.getLength() -> Number
+ *
+ * Returns the number of rows in the document.
+ **/
this.getLength = function() {
return this.$lines.length;
};
+ /**
+ * Document.getTextRange(range) -> String
+ * - range (Range): The range to work with
+ *
+ * [Given a range within the document, this function returns all the text within that range as a single string.]{: #Document.getTextRange.desc}
+ **/
this.getTextRange = function(range) {
if (range.start.row == range.end.row) {
return this.$lines[range.start.row].substring(range.start.column,
range.end.column);
}
else {
- var lines = [];
- lines.push(this.$lines[range.start.row].substring(range.start.column));
- lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
- lines.push(this.$lines[range.end.row].substring(0, range.end.column));
+ var lines = this.getLines(range.start.row+1, range.end.row-1);
+ lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
+ lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
return lines.join(this.getNewLineCharacter());
}
};
+ /** internal, hide
+ * Document.$clipPosition(position) -> Number
+ *
+ *
+ **/
this.$clipPosition = function(position) {
var length = this.getLength();
if (position.row >= length) {
@@ -7113,6 +8440,15 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insert(position, text) -> Number
+ * - position (Number): The position to start inserting at
+ * - text (String): A chunk of text to insert
+ * + (Number): The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.
+ * Inserts a block of `text` and the indicated `position`.
+ *
+ *
+ **/
this.insert = function(position, text) {
if (!text || text.length === 0)
return position;
@@ -7136,6 +8472,19 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insertLines(row, lines) -> Object
+ * - row (Number): The index of the row to insert at
+ * - lines (Array): An array of strings
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * If `lines` is empty, this function returns an object containing the current row, and column, like this:
+ * ```{row: row, column: 0}```
+ *
+ * Inserts the elements in `lines` into the document, starting at the row index given by `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.insertLines = function(row, lines) {
if (lines.length == 0)
return {row: row, column: 0};
@@ -7154,6 +8503,17 @@ var Document = function(text) {
return range.end;
};
+ /**
+ * Document.insertNewLine(position) -> Object
+ * - position (String): The position to insert at
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ *
+ * Inserts a new line into the document at the current row's `position`. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertNewLine = function(position) {
position = this.$clipPosition(position);
var line = this.$lines[position.row] || "";
@@ -7176,6 +8536,19 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.insertInLine(position, text) -> Object | Number
+ * - position (Number): The position to insert at
+ * - text (String): A chunk of text
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * + (Number): If `text` is empty, this function returns the value of `position`
+ *
+ * Inserts `text` into the `position` at the current row. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertInLine = function(position, text) {
if (text.length == 0)
return position;
@@ -7200,6 +8573,15 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.remove(range) -> Object
+ * - range (Range): A specified Range to remove
+ * + (Object): Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
+ *
+ * Removes the `range` from the document.
+ *
+ *
+ **/
this.remove = function(range) {
// clip to document
range.start = this.$clipPosition(range.start);
@@ -7232,6 +8614,17 @@ var Document = function(text) {
return range.start;
};
+ /**
+ * Document.removeInLine(row, startColumn, endColumn) -> Object
+ * - row (Number): The row to remove from
+ * - startColumn (Number): The column to start removing at
+ * - endColumn (Number): The column to stop removing at
+ * + (Object): Returns an object containing `startRow` and `startColumn`, indicating the new row and column values. If `startColumn` is equal to `endColumn`, this function returns nothing.
+ *
+ * Removes the specified columns from the `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeInLine = function(row, startColumn, endColumn) {
if (startColumn == endColumn)
return;
@@ -7252,12 +8645,15 @@ var Document = function(text) {
};
/**
- * Removes a range of full lines
- *
- * @param firstRow {Integer} The first row to be removed
- * @param lastRow {Integer} The last row to be removed
- * @return {String[]} The removed lines
- */
+ * Document.removeLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row to be removed
+ * - lastRow (Number): The last row to be removed
+ * + ([String]): Returns all the removed lines.
+ *
+ * Removes a range of full lines. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeLines = function(firstRow, lastRow) {
var range = new Range(firstRow, 0, lastRow + 1, 0);
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
@@ -7272,6 +8668,13 @@ var Document = function(text) {
return removed;
};
+ /**
+ * Document.removeNewLine(row) -> Void
+ * - row (Number): The row to check
+ *
+ * Removes the new line between `row` and the row immediately following it. This method also triggers the `'change'` event.
+ *
+ **/
this.removeNewLine = function(row) {
var firstLine = this.getLine(row);
var secondLine = this.getLine(row+1);
@@ -7289,6 +8692,18 @@ var Document = function(text) {
this._emit("change", { data: delta });
};
+ /**
+ * Document.replace(range, text) -> Object
+ * - range (Range): A specified Range to replace
+ * - text (String): The new text to use as a replacement
+ * + (Object): Returns an object containing the final row and column, like this:
+ * {row: endRow, column: 0}
+ * If the text and range are empty, this function returns an object containing the current `range.start` value.
+ * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
+ *
+ * Replaces a range in the document with the new `text`.
+ *
+ **/
this.replace = function(range, text) {
if (text.length == 0 && range.isEmpty())
return range.start;
@@ -7309,6 +8724,11 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.applyDeltas(deltas) -> Void
+ *
+ * Applies all the changes previously accumulated. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.applyDeltas = function(deltas) {
for (var i=0; i Void
+ *
+ * Reverts any changes previously applied. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.revertDeltas = function(deltas) {
for (var i=deltas.length-1; i>=0; i--) {
var delta = deltas[i];
@@ -7390,9 +8815,22 @@ var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
/**
- * An Anchor is a floating pointer in the document. Whenever text is inserted or
- * deleted before the cursor, the position of the cursor is updated
- */
+ * class Anchor
+ *
+ * Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated
+ *
+ **/
+
+/**
+ * new Anchor(doc, row, column)
+ * - doc (Document): The document to associate with the anchor
+ * - row (Number): The starting row position
+ * - column (Number): The starting column position
+ *
+ * Creates a new `Anchor` and associates it with a document.
+ *
+ **/
+
var Anchor = exports.Anchor = function(doc, row, column) {
this.document = doc;
@@ -7409,14 +8847,36 @@ var Anchor = exports.Anchor = function(doc, row, column) {
oop.implement(this, EventEmitter);
+ /**
+ * Anchor.getPosition() -> Object
+ *
+ * Returns an object identifying the `row` and `column` position of the current anchor.
+ *
+ **/
+
this.getPosition = function() {
return this.$clipPositionToDocument(this.row, this.column);
};
-
+
+ /**
+ * Anchor.getDocument() -> Document
+ *
+ * Returns the current document.
+ *
+ **/
+
this.getDocument = function() {
return this.document;
};
+ /**
+ * Anchor@onChange(e)
+ * - e (Event): Contains data about the event
+ *
+ * Fires whenever the anchor position changes. Events that can trigger this function include `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ *
+ **/
+
this.onChange = function(e) {
var delta = e.data;
var range = delta.range;
@@ -7482,6 +8942,16 @@ var Anchor = exports.Anchor = function(doc, row, column) {
this.setPosition(row, column, true);
};
+ /**
+ * Anchor.setPosition(row, column, noClip)
+ * - row (Number): The row index to move the anchor to
+ * - column (Number): The column index to move the anchor to
+ * - noClip (Boolean): Identifies if you want the position to be clipped
+ *
+ * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.
+ *
+ **/
+
this.setPosition = function(row, column, noClip) {
var pos;
if (noClip) {
@@ -7510,10 +8980,26 @@ var Anchor = exports.Anchor = function(doc, row, column) {
});
};
+ /**
+ * Anchor.detach()
+ *
+ * When called, the `'change'` event listener is removed.
+ *
+ **/
+
this.detach = function() {
this.document.removeEventListener("change", this.$onChange);
};
+ /** internal, hide
+ * Anchor.clipPositionToDocument(row, column)
+ * - row (Number): The row index to clip the anchor to
+ * - column (Number): The column index to clip the anchor to
+ *
+ * Clips the anchor position to the specified row and column.
+ *
+ **/
+
this.$clipPositionToDocument = function(row, column) {
var pos = {};
@@ -7582,6 +9068,23 @@ define('ace/background_tokenizer', ['require', 'exports', 'module' , 'ace/lib/oo
var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
+/**
+ * class BackgroundTokenizer
+ *
+ * Tokenizes the current [[Document `Document`]] in the background, and caches the tokenized rows for future use. If a certain row is changed, everything below that row is re-tokenized.
+ *
+ **/
+
+/**
+ * new BackgroundTokenizer(tokenizer, editor)
+ * - tokenizer (Tokenizer): The tokenizer to use
+ * - editor (Editor): The editor to associate with
+ *
+ * Creates a new `BackgroundTokenizer` object.
+ *
+ *
+ **/
+
var BackgroundTokenizer = function(tokenizer, editor) {
this.running = false;
this.lines = [];
@@ -7623,6 +9126,14 @@ var BackgroundTokenizer = function(tokenizer, editor) {
oop.implement(this, EventEmitter);
+ /**
+ * BackgroundTokenizer.setTokenizer(tokenizer)
+ * - tokenizer (Tokenizer): The new tokenizer to use
+ *
+ * Sets a new tokenizer for this object.
+ *
+ **/
+
this.setTokenizer = function(tokenizer) {
this.tokenizer = tokenizer;
this.lines = [];
@@ -7630,6 +9141,14 @@ var BackgroundTokenizer = function(tokenizer, editor) {
this.start(0);
};
+ /**
+ * BackgroundTokenizer.setDocument(doc)
+ * - doc (Document): The new document to associate with
+ *
+ * Sets a new document to associate with this object.
+ *
+ **/
+
this.setDocument = function(doc) {
this.doc = doc;
this.lines = [];
@@ -7637,6 +9156,15 @@ var BackgroundTokenizer = function(tokenizer, editor) {
this.stop();
};
+ /**
+ * BackgroundTokenizer.fireUpdateEvent(firstRow, lastRow)
+ * - firstRow (Number): The starting row region
+ * - lastRow (Number): The final row region
+ *
+ * Emits the `'update'` event. `firstRow` and `lastRow` are used to define the boundaries of the region to be updated.
+ *
+ **/
+
this.fireUpdateEvent = function(firstRow, lastRow) {
var data = {
first: firstRow,
@@ -7645,6 +9173,14 @@ var BackgroundTokenizer = function(tokenizer, editor) {
this._emit("update", {data: data});
};
+ /**
+ * BackgroundTokenizer.start(startRow)
+ * - startRow (Number): The row to start at
+ *
+ * Starts tokenizing at the row indicated.
+ *
+ **/
+
this.start = function(startRow) {
this.currentLine = Math.min(startRow || 0, this.currentLine,
this.doc.getLength());
@@ -7657,20 +9193,54 @@ var BackgroundTokenizer = function(tokenizer, editor) {
this.running = setTimeout(this.$worker, 700);
};
+ /**
+ * BackgroundTokenizer.stop()
+ *
+ * Stops tokenizing.
+ *
+ **/
+
this.stop = function() {
if (this.running)
clearTimeout(this.running);
this.running = false;
};
+ /** related to: BackgroundTokenizer.$tokenizeRows
+ * BackgroundTokenizer.getTokens(firstRow, lastRow) -> [Object]
+ * - firstRow (Number): The row to start at
+ * - lastRow (Number): The row to finish at
+ *
+ * Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.
+ *
+ **/
+
this.getTokens = function(firstRow, lastRow) {
return this.$tokenizeRows(firstRow, lastRow);
};
+ /**
+ * BackgroundTokenizer.getState(row) -> String
+ * - row (Number): The row to start at
+ *
+ * [Returns the state of tokenization for a row.]{: #BackgroundTokenizer.getState}
+ *
+ **/
+
this.getState = function(row) {
return this.$tokenizeRows(row, row)[0].state;
};
+ /**
+ * BackgroundTokenizer.$tokenizeRows(firstRow, lastRow) -> [Object]
+ * - startRow (Number): The row to start at
+ * - lastRow (Number): The row to finish at
+ * + ([Object]): A list of the tokenized rows. Each item in the list is an object with two properties, `state` and `start`.
+ *
+ * Tokenizes all the rows within the specified region.
+ *
+ *
+ **/
this.$tokenizeRows = function(firstRow, lastRow) {
if (!this.doc || isNaN(firstRow) || isNaN(lastRow))
return [{'state':'start','tokens':[]}];
@@ -7762,7 +9332,7 @@ var Fold = require("./fold").Fold;
var TokenIterator = require("../token_iterator").TokenIterator;
function Folding() {
- /**
+ /*
* Looks up a fold at a given row/column. Possible values for side:
* -1: ignore a fold if fold.start = row/column
* +1: ignore a fold if fold.end = row/column
@@ -7786,7 +9356,7 @@ function Folding() {
}
};
- /**
+ /*
* Returns all folds in the given range. Note, that this will return folds
*
*/
@@ -7832,7 +9402,7 @@ function Folding() {
return foundFolds;
};
- /**
+ /*
* Returns all folds in the document
*/
this.getAllFolds = function() {
@@ -7855,7 +9425,7 @@ function Folding() {
return folds;
};
- /**
+ /*
* Returns the string between folds at the given position.
* E.g.
* foob|arwolrd -> "bar"
@@ -7974,7 +9544,7 @@ function Folding() {
return foldLine;
};
- /**
+ /*
* Adds a new fold.
*
* @returns
@@ -8174,7 +9744,7 @@ function Folding() {
}
};
- /**
+ /*
* Checks if a given documentRow is folded. This is true if there are some
* folded parts such that some parts of the line is still visible.
**/
@@ -8514,7 +10084,7 @@ define('ace/edit_session/fold_line', ['require', 'exports', 'module' , 'ace/rang
var Range = require("../range").Range;
-/**
+/*
* If an array is passed in, the folds are expected to be sorted already.
*/
function FoldLine(foldData, folds) {
@@ -8537,7 +10107,7 @@ function FoldLine(foldData, folds) {
}
(function() {
- /**
+ /*
* Note: This doesn't update wrapData!
*/
this.shiftRow = function(shift) {
@@ -8650,7 +10220,9 @@ function FoldLine(foldData, folds) {
&& fold.start.column != column
&& fold.start.row != row)
{
- throw "Moving characters inside of a fold should never be reached";
+ //throwing here breaks whole editor
+ //@todo properly handle this
+ window.console && window.console.log(row, column, fold);
} else if (fold.start.row == row) {
folds = this.folds;
var i = folds.indexOf(fold);
@@ -8744,7 +10316,8 @@ function FoldLine(foldData, folds) {
}).call(FoldLine.prototype);
exports.FoldLine = FoldLine;
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -8785,7 +10358,7 @@ exports.FoldLine = FoldLine;
define('ace/edit_session/fold', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
-/**
+/*
* Simple fold-data struct.
**/
var Fold = exports.Fold = function(range, placeholder) {
@@ -8859,7 +10432,8 @@ var Fold = exports.Fold = function(range, placeholder) {
}).call(Fold.prototype);
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -8900,6 +10474,22 @@ var Fold = exports.Fold = function(range, placeholder) {
define('ace/token_iterator', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class TokenIterator
+ *
+ * This class provides an essay way to treat the document as a stream of tokens, and provides methods to iterate over these tokens.
+ *
+ **/
+
+/**
+ * new TokenIterator(session, initialRow, initialColumn)
+ * - session (EditSession): The session to associate with
+ * - initialRow (Number): The row to start the tokenizing at
+ * - initialColumn (Number): The column to start the tokenizing at
+ *
+ * Creates a new token iterator object. The inital token index is set to the provided row and column coordinates.
+ *
+ **/
var TokenIterator = function(session, initialRow, initialColumn) {
this.$session = session;
this.$row = initialRow;
@@ -8910,7 +10500,13 @@ var TokenIterator = function(session, initialRow, initialColumn) {
};
(function() {
-
+
+ /**
+ * TokenIterator.stepBackward() -> [String]
+ * + (String): If the current point is not at the top of the file, this function returns `null`. Otherwise, it returns an array of the tokenized strings.
+ *
+ * Tokenizes all the items from the current point to the row prior in the document.
+ **/
this.stepBackward = function() {
this.$tokenIndex -= 1;
@@ -8927,7 +10523,12 @@ var TokenIterator = function(session, initialRow, initialColumn) {
return this.$rowTokens[this.$tokenIndex];
};
-
+
+ /**
+ * TokenIterator.stepForward() -> String
+ *
+ * Tokenizes all the items from the current point until the next row in the document. If the current point is at the end of the file, this function returns `null`. Otherwise, it returns the tokenized string.
+ **/
this.stepForward = function() {
var rowCount = this.$session.getLength();
this.$tokenIndex += 1;
@@ -8945,15 +10546,33 @@ var TokenIterator = function(session, initialRow, initialColumn) {
return this.$rowTokens[this.$tokenIndex];
};
-
+
+ /**
+ * TokenIterator.getCurrentToken() -> String
+ *
+ * Returns the current tokenized string.
+ *
+ **/
this.getCurrentToken = function () {
return this.$rowTokens[this.$tokenIndex];
};
-
+
+ /**
+ * TokenIterator.getCurrentTokenRow() -> Number
+ *
+ * Returns the current row.
+ *
+ **/
this.getCurrentTokenRow = function () {
return this.$row;
};
-
+
+ /**
+ * TokenIterator.getCurrentTokenColumn() -> Number
+ *
+ * Returns the current column.
+ *
+ **/
this.getCurrentTokenColumn = function() {
var rowTokens = this.$rowTokens;
var tokenIndex = this.$tokenIndex;
@@ -9019,8 +10638,34 @@ define('ace/edit_session/bracket_match', ['require', 'exports', 'module' , 'ace/
var TokenIterator = require("../token_iterator").TokenIterator;
+/**
+ * class BracketMatch
+ *
+ *
+ *
+ *
+ **/
+
+/**
+ * new BracketMatch(position)
+ * - platform (String): Identifier for the platform; must be either `'mac'` or `'win'`
+ * - commands (Array): A list of commands
+ *
+ * TODO
+ *
+ *
+ **/
function BracketMatch() {
+ /**
+ * new findMatchingBracket(position)
+ * - position (Number): Identifier for the platform; must be either `'mac'` or `'win'`
+ * - commands (Array): A list of commands
+ *
+ * TODO
+ *
+ *
+ **/
this.findMatchingBracket = function(position) {
if (position.column == 0) return null;
@@ -9199,12 +10844,33 @@ exports.BracketMatch = BracketMatch;
define('ace/undomanager', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class UndoManager
+ *
+ * This object maintains the undo stack for an [[EditSession `EditSession`]].
+ *
+ **/
+
+/**
+ * new UndoManager()
+ *
+ * Resets the current undo state and creates a new `UndoManager`.
+ **/
var UndoManager = function() {
this.reset();
};
(function() {
+ /**
+ * UndoManager.execute(options) -> Void
+ * - options (Object): Contains additional properties
+ *
+ * Provides a means for implementing your own undo manager. `options` has one property, `args`, an [[Array `Array`]], with two elements:
+ * * `args[0]` is an array of deltas
+ * * `args[1]` is the document to associate with
+ *
+ **/
this.execute = function(options) {
var deltas = options.args[0];
this.$doc = options.args[1];
@@ -9212,6 +10878,12 @@ var UndoManager = function() {
this.$redoStack = [];
};
+ /**
+ * UndoManager.undo(dontSelect) -> Range
+ * - dontSelect (Boolean): {:dontSelect}
+ *
+ * [Perform an undo operation on the document, reverting the last change. Returns the range of the undo.]{: #UndoManager.undo}
+ **/
this.undo = function(dontSelect) {
var deltas = this.$undoStack.pop();
var undoSelectionRange = null;
@@ -9223,6 +10895,12 @@ var UndoManager = function() {
return undoSelectionRange;
};
+ /**
+ * UndoManager.redo(dontSelect) -> Void
+ * - dontSelect (Boolean): {:dontSelect}
+ *
+ * [Perform a redo operation on the document, reimplementing the last change.]{: #UndoManager.redo}
+ **/
this.redo = function(dontSelect) {
var deltas = this.$redoStack.pop();
var redoSelectionRange = null;
@@ -9234,15 +10912,30 @@ var UndoManager = function() {
return redoSelectionRange;
};
+ /**
+ * UndoManager.reset() -> Void
+ *
+ * Destroys the stack of undo and redo redo operations.
+ **/
this.reset = function() {
this.$undoStack = [];
this.$redoStack = [];
};
+ /**
+ * UndoManager.hasUndo() -> Boolean
+ *
+ * Returns `true` if there are undo operations left to perform.
+ **/
this.hasUndo = function() {
return this.$undoStack.length > 0;
};
+ /**
+ * UndoManager.hasRedo() -> Boolean
+ *
+ * Returns `true` if there are redo operations left to perform.
+ **/
this.hasRedo = function() {
return this.$redoStack.length > 0;
};
@@ -9438,7 +11131,7 @@ function StateHandler(keymapping) {
}
StateHandler.prototype = {
- /**
+ /*
* Build the RegExp from the keymapping as RegExp can't stored directly
* in the metadata JSON and as the RegExp used to match the keys/buffer
* need to be adapted.
@@ -9589,7 +11282,7 @@ StateHandler.prototype = {
}
},
- /**
+ /*
* This function is called by keyBinding.
*/
handleKeyboard: function(data, hashId, key, keyCode, e) {
@@ -9615,7 +11308,7 @@ StateHandler.prototype = {
}
}
-/**
+/*
* This is a useful matching function and therefore is defined here so that
* users of KeyboardStateMapper can use it.
*
@@ -9874,6 +11567,18 @@ function HashHandler(config, platform) {
}
};
+ this.bindKey = function(key, command) {
+ if(!key)
+ return;
+
+ var ckb = this.commmandKeyBinding;
+ key.split("|").forEach(function(keyPart) {
+ var binding = this.parseKeys(keyPart, command);
+ var hashId = binding.hashId;
+ (ckb[hashId] || (ckb[hashId] = {}))[binding.key] = command;
+ }, this);
+ };
+
this.addCommands = function(commands) {
commands && Object.keys(commands).forEach(function(name) {
var command = commands[name];
@@ -9896,18 +11601,6 @@ function HashHandler(config, platform) {
}, this);
};
- this.bindKey = function(key, command) {
- if(!key)
- return;
-
- var ckb = this.commmandKeyBinding;
- key.split("|").forEach(function(keyPart) {
- var binding = parseKeys(keyPart, command);
- var hashId = binding.hashId;
- (ckb[hashId] || (ckb[hashId] = {}))[binding.key] = command;
- });
- };
-
this.bindKeys = function(keyList) {
Object.keys(keyList).forEach(function(key) {
this.bindKey(key, keyList[key]);
@@ -9923,10 +11616,10 @@ function HashHandler(config, platform) {
this.bindKey(key, command);
};
- function parseKeys(keys, val, ret) {
+ this.parseKeys = function(keys, val) {
var key;
var hashId = 0;
- var parts = splitSafe(keys.toLowerCase());
+ var parts = keys.toLowerCase().trim().split(/\s*\-\s*/);
for (var i = 0, l = parts.length; i < l; i++) {
if (keyUtil.KEY_MODS[parts[i]])
@@ -9939,17 +11632,12 @@ function HashHandler(config, platform) {
key: key,
hashId: hashId
};
- }
-
- function splitSafe(s) {
- return (s.trim()
- .split(new RegExp("[\\s ]*\\-[\\s ]*", "g"), 999));
- }
+ };
this.findKeyCommand = function findKeyCommand(hashId, keyString) {
var ckbr = this.commmandKeyBinding;
return ckbr[hashId] && ckbr[hashId][keyString.toLowerCase()];
- }
+ };
this.handleKeyboard = function(data, hashId, keyString, keyCode) {
return {
@@ -11227,6 +12915,23 @@ var Editor = require("./editor").Editor;
var Renderer = require("./virtual_renderer").VirtualRenderer;
var EditSession = require("./edit_session").EditSession;
+/** internal, hide
+ * class Split
+ *
+ *
+ *
+ **/
+
+/** internal, hide
+ * new Split(container, theme, splits)
+ * - container (Document): The document to associate with the split
+ * - theme (String): The name of the initial theme
+ * - splits (Number): The number of initial splits
+ *
+ *
+ *
+ **/
+
var Split = function(container, theme, splits) {
this.BELOW = 1;
this.BESIDE = 0;
@@ -11267,6 +12972,13 @@ var Split = function(container, theme, splits) {
return editor;
};
+ /** internal, hide
+ * Split.setSplits(splits) -> Void
+ * - splits (Number): The new number of splits
+ *
+ *
+ *
+ **/
this.setSplits = function(splits) {
var editor;
if (splits < 1) {
@@ -11296,42 +13008,100 @@ var Split = function(container, theme, splits) {
this.resize();
};
+ /**
+ * Split.getSplits() -> Number
+ *
+ * Returns the number of splits.
+ *
+ **/
this.getSplits = function() {
return this.$splits;
};
+ /**
+ * Split.getEditor(idx) -> Editor
+ * -idx (Number): The index of the editor you want
+ *
+ * Returns the editor identified by the index `idx`.
+ *
+ **/
this.getEditor = function(idx) {
return this.$editors[idx];
};
+ /**
+ * Split.getCurrentEditor() -> Editor
+ *
+ * Returns the current editor.
+ *
+ **/
this.getCurrentEditor = function() {
return this.$cEditor;
};
+ /** related to: Editor.focus
+ * Split.focus() -> Void
+ *
+ * Focuses the current editor.
+ *
+ **/
this.focus = function() {
this.$cEditor.focus();
};
+ /** related to: Editor.blur
+ * Split.blur() -> Void
+ *
+ * Blurs the current editor.
+ *
+ **/
this.blur = function() {
this.$cEditor.blur();
};
+ /** related to: Editor.setTheme
+ * Split.setTheme(theme) -> Void
+ * - theme (String): The name of the theme to set
+ *
+ * Sets a theme for each of the available editors.
+ **/
this.setTheme = function(theme) {
this.$editors.forEach(function(editor) {
editor.setTheme(theme);
});
};
+ /** internal, hide
+ * Split.setKeyboardHandler(keybinding) -> Void
+ * - keybinding (String):
+ *
+ *
+ **/
this.setKeyboardHandler = function(keybinding) {
this.$editors.forEach(function(editor) {
editor.setKeyboardHandler(keybinding);
});
};
+ /** internal, hide
+ * Split.forEach(callback, scope) -> Void
+ * - callback (Function): A callback function to execute
+ * - scope (String):
+ *
+ * Executes `callback` on all of the available editors.
+ *
+ **/
this.forEach = function(callback, scope) {
this.$editors.forEach(callback, scope);
};
+ /** related to: Editor.setFontSize
+ * Split.setFontSize(size) -> Void
+ * - size (Number): The new font size
+ *
+ * Sets the font size, in pixels, for all the available editors.
+ *
+ **/
this.$fontSize = "";
this.setFontSize = function(size) {
this.$fontSize = size;
@@ -11367,6 +13137,14 @@ var Split = function(container, theme, splits) {
return s;
};
+ /** related to: Editor.setSession
+ * Split.setSession(session, idx) -> Void
+ * - session (EditSession): The new edit session
+ * - idx (Number): The editor's index you're interested in
+ *
+ * Sets a new [[EditSession `EditSession`]] for the indicated editor.
+ *
+ **/
this.setSession = function(session, idx) {
var editor;
if (idx == null) {
@@ -11393,10 +13171,23 @@ var Split = function(container, theme, splits) {
return session;
};
+ /** internal, hide
+ * Split.getOrientation() -> Number
+ *
+ * Returns the orientation.
+ *
+ **/
this.getOrientation = function() {
return this.$orientation;
};
+ /** internal, hide
+ * Split.setOrientation(oriantation) -> Void
+ * - oriantation (Number):
+ *
+ * Sets the orientation.
+ *
+ **/
this.setOrientation = function(orientation) {
if (this.$orientation == orientation) {
return;
@@ -11405,6 +13196,12 @@ var Split = function(container, theme, splits) {
this.resize();
};
+ /** internal
+ * Split.resize() -> Void
+ *
+ *
+ *
+ **/
this.resize = function() {
var width = this.$container.clientWidth;
var height = this.$container.clientHeight;
@@ -11435,6 +13232,12 @@ var Split = function(container, theme, splits) {
}).call(Split.prototype);
+ /** internal
+ * Split.UndoManagerProxy() -> Void
+ *
+ *
+ *
+ **/
function UndoManagerProxy(undoManager, session) {
this.$u = undoManager;
this.$doc = session;
@@ -11534,12 +13337,29 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var CommandManager = require("./commands/command_manager").CommandManager;
var defaultCommands = require("./commands/default_commands").commands;
+/**
+ * class Editor
+ *
+ * The main entry point into the Ace functionality. The `Editor` manages the `EditSession` (which manages `Document`s), as well as the `VirtualRenderer`, which draws everything to the screen. Event sessions dealing with the mouse and keyboard are bubbled up from `Document` to the `Editor`, which decides what to do with them.
+ *
+ **/
+
+/**
+ * new Editor(renderer, session)
+ * - renderer (VirtualRenderer): Associated `VirtualRenderer` that draws everything
+ * - session (EditSession): The `EditSession` to refer to
+ *
+ * Creates a new `Editor` object.
+ *
+ **/
var Editor = function(renderer, session) {
var container = renderer.getContainerElement();
this.container = container;
this.renderer = renderer;
+ this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
+ this.renderer.textarea = this.textInput.getElement();
this.keyBinding = new KeyBinding(this);
// TODO detect touch event support
@@ -11555,7 +13375,6 @@ var Editor = function(renderer, session) {
wrap: true
});
- this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands);
this.setSession(session || new EditSession(""));
};
@@ -11563,14 +13382,30 @@ var Editor = function(renderer, session) {
oop.implement(this, EventEmitter);
+ /**
+ * Editor.setKeyboardHandler(keyboardHandler)
+ *
+ * Sets a new keyboard handler.
+ **/
this.setKeyboardHandler = function(keyboardHandler) {
this.keyBinding.setKeyboardHandler(keyboardHandler);
};
+ /** related to: KeyBinding
+ * Editor.getKeyboardHandler() -> String
+ *
+ * Returns the keyboard handler.
+ **/
this.getKeyboardHandler = function() {
return this.keyBinding.getKeyboardHandler();
};
+ /**
+ * Editor.setSession(session)
+ * - session (EditSession): The new session to use
+ *
+ * Sets a new editsession to use. This method also emits the `'changeSession'` event.
+ **/
this.setSession = function(session) {
if (this.session == session)
return;
@@ -11670,39 +13505,84 @@ var Editor = function(renderer, session) {
});
};
+ /**
+ * Editor.getSession() -> EditSession
+ *
+ * Returns the current session being used.
+ **/
this.getSession = function() {
return this.session;
};
+ /**
+ * Editor.getSelection() -> String
+ *
+ * Returns the currently highlighted selection.
+ **/
this.getSelection = function() {
return this.selection;
};
+ /** related to: VirtualRenderer.onResize
+ * Editor.resize()
+ *
+ * {:VirtualRenderer.onResize}
+ **/
this.resize = function() {
this.renderer.onResize();
};
+ /**
+ * Editor.setTheme(theme)
+ *
+ * {:VirtualRenderer.setTheme}
+ **/
this.setTheme = function(theme) {
this.renderer.setTheme(theme);
};
+ /** related to: VirtualRenderer.getTheme
+ * Editor.getTheme() -> String
+ *
+ * {:VirtualRenderer.getTheme}
+ **/
this.getTheme = function() {
return this.renderer.getTheme();
};
+ /** related to: VirtualRenderer.setStyle
+ * Editor.setStyle(style)
+ *
+ * {:VirtualRenderer.setStyle}
+ **/
this.setStyle = function(style) {
this.renderer.setStyle(style);
};
+ /** related to: VirtualRenderer.unsetStyle
+ * Editor.unsetStyle(style)
+ *
+ * {:VirtualRenderer.unsetStyle}
+ **/
this.unsetStyle = function(style) {
this.renderer.unsetStyle(style);
};
+ /**
+ * Editor.setFontSize(size)
+ * - size (Number): A font size
+ *
+ * Set a new font size (in pixels) for the editor text.
+ **/
this.setFontSize = function(size) {
this.container.style.fontSize = size;
this.renderer.updateFontSize();
};
+ /** internal, hide
+ * Editor.$highlightBrackets()
+ *
+ **/
this.$highlightBrackets = function() {
if (this.session.$bracketHighlight) {
this.session.removeMarker(this.session.$bracketHighlight);
@@ -11727,6 +13607,11 @@ var Editor = function(renderer, session) {
}, 10);
};
+ /**
+ * Editor.focus()
+ *
+ * Brings the current `textInput` into focus.
+ **/
this.focus = function() {
// Safari needs the timeout
// iOS and Firefox need it called immediately
@@ -11738,26 +13623,57 @@ var Editor = function(renderer, session) {
this.textInput.focus();
};
+ /**
+ * Editor.isFocused() -> Boolean
+ *
+ * Returns true if the current `textInput` is in focus.
+ **/
this.isFocused = function() {
return this.textInput.isFocused();
};
+ /**
+ * Editor.blur()
+ *
+ * Blurs the current `textInput`.
+ **/
this.blur = function() {
this.textInput.blur();
};
+ /**
+ * Editor@onFocus()
+ *
+ * Emitted once the editor comes into focus.
+ **/
this.onFocus = function() {
this.renderer.showCursor();
this.renderer.visualizeFocus();
this._emit("focus");
};
+ /**
+ * Editor@onBlur()
+ *
+ * Emitted once the editor has been blurred.
+ **/
this.onBlur = function() {
this.renderer.hideCursor();
this.renderer.visualizeBlur();
this._emit("blur");
};
+ this.$cursorChange = function() {
+ this.renderer.updateCursor();
+ };
+
+ /**
+ * Editor@onDocumentChange(e)
+ * - e (Object): Contains a single property, `data`, which has the delta of changes
+ *
+ * Emitted whenever the document is changed.
+ *
+ **/
this.onDocumentChange = function(e) {
var delta = e.data;
var range = delta.range;
@@ -11772,51 +13688,70 @@ var Editor = function(renderer, session) {
this._emit("change", e);
// update cursor because tab characters can influence the cursor position
- this.onCursorChange();
+ this.$cursorChange();
};
+ /**
+ * Editor@onTokenizerUpdate(e)
+ * - e (Object): Contains a single property, `data`, which indicates the changed rows
+ *
+ * Emitted when the a tokenizer is updated.
+ **/
this.onTokenizerUpdate = function(e) {
var rows = e.data;
this.renderer.updateLines(rows.first, rows.last);
};
+ /**
+ * Editor@onScrollTopChange()
+ *
+ * Emitted when the scroll top changes.
+ **/
this.onScrollTopChange = function() {
this.renderer.scrollToY(this.session.getScrollTop());
};
+ /**
+ * Editor@onScrollLeftChange()
+ *
+ * Emitted when the scroll left changes.
+ **/
this.onScrollLeftChange = function() {
this.renderer.scrollToX(this.session.getScrollLeft());
};
+ /**
+ * Editor@onCursorChange()
+ *
+ * Emitted when the cursor changes.
+ **/
this.onCursorChange = function() {
- this.renderer.updateCursor();
+ this.$cursorChange();
if (!this.$blockScrolling) {
this.renderer.scrollCursorIntoView();
}
- // move text input over the cursor
- // this is required for iOS and IME
- this.renderer.moveTextAreaToCursor(this.textInput.getElement());
-
this.$highlightBrackets();
this.$updateHighlightActiveLine();
};
+ /** internal, hide
+ * Editor.$updateHighlightActiveLine()
+ *
+ *
+ **/
this.$updateHighlightActiveLine = function() {
var session = this.getSession();
if (session.$highlightLineMarker)
session.removeMarker(session.$highlightLineMarker);
- if (typeof this.$lastrow == "number")
- this.renderer.removeGutterDecoration(this.$lastrow, "ace_gutter_active_line");
session.$highlightLineMarker = null;
- this.$lastrow = null;
- if (this.getHighlightActiveLine()) {
- var cursor = this.getCursorPosition(),
- foldLine = this.session.getFoldLine(cursor.row);
+ if (this.$highlightActiveLine) {
+ var cursor = this.getCursorPosition();
+ var foldLine = this.session.getFoldLine(cursor.row);
if ((this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) {
var range;
@@ -11827,11 +13762,16 @@ var Editor = function(renderer, session) {
}
session.$highlightLineMarker = session.addMarker(range, "ace_active_line", "background");
}
-
- this.renderer.addGutterDecoration(this.$lastrow = cursor.row, "ace_gutter_active_line");
}
};
+
+ /**
+ * Editor@onSelectionChange(e)
+ * - e (Object): Contains a single property, `data`, which has the delta of changes
+ *
+ * Emitted when a selection has changed.
+ **/
this.onSelectionChange = function(e) {
var session = this.getSession();
@@ -11852,34 +13792,74 @@ var Editor = function(renderer, session) {
this.session.getMode().highlightSelection(this);
};
+ /**
+ * Editor@onChangeFrontMarker()
+ *
+ * Emitted when a front marker changes.
+ **/
this.onChangeFrontMarker = function() {
this.renderer.updateFrontMarkers();
};
+ /**
+ * Editor@onChangeBackMarker()
+ *
+ * Emitted when a back marker changes.
+ **/
this.onChangeBackMarker = function() {
this.renderer.updateBackMarkers();
};
+ /**
+ * Editor@onChangeBreakpoint()
+ *
+ * Emitted when a breakpoint changes.
+ **/
this.onChangeBreakpoint = function() {
this.renderer.setBreakpoints(this.session.getBreakpoints());
};
+ /**
+ * Editor@onChangeAnnotation()
+ *
+ * Emitted when an annotation changes.
+ **/
this.onChangeAnnotation = function() {
this.renderer.setAnnotations(this.session.getAnnotations());
};
+ /**
+ * Editor@onChangeMode()
+ *
+ * Emitted when the mode changes.
+ **/
this.onChangeMode = function() {
this.renderer.updateText();
};
+ /**
+ * Editor@onChangeWrapLimit()
+ *
+ * Emitted when the wrap limit changes.
+ **/
this.onChangeWrapLimit = function() {
this.renderer.updateFull();
};
+ /**
+ * Editor@onChangeWrapMode()
+ *
+ * Emitted when the wrap mode changes.
+ **/
this.onChangeWrapMode = function() {
this.renderer.onResize(true);
};
+ /**
+ * Editor@onChangeFold()
+ *
+ * Emitted when the code folds change.
+ **/
this.onChangeFold = function() {
// Update the active line marker as due to folding changes the current
// line range on the screen might have changed.
@@ -11888,6 +13868,11 @@ var Editor = function(renderer, session) {
this.renderer.updateFull();
};
+ /**
+ * Editor.getCopyText() -> String
+ *
+ * Returns the string of text currently highlighted.
+ **/
this.getCopyText = function() {
var text = "";
if (!this.selection.isEmpty())
@@ -11897,10 +13882,40 @@ var Editor = function(renderer, session) {
return text;
};
+ /**
+ * Editor.onCopy()
+ *
+ * Called whenever a text "copy" happens.
+ **/
+ this.onCopy = function() {
+ this.commands.exec("copy", this);
+ };
+
+ /**
+ * Editor.onCut()
+ *
+ * called whenever a text "cut" happens.
+ **/
this.onCut = function() {
this.commands.exec("cut", this);
};
+ /**
+ * Editor.onPaste()
+ *
+ * called whenever a text "paste" happens.
+ **/
+ this.onPaste = function(text) {
+ this._emit("paste", text);
+ this.insert(text);
+ };
+
+ /**
+ * Editor.insert(text)
+ * - text (String): The new text to add
+ *
+ * Inserts `text` into wherever the cursor is pointing.
+ **/
this.insert = function(text) {
var session = this.session;
var mode = session.getMode();
@@ -11993,46 +14008,103 @@ var Editor = function(renderer, session) {
mode.autoOutdent(lineState, session, cursor.row);
};
- this.onTextInput = function(text, pasted) {
- if (pasted)
- this._emit("paste", text);
-
- this.keyBinding.onTextInput(text, pasted);
+ /**
+ * Editor@onTextInput(text, pasted)
+ * - text (String): The text entered
+ * - pasted (Boolean): Identifies whether the text was pasted (`true`) or not
+ *
+ * Emitted when text is entered.
+ **/
+ this.onTextInput = function(text) {
+ this.keyBinding.onTextInput(text);
};
+ /**
+ * Editor@onCommandKey(e, hashId, keyCode)
+ *
+ * Emitted when the command-key is pressed.
+ **/
this.onCommandKey = function(e, hashId, keyCode) {
this.keyBinding.onCommandKey(e, hashId, keyCode);
};
+ /** related to: EditSession.setOverwrite
+ * Editor.setOverwrite(overwrite)
+ * - overwrite (Boolean): Defines wheter or not to set overwrites
+ *
+ * Pass in `true` to enable overwrites in your session, or `false` to disable. If overwrites is enabled, any text you enter will type over any text after it. If the value of `overwrite` changes, this function also emites the `changeOverwrite` event.
+ *
+ **/
this.setOverwrite = function(overwrite) {
this.session.setOverwrite(overwrite);
};
+ /** related to: EditSession.getOverwrite
+ * Editor.getOverwrite() -> Boolean
+ *
+ * Returns `true` if overwrites are enabled; `false` otherwise.
+ **/
this.getOverwrite = function() {
return this.session.getOverwrite();
};
+ /** related to: EditSession.toggleOverwrite
+ * Editor.toggleOverwrite()
+ *
+ * Sets the value of overwrite to the opposite of whatever it currently is.
+ **/
this.toggleOverwrite = function() {
this.session.toggleOverwrite();
};
+ /**
+ * Editor.setScrollSpeed(speed)
+ * - speed (Number): A value indicating the new speed
+ *
+ * Sets how fast the mouse scrolling should do.
+ *
+ **/
this.setScrollSpeed = function(speed) {
this.$mouseHandler.setScrollSpeed(speed);
};
+ /**
+ * Editor.getScrollSpeed() -> Number
+ *
+ * Returns the value indicating how fast the mouse scroll speed is.
+ **/
this.getScrollSpeed = function() {
return this.$mouseHandler.getScrollSpeed();
};
+ /**
+ * Editor.setDragDelay(dragDelay)
+ * - dragDelay (Number): A value indicating the new delay
+ *
+ * Sets the delay (in milliseconds) of the mouse drag.
+ *
+ **/
this.setDragDelay = function(dragDelay) {
this.$mouseHandler.setDragDelay(dragDelay);
};
+ /**
+ * Editor.getDragDelay() -> Number
+ *
+ * Returns the current mouse drag delay.
+ **/
this.getDragDelay = function() {
return this.$mouseHandler.getDragDelay();
};
this.$selectionStyle = "line";
+ /**
+ * Editor.setSelectionStyle(style)
+ * - style (String): The new selection style
+ *
+ * Indicates how selections should occur. By default, selections are set to "line". This function also emits the `'changeSelectionStyle'` event.
+ *
+ **/
this.setSelectionStyle = function(style) {
if (this.$selectionStyle == style) return;
@@ -12041,23 +14113,60 @@ var Editor = function(renderer, session) {
this._emit("changeSelectionStyle", {data: style});
};
+ /**
+ * Editor.getSelectionStyle() -> String
+ *
+ * Returns the current selection style.
+ **/
this.getSelectionStyle = function() {
return this.$selectionStyle;
};
this.$highlightActiveLine = true;
+
+ /**
+ * Editor.setHighlightActiveLine(shouldHighlight)
+ * - shouldHighlight (Boolean): Set to `true` to highlight the current line
+ *
+ * Determines whether or not the current line should be highlighted.
+ *
+ **/
this.setHighlightActiveLine = function(shouldHighlight) {
- if (this.$highlightActiveLine == shouldHighlight) return;
+ if (this.$highlightActiveLine == shouldHighlight)
+ return;
this.$highlightActiveLine = shouldHighlight;
this.$updateHighlightActiveLine();
};
+ /**
+ * Editor.getHighlightActiveLine() -> Boolean
+ *
+ * Returns `true` if current lines are always highlighted.
+ **/
this.getHighlightActiveLine = function() {
return this.$highlightActiveLine;
};
+ this.$highlightGutterLine = true;
+ this.setHighlightGutterLine = function(shouldHighlight) {
+ if (this.$highlightGutterLine == shouldHighlight)
+ return;
+
+ this.renderer.setHighlightGutterLine(shouldHighlight);
+ };
+
+ this.getHighlightGutterLine = function() {
+ return this.$highlightGutterLine;
+ };
+
this.$highlightSelectedWord = true;
+ /**
+ * Editor.setHighlightSelectedWord(shouldHighlight)
+ * - shouldHighlight (Boolean): Set to `true` to highlight the currently selected word
+ *
+ * Determines if the currently selected word should be highlighted.
+ **/
this.setHighlightSelectedWord = function(shouldHighlight) {
if (this.$highlightSelectedWord == shouldHighlight)
return;
@@ -12069,6 +14178,11 @@ var Editor = function(renderer, session) {
this.session.getMode().clearSelectionHighlight(this);
};
+ /**
+ * Editor.getHighlightSelectedWord() -> Boolean
+ *
+ * Returns `true` if currently highlighted words are to be highlighted.
+ **/
this.getHighlightSelectedWord = function() {
return this.$highlightSelectedWord;
};
@@ -12081,6 +14195,12 @@ var Editor = function(renderer, session) {
return this.renderer.getAnimatedScroll();
};
+ /**
+ * Editor.setShowInvisibles(showInvisibles)
+ * - showInvisibles (Boolean): Specifies whether or not to show invisible characters
+ *
+ * If `showInvisibiles` is set to `true`, invisible characters—like spaces or new lines—are show in the editor.
+ **/
this.setShowInvisibles = function(showInvisibles) {
if (this.getShowInvisibles() == showInvisibles)
return;
@@ -12088,44 +14208,101 @@ var Editor = function(renderer, session) {
this.renderer.setShowInvisibles(showInvisibles);
};
+ /**
+ * Editor.getShowInvisibles() -> Boolean
+ *
+ * Returns `true` if invisible characters are being shown.
+ **/
this.getShowInvisibles = function() {
return this.renderer.getShowInvisibles();
};
+ /**
+ * Editor.setShowPrintMargin(showPrintMargin)
+ * - showPrintMargin (Boolean): Specifies whether or not to show the print margin
+ *
+ * If `showPrintMargin` is set to `true`, the print margin is shown in the editor.
+ **/
this.setShowPrintMargin = function(showPrintMargin) {
this.renderer.setShowPrintMargin(showPrintMargin);
};
+ /**
+ * Editor.getShowPrintMargin() -> Boolean
+ *
+ * Returns `true` if the print margin is being shown.
+ **/
this.getShowPrintMargin = function() {
return this.renderer.getShowPrintMargin();
};
+ /**
+ * Editor.setPrintMarginColumn(showPrintMargin)
+ * - showPrintMargin (Number): Specifies the new print margin
+ *
+ * Sets the column defining where the print margin should be.
+ *
+ **/
this.setPrintMarginColumn = function(showPrintMargin) {
this.renderer.setPrintMarginColumn(showPrintMargin);
};
+ /**
+ * Editor.getPrintMarginColumn() -> Number
+ *
+ * Returns the column number of where the print margin is.
+ **/
this.getPrintMarginColumn = function() {
return this.renderer.getPrintMarginColumn();
};
this.$readOnly = false;
+ /**
+ * Editor.setReadOnly(readOnly)
+ * - readOnly (Boolean): Specifies whether the editor can be modified or not
+ *
+ * If `readOnly` is true, then the editor is set to read-only mode, and none of the content can change.
+ **/
this.setReadOnly = function(readOnly) {
this.$readOnly = readOnly;
};
+ /**
+ * Editor.getReadOnly() -> Boolean
+ *
+ * Returns `true` if the editor is set to read-only mode.
+ **/
this.getReadOnly = function() {
return this.$readOnly;
};
this.$modeBehaviours = true;
+
+ /**
+ * Editor.setBehavioursEnabled()
+ * - enabled (Boolean): Enables or disables behaviors
+ *
+ * Specifies whether to use behaviors or not. ["Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.]{: #BehaviorsDef}
+ **/
this.setBehavioursEnabled = function (enabled) {
this.$modeBehaviours = enabled;
};
+ /**
+ * Editor.getBehavioursEnabled() -> Boolean
+ *
+ * Returns `true` if the behaviors are currently enabled. {:BehaviorsDef}
+ **/
this.getBehavioursEnabled = function () {
return this.$modeBehaviours;
};
+ /**
+ * Editor.setShowFoldWidgets(show)
+ * - show (Boolean): Specifies whether the fold widgets are shown
+ *
+ * Indicates whether the fold widgets are shown or not.
+ **/
this.setShowFoldWidgets = function(show) {
var gutter = this.renderer.$gutterLayer;
if (gutter.getShowFoldWidgets() == show)
@@ -12136,13 +14313,33 @@ var Editor = function(renderer, session) {
this.renderer.updateFull();
};
+ /**
+ * Editor.getShowFoldWidgets() -> Boolean
+ *
+ * Returns `true` if the fold widgets are shown.
+ **/
this.getShowFoldWidgets = function() {
return this.renderer.$gutterLayer.getShowFoldWidgets();
};
+ this.setFadeFoldWidgets = function(show) {
+ this.renderer.setFadeFoldWidgets(show);
+ };
+
+ this.getFadeFoldWidgets = function() {
+ return this.renderer.getFadeFoldWidgets();
+ };
+
+ /**
+ * Editor.remove(dir)
+ * - dir (String): The direction of the deletion to occur, either "left" or "right"
+ *
+ * Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.
+ *
+ **/
this.remove = function(dir) {
if (this.selection.isEmpty()){
- if(dir == "left")
+ if (dir == "left")
this.selection.selectLeft();
else
this.selection.selectRight();
@@ -12161,6 +14358,11 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
+ /**
+ * Editor.removeWordRight()
+ *
+ * Removes the word directly to the right of the current selection.
+ **/
this.removeWordRight = function() {
if (this.selection.isEmpty())
this.selection.selectWordRight();
@@ -12169,6 +14371,11 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
+ /**
+ * Editor.removeWordLeft()
+ *
+ * Removes the word directly to the left of the current selection.
+ **/
this.removeWordLeft = function() {
if (this.selection.isEmpty())
this.selection.selectWordLeft();
@@ -12177,6 +14384,11 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
+ /**
+ * Editor.removeToLineStart()
+ *
+ * Removes all the words to the left of the current selection, until the start of the line.
+ **/
this.removeToLineStart = function() {
if (this.selection.isEmpty())
this.selection.selectLineStart();
@@ -12185,6 +14397,11 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
+ /**
+ * Editor.removeToLineEnd()
+ *
+ * Removes all the words to the right of the current selection, until the end of the line.
+ **/
this.removeToLineEnd = function() {
if (this.selection.isEmpty())
this.selection.selectLineEnd();
@@ -12199,6 +14416,11 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
+ /**
+ * Editor.splitLine()
+ *
+ * Splits the line at the current selection (by inserting an `'\n'`).
+ **/
this.splitLine = function() {
if (!this.selection.isEmpty()) {
this.session.remove(this.getSelectionRange());
@@ -12210,6 +14432,11 @@ var Editor = function(renderer, session) {
this.moveCursorToPosition(cursor);
};
+ /**
+ * Editor.transposeLetters()
+ *
+ * Transposes current line.
+ **/
this.transposeLetters = function() {
if (!this.selection.isEmpty()) {
return;
@@ -12233,6 +14460,11 @@ var Editor = function(renderer, session) {
this.session.replace(range, swap);
};
+ /**
+ * Editor.toLowerCase()
+ *
+ * Converts the current selection entirely into lowercase.
+ **/
this.toLowerCase = function() {
var originalRange = this.getSelectionRange();
if (this.selection.isEmpty()) {
@@ -12245,6 +14477,11 @@ var Editor = function(renderer, session) {
this.selection.setSelectionRange(originalRange);
};
+ /**
+ * Editor.toUpperCase()
+ *
+ * Converts the current selection entirely into uppercase.
+ **/
this.toUpperCase = function() {
var originalRange = this.getSelectionRange();
if (this.selection.isEmpty()) {
@@ -12257,6 +14494,11 @@ var Editor = function(renderer, session) {
this.selection.setSelectionRange(originalRange);
};
+ /** related to: EditSession.indentRows
+ * Editor.indent()
+ *
+ * Indents the current line.
+ **/
this.indent = function() {
var session = this.session;
var range = this.getSelectionRange();
@@ -12280,17 +14522,32 @@ var Editor = function(renderer, session) {
}
};
+ /** related to: EditSession.outdentRows
+ * Editor.blockOutdent()
+ *
+ * Outdents the current line.
+ **/
this.blockOutdent = function() {
var selection = this.session.getSelection();
this.session.outdentRows(selection.getRange());
};
+ /**
+ * Editor.toggleCommentLines()
+ *
+ * Given the currently selected range, this function either comments all lines or uncomments all lines (depending on whether it's commented or not).
+ **/
this.toggleCommentLines = function() {
var state = this.session.getState(this.getCursorPosition().row);
var rows = this.$getSelectedRows();
this.session.getMode().toggleCommentLines(state, this.session, rows.first, rows.last);
};
+ /** related to: EditSession.remove
+ * Editor.removeLines()
+ *
+ * Removes all the lines in the current selection
+ **/
this.removeLines = function() {
var rows = this.$getSelectedRows();
var range;
@@ -12305,18 +14562,47 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
+ /** related to: EditSession.moveLinesDown
+ * Editor.moveLinesDown() -> Number
+ * + (Number): On success, it returns -1.
+ *
+ * Shifts all the selected lines down one row.
+ *
+ *
+ *
+ **/
this.moveLinesDown = function() {
this.$moveLines(function(firstRow, lastRow) {
return this.session.moveLinesDown(firstRow, lastRow);
});
};
+ /** related to: EditSession.moveLinesUp
+ * Editor.moveLinesUp() -> Number
+ * + (Number): On success, it returns -1.
+ *
+ * Shifts all the selected lines up one row.
+ *
+ *
+ **/
this.moveLinesUp = function() {
this.$moveLines(function(firstRow, lastRow) {
return this.session.moveLinesUp(firstRow, lastRow);
});
};
+ /** related to: EditSession.moveText
+ * Editor.moveText(fromRange, toPosition) -> Range
+ * - fromRange (Range): The range of text you want moved within the document
+ * - toPosition (Object): The location (row and column) where you want to move the text to
+ * + (Range): The new range where the text was moved to.
+ *
+ * Moves a range of text from the given range to the given position. `toPosition` is an object that looks like this:
+ *
+ * { row: newRowLocation, column: newColumnLocation }
+ *
+ *
+ **/
this.moveText = function(range, toPosition) {
if (this.$readOnly)
return null;
@@ -12324,6 +14610,14 @@ var Editor = function(renderer, session) {
return this.session.moveText(range, toPosition);
};
+ /** related to: EditSession.duplicateLines
+ * Editor.copyLinesUp() -> Number
+ * + (Number): On success, returns 0.
+ *
+ * Copies all the selected lines up one row.
+ *
+ *
+ **/
this.copyLinesUp = function() {
this.$moveLines(function(firstRow, lastRow) {
this.session.duplicateLines(firstRow, lastRow);
@@ -12331,6 +14625,15 @@ var Editor = function(renderer, session) {
});
};
+ /** related to: EditSession.duplicateLines
+ * Editor.copyLinesDown() -> Number
+ * + (Number): On success, returns the number of new rows added; in other words, `lastRow - firstRow + 1`.
+ *
+ * Copies all the selected lines down one row.
+ *
+ *
+ *
+ **/
this.copyLinesDown = function() {
this.$moveLines(function(firstRow, lastRow) {
return this.session.duplicateLines(firstRow, lastRow);
@@ -12338,6 +14641,13 @@ var Editor = function(renderer, session) {
};
+ /**
+ * Editor.$moveLines(mover)
+ * - mover (Function): A method to call on each selected row
+ *
+ * Executes a specific function, which can be anything that manipulates selected lines, such as copying them, duplicating them, or shifting them.
+ *
+ **/
this.$moveLines = function(mover) {
var rows = this.$getSelectedRows();
var selection = this.selection;
@@ -12361,6 +14671,14 @@ var Editor = function(renderer, session) {
}
};
+ /**
+ * Editor.$getSelectedRows() -> Object
+ *
+ * Returns an object indicating the currently selected rows. The object looks like this:
+ *
+ * { first: range.start.row, last: range.end.row }
+ *
+ **/
this.$getSelectedRows = function() {
var range = this.getSelectionRange().collapseRows();
@@ -12370,141 +14688,278 @@ var Editor = function(renderer, session) {
};
};
+ /** internal, hide
+ * Editor@onCompositionStart(text)
+ * - text (String): The text being written
+ *
+ *
+ **/
this.onCompositionStart = function(text) {
this.renderer.showComposition(this.getCursorPosition());
};
+ /** internal, hide
+ * Editor@onCompositionUpdate(text)
+ * - text (String): The text being written
+ *
+ *
+ **/
this.onCompositionUpdate = function(text) {
this.renderer.setCompositionText(text);
};
+ /** internal, hide
+ * Editor@onCompositionEnd()
+ *
+ *
+ **/
this.onCompositionEnd = function() {
this.renderer.hideComposition();
};
+ /** related to: VirtualRenderer.getFirstVisibleRow
+ * Editor.getFirstVisibleRow() -> Number
+ *
+ * {:VirtualRenderer.getFirstVisibleRow}
+ **/
this.getFirstVisibleRow = function() {
return this.renderer.getFirstVisibleRow();
};
+ /** related to: VirtualRenderer.getLastVisibleRow
+ * Editor.getLastVisibleRow() -> Number
+ *
+ * {:VirtualRenderer.getLastVisibleRow}
+ **/
this.getLastVisibleRow = function() {
return this.renderer.getLastVisibleRow();
};
+ /**
+ * Editor.isRowVisible(row) -> Boolean
+ * - row (Number): The row to check
+ *
+ * Indicates if the row is currently visible on the screen.
+ **/
this.isRowVisible = function(row) {
return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow());
};
+ /**
+ * Editor.isRowFullyVisible(row) -> Boolean
+ * - row (Number): The row to check
+ *
+ * Indicates if the entire row is currently visible on the screen.
+ **/
this.isRowFullyVisible = function(row) {
return (row >= this.renderer.getFirstFullyVisibleRow() && row <= this.renderer.getLastFullyVisibleRow());
};
+ /**
+ * Editor.$getVisibleRowCount() -> Number
+ *
+ * Returns the number of currently visibile rows.
+ **/
this.$getVisibleRowCount = function() {
return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1;
};
- this.$getPageDownRow = function() {
- return this.renderer.getScrollBottomRow();
- };
-
- this.$getPageUpRow = function() {
- var firstRow = this.renderer.getScrollTopRow();
- var lastRow = this.renderer.getScrollBottomRow();
-
- return firstRow - (lastRow - firstRow);
+ this.$moveByPage = function(dir, select) {
+ var renderer = this.renderer;
+ var config = this.renderer.layerConfig;
+ var rows = dir * Math.floor(config.height / config.lineHeight);
+
+ this.$blockScrolling++;
+ if (select == true) {
+ this.selection.$moveSelection(function(){
+ this.moveCursorBy(rows, 0);
+ });
+ } else if (select == false) {
+ this.selection.moveCursorBy(rows, 0);
+ this.selection.clearSelection();
+ }
+ this.$blockScrolling--;
+
+ var scrollTop = renderer.scrollTop;
+
+ renderer.scrollBy(0, rows * config.lineHeight);
+ if (select != null)
+ renderer.scrollCursorIntoView(null, 0.5);
+
+ renderer.animateScrolling(scrollTop);
};
+ /**
+ * Editor.selectPageDown()
+ *
+ * Selects the text from the current position of the document until where a "page down" finishes.
+ **/
this.selectPageDown = function() {
- var row = this.$getPageDownRow() + Math.floor(this.$getVisibleRowCount() / 2);
-
- this.scrollPageDown();
-
- var selection = this.getSelection();
- var leadScreenPos = this.session.documentToScreenPosition(selection.getSelectionLead());
- var dest = this.session.screenToDocumentPosition(row, leadScreenPos.column);
- selection.selectTo(dest.row, dest.column);
+ this.$moveByPage(1, true);
};
+ /**
+ * Editor.selectPageUp()
+ *
+ * Selects the text from the current position of the document until where a "page up" finishes.
+ **/
this.selectPageUp = function() {
- var visibleRows = this.renderer.getScrollTopRow() - this.renderer.getScrollBottomRow();
- var row = this.$getPageUpRow() + Math.round(visibleRows / 2);
-
- this.scrollPageUp();
-
- var selection = this.getSelection();
- var leadScreenPos = this.session.documentToScreenPosition(selection.getSelectionLead());
- var dest = this.session.screenToDocumentPosition(row, leadScreenPos.column);
- selection.selectTo(dest.row, dest.column);
+ this.$moveByPage(-1, true);
};
+ /**
+ * Editor.gotoPageDown()
+ *
+ * Shifts the document to wherever "page down" is, as well as moving the cursor position.
+ **/
this.gotoPageDown = function() {
- var row = this.$getPageDownRow();
- var column = this.getCursorPositionScreen().column;
-
- this.scrollToRow(row);
- this.getSelection().moveCursorToScreen(row, column);
+ this.$moveByPage(1, false);
};
+ /**
+ * Editor.gotoPageUp()
+ *
+ * Shifts the document to wherever "page up" is, as well as moving the cursor position.
+ **/
this.gotoPageUp = function() {
- var row = this.$getPageUpRow();
- var column = this.getCursorPositionScreen().column;
-
- this.scrollToRow(row);
- this.getSelection().moveCursorToScreen(row, column);
+ this.$moveByPage(-1, false);
};
+ /**
+ * Editor.scrollPageDown()
+ *
+ * Scrolls the document to wherever "page down" is, without changing the cursor position.
+ **/
this.scrollPageDown = function() {
- this.scrollToRow(this.$getPageDownRow());
+ this.$moveByPage(1);
};
+ /**
+ * Editor.scrollPageUp()
+ *
+ * Scrolls the document to wherever "page up" is, without changing the cursor position.
+ **/
this.scrollPageUp = function() {
- this.renderer.scrollToRow(this.$getPageUpRow());
+ this.$moveByPage(-1);
};
+ /** related to: VirtualRenderer.scrollToRow
+ * Editor.scrollToRow(row)
+ * - row (Number): The row to move to
+ *
+ * Moves the editor to the specified row.
+ *
+ **/
this.scrollToRow = function(row) {
this.renderer.scrollToRow(row);
};
- this.scrollToLine = function(line, center) {
- this.renderer.scrollToLine(line, center);
+ /** related to: VirtualRenderer.scrollToLine
+ * Editor.scrollToLine(line, center)
+ * - line (Number): The line to scroll to
+ * - center (Boolean): If `true`
+ * - animate (Boolean): If `true` animates scrolling
+ * - callback (Function): Function to be called when the animation has finished
+ *
+ * TODO scrolls a to line, if center == true, puts line in middle of screen or attempts to)
+ **/
+ this.scrollToLine = function(line, center, animate, callback) {
+ this.renderer.scrollToLine(line, center, animate, callback);
};
+ /**
+ * Editor.centerSelection()
+ *
+ * Attempts to center the current selection on the screen.
+ **/
this.centerSelection = function() {
var range = this.getSelectionRange();
var line = Math.floor(range.start.row + (range.end.row - range.start.row) / 2);
this.renderer.scrollToLine(line, true);
};
+ /** related to: Selection.getCursor
+ * Editor.getCursorPosition() -> Object
+ * + (Object): This returns an object that looks something like this:
+ * ```{ row: currRow, column: currCol }```
+ *
+ * Gets the current position of the cursor.
+ *
+ *
+ *
+ **/
this.getCursorPosition = function() {
return this.selection.getCursor();
};
+ /** related to: EditSession.documentToScreenPosition
+ * Editor.getCursorPositionScreen() -> Number
+ *
+ * Returns the screen position of the cursor.
+ **/
this.getCursorPositionScreen = function() {
return this.session.documentToScreenPosition(this.getCursorPosition());
};
+ /** related to: Selection.getRange
+ * Editor.getSelectionRange() -> Range
+ *
+ * {:Selection.getRange}
+ **/
this.getSelectionRange = function() {
return this.selection.getRange();
};
+ /** related to: Selection.selectAll
+ * Editor.selectAll()
+ *
+ * Selects all the text in editor.
+ **/
this.selectAll = function() {
this.$blockScrolling += 1;
this.selection.selectAll();
this.$blockScrolling -= 1;
};
+ /** related to: Selection.clearSelection
+ * Editor.clearSelection()
+ *
+ * {:Selection.clearSelection}
+ **/
this.clearSelection = function() {
this.selection.clearSelection();
};
+ /** related to: Selection.moveCursorTo
+ * Editor.moveCursorTo(row, column)
+ * - row (Number): The new row number
+ * - column (Number): The new column number
+ *
+ * Moves the cursor to the specified row and column. Note that this does not de-select the current selection.
+ *
+ **/
this.moveCursorTo = function(row, column) {
this.selection.moveCursorTo(row, column);
};
+ /** related to: Selection.moveCursorToPosition
+ * Editor.moveCursorToPosition(pos)
+ * - pos (Object): An object with two properties, row and column
+ *
+ * Moves the cursor to the position indicated by `pos.row` and `pos.column`.
+ *
+ **/
this.moveCursorToPosition = function(pos) {
this.selection.moveCursorToPosition(pos);
};
+ /**
+ * Editor.jumpToMatching()
+ *
+ * Moves the cursor's row and column to the next matching bracket.
+ *
+ **/
this.jumpToMatching = function() {
var cursor = this.getCursorPosition();
var pos = this.session.findMatchingBracket(cursor);
@@ -12523,34 +14978,70 @@ var Editor = function(renderer, session) {
}
};
- this.gotoLine = function(lineNumber, column) {
+ /**
+ * Editor.gotoLine(lineNumber, column)
+ * - lineNumber (Number): The line number to go to
+ * - column (Number): A column number to go to
+ * - animate (Boolean): If `true` animates scolling
+ *
+ * Moves the cursor to the specified line number, and also into the indiciated column.
+ *
+ **/
+ this.gotoLine = function(lineNumber, column, animate) {
this.selection.clearSelection();
this.session.unfold({row: lineNumber - 1, column: column || 0});
this.$blockScrolling += 1;
- this.moveCursorTo(lineNumber-1, column || 0);
+ this.moveCursorTo(lineNumber - 1, column || 0);
this.$blockScrolling -= 1;
- if (!this.isRowFullyVisible(this.getCursorPosition().row))
- this.scrollToLine(lineNumber, true);
+
+ if (!this.isRowFullyVisible(lineNumber - 1))
+ this.scrollToLine(lineNumber - 1, true, animate);
};
+ /** related to: Editor.moveCursorTo
+ * Editor.navigateTo(row, column)
+ * - row (Number): The new row number
+ * - column (Number): The new column number
+ *
+ * Moves the cursor to the specified row and column. Note that this does de-select the current selection.
+ *
+ **/
this.navigateTo = function(row, column) {
this.clearSelection();
this.moveCursorTo(row, column);
};
+ /**
+ * Editor.navigateUp(times)
+ * - times (Number): The number of times to change navigation
+ *
+ * Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.
+ **/
this.navigateUp = function(times) {
this.selection.clearSelection();
times = times || 1;
this.selection.moveCursorBy(-times, 0);
};
+ /**
+ * Editor.navigateDown(times)
+ * - times (Number): The number of times to change navigation
+ *
+ * Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.
+ **/
this.navigateDown = function(times) {
this.selection.clearSelection();
times = times || 1;
this.selection.moveCursorBy(times, 0);
};
+ /**
+ * Editor.navigateLeft(times)
+ * - times (Number): The number of times to change navigation
+ *
+ * Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.
+ **/
this.navigateLeft = function(times) {
if (!this.selection.isEmpty()) {
var selectionStart = this.getSelectionRange().start;
@@ -12565,6 +15056,12 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
+ /**
+ * Editor.navigateRight(times)
+ * - times (Number): The number of times to change navigation
+ *
+ * Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.
+ **/
this.navigateRight = function(times) {
if (!this.selection.isEmpty()) {
var selectionEnd = this.getSelectionRange().end;
@@ -12579,36 +15076,77 @@ var Editor = function(renderer, session) {
this.clearSelection();
};
+ /**
+ * Editor.navigateLineStart()
+ *
+ * Moves the cursor to the start of the current line. Note that this does de-select the current selection.
+ **/
this.navigateLineStart = function() {
this.selection.moveCursorLineStart();
this.clearSelection();
};
+ /**
+ * Editor.navigateLineEnd()
+ *
+ * Moves the cursor to the end of the current line. Note that this does de-select the current selection.
+ **/
this.navigateLineEnd = function() {
this.selection.moveCursorLineEnd();
this.clearSelection();
};
+ /**
+ * Editor.navigateFileEnd()
+ *
+ * Moves the cursor to the end of the current file. Note that this does de-select the current selection.
+ **/
this.navigateFileEnd = function() {
+ var scrollTop = this.renderer.scrollTop;
this.selection.moveCursorFileEnd();
this.clearSelection();
+ this.renderer.animateScrolling(scrollTop);
};
+ /**
+ * Editor.navigateFileStart()
+ *
+ * Moves the cursor to the start of the current file. Note that this does de-select the current selection.
+ **/
this.navigateFileStart = function() {
+ var scrollTop = this.renderer.scrollTop;
this.selection.moveCursorFileStart();
this.clearSelection();
+ this.renderer.animateScrolling(scrollTop);
};
+ /**
+ * Editor.navigateWordRight()
+ *
+ * Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.
+ **/
this.navigateWordRight = function() {
this.selection.moveCursorWordRight();
this.clearSelection();
};
+ /**
+ * Editor.navigateWordLeft()
+ *
+ * Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.
+ **/
this.navigateWordLeft = function() {
this.selection.moveCursorWordLeft();
this.clearSelection();
};
+ /**
+ * Editor.replace(replacement, options)
+ * - replacement (String): The text to replace with
+ * - options (Object): The [[Search `Search`]] options to use
+ *
+ * Replaces the first occurance of `options.needle` with the value in `replacement`.
+ **/
this.replace = function(replacement, options) {
if (options)
this.$search.set(options);
@@ -12629,6 +15167,13 @@ var Editor = function(renderer, session) {
return replaced;
};
+ /**
+ * Editor.replaceAll(replacement, options)
+ * - replacement (String): The text to replace with
+ * - options (Object): The [[Search `Search`]] options to use
+ *
+ * Replaces all occurances of `options.needle` with the value in `replacement`.
+ **/
this.replaceAll = function(replacement, options) {
if (options) {
this.$search.set(options);
@@ -12668,35 +15213,58 @@ var Editor = function(renderer, session) {
}
};
+ /** related to: Search.getOptions
+ * Editor.getLastSearchOptions() -> Object
+ *
+ * {:Search.getOptions} For more information on `options`, see [[Search `Search`]].
+ **/
this.getLastSearchOptions = function() {
return this.$search.getOptions();
};
- this.find = function(needle, options) {
+ /** related to: Search.find
+ * Editor.find(needle, options)
+ * - needle (String): The text to search for
+ * - options (Object): An object defining various search properties
+ * - animate (Boolean): If `true` animate scrolling
+ *
+ * Attempts to find `needle` within the document. For more information on `options`, see [[Search `Search`]].
+ **/
+ this.find = function(needle, options, animate) {
this.clearSelection();
options = options || {};
options.needle = needle;
this.$search.set(options);
- this.$find();
+ this.$find(false, animate);
};
- this.findNext = function(options) {
+ /** related to: Editor.find
+ * Editor.findNext(options)
+ * - options (Object): search options
+ * - animate (Boolean): If `true` animate scrolling
+ *
+ * Performs another search for `needle` in the document. For more information on `options`, see [[Search `Search`]].
+ **/
+ this.findNext = function(options, animate) {
options = options || {};
- if (typeof options.backwards == "undefined")
- options.backwards = false;
this.$search.set(options);
- this.$find();
+ this.$find(false, animate);
};
- this.findPrevious = function(options) {
+ /** related to: Editor.find
+ * Editor.findPrevious(options)
+ * - options (Object): search options
+ * - animate (Boolean): If `true` animate scrolling
+ *
+ * Performs a search for `needle` backwards. For more information on `options`, see [[Search `Search`]].
+ **/
+ this.findPrevious = function(options, animate) {
options = options || {};
- if (typeof options.backwards == "undefined")
- options.backwards = true;
this.$search.set(options);
- this.$find();
+ this.$find(true, animate);
};
- this.$find = function(backwards) {
+ this.$find = function(backwards, animate) {
if (!this.selection.isEmpty())
this.$search.set({needle: this.session.getTextRange(this.getSelectionRange())});
@@ -12705,35 +15273,46 @@ var Editor = function(renderer, session) {
var range = this.$search.find(this.session);
if (range) {
- this.session.unfold(range);
-
this.$blockScrolling += 1;
+ this.session.unfold(range);
this.selection.setSelectionRange(range);
this.$blockScrolling -= 1;
- if (this.getAnimatedScroll()) {
- var cursor = this.getCursorPosition();
- if (!this.isRowFullyVisible(cursor.row))
- this.scrollToLine(cursor.row, true);
-
- //@todo scroll X
- //if (!this.isColumnFullyVisible(cursor.column))
- //this.scrollToRow(cursor.column);
- }
- else {
- this.renderer.scrollSelectionIntoView(range.start, range.end);
- }
+ var scrollTop = this.renderer.scrollTop;
+ this.renderer.scrollSelectionIntoView(range.start, range.end, 0.5);
+ this.renderer.animateScrolling(scrollTop);
}
};
+ /** related to: UndoManager.undo
+ * Editor.undo()
+ *
+ * {:UndoManager.undo}
+ **/
this.undo = function() {
+ this.$blockScrolling++;
this.session.getUndoManager().undo();
+ this.$blockScrolling--;
+ this.renderer.scrollCursorIntoView(null, 0.5);
};
+ /** related to: UndoManager.redo
+ * Editor.redo()
+ *
+ * {:UndoManager.redo}
+ **/
this.redo = function() {
+ this.$blockScrolling++;
this.session.getUndoManager().redo();
+ this.$blockScrolling--;
+ this.renderer.scrollCursorIntoView(null, 0.5);
};
+ /**
+ * Editor.destroy()
+ *
+ * Cleans up the entire editor.
+ **/
this.destroy = function() {
this.renderer.destroy();
};
@@ -12794,7 +15373,9 @@ var TextInput = function(parentNode, host) {
var text = dom.createElement("textarea");
if (useragent.isTouchPad)
text.setAttribute("x-palm-disable-auto-cap", true);
-
+
+ text.setAttribute("wrap", "off");
+
text.style.left = "-10000px";
text.style.position = "fixed";
parentNode.insertBefore(text, parentNode.firstChild);
@@ -12817,13 +15398,18 @@ var TextInput = function(parentNode, host) {
if (!copied) {
var value = valueToSend || text.value;
if (value) {
- if (value.charCodeAt(value.length-1) == PLACEHOLDER.charCodeAt(0)) {
- value = value.slice(0, -1);
- if (value)
- host.onTextInput(value, pasted);
+ if (value.length > 1) {
+ if (value.charAt(0) == PLACEHOLDER)
+ value = value.substr(1);
+ else if (value.charAt(value.length - 1) == PLACEHOLDER)
+ value = value.slice(0, -1);
}
- else {
- host.onTextInput(value, pasted);
+
+ if (value && value != PLACEHOLDER) {
+ if (pasted)
+ host.onPaste(value);
+ else
+ host.onTextInput(value);
}
// If editor is no longer focused we quit immediately, since
@@ -12844,7 +15430,7 @@ var TextInput = function(parentNode, host) {
var onTextInput = function(e) {
setTimeout(function () {
if (!inCompostion)
- sendText(e.data);
+ sendText(e.data);
}, 0);
};
@@ -12900,6 +15486,7 @@ var TextInput = function(parentNode, host) {
};
event.addCommandKeyListener(text, host.onCommandKey.bind(host));
+
if (useragent.isOldIE) {
var keytable = { 13:1, 27:1 };
event.addListener(text, "keyup", function (e) {
@@ -13070,10 +15657,10 @@ var MouseEvent = require("./mouse_event").MouseEvent;
var MouseHandler = function(editor) {
this.editor = editor;
-
- new DefaultHandlers(editor);
- new DefaultGutterHandler(editor);
-
+
+ new DefaultHandlers(this);
+ new DefaultGutterHandler(this);
+
event.addListener(editor.container, "mousedown", function(e) {
editor.focus();
return event.preventDefault(e);
@@ -13090,7 +15677,7 @@ var MouseHandler = function(editor) {
event.addMultiMouseDownListener(mouseTarget, 0, 3, 600, this.onMouseEvent.bind(this, "tripleclick"));
event.addMultiMouseDownListener(mouseTarget, 0, 4, 600, this.onMouseEvent.bind(this, "quadclick"));
event.addMouseWheelListener(editor.container, this.onMouseWheel.bind(this, "mousewheel"));
-
+
var gutterEl = editor.renderer.$gutter;
event.addListener(gutterEl, "mousedown", this.onMouseEvent.bind(this, "guttermousedown"));
event.addListener(gutterEl, "click", this.onMouseEvent.bind(this, "gutterclick"));
@@ -13112,7 +15699,7 @@ var MouseHandler = function(editor) {
this.onMouseEvent = function(name, e) {
this.editor._emit(name, new MouseEvent(e, this.editor));
};
-
+
this.$dragDelay = 250;
this.setDragDelay = function(dragDelay) {
this.$dragDelay = dragDelay;
@@ -13136,10 +15723,48 @@ var MouseHandler = function(editor) {
mouseEvent.speed = this.$scrollSpeed * 2;
mouseEvent.wheelX = e.wheelX;
mouseEvent.wheelY = e.wheelY;
-
+
this.editor._emit(name, mouseEvent);
};
+ this.setState = function(state) {
+ this.state = state;
+ };
+
+ this.captureMouse = function(ev, state) {
+ if (state)
+ this.setState(state);
+
+ this.x = ev.x;
+ this.y = ev.y;
+
+ // do not move textarea during selection
+ var kt = this.editor.renderer.$keepTextAreaAtCursor;
+ this.editor.renderer.$keepTextAreaAtCursor = false;
+
+ var self = this;
+ var onMouseSelection = function(e) {
+ self.x = e.clientX;
+ self.y = e.clientY;
+ };
+
+ var onMouseSelectionEnd = function(e) {
+ clearInterval(timerId);
+ self[self.state + "End"] && self[self.state + "End"](e);
+ self.$clickSelection = null;
+ self.editor.renderer.$keepTextAreaAtCursor = kt;
+ self.editor.renderer.$moveTextAreaToCursor();
+ };
+
+ var onSelectionInterval = function() {
+ self[self.state] && self[self.state]();
+ }
+
+ event.capture(this.editor.container, onMouseSelection, onMouseSelectionEnd);
+ var timerId = setInterval(onSelectionInterval, 20);
+
+ ev.preventDefault();
+ };
}).call(MouseHandler.prototype);
exports.MouseHandler = MouseHandler;
@@ -13168,6 +15793,7 @@ exports.MouseHandler = MouseHandler;
* Contributor(s):
* Fabian Jakobs
* Mike de Boer
+ * Harutyun Amirjanyan
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -13183,240 +15809,290 @@ exports.MouseHandler = MouseHandler;
*
* ***** END LICENSE BLOCK ***** */
-define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/dom', 'ace/lib/browser_focus'], function(require, exports, module) {
+define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/browser_focus'], function(require, exports, module) {
"use strict";
-var event = require("../lib/event");
var dom = require("../lib/dom");
var BrowserFocus = require("../lib/browser_focus").BrowserFocus;
-var STATE_UNKNOWN = 0;
-var STATE_SELECT = 1;
-var STATE_DRAG = 2;
var DRAG_OFFSET = 5; // pixels
-function DefaultHandlers(editor) {
- this.editor = editor;
- this.$clickSelection = null;
- this.browserFocus = new BrowserFocus();
- editor.setDefaultHandler("mousedown", this.onMouseDown.bind(this));
- editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(this));
- editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(this));
- editor.setDefaultHandler("quadclick", this.onQuadClick.bind(this));
- editor.setDefaultHandler("mousewheel", this.onScroll.bind(this));
+
+function DefaultHandlers(mouseHandler) {
+ mouseHandler.$clickSelection = null;
+ mouseHandler.browserFocus = new BrowserFocus();
+
+ var editor = mouseHandler.editor;
+ editor.setDefaultHandler("mousedown", this.onMouseDown.bind(mouseHandler));
+ editor.setDefaultHandler("dblclick", this.onDoubleClick.bind(mouseHandler));
+ editor.setDefaultHandler("tripleclick", this.onTripleClick.bind(mouseHandler));
+ editor.setDefaultHandler("quadclick", this.onQuadClick.bind(mouseHandler));
+ editor.setDefaultHandler("mousewheel", this.onScroll.bind(mouseHandler));
+
+ var exports = ["select", "startSelect", "drag", "dragEnd", "dragWait",
+ "dragWaitEnd", "startDrag"];
+
+ exports.forEach(function(x) {
+ mouseHandler[x] = this[x];
+ }, this);
+
+ mouseHandler.selectByLines = this.extendSelectionBy.bind(mouseHandler, "getLineRange");
+ mouseHandler.selectByWords = this.extendSelectionBy.bind(mouseHandler, "getWordRange");
}
(function() {
-
+
this.onMouseDown = function(ev) {
+ this.mousedownEvent = ev;
var inSelection = ev.inSelection();
- var pageX = ev.pageX;
- var pageY = ev.pageY;
var pos = ev.getDocumentPosition();
var editor = this.editor;
var _self = this;
-
+
+ this.ev = ev
var selectionRange = editor.getSelectionRange();
var selectionEmpty = selectionRange.isEmpty();
- var state = STATE_UNKNOWN;
-
- // if this click caused the editor to be focused should not clear the
- // selection
- if (
- inSelection && (
- !this.browserFocus.isFocused()
- || new Date().getTime() - this.browserFocus.lastFocus < 20
- || !editor.isFocused()
- )
- ) {
- editor.focus();
- return;
- }
var button = ev.getButton();
if (button !== 0) {
if (selectionEmpty) {
editor.moveCursorToPosition(pos);
+ editor.selection.clearSelection();
}
- if (button == 2) {
- editor.textInput.onContextMenu({x: ev.clientX, y: ev.clientY}, selectionEmpty);
- event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose);
- }
+ // 2: contextmenu, 1: linux paste
+ this.moveTextarea = function() {
+ editor.textInput.onContextMenu({x: _self.x, y: _self.y});
+ };
+ this.moveTextareaEnd = editor.textInput.onContextMenuClose;
+
+ editor.textInput.onContextMenu({x: this.x, y: this.y}, selectionEmpty);
+ this.captureMouse(ev, "moveTextarea");
+
return;
}
- if (!inSelection) {
+ // if this click caused the editor to be focused should not clear the
+ // selection
+ if (inSelection && !editor.isFocused()) {
+ editor.focus();
+ return;
+ }
+
+ if (!inSelection || this.$clickSelection || ev.getShiftKey()) {
// Directly pick STATE_SELECT, since the user is not clicking inside
// a selection.
- onStartSelect(pos);
- }
-
- var mousePageX = pageX, mousePageY = pageY;
- var mousedownTime = (new Date()).getTime();
- var dragCursor, dragRange, dragSelectionMarker;
-
- var onMouseSelection = function(e) {
- mousePageX = event.getDocumentX(e);
- mousePageY = event.getDocumentY(e);
- };
-
- var onMouseSelectionEnd = function(e) {
- clearInterval(timerId);
- if (state == STATE_UNKNOWN)
- onStartSelect(pos);
- else if (state == STATE_DRAG)
- onMouseDragSelectionEnd(e);
-
- _self.$clickSelection = null;
- state = STATE_UNKNOWN;
- };
-
- var onMouseDragSelectionEnd = function(e) {
- dom.removeCssClass(editor.container, "ace_dragging");
- editor.session.removeMarker(dragSelectionMarker);
-
- if (!editor.$mouseHandler.$clickSelection) {
- if (!dragCursor) {
- editor.moveCursorToPosition(pos);
- editor.selection.clearSelection();
- }
- }
-
- if (!dragCursor)
- return;
-
- if (dragRange.contains(dragCursor.row, dragCursor.column)) {
- dragCursor = null;
- return;
- }
-
- editor.clearSelection();
- if (e && (e.ctrlKey || e.altKey)) {
- var session = editor.session;
- var newRange = session.insert(dragCursor, session.getTextRange(dragRange));
+ this.startSelect(pos);
+ } else if (inSelection) {
+ var e = ev.domEvent;
+ if ((e.ctrlKey || e.altKey)) {
+ this.startDrag();
} else {
- var newRange = editor.moveText(dragRange, dragCursor);
+ this.mousedownEvent.time = (new Date()).getTime();
+ this.setState("dragWait");
}
- if (!newRange) {
- dragCursor = null;
- return;
- }
-
- editor.selection.setSelectionRange(newRange);
- };
-
- var onSelectionInterval = function() {
- if (state == STATE_UNKNOWN) {
- var distance = calcDistance(pageX, pageY, mousePageX, mousePageY);
- var time = (new Date()).getTime();
-
- if (distance > DRAG_OFFSET) {
- state = STATE_SELECT;
- var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
- onStartSelect(cursor);
- }
- else if ((time - mousedownTime) > editor.getDragDelay()) {
- state = STATE_DRAG;
- dragRange = editor.getSelectionRange();
- var style = editor.getSelectionStyle();
- dragSelectionMarker = editor.session.addMarker(dragRange, "ace_selection", style);
- editor.clearSelection();
- dom.addCssClass(editor.container, "ace_dragging");
- }
-
- }
-
- if (state == STATE_DRAG)
- onDragSelectionInterval();
- else if (state == STATE_SELECT)
- onUpdateSelectionInterval();
- };
-
- function onStartSelect(pos) {
- if (ev.getShiftKey()) {
- editor.selection.selectToPosition(pos);
- }
- else {
- if (!_self.$clickSelection) {
- editor.moveCursorToPosition(pos);
- editor.selection.clearSelection();
- }
- }
- state = STATE_SELECT;
}
- var onUpdateSelectionInterval = function() {
- var anchor;
- var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
-
- if (_self.$clickSelection) {
- if (_self.$clickSelection.contains(cursor.row, cursor.column)) {
- editor.selection.setSelectionRange(_self.$clickSelection);
- }
- else {
- if (_self.$clickSelection.compare(cursor.row, cursor.column) == -1) {
- anchor = _self.$clickSelection.end;
- }
- else {
- anchor = _self.$clickSelection.start;
- }
- editor.selection.setSelectionAnchor(anchor.row, anchor.column);
- editor.selection.selectToPosition(cursor);
- }
- }
- else {
- editor.selection.selectToPosition(cursor);
- }
-
- editor.renderer.scrollCursorIntoView();
- };
-
- var onDragSelectionInterval = function() {
- dragCursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
- editor.moveCursorToPosition(dragCursor);
- };
-
- event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
- var timerId = setInterval(onSelectionInterval, 20);
-
- return ev.preventDefault();
+ this.captureMouse(ev)
};
-
+
+ this.startSelect = function(pos) {
+ pos = pos || this.editor.renderer.screenToTextCoordinates(this.x, this.y);
+ if (this.mousedownEvent.getShiftKey()) {
+ this.editor.selection.selectToPosition(pos);
+ }
+ else if (!this.$clickSelection) {
+ this.editor.moveCursorToPosition(pos);
+ this.editor.selection.clearSelection();
+ }
+ this.setState("select");
+ }
+
+ this.select = function() {
+ var anchor, editor = this.editor;
+ var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
+
+ if (this.$clickSelection) {
+ var cmp = this.$clickSelection.comparePoint(cursor);
+
+ if (cmp == -1) {
+ anchor = this.$clickSelection.end;
+ } else if (cmp == 1) {
+ anchor = this.$clickSelection.start;
+ } else {
+ cursor = this.$clickSelection.end;
+ anchor = this.$clickSelection.start;
+ }
+ editor.selection.setSelectionAnchor(anchor.row, anchor.column);
+ }
+ editor.selection.selectToPosition(cursor);
+
+ editor.renderer.scrollCursorIntoView();
+ };
+
+ this.extendSelectionBy = function(unitName) {
+ var anchor, editor = this.editor;
+ var cursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
+ var range = editor.selection[unitName](cursor.row, cursor.column);
+
+ if (this.$clickSelection) {
+ var cmpStart = this.$clickSelection.comparePoint(range.start);
+ var cmpEnd = this.$clickSelection.comparePoint(range.end);
+
+ if (cmpStart == -1 && cmpEnd <= 0) {
+ anchor = this.$clickSelection.end;
+ cursor = range.start;
+ } else if (cmpEnd == 1 && cmpStart >= 0) {
+ anchor = this.$clickSelection.start;
+ cursor = range.end;
+ } else if (cmpStart == -1 && cmpEnd == 1) {
+ cursor = range.end;
+ anchor = range.start;
+ } else {
+ cursor = this.$clickSelection.end;
+ anchor = this.$clickSelection.start;
+ }
+ editor.selection.setSelectionAnchor(anchor.row, anchor.column);
+ }
+ editor.selection.selectToPosition(cursor);
+
+ editor.renderer.scrollCursorIntoView();
+ };
+
+ this.startDrag = function() {
+ var editor = this.editor;
+ this.setState("drag");
+ this.dragRange = editor.getSelectionRange();
+ var style = editor.getSelectionStyle();
+ this.dragSelectionMarker = editor.session.addMarker(this.dragRange, "ace_selection", style);
+ editor.clearSelection();
+ dom.addCssClass(editor.container, "ace_dragging");
+ if (!this.$dragKeybinding) {
+ this.$dragKeybinding = {
+ handleKeyboard: function(data, hashId, keyString, keyCode) {
+ if (keyString == "esc")
+ return {command: this.command};
+ },
+ command: {
+ exec: function(editor) {
+ var self = editor.$mouseHandler;
+ self.dragCursor = null
+ self.dragEnd();
+ self.startSelect();
+ }
+ }
+ }
+ }
+
+ editor.keyBinding.addKeyboardHandler(this.$dragKeybinding);
+ };
+
+ this.dragWait = function() {
+ var distance = calcDistance(this.mousedownEvent.x, this.mousedownEvent.y, this.x, this.y);
+ var time = (new Date()).getTime();
+ var editor = this.editor;
+
+ if (distance > DRAG_OFFSET) {
+ this.startSelect();
+ } else if ((time - this.mousedownEvent.time) > editor.getDragDelay()) {
+ this.startDrag()
+ }
+ };
+
+ this.dragWaitEnd = function(e) {
+ this.mousedownEvent.domEvent = e;
+ this.startSelect();
+ };
+
+ this.drag = function() {
+ var editor = this.editor;
+ this.dragCursor = editor.renderer.screenToTextCoordinates(this.x, this.y);
+ editor.moveCursorToPosition(this.dragCursor);
+ editor.renderer.scrollCursorIntoView();
+ };
+
+ this.dragEnd = function(e) {
+ var editor = this.editor;
+ var dragCursor = this.dragCursor;
+ var dragRange = this.dragRange;
+ dom.removeCssClass(editor.container, "ace_dragging");
+ editor.session.removeMarker(this.dragSelectionMarker);
+ editor.keyBinding.removeKeyboardHandler(this.$dragKeybinding);
+
+ if (!dragCursor)
+ return;
+
+ editor.clearSelection();
+ if (e && (e.ctrlKey || e.altKey)) {
+ var session = editor.session;
+ var newRange = dragRange;
+ newRange.end = session.insert(dragCursor, session.getTextRange(dragRange));
+ newRange.start = dragCursor;
+ } else if (dragRange.contains(dragCursor.row, dragCursor.column)) {
+ return;
+ } else {
+ var newRange = editor.moveText(dragRange, dragCursor);
+ }
+
+ if (!newRange)
+ return;
+
+ editor.selection.setSelectionRange(newRange);
+ };
+
this.onDoubleClick = function(ev) {
var pos = ev.getDocumentPosition();
var editor = this.editor;
-
+
+ this.setState("selectByWords");
+
editor.moveCursorToPosition(pos);
editor.selection.selectWord();
this.$clickSelection = editor.getSelectionRange();
};
-
+
this.onTripleClick = function(ev) {
var pos = ev.getDocumentPosition();
var editor = this.editor;
-
+
+ this.setState("selectByLines");
+
editor.moveCursorToPosition(pos);
editor.selection.selectLine();
this.$clickSelection = editor.getSelectionRange();
};
-
+
this.onQuadClick = function(ev) {
var editor = this.editor;
-
+
editor.selectAll();
this.$clickSelection = editor.getSelectionRange();
+ this.setState("select");
};
-
+
this.onScroll = function(ev) {
var editor = this.editor;
-
+ var isScrolable = editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
+ if (isScrolable) {
+ this.$passScrollEvent = false;
+ } else {
+ if (this.$passScrollEvent)
+ return;
+
+ if (!this.$scrollStopTimeout) {
+ var self = this;
+ this.$scrollStopTimeout = setTimeout(function() {
+ self.$passScrollEvent = true;
+ self.$scrollStopTimeout = null;
+ }, 200);
+ }
+ }
+
editor.renderer.scrollBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed);
- if (editor.renderer.isScrollableBy(ev.wheelX * ev.speed, ev.wheelY * ev.speed))
- return ev.preventDefault();
+ return ev.preventDefault();
};
-
+
}).call(DefaultHandlers.prototype);
exports.DefaultHandlers = DefaultHandlers;
@@ -13473,7 +16149,7 @@ var oop = require("./oop");
var event = require("./event");
var EventEmitter = require("./event_emitter").EventEmitter;
-/**
+/*
* This class keeps track of the focus state of the given window.
* Focus changes for example when the user switches a browser tab,
* goes to the location bar or switches to another application.
@@ -13572,19 +16248,31 @@ exports.BrowserFocus = BrowserFocus;
define('ace/mouse/default_gutter_handler', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
-function GutterHandler(editor) {
- editor.setDefaultHandler("gutterclick", function(e) {
+function GutterHandler(mouseHandler) {
+ var editor = mouseHandler.editor;
+
+ mouseHandler.editor.setDefaultHandler("guttermousedown", function(e) {
+ if (e.domEvent.target.className.indexOf("ace_gutter-cell") == -1)
+ return;
+
+ if (!editor.isFocused())
+ return;
+
var row = e.getDocumentPosition().row;
var selection = editor.session.selection;
-
+
selection.moveCursorTo(row, 0);
selection.selectLine();
+
+ mouseHandler.$clickSelection = selection.getRange();
+ mouseHandler.captureMouse(e, "selectByLines");
});
}
exports.GutterHandler = GutterHandler;
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -13627,18 +16315,15 @@ define('ace/mouse/mouse_event', ['require', 'exports', 'module' , 'ace/lib/event
var event = require("../lib/event");
-/**
+/*
* Custom Ace mouse event
*/
var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
this.domEvent = domEvent;
this.editor = editor;
- this.pageX = event.getDocumentX(domEvent);
- this.pageY = event.getDocumentY(domEvent);
-
- this.clientX = domEvent.clientX;
- this.clientY = domEvent.clientY;
+ this.x = this.clientX = domEvent.clientX;
+ this.y = this.clientY = domEvent.clientY;
this.$pos = null;
this.$inSelection = null;
@@ -13664,7 +16349,7 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
this.preventDefault();
};
- /**
+ /*
* Get the document position below the mouse cursor
*
* @return {Object} 'row' and 'column' of the document position
@@ -13672,14 +16357,12 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
this.getDocumentPosition = function() {
if (this.$pos)
return this.$pos;
-
- var pageX = event.getDocumentX(this.domEvent);
- var pageY = event.getDocumentY(this.domEvent);
- this.$pos = this.editor.renderer.screenToTextCoordinates(pageX, pageY);
+
+ this.$pos = this.editor.renderer.screenToTextCoordinates(this.clientX, this.clientY);
return this.$pos;
};
- /**
+ /*
* Check if the mouse cursor is inside of the text selection
*
* @return {Boolean} whether the mouse cursor is inside of the selection
@@ -13705,7 +16388,7 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
return this.$inSelection;
};
- /**
+ /*
* Get the clicked mouse button
*
* @return {Number} 0 for left button, 1 for middle button, 2 for right button
@@ -13714,7 +16397,7 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
return event.getButton(this.domEvent);
};
- /**
+ /*
* @return {Boolean} whether the shift key was pressed when the event was emitted
*/
this.getShiftKey = function() {
@@ -13798,7 +16481,8 @@ function FoldHandler(editor) {
exports.FoldHandler = FoldHandler;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -13847,15 +16531,27 @@ require("../commands/default_commands");
var KeyBinding = function(editor) {
this.$editor = editor;
this.$data = { };
- this.$handlers = [this];
+ this.$handlers = [];
+ this.setDefaultHandler(editor.commands);
};
(function() {
+ this.setDefaultHandler = function(keyboardHandler) {
+ this.removeKeyboardHandler(this.$defaultHandler);
+ this.$defaultHandler = keyboardHandler;
+ if (keyboardHandler)
+ this.$handlers.unshift(keyboardHandler);
+ this.$data = { };
+ };
+
this.setKeyboardHandler = function(keyboardHandler) {
if (this.$handlers[this.$handlers.length - 1] == keyboardHandler)
return;
this.$data = { };
- this.$handlers = keyboardHandler ? [this, keyboardHandler] : [this];
+ this.$handlers = [];
+ this.setDefaultHandler(this.$defaultHandler);
+ if (keyboardHandler)
+ this.$handlers.push(keyboardHandler);
};
this.addKeyboardHandler = function(keyboardHandler) {
@@ -13893,7 +16589,7 @@ var KeyBinding = function(editor) {
// allow keyboardHandler to consume keys
if (toExecute.command != "null")
- success = commands.exec(toExecute.command, this.$editor, toExecute.args);
+ success = commands.exec(toExecute.command, this.$editor, toExecute.args, e);
else
success = true;
@@ -13903,20 +16599,14 @@ var KeyBinding = function(editor) {
return success;
};
- this.handleKeyboard = function(data, hashId, keyString) {
- return {
- command: this.$editor.commands.findKeyCommand(hashId, keyString)
- };
- };
-
this.onCommandKey = function(e, hashId, keyCode) {
var keyString = keyUtil.keyCodeToString(keyCode);
this.$callKeyboardHandlers(hashId, keyString, keyCode, e);
};
- this.onTextInput = function(text, pasted) {
+ this.onTextInput = function(text) {
var success = false;
- if (!pasted && text.length == 1)
+ if (text.length == 1)
success = this.$callKeyboardHandlers(0, text);
if (!success)
this.$editor.commands.exec("insertstring", this.$editor, text);
@@ -14239,7 +16929,7 @@ exports.commands = [{
multiSelectAction: "forEach"
}, {
name: "togglecomment",
- bindKey: bindKey("Ctrl-7", "Command-7"),
+ bindKey: bindKey("Ctrl-/", "Command-/"),
exec: function(editor) { editor.toggleCommentLines(); },
multiSelectAction: "forEach"
}, {
@@ -14412,6 +17102,28 @@ var lang = require("./lib/lang");
var oop = require("./lib/oop");
var Range = require("./range").Range;
+/**
+ * class Search
+ *
+ * A class designed to handle all sorts of text searches within a [[Document `Document`]].
+ *
+ **/
+
+/**
+ * new Search()
+ *
+ * Creates a new `Search` object. The search options contain the following defaults:
+ *
+ * * `needle`: `""`
+ * * `backwards`: `false`
+ * * `wrap`: `false`
+ * * `caseSensitive`: `false`
+ * * `wholeWord`: `false`
+ * * `scope`: `ALL`
+ * * `regExp`: `false`
+ *
+**/
+
var Search = function() {
this.$options = {
needle: "",
@@ -14429,15 +17141,35 @@ Search.SELECTION = 2;
(function() {
+ /**
+ * Search.set(options) -> Search
+ * - options (Object): An object containing all the new search properties
+ *
+ * Sets the search options via the `options` parameter.
+ *
+ **/
this.set = function(options) {
oop.mixin(this.$options, options);
return this;
};
-
+
+ /**
+ * Search.getOptions() -> Object
+ *
+ * [Returns an object containing all the search options.]{: #Search.getOptions}
+ *
+ **/
this.getOptions = function() {
return lang.copyObject(this.$options);
};
+ /**
+ * Search.find(session) -> Range
+ * - session (EditSession): The session to search with
+ *
+ * Searches for `options.needle`. If found, this method returns the [[Range `Range`]] where the text first occurs. If `options.backwards` is `true`, the search goes backwards in the session.
+ *
+ **/
this.find = function(session) {
if (!this.$options.needle)
return null;
@@ -14457,6 +17189,13 @@ Search.SELECTION = 2;
return firstRange;
};
+ /**
+ * Search.findAll(session) -> [Range]
+ * - session (EditSession): The session to search with
+ *
+ * Searches for all occurances `options.needle`. If found, this method returns an array of [[Range `Range`s]] where the text first occurs. If `options.backwards` is `true`, the search goes backwards in the session.
+ *
+ **/
this.findAll = function(session) {
var options = this.$options;
if (!options.needle)
@@ -14483,6 +17222,18 @@ Search.SELECTION = 2;
return ranges;
};
+ /**
+ * Search.replace(input, replacement) -> String
+ * - input (String): The text to search in
+ * - replacement (String): The replacing text
+ * + (String): If `options.regExp` is `true`, this function returns `input` with the replacement already made. Otherwise, this function just returns `replacement`.
+ * If `options.needle` was not found, this function returns `null`.
+ *
+ * Searches for `options.needle` in `input`, and, if found, replaces it with `replacement`.
+ *
+ *
+ *
+ **/
this.replace = function(input, replacement) {
var re = this.$assembleRegExp();
var match = re.exec(input);
@@ -14497,6 +17248,13 @@ Search.SELECTION = 2;
}
};
+ /** internal, hide
+ * Search.$forwardMatchIterator(session) -> String | Boolean
+ * - session (EditSession): The session to search with
+ *
+ *
+ *
+ **/
this.$forwardMatchIterator = function(session) {
var re = this.$assembleRegExp();
var self = this;
@@ -14531,6 +17289,13 @@ Search.SELECTION = 2;
};
};
+ /** internal, hide
+ * Search.$backwardMatchIterator(session) -> String
+ * - session (EditSession): The session to search with
+ *
+ *
+ *
+ **/
this.$backwardMatchIterator = function(session) {
var re = this.$assembleRegExp();
var self = this;
@@ -14716,6 +17481,24 @@ var oop = require("../lib/oop");
var HashHandler = require("../keyboard/hash_handler").HashHandler;
var EventEmitter = require("../lib/event_emitter").EventEmitter;
+/**
+ * class CommandManager
+ *
+ *
+ *
+ *
+ **/
+
+/**
+ * new CommandManager(platform, commands)
+ * - platform (String): Identifier for the platform; must be either `'mac'` or `'win'`
+ * - commands (Array): A list of commands
+ *
+ * TODO
+ *
+ *
+ **/
+
var CommandManager = function(platform, commands) {
this.platform = platform;
this.commands = {};
@@ -14724,7 +17507,7 @@ var CommandManager = function(platform, commands) {
this.addCommands(commands);
this.setDefaultHandler("exec", function(e) {
- e.command.exec(e.editor, e.args || {});
+ return e.command.exec(e.editor, e.args || {});
});
};
@@ -14744,8 +17527,18 @@ oop.inherits(CommandManager, HashHandler);
if (editor && editor.$readOnly && !command.readOnly)
return false;
- this._emit("exec", {editor: editor, command: command, args: args});
- return true;
+ try {
+ var retvalue = this._emit("exec", {
+ editor: editor,
+ command: command,
+ args: args
+ });
+ } catch (e) {
+ window.console && window.console.log(e);
+ return true;
+ }
+
+ return retvalue === false ? false : true;
};
this.toggleRecording = function() {
@@ -14867,6 +17660,22 @@ var editorCss = require("text!./css/editor.css");
dom.importCssString(editorCss, "ace_editor");
+/**
+ * class VirtualRenderer
+ *
+ * The class that is responsible for drawing everything you see on the screen!
+ *
+ **/
+
+/**
+ * new VirtualRenderer(container, theme)
+ * - container (DOMElement): The root element of the editor
+ * - theme (String): The starting theme
+ *
+ * Constructs a new `VirtualRenderer` within the `container` specified, applying the given `theme`.
+ *
+ **/
+
var VirtualRenderer = function(container, theme) {
var _self = this;
@@ -14875,6 +17684,9 @@ var VirtualRenderer = function(container, theme) {
// TODO: this breaks rendering in Cloud9 with multiple ace instances
// // Imports CSS once per DOM document ('ace_editor' serves as an identifier).
// dom.importCssString(editorCss, "ace_editor", container.ownerDocument);
+
+ // in IE <= 9 the native cursor always shines through
+ this.$keepTextAreaAtCursor = !useragent.isIE;
dom.addCssClass(container, "ace_editor");
@@ -14892,8 +17704,10 @@ var VirtualRenderer = function(container, theme) {
this.content.className = "ace_content";
this.scroller.appendChild(this.content);
+ this.setHighlightGutterLine(true);
this.$gutterLayer = new GutterLayer(this.$gutter);
this.$gutterLayer.on("changeGutterWidth", this.onResize.bind(this, true));
+ this.setFadeFoldWidgets(true);
this.$markerBack = new MarkerLayer(this.content);
@@ -14909,14 +17723,15 @@ var VirtualRenderer = function(container, theme) {
this.$cursorPadding = 8;
// Indicates whether the horizontal scrollbar is visible
- this.$horizScroll = true;
- this.$horizScrollAlwaysVisible = true;
+ this.$horizScroll = false;
+ this.$horizScrollAlwaysVisible = false;
this.$animatedScroll = false;
this.scrollBar = new ScrollBar(container);
this.scrollBar.addEventListener("scroll", function(e) {
- _self.session.setScrollTop(e.data);
+ if (!_self.$inScrollAnimation)
+ _self.session.setScrollTop(e.data);
});
this.scrollTop = 0;
@@ -14927,12 +17742,9 @@ var VirtualRenderer = function(container, theme) {
_self.scrollLeft = scrollLeft;
_self.session.setScrollLeft(scrollLeft);
- if (scrollLeft == 0) {
- _self.$gutter.className = "ace_gutter";
- }
- else {
- _self.$gutter.className = "ace_gutter horscroll";
- }
+ _self.scroller.className = scrollLeft == 0
+ ? "ace_scroller"
+ : "ace_scroller horscroll";
});
this.cursorPos = {
@@ -14997,19 +17809,32 @@ var VirtualRenderer = function(container, theme) {
oop.implement(this, EventEmitter);
+ /**
+ * VirtualRenderer.setSession(session) -> Void
+ *
+ * Associates an [[EditSession `EditSession`]].
+ **/
this.setSession = function(session) {
this.session = session;
+
+ this.scroller.className = "ace_scroller";
+
this.$cursorLayer.setSession(session);
this.$markerBack.setSession(session);
this.$markerFront.setSession(session);
this.$gutterLayer.setSession(session);
this.$textLayer.setSession(session);
this.$loop.schedule(this.CHANGE_FULL);
+
};
/**
- * Triggers partial update of the text layer
- */
+ * VirtualRenderer.updateLines(firstRow, lastRow) -> Void
+ * - firstRow (Number): The first row to update
+ * - lastRow (Number): The last row to update
+ *
+ * Triggers a partial update of the text, from the range given by the two parameters.
+ **/
this.updateLines = function(firstRow, lastRow) {
if (lastRow === undefined)
lastRow = Infinity;
@@ -15032,26 +17857,38 @@ var VirtualRenderer = function(container, theme) {
};
/**
- * Triggers full update of the text layer
- */
+ * VirtualRenderer.updateText() -> Void
+ *
+ * Triggers a full update of the text, for all the rows.
+ **/
this.updateText = function() {
this.$loop.schedule(this.CHANGE_TEXT);
};
/**
- * Triggers a full update of all layers
- */
+ * VirtualRenderer.updateFull() -> Void
+ *
+ * Triggers a full update of all the layers, for all the rows.
+ **/
this.updateFull = function() {
this.$loop.schedule(this.CHANGE_FULL);
};
+ /**
+ * VirtualRenderer.updateFontSize() -> Void
+ *
+ * Updates the font size.
+ **/
this.updateFontSize = function() {
this.$textLayer.checkForSizeChanges();
};
/**
- * Triggers resize of the editor
- */
+ * VirtualRenderer.onResize(force) -> Void
+ * - force (Boolean): If `true`, recomputes the size, even if the height and width haven't changed
+ *
+ * [Triggers a resize of the editor.]{: #VirtualRenderer.onResize}
+ **/
this.onResize = function(force) {
var changes = this.CHANGE_SIZE;
var size = this.$size;
@@ -15086,53 +17923,119 @@ var VirtualRenderer = function(container, theme) {
this.$loop.schedule(changes);
};
+ /**
+ * VirtualRenderer.adjustWrapLimit() -> Void
+ *
+ * Adjusts the wrap limit, which is the number of characters that can fit within the width of the edit area on screen.
+ **/
this.adjustWrapLimit = function() {
var availableWidth = this.$size.scrollerWidth - this.$padding * 2;
var limit = Math.floor(availableWidth / this.characterWidth);
return this.session.adjustWrapLimit(limit);
};
+ /**
+ * VirtualRenderer.setAnimatedScroll(shouldAnimate) -> Void
+ * - shouldAnimate (Boolean): Set to `true` to show animated scrolls
+ *
+ * Identifies whether you want to have an animated scroll or not.
+ *
+ **/
this.setAnimatedScroll = function(shouldAnimate){
this.$animatedScroll = shouldAnimate;
};
+ /**
+ * VirtualRenderer.getAnimatedScroll() -> Boolean
+ *
+ * Returns whether an animated scroll happens or not.
+ **/
this.getAnimatedScroll = function() {
return this.$animatedScroll;
};
+ /**
+ * VirtualRenderer.setShowInvisibles(showInvisibles) -> Void
+ * - showInvisibles (Boolean): Set to `true` to show invisibles
+ *
+ * Identifies whether you want to show invisible characters or not.
+ *
+ **/
this.setShowInvisibles = function(showInvisibles) {
if (this.$textLayer.setShowInvisibles(showInvisibles))
this.$loop.schedule(this.CHANGE_TEXT);
};
+ /**
+ * VirtualRenderer.getShowInvisibles() -> Boolean
+ *
+ * Returns whether invisible characters are being shown or not.
+ **/
this.getShowInvisibles = function() {
return this.$textLayer.showInvisibles;
};
this.$showPrintMargin = true;
+
+ /**
+ * VirtualRenderer.setShowPrintMargin(showPrintMargin)
+ * - showPrintMargin (Boolean): Set to `true` to show the print margin
+ *
+ * Identifies whether you want to show the print margin or not.
+ *
+ **/
this.setShowPrintMargin = function(showPrintMargin) {
this.$showPrintMargin = showPrintMargin;
this.$updatePrintMargin();
};
+ /**
+ * VirtualRenderer.getShowPrintMargin() -> Boolean
+ *
+ * Returns whetherthe print margin is being shown or not.
+ **/
this.getShowPrintMargin = function() {
return this.$showPrintMargin;
};
this.$printMarginColumn = 80;
+
+ /**
+ * VirtualRenderer.setPrintMarginColumn(showPrintMargin)
+ * - showPrintMargin (Boolean): Set to `true` to show the print margin column
+ *
+ * Identifies whether you want to show the print margin column or not.
+ *
+ **/
this.setPrintMarginColumn = function(showPrintMargin) {
this.$printMarginColumn = showPrintMargin;
this.$updatePrintMargin();
};
+ /**
+ * VirtualRenderer.getPrintMarginColumn() -> Boolean
+ *
+ * Returns whether the print margin column is being shown or not.
+ **/
this.getPrintMarginColumn = function() {
return this.$printMarginColumn;
};
+ /**
+ * VirtualRenderer.getShowGutter() -> Boolean
+ *
+ * Returns `true` if the gutter is being shown.
+ **/
this.getShowGutter = function(){
return this.showGutter;
};
+ /**
+ * VirtualRenderer.setShowGutter(show) -> Void
+ * - show (Boolean): Set to `true` to show the gutter
+ *
+ * Identifies whether you want to show the gutter or not.
+ **/
this.setShowGutter = function(show){
if(this.showGutter === show)
return;
@@ -15141,6 +18044,44 @@ var VirtualRenderer = function(container, theme) {
this.onResize(true);
};
+ this.getFadeFoldWidgets = function(){
+ return dom.hasCssClass(this.$gutter, "ace_fade-fold-widgets");
+ };
+
+ this.setFadeFoldWidgets = function(show) {
+ if (show)
+ dom.addCssClass(this.$gutter, "ace_fade-fold-widgets");
+ else
+ dom.removeCssClass(this.$gutter, "ace_fade-fold-widgets");
+ };
+
+ this.$highlightGutterLine = false;
+ this.setHighlightGutterLine = function(shouldHighlight) {
+ if (this.$highlightGutterLine == shouldHighlight)
+ return;
+ this.$highlightGutterLine = shouldHighlight;
+
+
+ if (!this.$gutterLineHighlight) {
+ this.$gutterLineHighlight = dom.createElement("div");
+ this.$gutterLineHighlight.className = "ace_gutter_active_line";
+ this.$gutter.appendChild(this.$gutterLineHighlight);
+ return;
+ }
+
+ this.$gutterLineHighlight.style.display = shouldHighlight ? "" : "none";
+ this.$updateGutterLineHighlight();
+ };
+
+ this.getHighlightGutterLine = function() {
+ return this.$highlightGutterLine;
+ };
+
+ this.$updateGutterLineHighlight = function() {
+ this.$gutterLineHighlight.style.top = this.$cursorLayer.$pixelPos.top + "px";
+ this.$gutterLineHighlight.style.height = this.layerConfig.lineHeight + "px";
+ };
+
this.$updatePrintMargin = function() {
var containerEl;
@@ -15161,56 +18102,98 @@ var VirtualRenderer = function(container, theme) {
style.visibility = this.$showPrintMargin ? "visible" : "hidden";
};
+ /**
+ * VirtualRenderer.getContainerElement() -> DOMElement
+ *
+ * Returns the root element containing this renderer.
+ **/
this.getContainerElement = function() {
return this.container;
};
+ /**
+ * VirtualRenderer.getMouseEventTarget() -> DOMElement
+ *
+ * Returns the element that the mouse events are attached to
+ **/
this.getMouseEventTarget = function() {
return this.content;
};
+ /**
+ * VirtualRenderer.getTextAreaContainer() -> DOMElement
+ *
+ * Returns the element to which the hidden text area is added.
+ **/
this.getTextAreaContainer = function() {
return this.container;
};
- this.moveTextAreaToCursor = function(textarea) {
- // in IE the native cursor always shines through
- // this persists in IE9
- if (useragent.isIE)
+ // move text input over the cursor
+ // this is required for iOS and IME
+ this.$moveTextAreaToCursor = function() {
+ if (!this.$keepTextAreaAtCursor)
return;
- if (this.layerConfig.lastRow === 0)
+ var posTop = this.$cursorLayer.$pixelPos.top;
+ var posLeft = this.$cursorLayer.$pixelPos.left;
+ posTop -= this.layerConfig.offset;
+
+ if (posTop < 0 || posTop > this.layerConfig.height)
return;
- var pos = this.$cursorLayer.getPixelPosition();
- if (!pos)
- return;
-
- var bounds = this.content.getBoundingClientRect();
- var offset = this.layerConfig.offset;
-
- textarea.style.left = (bounds.left + pos.left) + "px";
- textarea.style.top = (bounds.top + pos.top - this.scrollTop + offset) + "px";
+ posLeft += (this.showGutter ? this.$gutterLayer.gutterWidth : 0) - this.scrollLeft;
+ var bounds = this.container.getBoundingClientRect();
+ this.textarea.style.left = (bounds.left + posLeft) + "px";
+ this.textarea.style.top = (bounds.top + posTop) + "px";
};
+ /**
+ * VirtualRenderer.getFirstVisibleRow() -> Number
+ *
+ * [Returns the index of the first visible row.]{: #VirtualRenderer.getFirstVisibleRow}
+ **/
this.getFirstVisibleRow = function() {
return this.layerConfig.firstRow;
};
+ /**
+ * VirtualRenderer.getFirstFullyVisibleRow() -> Number
+ *
+ * Returns the index of the first fully visible row. "Fully" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.
+ **/
this.getFirstFullyVisibleRow = function() {
return this.layerConfig.firstRow + (this.layerConfig.offset === 0 ? 0 : 1);
};
+ /**
+ * VirtualRenderer.getLastFullyVisibleRow() -> Number
+ *
+ * Returns the index of the last fully visible row. "Fully" here means that the characters in the row are not truncated; that the top and the bottom of the row are on the screen.
+ **/
this.getLastFullyVisibleRow = function() {
var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight);
return this.layerConfig.firstRow - 1 + flint;
};
+ /**
+ * VirtualRenderer.getLastVisibleRow() -> Number
+ *
+ * [Returns the index of the last visible row.]{: #VirtualRenderer.getLastVisibleRow}
+ **/
this.getLastVisibleRow = function() {
return this.layerConfig.lastRow;
};
this.$padding = null;
+
+ /**
+ * VirtualRenderer.setPadding(padding) -> Void
+ * - padding (Number): A new padding value (in pixels)
+ *
+ * Sets the padding for all the layers.
+ *
+ **/
this.setPadding = function(padding) {
this.$padding = padding;
this.$textLayer.setPadding(padding);
@@ -15221,10 +18204,21 @@ var VirtualRenderer = function(container, theme) {
this.$updatePrintMargin();
};
+ /**
+ * VirtualRenderer.getHScrollBarAlwaysVisible() -> Boolean
+ *
+ * Returns whether the horizontal scrollbar is set to be always visible.
+ **/
this.getHScrollBarAlwaysVisible = function() {
return this.$horizScrollAlwaysVisible;
};
+ /**
+ * VirtualRenderer.setHScrollBarAlwaysVisible(alwaysVisible) -> Void
+ * - alwaysVisible (Boolean): Set to `true` to make the horizontal scroll bar visible
+ *
+ * Identifies whether you want to show the horizontal scrollbar or not.
+ **/
this.setHScrollBarAlwaysVisible = function(alwaysVisible) {
if (this.$horizScrollAlwaysVisible != alwaysVisible) {
this.$horizScrollAlwaysVisible = alwaysVisible;
@@ -15272,6 +18266,8 @@ var VirtualRenderer = function(container, theme) {
this.$markerBack.update(this.layerConfig);
this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
+ this.$moveTextAreaToCursor();
+ this.$highlightGutterLine && this.$updateGutterLineHighlight();
return;
}
@@ -15288,6 +18284,8 @@ var VirtualRenderer = function(container, theme) {
this.$markerBack.update(this.layerConfig);
this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
+ this.$moveTextAreaToCursor();
+ this.$highlightGutterLine && this.$updateGutterLineHighlight();
return;
}
@@ -15307,8 +18305,11 @@ var VirtualRenderer = function(container, theme) {
this.$gutterLayer.update(this.layerConfig);
}
- if (changes & this.CHANGE_CURSOR)
+ if (changes & this.CHANGE_CURSOR) {
this.$cursorLayer.update(this.layerConfig);
+ this.$moveTextAreaToCursor();
+ this.$highlightGutterLine && this.$updateGutterLineHighlight();
+ }
if (changes & (this.CHANGE_MARKER | this.CHANGE_MARKER_FRONT)) {
this.$markerFront.update(this.layerConfig);
@@ -15385,7 +18386,7 @@ var VirtualRenderer = function(container, theme) {
// For debugging.
// console.log(JSON.stringify(this.layerConfig));
- this.$gutterLayer.element.style.marginTop = (-offset) + "px";
+ this.$gutter.style.marginTop = (-offset) + "px";
this.content.style.marginTop = (-offset) + "px";
this.content.style.width = longestLine + 2 * this.$padding + "px";
this.content.style.height = minHeight + "px";
@@ -15431,55 +18432,111 @@ var VirtualRenderer = function(container, theme) {
return Math.max(this.$size.scrollerWidth - 2 * this.$padding, Math.round(charCount * this.characterWidth));
};
+ /**
+ * VirtualRenderer.updateFrontMarkers() -> Void
+ *
+ * Schedules an update to all the front markers in the document.
+ **/
this.updateFrontMarkers = function() {
this.$markerFront.setMarkers(this.session.getMarkers(true));
this.$loop.schedule(this.CHANGE_MARKER_FRONT);
};
+ /**
+ * VirtualRenderer.updateBackMarkers() -> Void
+ *
+ * Schedules an update to all the back markers in the document.
+ **/
this.updateBackMarkers = function() {
this.$markerBack.setMarkers(this.session.getMarkers());
this.$loop.schedule(this.CHANGE_MARKER_BACK);
};
+ /**
+ * VirtualRenderer.addGutterDecoration(row, className) -> Void
+ * - row (Number): The row number
+ * - className (String): The class to add
+ *
+ * Adds `className` to the `row`, to be used for CSS stylings and whatnot.
+ **/
this.addGutterDecoration = function(row, className){
this.$gutterLayer.addGutterDecoration(row, className);
this.$loop.schedule(this.CHANGE_GUTTER);
};
+ /**
+ * VirtualRenderer.removeGutterDecoration(row, className)-> Void
+ * - row (Number): The row number
+ * - className (String): The class to add
+ *
+ * Removes `className` from the `row`.
+ **/
this.removeGutterDecoration = function(row, className){
this.$gutterLayer.removeGutterDecoration(row, className);
this.$loop.schedule(this.CHANGE_GUTTER);
};
+ /**
+ * VirtualRenderer.setBreakpoints(rows) -> Void
+ * - rows (Array): An array containg row numbers
+ *
+ * Sets a breakpoint for every row number indicated on `rows`.
+ **/
this.setBreakpoints = function(rows) {
this.$gutterLayer.setBreakpoints(rows);
this.$loop.schedule(this.CHANGE_GUTTER);
};
+ /**
+ * VirtualRenderer.setAnnotations(annotations) -> Void
+ * - annotations (Array): An array containing annotations
+ *
+ * Sets annotations for the gutter.
+ **/
this.setAnnotations = function(annotations) {
this.$gutterLayer.setAnnotations(annotations);
this.$loop.schedule(this.CHANGE_GUTTER);
};
+ /**
+ * VirtualRenderer.updateCursor() -> Void
+ *
+ * Updates the cursor icon.
+ **/
this.updateCursor = function() {
this.$loop.schedule(this.CHANGE_CURSOR);
};
+ /**
+ * VirtualRenderer.hideCursor() -> Void
+ *
+ * Hides the cursor icon.
+ **/
this.hideCursor = function() {
this.$cursorLayer.hideCursor();
};
+ /**
+ * VirtualRenderer.showCursor() -> Void
+ *
+ * Shows the cursor icon.
+ **/
this.showCursor = function() {
this.$cursorLayer.showCursor();
};
- this.scrollSelectionIntoView = function(anchor, lead) {
+ this.scrollSelectionIntoView = function(anchor, lead, offset) {
// first scroll anchor into view then scroll lead into view
- this.scrollCursorIntoView(anchor);
- this.scrollCursorIntoView(lead);
+ this.scrollCursorIntoView(anchor, offset);
+ this.scrollCursorIntoView(lead, offset);
};
- this.scrollCursorIntoView = function(cursor) {
+ /**
+ * VirtualRenderer.scrollCursorIntoView(cursor, offset) -> Void
+ *
+ * Scrolls the cursor into the first visibile area of the editor
+ **/
+ this.scrollCursorIntoView = function(cursor, offset) {
// the editor is not visible
if (this.$size.scrollerHeight === 0)
return;
@@ -15490,10 +18547,12 @@ var VirtualRenderer = function(container, theme) {
var top = pos.top;
if (this.scrollTop > top) {
+ if (offset)
+ top -= offset * this.$size.scrollerHeight;
this.session.setScrollTop(top);
- }
-
- if (this.scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
+ } else if (this.scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
+ if (offset)
+ top += offset * this.$size.scrollerHeight;
this.session.setScrollTop(top + this.lineHeight - this.$size.scrollerHeight);
}
@@ -15503,75 +18562,128 @@ var VirtualRenderer = function(container, theme) {
if (left < this.$padding + 2 * this.layerConfig.characterWidth)
left = 0;
this.session.setScrollLeft(left);
- }
-
- if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
+ } else if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
}
};
+ /** related to: EditSession.getScrollTop
+ * VirtualRenderer.getScrollTop() -> Number
+ *
+ * {:EditSession.getScrollTop}
+ **/
this.getScrollTop = function() {
return this.session.getScrollTop();
};
+ /** related to: EditSession.getScrollLeft
+ * VirtualRenderer.getScrollLeft() -> Number
+ *
+ * {:EditSession.getScrollLeft}
+ **/
this.getScrollLeft = function() {
return this.session.getScrollLeft();
};
+ /**
+ * VirtualRenderer.getScrollTopRow() -> Number
+ *
+ * Returns the first visible row, regardless of whether it's fully visible or not.
+ **/
this.getScrollTopRow = function() {
return this.scrollTop / this.lineHeight;
};
+ /**
+ * VirtualRenderer.getScrollBottomRow() -> Number
+ *
+ * Returns the last visible row, regardless of whether it's fully visible or not.
+ **/
this.getScrollBottomRow = function() {
return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1);
};
+ /** related to: EditSession.setScrollTop
+ * VirtualRenderer.scrollToRow(row) -> Void
+ * - row (Number): A row id
+ *
+ * Gracefully scrolls the top of the editor to the row indicated.
+ **/
this.scrollToRow = function(row) {
this.session.setScrollTop(row * this.lineHeight);
};
- this.STEPS = 10;
+ this.STEPS = 8;
this.$calcSteps = function(fromValue, toValue){
var i = 0;
var l = this.STEPS;
var steps = [];
var func = function(t, x_min, dx) {
- if ((t /= .5) < 1)
- return dx / 2 * Math.pow(t, 3) + x_min;
- return dx / 2 * (Math.pow(t - 2, 3) + 2) + x_min;
+ return dx * (Math.pow(t - 1, 3) + 1) + x_min;
};
for (i = 0; i < l; ++i)
steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));
- steps.push(toValue);
return steps;
};
- this.scrollToLine = function(line, center) {
+ /**
+ * VirtualRenderer.scrollToLine(line, center, animate, callback) -> Void
+ * - line (Number): A line number
+ * - center (Boolean): If `true`, centers the editor the to indicated line
+ * - animate (Boolean): If `true` animates scrolling
+ * - callback (Function): Function to be called after the animation has finished
+ *
+ * Gracefully scrolls the editor to the row indicated.
+ **/
+ this.scrollToLine = function(line, center, animate, callback) {
var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0});
var offset = pos.top;
if (center)
offset -= this.$size.scrollerHeight / 2;
- if (this.$animatedScroll && Math.abs(offset - this.scrollTop) < 10000) {
- var _self = this;
- var steps = _self.$calcSteps(this.scrollTop, offset);
-
- clearInterval(this.$timer);
- this.$timer = setInterval(function() {
- _self.session.setScrollTop(steps.shift());
-
- if (!steps.length)
- clearInterval(_self.$timer);
- }, 10);
- }
- else {
- this.session.setScrollTop(offset);
- }
+ var initialScroll = this.scrollTop;
+ this.session.setScrollTop(offset);
+ if (animate !== false)
+ this.animateScrolling(initialScroll, callback);
};
+ this.animateScrolling = function(fromValue, callback) {
+ var toValue = this.scrollTop;
+ if (this.$animatedScroll && Math.abs(fromValue - toValue) < 100000) {
+ var _self = this;
+ var steps = _self.$calcSteps(fromValue, toValue);
+ this.$inScrollAnimation = true;
+
+ clearInterval(this.$timer);
+
+ _self.session.setScrollTop(steps.shift());
+ this.$timer = setInterval(function() {
+ if (steps.length) {
+ _self.session.setScrollTop(steps.shift());
+ // trick session to think it's already scrolled to not loose toValue
+ _self.session.$scrollTop = toValue;
+ } else {
+ this.$inScrollAnimation = false;
+ clearInterval(_self.$timer);
+
+ _self.session.$scrollTop = -1;
+ _self.session.setScrollTop(toValue);
+ callback && callback();
+ }
+ }, 10);
+ }
+ };
+
+ /**
+ * VirtualRenderer.scrollToY(scrollTop) -> Number
+ * - scrollTop (Number): The position to scroll to
+ *
+ * Scrolls the editor to the y pixel indicated.
+ *
+ **/
this.scrollToY = function(scrollTop) {
// after calling scrollBar.setScrollTop
// scrollbar sends us event with same scrollTop. ignore it
@@ -15581,6 +18693,13 @@ var VirtualRenderer = function(container, theme) {
}
};
+ /**
+ * VirtualRenderer.scrollToX(scrollLeft) -> Number
+ * - scrollLeft (Number): The position to scroll to
+ *
+ * Scrolls the editor to the x pixel indicated.
+ *
+ **/
this.scrollToX = function(scrollLeft) {
if (scrollLeft <= this.$padding)
scrollLeft = 0;
@@ -15590,11 +18709,25 @@ var VirtualRenderer = function(container, theme) {
this.$loop.schedule(this.CHANGE_H_SCROLL);
};
+ /**
+ * VirtualRenderer.scrollBy(deltaX, deltaY) -> Void
+ * - deltaX (Number): The x value to scroll by
+ * - deltaY (Number): The y value to scroll by
+ *
+ * Scrolls the editor across both x- and y-axes.
+ **/
this.scrollBy = function(deltaX, deltaY) {
deltaY && this.session.setScrollTop(this.session.getScrollTop() + deltaY);
deltaX && this.session.setScrollLeft(this.session.getScrollLeft() + deltaX);
};
+ /**
+ * VirtualRenderer.isScrollableBy(deltaX, deltaY) -> Boolean
+ * - deltaX (Number): The x value to scroll by
+ * - deltaY (Number): The y value to scroll by
+ *
+ * Returns `true` if you can still scroll by either parameter; in other words, you haven't reached the end of the file or line.
+ **/
this.isScrollableBy = function(deltaX, deltaY) {
if (deltaY < 0 && this.session.getScrollTop() > 0)
return true;
@@ -15603,32 +18736,38 @@ var VirtualRenderer = function(container, theme) {
// todo: handle horizontal scrolling
};
- this.pixelToScreenCoordinates = function(pageX, pageY) {
+ this.pixelToScreenCoordinates = function(x, y) {
var canvasPos = this.scroller.getBoundingClientRect();
- var col = Math.round(
- (pageX + this.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) / this.characterWidth
- );
- var row = Math.floor(
- (pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.lineHeight
- );
+ var offset = (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth;
+ var row = Math.floor((y + this.scrollTop - canvasPos.top) / this.lineHeight);
+ var col = Math.round(offset);
- return {row: row, column: col};
+ return {row: row, column: col, side: offset - col > 0 ? 1 : -1};
};
- this.screenToTextCoordinates = function(pageX, pageY) {
+ this.screenToTextCoordinates = function(x, y) {
var canvasPos = this.scroller.getBoundingClientRect();
var col = Math.round(
- (pageX + this.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) / this.characterWidth
+ (x + this.scrollLeft - canvasPos.left - this.$padding) / this.characterWidth
);
var row = Math.floor(
- (pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.lineHeight
+ (y + this.scrollTop - canvasPos.top) / this.lineHeight
);
return this.session.screenToDocumentPosition(row, Math.max(col, 0));
};
+ /**
+ * VirtualRenderer.textToScreenCoordinates(row, column) -> Object
+ * - row (Number): The document row position
+ * - column (Number): The document column position
+ *
+ * Returns an object containing the `pageX` and `pageY` coordinates of the document position.
+ *
+ *
+ **/
this.textToScreenCoordinates = function(row, column) {
var canvasPos = this.scroller.getBoundingClientRect();
var pos = this.session.documentToScreenPosition(row, column);
@@ -15642,14 +18781,29 @@ var VirtualRenderer = function(container, theme) {
};
};
+ /**
+ * VirtualRenderer.visualizeFocus() -> Void
+ *
+ * Focuses the current container.
+ **/
this.visualizeFocus = function() {
dom.addCssClass(this.container, "ace_focus");
};
+ /**
+ * VirtualRenderer.visualizeBlur() -> Void
+ *
+ * Blurs the current container.
+ **/
this.visualizeBlur = function() {
dom.removeCssClass(this.container, "ace_focus");
};
+ /** internal, hide
+ * VirtualRenderer.showComposition(position) -> Void
+ * - position (Number):
+ *
+ **/
this.showComposition = function(position) {
if (!this.$composition) {
this.$composition = dom.createElement("div");
@@ -15668,10 +18822,21 @@ var VirtualRenderer = function(container, theme) {
this.hideCursor();
};
+ /**
+ * VirtualRenderer.setCompositionText(text) -> Void
+ * - text (String): A string of text to use
+ *
+ * Sets the inner text of the current composition to `text`.
+ **/
this.setCompositionText = function(text) {
dom.setInnerText(this.$composition, text);
};
+ /**
+ * VirtualRenderer.hideComposition() -> Void
+ *
+ * Hides the current composition.
+ **/
this.hideComposition = function() {
this.showCursor();
@@ -15692,6 +18857,12 @@ var VirtualRenderer = function(container, theme) {
net.loadScript(filename, callback);
};
+ /**
+ * VirtualRenderer.setTheme(theme) -> Void
+ * - theme (String): The path to a theme
+ *
+ * [Sets a new theme for the editor. `theme` should exist, and be a directory path, like `ace/theme/textmate`.]{: #VirtualRenderer.setTheme}
+ **/
this.setTheme = function(theme) {
var _self = this;
@@ -15746,6 +18917,11 @@ var VirtualRenderer = function(container, theme) {
}
};
+ /**
+ * VirtualRenderer.getTheme() -> String
+ *
+ * [Returns the path of the current theme.]{: #VirtualRenderer.getTheme}
+ **/
this.getTheme = function() {
return this.$themeValue;
};
@@ -15754,14 +18930,31 @@ var VirtualRenderer = function(container, theme) {
// This feature can be used by plug-ins to provide a visual indication of
// a certain mode that editor is in.
+ /**
+ * VirtualRenderer.setStyle(style) -> Void
+ * - style (String): A class name
+ *
+ * [Adds a new class, `style`, to the editor.]{: #VirtualRenderer.setStyle}
+ **/
this.setStyle = function setStyle(style) {
dom.addCssClass(this.container, style);
};
+ /**
+ * VirtualRenderer.unsetStyle(style) -> Void
+ * - style (String): A class name
+ *
+ * [Removes the class `style` from the editor.]{: #VirtualRenderer.unsetStyle}
+ **/
this.unsetStyle = function unsetStyle(style) {
dom.removeCssClass(this.container, style);
};
+ /**
+ * VirtualRenderer.destroy()
+ *
+ * Destroys the text and cursor layers for this renderer.
+ **/
this.destroy = function() {
this.$textLayer.destroy();
this.$cursorLayer.destroy();
@@ -16071,9 +19264,7 @@ var Marker = function(parentEl) {
return (row - layerConfig.firstRowScreen) * layerConfig.lineHeight;
};
- /**
- * Draws a marker, which spans a range of text on multiple lines
- */
+ // Draws a marker, which spans a range of text on multiple lines
this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
// selection start
var row = range.start.row;
@@ -16097,9 +19288,7 @@ var Marker = function(parentEl) {
}
};
- /**
- * Draws a multi line marker, where lines span the full width
- */
+ // Draws a multi line marker, where lines span the full width
this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig, type) {
var padding = type === "background" ? 0 : this.$padding;
var layerWidth = layerConfig.width + 2 * this.$padding - padding;
@@ -16146,9 +19335,7 @@ var Marker = function(parentEl) {
);
};
- /**
- * Draws a marker which covers part or whole width of a single screen line
- */
+ // Draws a marker which covers part or whole width of a single screen line
this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength, type) {
var padding = type === "background" ? 0 : this.$padding;
var height = layerConfig.lineHeight;
@@ -16569,21 +19756,18 @@ var Text = function(parentEl) {
this.$renderToken = function(stringBuilder, screenColumn, token, value) {
var self = this;
- var replaceReg = /\t|&|<|( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])|[\u1100-\u115F]|[\u11A3-\u11A7]|[\u11FA-\u11FF]|[\u2329-\u232A]|[\u2E80-\u2E99]|[\u2E9B-\u2EF3]|[\u2F00-\u2FD5]|[\u2FF0-\u2FFB]|[\u3000-\u303E]|[\u3041-\u3096]|[\u3099-\u30FF]|[\u3105-\u312D]|[\u3131-\u318E]|[\u3190-\u31BA]|[\u31C0-\u31E3]|[\u31F0-\u321E]|[\u3220-\u3247]|[\u3250-\u32FE]|[\u3300-\u4DBF]|[\u4E00-\uA48C]|[\uA490-\uA4C6]|[\uA960-\uA97C]|[\uAC00-\uD7A3]|[\uD7B0-\uD7C6]|[\uD7CB-\uD7FB]|[\uF900-\uFAFF]|[\uFE10-\uFE19]|[\uFE30-\uFE52]|[\uFE54-\uFE66]|[\uFE68-\uFE6B]|[\uFF01-\uFF60]|[\uFFE0-\uFFE6]/g;
+ var replaceReg = /\t|&|<|( +)|([\u0000-\u0019\u00a0\u2000-\u200b\u2028\u2029\u3000])|[\u1100-\u115F\u11A3-\u11A7\u11FA-\u11FF\u2329-\u232A\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3000-\u303E\u3041-\u3096\u3099-\u30FF\u3105-\u312D\u3131-\u318E\u3190-\u31BA\u31C0-\u31E3\u31F0-\u321E\u3220-\u3247\u3250-\u32FE\u3300-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFAFF\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFF01-\uFF60\uFFE0-\uFFE6]/g;
var replaceFunc = function(c, a, b, tabIdx, idx4) {
- if (c.charCodeAt(0) == 32) {
+ if (a) {
return new Array(c.length+1).join(" ");
+ } else if (c == "&") {
+ return "&";
+ } else if (c == "<") {
+ return "<";
} else if (c == "\t") {
var tabSize = self.session.getScreenTabSize(screenColumn + tabIdx);
screenColumn += tabSize - 1;
return self.$tabStrings[tabSize];
- } else if (c == "&") {
- if (useragent.isOldGecko)
- return "&";
- else
- return "&";
- } else if (c == "<") {
- return "<";
} else if (c == "\u3000") {
// U+3000 is both invisible AND full-width, so must be handled uniquely
var classToUse = self.showInvisibles ? "ace_cjk ace_invisible" : "ace_cjk";
@@ -16592,13 +19776,8 @@ var Text = function(parentEl) {
return "" + space + "";
- } else if (c.match(/[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/)) {
- if (self.showInvisibles) {
- var space = new Array(c.length+1).join(self.SPACE_CHAR);
- return "" + space + "";
- } else {
- return " ";
- }
+ } else if (b) {
+ return "" + self.SPACE_CHAR + "";
} else {
screenColumn += 1;
return " Number
+ *
+ * Returns the width of the scroll bar.
+ *
+ **/
this.getWidth = function() {
return this.width;
};
+ /**
+ * ScrollBar.setHeight(height)
+ * - height (Number): The new height
+ *
+ * Sets the height of the scroll bar, in pixels.
+ *
+ **/
this.setHeight = function(height) {
this.element.style.height = height + "px";
};
+ /**
+ * ScrollBar.setInnerHeight(height)
+ * - height (Number): The new inner height
+ *
+ * Sets the inner height of the scroll bar, in pixels.
+ *
+ **/
this.setInnerHeight = function(height) {
this.inner.style.height = height + "px";
};
+ /**
+ * ScrollBar.setScrollTop(scrollTop)
+ * - scrollTop (Number): The new scroll top
+ *
+ * Sets the scroll top of the scroll bar.
+ *
+ **/
// TODO: on chrome 17+ after for small zoom levels after this function
// this.element.scrollTop != scrollTop which makes page to scroll up.
this.setScrollTop = function(scrollTop) {
@@ -17126,6 +20355,19 @@ define('ace/renderloop', ['require', 'exports', 'module' , 'ace/lib/event'], fun
var event = require("./lib/event");
+/** internal, hide
+ * class RenderLoop
+ *
+ * Batches changes (that force something to be redrawn) in the background.
+ *
+ **/
+
+/** internal, hide
+ * new RenderLoop(onRender, win)
+ *
+ *
+ *
+**/
var RenderLoop = function(onRender, win) {
this.onRender = onRender;
this.pending = false;
@@ -17135,6 +20377,12 @@ var RenderLoop = function(onRender, win) {
(function() {
+ /** internal, hide
+ * RenderLoop.schedule(change)
+ * - change (Array):
+ *
+ *
+ **/
this.schedule = function(change) {
//this.onRender(change);
//return;
@@ -17157,8 +20405,7 @@ var RenderLoop = function(onRender, win) {
exports.RenderLoop = RenderLoop;
});
-define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono);\n" +
- "\n" +
+define("text!ace/css/editor.css", [], "\n" +
".ace_editor {\n" +
" position: absolute;\n" +
" overflow: hidden;\n" +
@@ -17196,6 +20443,12 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
" z-index: 1000;\n" +
"}\n" +
"\n" +
+ ".ace_gutter_active_line {\n" +
+ " position: absolute;\n" +
+ " right: 0;\n" +
+ " width: 100%;\n" +
+ "}\n" +
+ "\n" +
".ace_gutter.horscroll {\n" +
" box-shadow: 0px 0px 20px rgba(0,0,0,0.4);\n" +
"}\n" +
@@ -17254,8 +20507,8 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
".ace_editor textarea {\n" +
" position: fixed;\n" +
" z-index: 0;\n" +
- " width: 10px;\n" +
- " height: 30px;\n" +
+ " width: 0.5em;\n" +
+ " height: 1em;\n" +
" opacity: 0;\n" +
" background: transparent;\n" +
" appearance: none;\n" +
@@ -17290,6 +20543,7 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
"\n" +
".ace_text-layer {\n" +
" color: black;\n" +
+ " font: inherit !important;\n" +
"}\n" +
"\n" +
".ace_cjk {\n" +
@@ -17338,10 +20592,6 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
" z-index: 2;\n" +
"}\n" +
"\n" +
- ".ace_gutter .ace_gutter_active_line{\n" +
- " background-color : #dcdcdc;\n" +
- "}\n" +
- "\n" +
".ace_marker-layer .ace_selected_word {\n" +
" position: absolute;\n" +
" z-index: 4;\n" +
@@ -17448,6 +20698,28 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
" background-color: #FFB4B4;\n" +
" border-color: #DE5555;\n" +
"}\n" +
+ "\n" +
+ ".ace_fade-fold-widgets .ace_fold-widget {\n" +
+ " -moz-transition: 0.5s opacity;\n" +
+ " -webkit-transition: 0.5s opacity;\n" +
+ " -o-transition: 0.5s opacity;\n" +
+ " -ms-transition: 0.5s opacity;\n" +
+ " transition: 0.5s opacity;\n" +
+ " opacity: 0;\n" +
+ "}\n" +
+ ".ace_fade-fold-widgets:hover .ace_fold-widget {\n" +
+ " -moz-transition-duration: 0.05s;\n" +
+ " -webkit-transition-duration: 0.05s;\n" +
+ " -o-transition-duration: 0.05s;\n" +
+ " -ms-transition-duration: 0.05s;\n" +
+ " transition-duration: 0.05s;\n" +
+ " -moz-transition-delay: 0.2s;\n" +
+ " -webkit-transition-delay: 0.2s;\n" +
+ " -o-transition-delay: 0.2s;\n" +
+ " -ms-transition-delay: 0.2s;\n" +
+ " transition-delay: 0.2s; \n" +
+ " opacity:1;\n" +
+ "}\n" +
"");
/* vim:ts=4:sts=4:sw=4:
@@ -17488,12 +20760,13 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
*
* ***** END LICENSE BLOCK ***** */
-define('ace/multi_select', ['require', 'exports', 'module' , 'ace/range_list', 'ace/range', 'ace/selection', 'ace/mouse/multi_select_handler', 'ace/commands/multi_select_commands', 'ace/search', 'ace/edit_session', 'ace/editor'], function(require, exports, module) {
+define('ace/multi_select', ['require', 'exports', 'module' , 'ace/range_list', 'ace/range', 'ace/selection', 'ace/mouse/multi_select_handler', 'ace/lib/event', 'ace/commands/multi_select_commands', 'ace/search', 'ace/edit_session', 'ace/editor'], function(require, exports, module) {
var RangeList = require("./range_list").RangeList;
var Range = require("./range").Range;
var Selection = require("./selection").Selection;
var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
+var event = require("./lib/event");
exports.commands = require("./commands/multi_select_commands");
// Todo: session.find or editor.findVolatile that returns range
@@ -17523,10 +20796,12 @@ var EditSession = require("./edit_session").EditSession;
// automatically sorted list of ranges
this.rangeList = null;
- /**
- * Selection.addRange(Range) -> Void
+ /** extension
+ * Selection.addRange(range, $blockChangeEvents)
+ * - range (Range): The new range to add
+ * - $blockChangeEvents (Boolean): Whether or not to block changing events
*
- * adds a range to selection entering multiselect mode if necessary
+ * Adds a range to a selection by entering multiselect mode, if necessary.
**/
this.addRange = function(range, $blockChangeEvents) {
if (!range)
@@ -17570,11 +20845,11 @@ var EditSession = require("./edit_session").EditSession;
range && this.fromOrientedRange(range);
};
- /**
- * Selection.addRange(pos) -> Range
- * pos: {row, column}
+ /** extension
+ * Selection.substractPoint(pos) -> Range
+ * - pos (Range): The position to remove, as a `{row, column}` object
*
- * removes range containing pos (if exists)
+ * Removes a Range containing pos (if it exists).
**/
this.substractPoint = function(pos) {
var removed = this.rangeList.substractPoint(pos);
@@ -17584,10 +20859,10 @@ var EditSession = require("./edit_session").EditSession;
}
};
- /**
- * Selection.mergeOverlappingRanges() -> Void
+ /** extension
+ * Selection.mergeOverlappingRanges()
*
- * merges overlapping ranges ensuring consistency after changes
+ * Merges overlapping ranges ensuring consistency after changes
**/
this.mergeOverlappingRanges = function() {
var removed = this.rangeList.merge();
@@ -17645,6 +20920,37 @@ var EditSession = require("./edit_session").EditSession;
};
this.splitIntoLines = function () {
+ if (this.rangeCount > 1) {
+ var ranges = this.rangeList.ranges;
+ var lastRange = ranges[ranges.length - 1];
+ var range = Range.fromPoints(ranges[0].start, lastRange.end);
+
+ this.toSingleRange();
+ this.setSelectionRange(range, lastRange.cursor == lastRange.start);
+ } else {
+ var range = this.getRange();
+ var startRow = range.start.row;
+ var endRow = range.end.row;
+ if (startRow == endRow)
+ return;
+
+ var rectSel = [];
+ var r = this.getLineRange(startRow, true);
+ r.start.column = range.start.column;
+ rectSel.push(r);
+
+ for (var i = startRow + 1; i < endRow; i++)
+ rectSel.push(this.getLineRange(i, true));
+
+ r = this.getLineRange(endRow, true);
+ r.end.column = range.end.column;
+ rectSel.push(r);
+
+ rectSel.forEach(this.addRange, this);
+ }
+ };
+
+ this.toggleBlockSelection = function () {
if (this.rangeCount > 1) {
var ranges = this.rangeList.ranges;
var lastRange = ranges[ranges.length - 1];
@@ -17661,11 +20967,14 @@ var EditSession = require("./edit_session").EditSession;
}
};
- /**
- * Selection.rectangularRangeBlock(screenCursor, screenAnchor, includeEmptyLines) -> [Range]
- * gets list of ranges composing rectangular block on the screen
- * @includeEmptyLines if true includes ranges inside the block which
- * are empty becuase of the clipping
+ /** extension
+ * Selection.rectangularRangeBlock(screenCursor, screenAnchor, includeEmptyLines) -> Range
+ * - screenCursor (Cursor): The cursor to use
+ * - screenAnchor (Anchor): The anchor to use
+ * - includeEmptyLins (Boolean): If true, this includes ranges inside the block which are empty due to clipping
+ *
+ * Gets list of ranges composing rectangular block on the screen
+ *
*/
this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
var rectSel = [];
@@ -17735,21 +21044,22 @@ var EditSession = require("./edit_session").EditSession;
// extend Editor
var Editor = require("./editor").Editor;
(function() {
- /**
- * Editor.updateSelectionMarkers() -> Void
+
+ /** extension
+ * Editor.updateSelectionMarkers()
*
- * updates cursor and marker layers
+ * Updates the cursor and marker layers.
**/
this.updateSelectionMarkers = function() {
this.renderer.updateCursor();
this.renderer.updateBackMarkers();
};
- /**
+ /** extension
* Editor.addSelectionMarker(orientedRange) -> Range
- * - orientedRange: range with cursor
+ * - orientedRange (Range): A range containing a cursor
*
- * adds selection and cursor
+ * Adds the selection and cursor.
**/
this.addSelectionMarker = function(orientedRange) {
if (!orientedRange.cursor)
@@ -17763,11 +21073,11 @@ var Editor = require("./editor").Editor;
return orientedRange;
};
- /**
- * Editor.removeSelectionMarker(range) -> Void
- * - range: selection range added with addSelectionMarker
+ /** extension
+ * Editor.removeSelectionMarker(range)
+ * - range (Range): The selection range added with [[Editor.addSelectionMarker `addSelectionMarker()`]].
*
- * removes selection marker
+ * Removes the selection marker.
**/
this.removeSelectionMarker = function(range) {
if (!range.marker)
@@ -17798,13 +21108,13 @@ var Editor = require("./editor").Editor;
this.renderer.updateCursor();
this.renderer.updateBackMarkers();
};
-
+
this.$onRemoveRange = function(e) {
this.removeSelectionMarkers(e.ranges);
this.renderer.updateCursor();
this.renderer.updateBackMarkers();
};
-
+
this.$onMultiSelect = function(e) {
if (this.inMultiSelectMode)
return;
@@ -17817,7 +21127,7 @@ var Editor = require("./editor").Editor;
this.renderer.updateCursor();
this.renderer.updateBackMarkers();
};
-
+
this.$onSingleSelect = function(e) {
if (this.session.multiSelect.inVirtualMode)
return;
@@ -17849,12 +21159,12 @@ var Editor = require("./editor").Editor;
e.preventDefault();
};
- /**
- * Editor.forEachSelection(cmd, args) -> Void
- * - cmd: command to execute
- * - args: arguments to the command
+ /** extension
+ * Editor.forEachSelection(cmd, args)
+ * - cmd (String): The command to execute
+ * - args (String): Any arguments for the command
*
- * executes command for each selection range
+ * Executes a command for each selection range.
**/
this.forEachSelection = function(cmd, args) {
if (this.inVirtualSelectionMode)
@@ -17885,11 +21195,11 @@ var Editor = require("./editor").Editor;
this.onCursorChange();
this.onSelectionChange();
};
-
- /**
+
+ /** extension
* Editor.exitMultiSelectMode() -> Void
*
- * removes all selections except the last added one.
+ * Removes all the selections except the last added one.
**/
this.exitMultiSelectMode = function() {
if (this.inVirtualSelectionMode)
@@ -17913,14 +21223,35 @@ var Editor = require("./editor").Editor;
return text;
};
- /**
+ this.onPaste = function(text) {
+ this._emit("paste", text);
+ if (!this.inMultiSelectMode)
+ return this.insert(text);
+
+ var lines = text.split(this.session.getDocument().getNewLineCharacter());
+ var ranges = this.selection.rangeList.ranges;
+
+ if (lines.length > ranges.length) {
+ this.commands.exec("insertstring", this, text);
+ return;
+ }
+
+ for (var i = ranges.length; i--; ) {
+ var range = ranges[i];
+ if (!range.isEmpty())
+ this.session.remove(range);
+
+ this.session.insert(range.start, lines[i]);
+ }
+ };
+
+ /** extension
* Editor.findAll(dir, options) -> Number
* - needle: text to find
* - options: search options
- * - additive: keeps
+ * - additive: keeps
*
- * finds and selects all the occurencies of needle
- * returns number of found ranges
+ * Finds and selects all the occurences of `needle`.
**/
this.findAll = function(needle, options, additive) {
options = options || {};
@@ -17933,10 +21264,10 @@ var Editor = require("./editor").Editor;
this.$blockScrolling += 1;
var selection = this.multiSelect;
-
+
if (!additive)
selection.toSingleRange(ranges[0]);
-
+
for (var i = ranges.length; i--; )
selection.addRange(ranges[i], true);
@@ -17946,12 +21277,12 @@ var Editor = require("./editor").Editor;
};
// commands
- /**
- * Editor.selectMoreLines(dir, skip) -> Void
- * - dir: -1 up, 1 down
- * - skip: remove active selection range if true
+ /** extension
+ * Editor.selectMoreLines(dir, skip)
+ * - dir (Number): The direction of lines to select: -1 for up, 1 for down
+ * - skip (Boolean): If `true`, removes the active selection range
*
- * adds cursor above or bellow active cursor
+ * Adds a cursor above or below the active cursor.
**/
this.selectMoreLines = function(dir, skip) {
var range = this.selection.toOrientedRange();
@@ -17991,12 +21322,11 @@ var Editor = require("./editor").Editor;
this.selection.substractPoint(toRemove);
};
- /**
- * Editor.transposeSelections(dir) -> Void
- * - dir: direction to rotate selections
+ /** extension
+ * Editor.transposeSelections(dir)
+ * - dir (Number): The direction to rotate selections
*
- * contents
- * empty ranges are expanded to word
+ * Transposes the selected ranges.
**/
this.transposeSelections = function(dir) {
var session = this.session;
@@ -18014,7 +21344,7 @@ var Editor = require("./editor").Editor;
}
}
sel.mergeOverlappingRanges();
-
+
var words = [];
for (var i = all.length; i--; ) {
var range = all[i];
@@ -18035,13 +21365,12 @@ var Editor = require("./editor").Editor;
}
}
- /**
- * Editor.selectMore(dir, skip) -> Void
- * - dir: 1 next, -1 previous
- * - skip: remove active selection range if true
+ /** extension
+ * Editor.selectMore(dir, skip)
+ * - dir (Number): The direction of lines to select: -1 for up, 1 for down
+ * - skip (Boolean): If `true`, removes the active selection range
*
- * finds next occurence of text in active selection
- * and adds it to the selections
+ * Finds the next occurence of text in an active selection and adds it to the selections.
**/
this.selectMore = function (dir, skip) {
var session = this.session;
@@ -18108,12 +21437,9 @@ exports.onSessionChange = function(e) {
}
};
-/**
- * MultiSelect(editor) -> Void
- *
- * adds multiple selection support to the editor
- * (note: should be called only once for each editor instance)
- **/
+// MultiSelect(editor)
+// adds multiple selection support to the editor
+// (note: should be called only once for each editor instance)
function MultiSelect(editor) {
editor.$onAddRange = editor.$onAddRange.bind(editor);
editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
@@ -18125,7 +21451,7 @@ function MultiSelect(editor) {
editor.on("mousedown", onMouseDown);
editor.commands.addCommands(exports.commands.defaultCommands);
-
+
addAltCursorListeners(editor);
}
@@ -18133,7 +21459,7 @@ function addAltCursorListeners(editor){
var el = editor.textInput.getElement();
var altCursor = false;
var contentEl = editor.renderer.content;
- el.addEventListener("keydown", function(e) {
+ event.addListener(el, "keydown", function(e) {
if (e.keyCode == 18 && !(e.ctrlKey || e.shiftKey || e.metaKey)) {
if (!altCursor) {
contentEl.style.cursor = "crosshair";
@@ -18143,9 +21469,9 @@ function addAltCursorListeners(editor){
contentEl.style.cursor = "";
}
});
-
- el.addEventListener("keyup", reset);
- el.addEventListener("blur", reset);
+
+ event.addListener(el, "keyup", reset);
+ event.addListener(el, "blur", reset);
function reset() {
if (altCursor) {
contentEl.style.cursor = "";
@@ -18156,7 +21482,8 @@ function addAltCursorListeners(editor){
exports.MultiSelect = MultiSelect;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -18465,10 +21792,10 @@ function onMouseDown(e) {
var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
- var mouseX = e.pageX, mouseY = e.pageY;
+ var mouseX = e.x, mouseY = e.y;
var onMouseSelection = function(e) {
- mouseX = event.getDocumentX(e);
- mouseY = event.getDocumentY(e);
+ mouseX = e.clientX;
+ mouseY = e.clientY;
};
var blockSelect = function() {
@@ -18553,7 +21880,8 @@ function onMouseDown(e) {
exports.onMouseDown = onMouseDown;
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -18639,20 +21967,22 @@ exports.defaultCommands = [{
exec: function(editor) { editor.multiSelect.splitIntoLines(); },
bindKey: {win: "Ctrl-Shift-L", mac: "Ctrl-Shift-L"},
readonly: true
-}];
-
-// commands active in multiselect mode
-exports.multiEditCommands = [{
+}, {
name: "singleSelection",
bindKey: "esc",
exec: function(editor) { editor.exitMultiSelectMode(); },
- readonly: true
+ readonly: true,
+ isAvailable: function(editor) {return editor.inMultiSelectMode}
}];
+// commands active in multiselect mode
+exports.multiEditCommands = {"singleSelection": "esc"};
+
var HashHandler = require("../keyboard/hash_handler").HashHandler;
exports.keyboardHandler = new HashHandler(exports.multiEditCommands);
-});;
+});
+;
(function() {
window.require(["ace/ace"], function(a) {
if (!window.ace)
diff --git a/build/demo/kitchen-sink/mode-c_cpp-uncompressed.js b/build/demo/kitchen-sink/mode-c_cpp-uncompressed.js
index d877348d..a2bcc872 100644
--- a/build/demo/kitchen-sink/mode-c_cpp-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-c_cpp-uncompressed.js
@@ -708,7 +708,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -802,7 +803,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-coffee-uncompressed.js b/build/demo/kitchen-sink/mode-coffee-uncompressed.js
index 19e30ecc..de5d31b0 100644
--- a/build/demo/kitchen-sink/mode-coffee-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-coffee-uncompressed.js
@@ -118,7 +118,8 @@ oop.inherits(Mode, TextMode);
exports.Mode = Mode;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -490,7 +491,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -655,7 +657,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
diff --git a/build/demo/kitchen-sink/mode-coldfusion-uncompressed.js b/build/demo/kitchen-sink/mode-coldfusion-uncompressed.js
index 8bb81e51..4c83e3d1 100644
--- a/build/demo/kitchen-sink/mode-coldfusion-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-coldfusion-uncompressed.js
@@ -480,7 +480,8 @@ var XmlBehaviour = function () {
oop.inherits(XmlBehaviour, Behaviour);
exports.XmlBehaviour = XmlBehaviour;
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -704,7 +705,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -807,7 +809,7 @@ oop.inherits(FoldMode, BaseFoldMode);
};
};
- /**
+ /*
* reads a full tag and places the iterator after the tag
*/
this._readTagForward = function(iterator) {
@@ -965,7 +967,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1923,7 +1926,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -2131,7 +2141,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-csharp-uncompressed.js b/build/demo/kitchen-sink/mode-csharp-uncompressed.js
index 33bc754c..4bcdd072 100644
--- a/build/demo/kitchen-sink/mode-csharp-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-csharp-uncompressed.js
@@ -558,7 +558,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -652,7 +653,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-css-uncompressed.js b/build/demo/kitchen-sink/mode-css-uncompressed.js
index 93634a57..07c79a61 100644
--- a/build/demo/kitchen-sink/mode-css-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-css-uncompressed.js
@@ -483,7 +483,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -691,7 +698,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-groovy-uncompressed.js b/build/demo/kitchen-sink/mode-groovy-uncompressed.js
index f3651008..6576df28 100644
--- a/build/demo/kitchen-sink/mode-groovy-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-groovy-uncompressed.js
@@ -867,7 +867,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -1205,7 +1212,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1299,7 +1307,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-haxe-uncompressed.js b/build/demo/kitchen-sink/mode-haxe-uncompressed.js
index c47c64c9..17634863 100644
--- a/build/demo/kitchen-sink/mode-haxe-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-haxe-uncompressed.js
@@ -558,7 +558,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -652,7 +653,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-html-uncompressed.js b/build/demo/kitchen-sink/mode-html-uncompressed.js
index e426271b..62e709f7 100644
--- a/build/demo/kitchen-sink/mode-html-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-html-uncompressed.js
@@ -926,7 +926,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -1264,7 +1271,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1358,7 +1366,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2200,7 +2209,8 @@ var XmlBehaviour = function () {
oop.inherits(XmlBehaviour, Behaviour);
exports.XmlBehaviour = XmlBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2285,7 +2295,8 @@ var FoldMode = exports.FoldMode = function() {
oop.inherits(FoldMode, MixedFoldMode);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2372,7 +2383,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2475,7 +2487,7 @@ oop.inherits(FoldMode, BaseFoldMode);
};
};
- /**
+ /*
* reads a full tag and places the iterator after the tag
*/
this._readTagForward = function(iterator) {
@@ -2633,4 +2645,4 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});
\ No newline at end of file
+});
diff --git a/build/demo/kitchen-sink/mode-java-uncompressed.js b/build/demo/kitchen-sink/mode-java-uncompressed.js
index 5bdfaa72..dfbf3680 100644
--- a/build/demo/kitchen-sink/mode-java-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-java-uncompressed.js
@@ -868,7 +868,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -1206,7 +1213,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1300,7 +1308,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-javascript-uncompressed.js b/build/demo/kitchen-sink/mode-javascript-uncompressed.js
index 0a6335de..296069a1 100644
--- a/build/demo/kitchen-sink/mode-javascript-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-javascript-uncompressed.js
@@ -843,7 +843,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -1181,7 +1188,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1275,7 +1283,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-json-uncompressed.js b/build/demo/kitchen-sink/mode-json-uncompressed.js
index a3d4f713..144bb932 100644
--- a/build/demo/kitchen-sink/mode-json-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-json-uncompressed.js
@@ -97,7 +97,8 @@ oop.inherits(Mode, TextMode);
}).call(Mode.prototype);
exports.Mode = Mode;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -489,7 +490,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -583,7 +585,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -748,7 +751,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
diff --git a/build/demo/kitchen-sink/mode-less-uncompressed.js b/build/demo/kitchen-sink/mode-less-uncompressed.js
index b59684dd..dbec8c25 100644
--- a/build/demo/kitchen-sink/mode-less-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-less-uncompressed.js
@@ -539,7 +539,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-lua-uncompressed.js b/build/demo/kitchen-sink/mode-lua-uncompressed.js
index c3f87547..93925249 100644
--- a/build/demo/kitchen-sink/mode-lua-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-lua-uncompressed.js
@@ -56,7 +56,7 @@ oop.inherits(Mode, TextMode);
var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
var tokens = tokenizedLine.tokens;
-
+
var chunks = ["function", "then", "do", "repeat"];
if (state == "start") {
@@ -198,7 +198,7 @@ var LuaHighlightRules = function() {
this.$rules = {
"start" :
-
+
// bracketed comments
[{
token : "comment", // --[[ comment
@@ -219,9 +219,9 @@ var LuaHighlightRules = function() {
token : "comment", // --[====+[ comment
regex : strPre + '\\-\\-\\[\\={5}\\=*\\[.*\\]\\={5}\\=*\\]'
},
-
- // multiline bracketed comments
- {
+
+ // multiline bracketed comments
+ {
token : "comment", // --[[ comment
regex : strPre + '\\-\\-\\[\\[.*$',
merge : true,
@@ -271,7 +271,7 @@ var LuaHighlightRules = function() {
},
// bracketed strings
- {
+ {
token : "string", // [[ string
regex : strPre + '\\[\\[.*\\]\\]'
}, {
@@ -290,8 +290,8 @@ var LuaHighlightRules = function() {
token : "string", // [====+[ string
regex : strPre + '\\[\\={5}\\=*\\[.*\\]\\={5}\\=*\\]'
},
-
- // multiline bracketed strings
+
+ // multiline bracketed strings
{
token : "string", // [[ string
regex : strPre + '\\[\\[.*$',
diff --git a/build/demo/kitchen-sink/mode-markdown-uncompressed.js b/build/demo/kitchen-sink/mode-markdown-uncompressed.js
index 984d2c49..e8ce538a 100644
--- a/build/demo/kitchen-sink/mode-markdown-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-markdown-uncompressed.js
@@ -78,7 +78,8 @@ oop.inherits(Mode, TextMode);
}).call(Mode.prototype);
exports.Mode = Mode;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -923,7 +924,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -1261,7 +1269,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1355,7 +1364,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1879,7 +1889,8 @@ var XmlBehaviour = function () {
oop.inherits(XmlBehaviour, Behaviour);
exports.XmlBehaviour = XmlBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1982,7 +1993,7 @@ oop.inherits(FoldMode, BaseFoldMode);
};
};
- /**
+ /*
* reads a full tag and places the iterator after the tag
*/
this._readTagForward = function(iterator) {
@@ -2140,7 +2151,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2800,7 +2812,8 @@ var FoldMode = exports.FoldMode = function() {
oop.inherits(FoldMode, MixedFoldMode);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2887,7 +2900,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -3081,4 +3095,4 @@ var MarkdownHighlightRules = function() {
oop.inherits(MarkdownHighlightRules, TextHighlightRules);
exports.MarkdownHighlightRules = MarkdownHighlightRules;
-});
\ No newline at end of file
+});
diff --git a/build/demo/kitchen-sink/mode-perl-uncompressed.js b/build/demo/kitchen-sink/mode-perl-uncompressed.js
index 04796f61..ff6f8ddd 100644
--- a/build/demo/kitchen-sink/mode-perl-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-perl-uncompressed.js
@@ -458,7 +458,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-php-uncompressed.js b/build/demo/kitchen-sink/mode-php-uncompressed.js
index 37733f26..eedc0308 100644
--- a/build/demo/kitchen-sink/mode-php-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-php-uncompressed.js
@@ -1674,7 +1674,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1768,7 +1769,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-powershell-uncompressed.js b/build/demo/kitchen-sink/mode-powershell-uncompressed.js
index e6f9deea..930ce6af 100644
--- a/build/demo/kitchen-sink/mode-powershell-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-powershell-uncompressed.js
@@ -499,7 +499,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -593,7 +594,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-python-uncompressed.js b/build/demo/kitchen-sink/mode-python-uncompressed.js
index 9a12dece..4783433a 100644
--- a/build/demo/kitchen-sink/mode-python-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-python-uncompressed.js
@@ -391,7 +391,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-scad-uncompressed.js b/build/demo/kitchen-sink/mode-scad-uncompressed.js
index 87418fee..f3cb57b4 100644
--- a/build/demo/kitchen-sink/mode-scad-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-scad-uncompressed.js
@@ -696,7 +696,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -790,7 +791,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-scala-uncompressed.js b/build/demo/kitchen-sink/mode-scala-uncompressed.js
index 5779b9cd..6831517a 100644
--- a/build/demo/kitchen-sink/mode-scala-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-scala-uncompressed.js
@@ -868,7 +868,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -1206,7 +1213,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1300,7 +1308,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-scss-uncompressed.js b/build/demo/kitchen-sink/mode-scss-uncompressed.js
index fc6d611f..63ed5684 100644
--- a/build/demo/kitchen-sink/mode-scss-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-scss-uncompressed.js
@@ -563,7 +563,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-svg-uncompressed.js b/build/demo/kitchen-sink/mode-svg-uncompressed.js
index 885f4611..3f5053d4 100644
--- a/build/demo/kitchen-sink/mode-svg-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-svg-uncompressed.js
@@ -487,7 +487,8 @@ var XmlBehaviour = function () {
oop.inherits(XmlBehaviour, Behaviour);
exports.XmlBehaviour = XmlBehaviour;
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -711,7 +712,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -814,7 +816,7 @@ oop.inherits(FoldMode, BaseFoldMode);
};
};
- /**
+ /*
* reads a full tag and places the iterator after the tag
*/
this._readTagForward = function(iterator) {
@@ -972,7 +974,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1930,7 +1933,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -2138,7 +2148,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -2296,4 +2307,4 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});
\ No newline at end of file
+});
diff --git a/build/demo/kitchen-sink/mode-xml-uncompressed.js b/build/demo/kitchen-sink/mode-xml-uncompressed.js
index e1af6912..5cdd3bc2 100644
--- a/build/demo/kitchen-sink/mode-xml-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-xml-uncompressed.js
@@ -409,7 +409,8 @@ var XmlBehaviour = function () {
oop.inherits(XmlBehaviour, Behaviour);
exports.XmlBehaviour = XmlBehaviour;
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -633,7 +634,8 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -736,7 +738,7 @@ oop.inherits(FoldMode, BaseFoldMode);
};
};
- /**
+ /*
* reads a full tag and places the iterator after the tag
*/
this._readTagForward = function(iterator) {
@@ -894,7 +896,8 @@ oop.inherits(FoldMode, BaseFoldMode);
}).call(FoldMode.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
diff --git a/build/demo/kitchen-sink/mode-xquery-uncompressed.js b/build/demo/kitchen-sink/mode-xquery-uncompressed.js
index 4a3958b1..fef5b873 100644
--- a/build/demo/kitchen-sink/mode-xquery-uncompressed.js
+++ b/build/demo/kitchen-sink/mode-xquery-uncompressed.js
@@ -244,7 +244,14 @@ var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
}
else {
- var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ var workerUrl;
+ if (typeof require.supports !== "undefined" && require.supports.indexOf("ucjs2-pinf-0") >= 0) {
+ // We are running in the sourcemint loader.
+ workerUrl = require.nameToUrl("ace/worker/worker_sourcemint");
+ } else {
+ // We are running in RequireJS.
+ workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ }
this.$worker = new Worker(workerUrl);
var tlns = {};
@@ -388,8 +395,8 @@ var XQueryHighlightRules = function() {
var keywords = lang.arrayToMap(
("return|for|let|where|order|by|declare|function|variable|xquery|version|option|namespace|import|module|when|encoding|" +
"switch|default|try|catch|group|tumbling|sliding|window|start|end|at|only|" +
- "using|stemming|" +
- "while|" +
+ "using|stemming|collection|schema|" +
+ "while|validate|on|nodes|index|" +
"external|" +
"if|then|else|as|and|or|typeswitch|case|ascending|descending|empty|in|count|updating|insert|delete|replace|value|node|attribute|text|element|into|of|with|contains").split("|")
);
@@ -795,4 +802,4 @@ var CstyleBehaviour = function () {
oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
-});
\ No newline at end of file
+});
diff --git a/build/demo/kitchen-sink/styles.css b/build/demo/kitchen-sink/styles.css
index 12bfa090..13470f49 100644
--- a/build/demo/kitchen-sink/styles.css
+++ b/build/demo/kitchen-sink/styles.css
@@ -1,3 +1,5 @@
+@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono);
+
html {
height: 100%;
width: 100%;
diff --git a/build/demo/kitchen-sink/theme-monokai-uncompressed.js b/build/demo/kitchen-sink/theme-monokai-uncompressed.js
index 414b07f7..4f639944 100644
--- a/build/demo/kitchen-sink/theme-monokai-uncompressed.js
+++ b/build/demo/kitchen-sink/theme-monokai-uncompressed.js
@@ -49,8 +49,8 @@ exports.cssText = "\
}\
\
.ace-monokai .ace_gutter {\
- background: #e8e8e8;\
- color: #333;\
+ background: #292a24;\
+ color: #f1f1f1;\
}\
\
.ace-monokai .ace_print_margin {\
@@ -94,9 +94,12 @@ exports.cssText = "\
border: 1px solid #49483E;\
}\
\
-.ace-monokai .ace_marker-layer .ace_active_line {\
+.ace-monokai .ace_marker-layer .ace_active_line{\
background: #49483E;\
}\
+.ace-monokai .ace_gutter_active_line{\
+ background: #191916;\
+}\
\
.ace-monokai .ace_marker-layer .ace_selected_word {\
border: 1px solid #49483E;\
diff --git a/build/demo/kitchen-sink/theme-solarized_dark-uncompressed.js b/build/demo/kitchen-sink/theme-solarized_dark-uncompressed.js
index 65ccdf28..f96e08e7 100644
--- a/build/demo/kitchen-sink/theme-solarized_dark-uncompressed.js
+++ b/build/demo/kitchen-sink/theme-solarized_dark-uncompressed.js
@@ -49,8 +49,8 @@ exports.cssText = "\
}\
\
.ace-solarized-dark .ace_gutter {\
- background: #e8e8e8;\
- color: #333;\
+ background: #09222b;\
+ color: #d0edf7;\
}\
\
.ace-solarized-dark .ace_print_margin {\
@@ -97,6 +97,9 @@ exports.cssText = "\
.ace-solarized-dark .ace_marker-layer .ace_active_line {\
background: #073642;\
}\
+.ace-solarized-dark .ace_gutter_active_line{\
+ background: #0d3440;\
+}\
\
.ace-solarized-dark .ace_marker-layer .ace_selected_word {\
border: 1px solid #073642;\
diff --git a/build/demo/kitchen-sink/theme-tomorrow_night_blue-uncompressed.js b/build/demo/kitchen-sink/theme-tomorrow_night_blue-uncompressed.js
index ff831a06..7c014296 100644
--- a/build/demo/kitchen-sink/theme-tomorrow_night_blue-uncompressed.js
+++ b/build/demo/kitchen-sink/theme-tomorrow_night_blue-uncompressed.js
@@ -49,8 +49,8 @@ exports.cssText = "\
}\
\
.ace-tomorrow-night-blue .ace_gutter {\
- background: #e8e8e8;\
- color: #333;\
+ background: #022346;\
+ color: #7388b5;\
}\
\
.ace-tomorrow-night-blue .ace_print_margin {\
@@ -94,9 +94,12 @@ exports.cssText = "\
border: 1px solid #404F7D;\
}\
\
-.ace-tomorrow-night-blue .ace_marker-layer .ace_active_line {\
+.ace-tomorrow-night-blue .ace_marker-layer .ace_active_line{\
background: #00346E;\
}\
+.ace-tomorrow-night-blue .ace_gutter_active_line{\
+ background: #022040;\
+}\
\
.ace-tomorrow-night-blue .ace_marker-layer .ace_selected_word {\
border: 1px solid #003F8E;\
diff --git a/build/demo/kitchen-sink/worker-coffee.js b/build/demo/kitchen-sink/worker-coffee.js
index f6bdddce..aa9daade 100644
--- a/build/demo/kitchen-sink/worker-coffee.js
+++ b/build/demo/kitchen-sink/worker-coffee.js
@@ -154,7 +154,8 @@ define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/rege
require("./regexp");
require("./es5-shim");
-});/**
+});
+/*
* Based on code from:
*
* XRegExp 1.5.0
@@ -292,7 +293,7 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
-/**
+/*
* Brings an environment as close to ECMAScript 5 compliance
* as is possible with the facilities of erstwhile engines.
*
@@ -1322,7 +1323,8 @@ var prepareString = "a"[0] != "a",
}
return Object(o);
};
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -1399,7 +1401,7 @@ EventEmitter._dispatchEvent = function(eventName, e) {
}
if (defaultHandler && !e.defaultPrevented)
- defaultHandler(e);
+ return defaultHandler(e);
};
EventEmitter.setDefaultHandler = function(eventName, callback) {
@@ -1442,7 +1444,8 @@ EventEmitter.removeAllListeners = function(eventName) {
exports.EventEmitter = EventEmitter;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1594,7 +1597,8 @@ oop.inherits(Worker, Mirror);
}).call(Worker.prototype);
-});define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
+});
+define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
"use strict";
var Document = require("../document").Document;
@@ -1636,7 +1640,8 @@ var Mirror = exports.Mirror = function(sender) {
}).call(Mirror.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1681,6 +1686,21 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
var Anchor = require("./anchor").Anchor;
+/**
+ * class Document
+ *
+ * Contains the text of the document. Documents are controlled by a single [[EditSession `EditSession`]]. At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.
+ *
+ *
+ **/
+
+ /**
+ * new Document([text])
+ * - text (String | Array): The starting text
+ *
+ * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.
+ *
+ **/
var Document = function(text) {
this.$lines = [];
@@ -1700,20 +1720,48 @@ var Document = function(text) {
oop.implement(this, EventEmitter);
+ /**
+ * Document.setValue(text) -> Void
+ * - text (String): The text to use
+ *
+ * Replaces all the lines in the current `Document` with the value of `text`.
+ **/
this.setValue = function(text) {
var len = this.getLength();
this.remove(new Range(0, 0, len, this.getLine(len-1).length));
this.insert({row: 0, column:0}, text);
};
+ /**
+ * Document.getValue() -> String
+ *
+ * Returns all the lines in the document as a single string, split by the new line character.
+ **/
this.getValue = function() {
return this.getAllLines().join(this.getNewLineCharacter());
};
+ /**
+ * Document.createAnchor(row, column) -> Anchor
+ * - row (Number): The row number to use
+ * - column (Number): The column number to use
+ *
+ * Creates a new `Anchor` to define a floating point in the document.
+ **/
this.createAnchor = function(row, column) {
return new Anchor(this, row, column);
};
+ /** internal, hide
+ * Document.$split(text) -> [String]
+ * - text (String): The text to work with
+ * + ([String]): A String array, with each index containing a piece of the original `text` string.
+ *
+ * Splits a string of text on any newline (`\n`) or carriage-return ('\r') characters.
+ *
+ *
+ **/
+
// check for IE split bug
if ("aaa".split(/a/).length == 0)
this.$split = function(text) {
@@ -1725,6 +1773,11 @@ var Document = function(text) {
};
+ /** internal, hide
+ * Document.$detectNewLine(text) -> Void
+ *
+ *
+ **/
this.$detectNewLine = function(text) {
var match = text.match(/^.*?(\r\n|\r|\n)/m);
if (match) {
@@ -1734,6 +1787,17 @@ var Document = function(text) {
}
};
+ /**
+ * Document.getNewLineCharacter() -> String
+ * + (String): If `newLineMode == windows`, `\r\n` is returned.
+ * If `newLineMode == unix`, `\n` is returned.
+ * If `newLineMode == auto`, the value of `autoNewLine` is returned.
+ *
+ * Returns the newline character that's being used, depending on the value of `newLineMode`.
+ *
+ *
+ *
+ **/
this.getNewLineCharacter = function() {
switch (this.$newLineMode) {
case "windows":
@@ -1749,6 +1813,12 @@ var Document = function(text) {
this.$autoNewLine = "\n";
this.$newLineMode = "auto";
+ /**
+ * Document.setNewLineMode(newLineMode) -> Void
+ * - newLineMode(String): [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param}
+ *
+ * [Sets the new line mode.]{: #Document.setNewLineMode.desc}
+ **/
this.setNewLineMode = function(newLineMode) {
if (this.$newLineMode === newLineMode)
return;
@@ -1756,51 +1826,92 @@ var Document = function(text) {
this.$newLineMode = newLineMode;
};
+ /**
+ * Document.getNewLineMode() -> String
+ *
+ * [Returns the type of newlines being used; either `windows`, `unix`, or `auto`]{: #Document.getNewLineMode}
+ *
+ **/
this.getNewLineMode = function() {
return this.$newLineMode;
};
+ /**
+ * Document.isNewLine(text) -> Boolean
+ * - text (String): The text to check
+ *
+ * Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`).
+ *
+ **/
this.isNewLine = function(text) {
return (text == "\r\n" || text == "\r" || text == "\n");
};
/**
- * Get a verbatim copy of the given line as it is in the document
- */
+ * Document.getLine(row) -> String
+ * - row (Number): The row index to retrieve
+ *
+ * Returns a verbatim copy of the given line as it is in the document
+ *
+ **/
this.getLine = function(row) {
return this.$lines[row] || "";
};
+ /**
+ * Document.getLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row index to retrieve
+ * - lastRow (Number): The final row index to retrieve
+ *
+ * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
+ *
+ **/
this.getLines = function(firstRow, lastRow) {
return this.$lines.slice(firstRow, lastRow + 1);
};
/**
- * Returns all lines in the document as string array. Warning: The caller
- * should not modify this array!
- */
+ * Document.getAllLines() -> [String]
+ *
+ * Returns all lines in the document as string array. Warning: The caller should not modify this array!
+ **/
this.getAllLines = function() {
return this.getLines(0, this.getLength());
};
+ /**
+ * Document.getLength() -> Number
+ *
+ * Returns the number of rows in the document.
+ **/
this.getLength = function() {
return this.$lines.length;
};
+ /**
+ * Document.getTextRange(range) -> String
+ * - range (Range): The range to work with
+ *
+ * [Given a range within the document, this function returns all the text within that range as a single string.]{: #Document.getTextRange.desc}
+ **/
this.getTextRange = function(range) {
if (range.start.row == range.end.row) {
return this.$lines[range.start.row].substring(range.start.column,
range.end.column);
}
else {
- var lines = [];
- lines.push(this.$lines[range.start.row].substring(range.start.column));
- lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
- lines.push(this.$lines[range.end.row].substring(0, range.end.column));
+ var lines = this.getLines(range.start.row+1, range.end.row-1);
+ lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
+ lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
return lines.join(this.getNewLineCharacter());
}
};
+ /** internal, hide
+ * Document.$clipPosition(position) -> Number
+ *
+ *
+ **/
this.$clipPosition = function(position) {
var length = this.getLength();
if (position.row >= length) {
@@ -1810,6 +1921,15 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insert(position, text) -> Number
+ * - position (Number): The position to start inserting at
+ * - text (String): A chunk of text to insert
+ * + (Number): The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.
+ * Inserts a block of `text` and the indicated `position`.
+ *
+ *
+ **/
this.insert = function(position, text) {
if (!text || text.length === 0)
return position;
@@ -1833,6 +1953,19 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insertLines(row, lines) -> Object
+ * - row (Number): The index of the row to insert at
+ * - lines (Array): An array of strings
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * If `lines` is empty, this function returns an object containing the current row, and column, like this:
+ * ```{row: row, column: 0}```
+ *
+ * Inserts the elements in `lines` into the document, starting at the row index given by `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.insertLines = function(row, lines) {
if (lines.length == 0)
return {row: row, column: 0};
@@ -1851,6 +1984,17 @@ var Document = function(text) {
return range.end;
};
+ /**
+ * Document.insertNewLine(position) -> Object
+ * - position (String): The position to insert at
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ *
+ * Inserts a new line into the document at the current row's `position`. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertNewLine = function(position) {
position = this.$clipPosition(position);
var line = this.$lines[position.row] || "";
@@ -1873,6 +2017,19 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.insertInLine(position, text) -> Object | Number
+ * - position (Number): The position to insert at
+ * - text (String): A chunk of text
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * + (Number): If `text` is empty, this function returns the value of `position`
+ *
+ * Inserts `text` into the `position` at the current row. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertInLine = function(position, text) {
if (text.length == 0)
return position;
@@ -1897,6 +2054,15 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.remove(range) -> Object
+ * - range (Range): A specified Range to remove
+ * + (Object): Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
+ *
+ * Removes the `range` from the document.
+ *
+ *
+ **/
this.remove = function(range) {
// clip to document
range.start = this.$clipPosition(range.start);
@@ -1929,6 +2095,17 @@ var Document = function(text) {
return range.start;
};
+ /**
+ * Document.removeInLine(row, startColumn, endColumn) -> Object
+ * - row (Number): The row to remove from
+ * - startColumn (Number): The column to start removing at
+ * - endColumn (Number): The column to stop removing at
+ * + (Object): Returns an object containing `startRow` and `startColumn`, indicating the new row and column values. If `startColumn` is equal to `endColumn`, this function returns nothing.
+ *
+ * Removes the specified columns from the `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeInLine = function(row, startColumn, endColumn) {
if (startColumn == endColumn)
return;
@@ -1949,12 +2126,15 @@ var Document = function(text) {
};
/**
- * Removes a range of full lines
- *
- * @param firstRow {Integer} The first row to be removed
- * @param lastRow {Integer} The last row to be removed
- * @return {String[]} The removed lines
- */
+ * Document.removeLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row to be removed
+ * - lastRow (Number): The last row to be removed
+ * + ([String]): Returns all the removed lines.
+ *
+ * Removes a range of full lines. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeLines = function(firstRow, lastRow) {
var range = new Range(firstRow, 0, lastRow + 1, 0);
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
@@ -1969,6 +2149,13 @@ var Document = function(text) {
return removed;
};
+ /**
+ * Document.removeNewLine(row) -> Void
+ * - row (Number): The row to check
+ *
+ * Removes the new line between `row` and the row immediately following it. This method also triggers the `'change'` event.
+ *
+ **/
this.removeNewLine = function(row) {
var firstLine = this.getLine(row);
var secondLine = this.getLine(row+1);
@@ -1986,6 +2173,18 @@ var Document = function(text) {
this._emit("change", { data: delta });
};
+ /**
+ * Document.replace(range, text) -> Object
+ * - range (Range): A specified Range to replace
+ * - text (String): The new text to use as a replacement
+ * + (Object): Returns an object containing the final row and column, like this:
+ * {row: endRow, column: 0}
+ * If the text and range are empty, this function returns an object containing the current `range.start` value.
+ * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
+ *
+ * Replaces a range in the document with the new `text`.
+ *
+ **/
this.replace = function(range, text) {
if (text.length == 0 && range.isEmpty())
return range.start;
@@ -2006,6 +2205,11 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.applyDeltas(deltas) -> Void
+ *
+ * Applies all the changes previously accumulated. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.applyDeltas = function(deltas) {
for (var i=0; i Void
+ *
+ * Reverts any changes previously applied. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.revertDeltas = function(deltas) {
for (var i=deltas.length-1; i>=0; i--) {
var delta = deltas[i];
@@ -2083,6 +2292,23 @@ exports.Document = Document;
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class Range
+ *
+ * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
+ *
+ **/
+
+/**
+ * new Range(startRow, startColumn, endRow, endColumn)
+ * - startRow (Number): The starting row
+ * - startColumn (Number): The starting column
+ * - endRow (Number): The ending row
+ * - endColumn (Number): The ending column
+ *
+ * Creates a new `Range` object with the given starting and ending row and column points.
+ *
+ **/
var Range = function(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
@@ -2096,6 +2322,13 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
(function() {
+ /**
+ * Range.isEqual(range) -> Boolean
+ * - range (Range): A range to check against
+ *
+ * Returns `true` if and only if the starting row and column, and ending tow and column, are equivalent to those given by `range`.
+ *
+ **/
this.isEqual = function(range) {
return this.start.row == range.start.row &&
this.end.row == range.end.row &&
@@ -2103,28 +2336,51 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
this.end.column == range.end.column
};
+ /**
+ * Range.toString() -> String
+ *
+ * Returns a string containing the range's row and column information, given like this:
+ *
+ * [start.row/start.column] -> [end.row/end.column]
+ *
+ **/
+
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
};
+ /** related to: Range.compare
+ * Range.contains(row, column) -> Boolean
+ * - row (Number): A row to check for
+ * - column (Number): A column to check for
+ *
+ * Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:
+ *
+ * this.start.row <= row <= this.end.row &&
+ * this.start.column <= column <= this.end.column
+ *
+ **/
+
this.contains = function(row, column) {
return this.compare(row, column) == 0;
};
- /**
- * Compares this range (A) with another range (B), where B is the passed in
- * range.
+ /** related to: Range.compare
+ * Range.compareRange(range) -> Number
+ * - range (Range): A range to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `-2`: (B) is in front of (A), and doesn't intersect with (A)
+ * * `-1`: (B) begins before (A) but ends inside of (A)
+ * * `0`: (B) is completely inside of (A) OR (A) is completely inside of (B)
+ * * `+1`: (B) begins inside of (A) but ends outside of (A)
+ * * `+2`: (B) is after (A) and doesn't intersect with (A)
+ * * `42`: FTW state: (B) ends in (A) but starts outside of (A)
+ *
+ * Compares `this` range (A) with another range (B).
*
- * Return values:
- * -2: (B) is infront of (A) and doesn't intersect with (A)
- * -1: (B) begins before (A) but ends inside of (A)
- * 0: (B) is completly inside of (A) OR (A) is complety inside of (B)
- * +1: (B) begins inside of (A) but ends outside of (A)
- * +2: (B) is after (A) and doesn't intersect with (A)
- *
- * 42: FTW state: (B) ends in (A) but starts outside of (A)
- */
+ **/
this.compareRange = function(range) {
var cmp,
end = range.end,
@@ -2154,27 +2410,86 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.comparePoint(p) -> Number
+ * - p (Range): A point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points of `p` with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.comparePoint = function(p) {
return this.compare(p.row, p.column);
}
+ /** related to: Range.comparePoint
+ * Range.containsRange(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
+ *
+ **/
this.containsRange = function(range) {
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
}
+ /**
+ * Range.intersects(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Returns `true` if passed in `range` intersects with the one calling this method.
+ *
+ **/
this.intersects = function(range) {
var cmp = this.compareRange(range);
return (cmp == -1 || cmp == 0 || cmp == 1);
}
+ /**
+ * Range.isEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's ending row point is the same as `row`, and if the caller's ending column is the same as `column`.
+ *
+ **/
this.isEnd = function(row, column) {
return this.end.row == row && this.end.column == column;
}
+ /**
+ * Range.isStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's starting row point is the same as `row`, and if the caller's starting column is the same as `column`.
+ *
+ **/
this.isStart = function(row, column) {
return this.start.row == row && this.start.column == column;
}
+ /**
+ * Range.setStart(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setStart = function(row, column) {
if (typeof row == "object") {
this.start.column = row.column;
@@ -2185,6 +2500,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.setEnd(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setEnd = function(row, column) {
if (typeof row == "object") {
this.end.column = row.column;
@@ -2195,6 +2518,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.inside(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range.
+ *
+ **/
this.inside = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column) || this.isStart(row, column)) {
@@ -2206,6 +2537,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's starting points.
+ *
+ **/
this.insideStart = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column)) {
@@ -2217,6 +2556,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's ending points.
+ *
+ **/
this.insideEnd = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isStart(row, column)) {
@@ -2228,6 +2575,27 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /**
+ * Range.compare(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compare = function(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
@@ -2251,8 +2619,28 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
/**
- * Like .compare(), but if isStart is true, return -1;
- */
+ * Range.compareStart(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isStart` is `true`.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareStart = function(row, column) {
if (this.start.row == row && this.start.column == column) {
return -1;
@@ -2262,8 +2650,26 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
/**
- * Like .compare(), but if isEnd is true, return 1;
- */
+ * Range.compareEnd(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isEnd` is `true.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compareEnd = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2272,6 +2678,21 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.compareInside(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`
+ * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`
+ *
+ * Otherwise, it returns the value after calling [[Range.compare `compare()`]].
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareInside = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2282,6 +2703,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.clipRows(firstRow, lastRow) -> Range
+ * - firstRow (Number): The starting row
+ * - lastRow (Number): The ending row
+ *
+ * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
+ *
+ **/
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
var end = {
@@ -2313,6 +2742,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
+ /**
+ * Range.extend(row, column) -> Range
+ * - row (Number): A new row to extend to
+ * - column (Number): A new column to extend to
+ *
+ * Changes the row and column points for the calling range for both the starting and ending points. This method returns that range with a new row.
+ *
+ **/
this.extend = function(row, column) {
var cmp = this.compare(row, column);
@@ -2326,33 +2763,36 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
- this.fixOrientation = function() {
- if (
- this.start.row < this.end.row
- || (this.start.row == this.end.row && this.start.column < this.end.column)
- ) {
- return false;
- }
-
- var temp = this.start;
- this.end = this.start;
- this.start = temp;
- return true;
- };
-
-
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
+ /**
+ * Range.isMultiLine() -> Boolean
+ *
+ * Returns true if the range spans across multiple lines.
+ *
+ **/
this.isMultiLine = function() {
return (this.start.row !== this.end.row);
};
+ /**
+ * Range.clone() -> Range
+ *
+ * Returns a duplicate of the calling range.
+ *
+ **/
this.clone = function() {
return Range.fromPoints(this.start, this.end);
};
+ /**
+ * Range.collapseRows() -> Range
+ *
+ * Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
+ *
+ **/
this.collapseRows = function() {
if (this.end.column == 0)
return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
@@ -2360,6 +2800,12 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return new Range(this.start.row, 0, this.end.row, 0)
};
+ /**
+ * Range.toScreenRange(session) -> Range
+ * - session (EditSession): The `EditSession` to retrieve coordinates from
+ *
+ * Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
+ **/
this.toScreenRange = function(session) {
var screenPosStart =
session.documentToScreenPosition(this.start);
@@ -2374,7 +2820,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}).call(Range.prototype);
-
+/**
+ * Range.fromPoints(start, end) -> Range
+ * - start (Range): A starting point to use
+ * - end (Range): An ending point to use
+ *
+ * Creates and returns a new `Range` based on the row and column of the given parameters.
+ *
+**/
Range.fromPoints = function(start, end) {
return new Range(start.row, start.column, end.row, end.column);
};
@@ -2425,9 +2878,22 @@ var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
/**
- * An Anchor is a floating pointer in the document. Whenever text is inserted or
- * deleted before the cursor, the position of the cursor is updated
- */
+ * class Anchor
+ *
+ * Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated
+ *
+ **/
+
+/**
+ * new Anchor(doc, row, column)
+ * - doc (Document): The document to associate with the anchor
+ * - row (Number): The starting row position
+ * - column (Number): The starting column position
+ *
+ * Creates a new `Anchor` and associates it with a document.
+ *
+ **/
+
var Anchor = exports.Anchor = function(doc, row, column) {
this.document = doc;
@@ -2444,14 +2910,36 @@ var Anchor = exports.Anchor = function(doc, row, column) {
oop.implement(this, EventEmitter);
+ /**
+ * Anchor.getPosition() -> Object
+ *
+ * Returns an object identifying the `row` and `column` position of the current anchor.
+ *
+ **/
+
this.getPosition = function() {
return this.$clipPositionToDocument(this.row, this.column);
};
-
+
+ /**
+ * Anchor.getDocument() -> Document
+ *
+ * Returns the current document.
+ *
+ **/
+
this.getDocument = function() {
return this.document;
};
+ /**
+ * Anchor@onChange(e)
+ * - e (Event): Contains data about the event
+ *
+ * Fires whenever the anchor position changes. Events that can trigger this function include `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ *
+ **/
+
this.onChange = function(e) {
var delta = e.data;
var range = delta.range;
@@ -2517,6 +3005,16 @@ var Anchor = exports.Anchor = function(doc, row, column) {
this.setPosition(row, column, true);
};
+ /**
+ * Anchor.setPosition(row, column, noClip)
+ * - row (Number): The row index to move the anchor to
+ * - column (Number): The column index to move the anchor to
+ * - noClip (Boolean): Identifies if you want the position to be clipped
+ *
+ * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.
+ *
+ **/
+
this.setPosition = function(row, column, noClip) {
var pos;
if (noClip) {
@@ -2545,10 +3043,26 @@ var Anchor = exports.Anchor = function(doc, row, column) {
});
};
+ /**
+ * Anchor.detach()
+ *
+ * When called, the `'change'` event listener is removed.
+ *
+ **/
+
this.detach = function() {
this.document.removeEventListener("change", this.$onChange);
};
+ /** internal, hide
+ * Anchor.clipPositionToDocument(row, column)
+ * - row (Number): The row index to clip the anchor to
+ * - column (Number): The column index to clip the anchor to
+ *
+ * Clips the anchor position to the specified row and column.
+ *
+ **/
+
this.$clipPositionToDocument = function(row, column) {
var pos = {};
@@ -2677,7 +3191,7 @@ exports.arrayToMap = function(arr) {
};
-/**
+/*
* splice out of 'array' anything that === 'value'
*/
exports.arrayRemove = function(array, value) {
@@ -2786,7 +3300,8 @@ define('ace/mode/coffee/coffee-script', ['require', 'exports', 'module' , 'ace/m
exports.parse = function(code) {
return parser.parse(lexer.tokenize(code));
};
-});/**
+});
+/*
* Copyright (c) 2011 Jeremy Ashkenas
*
* Permission is hereby granted, free of charge, to any person
@@ -3524,7 +4039,8 @@ define('ace/mode/coffee/lexer', ['require', 'exports', 'module' , 'ace/mode/coff
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
-});/**
+});
+/*
* Copyright (c) 2011 Jeremy Ashkenas
*
* Permission is hereby granted, free of charge, to any person
@@ -3865,7 +4381,8 @@ define('ace/mode/coffee/rewriter', ['require', 'exports', 'module' ], function(r
LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'];
-});/**
+});
+/*
* Copyright (c) 2011 Jeremy Ashkenas
*
* Permission is hereby granted, free of charge, to any person
@@ -3964,7 +4481,8 @@ define('ace/mode/coffee/helpers', ['require', 'exports', 'module' ], function(re
};
-});/**
+});
+/*
* Copyright (c) 2011 Jeremy Ashkenas
*
* Permission is hereby granted, free of charge, to any person
@@ -4566,7 +5084,8 @@ parse: function parse(input) {
module.exports = parser;
-});/**
+});
+/*
* Copyright (c) 2011 Jeremy Ashkenas
*
* Permission is hereby granted, free of charge, to any person
@@ -7321,7 +7840,8 @@ define('ace/mode/coffee/nodes', ['require', 'exports', 'module' , 'ace/mode/coff
};
-});/**
+});
+/*
* Copyright (c) 2011 Jeremy Ashkenas
*
* Permission is hereby granted, free of charge, to any person
@@ -7474,4 +7994,4 @@ define('ace/mode/coffee/scope', ['require', 'exports', 'module' , 'ace/mode/coff
})();
-});
\ No newline at end of file
+});
diff --git a/build/demo/kitchen-sink/worker-css.js b/build/demo/kitchen-sink/worker-css.js
index ed475ec5..a86bbcb0 100644
--- a/build/demo/kitchen-sink/worker-css.js
+++ b/build/demo/kitchen-sink/worker-css.js
@@ -154,7 +154,8 @@ define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/rege
require("./regexp");
require("./es5-shim");
-});/**
+});
+/*
* Based on code from:
*
* XRegExp 1.5.0
@@ -292,7 +293,7 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
-/**
+/*
* Brings an environment as close to ECMAScript 5 compliance
* as is possible with the facilities of erstwhile engines.
*
@@ -1322,7 +1323,8 @@ var prepareString = "a"[0] != "a",
}
return Object(o);
};
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -1399,7 +1401,7 @@ EventEmitter._dispatchEvent = function(eventName, e) {
}
if (defaultHandler && !e.defaultPrevented)
- defaultHandler(e);
+ return defaultHandler(e);
};
EventEmitter.setDefaultHandler = function(eventName, callback) {
@@ -1442,7 +1444,8 @@ EventEmitter.removeAllListeners = function(eventName) {
exports.EventEmitter = EventEmitter;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1568,7 +1571,8 @@ oop.inherits(Worker, Mirror);
}).call(Worker.prototype);
-});define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
+});
+define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
"use strict";
var Document = require("../document").Document;
@@ -1610,7 +1614,8 @@ var Mirror = exports.Mirror = function(sender) {
}).call(Mirror.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1655,6 +1660,21 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
var Anchor = require("./anchor").Anchor;
+/**
+ * class Document
+ *
+ * Contains the text of the document. Documents are controlled by a single [[EditSession `EditSession`]]. At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.
+ *
+ *
+ **/
+
+ /**
+ * new Document([text])
+ * - text (String | Array): The starting text
+ *
+ * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.
+ *
+ **/
var Document = function(text) {
this.$lines = [];
@@ -1674,20 +1694,48 @@ var Document = function(text) {
oop.implement(this, EventEmitter);
+ /**
+ * Document.setValue(text) -> Void
+ * - text (String): The text to use
+ *
+ * Replaces all the lines in the current `Document` with the value of `text`.
+ **/
this.setValue = function(text) {
var len = this.getLength();
this.remove(new Range(0, 0, len, this.getLine(len-1).length));
this.insert({row: 0, column:0}, text);
};
+ /**
+ * Document.getValue() -> String
+ *
+ * Returns all the lines in the document as a single string, split by the new line character.
+ **/
this.getValue = function() {
return this.getAllLines().join(this.getNewLineCharacter());
};
+ /**
+ * Document.createAnchor(row, column) -> Anchor
+ * - row (Number): The row number to use
+ * - column (Number): The column number to use
+ *
+ * Creates a new `Anchor` to define a floating point in the document.
+ **/
this.createAnchor = function(row, column) {
return new Anchor(this, row, column);
};
+ /** internal, hide
+ * Document.$split(text) -> [String]
+ * - text (String): The text to work with
+ * + ([String]): A String array, with each index containing a piece of the original `text` string.
+ *
+ * Splits a string of text on any newline (`\n`) or carriage-return ('\r') characters.
+ *
+ *
+ **/
+
// check for IE split bug
if ("aaa".split(/a/).length == 0)
this.$split = function(text) {
@@ -1699,6 +1747,11 @@ var Document = function(text) {
};
+ /** internal, hide
+ * Document.$detectNewLine(text) -> Void
+ *
+ *
+ **/
this.$detectNewLine = function(text) {
var match = text.match(/^.*?(\r\n|\r|\n)/m);
if (match) {
@@ -1708,6 +1761,17 @@ var Document = function(text) {
}
};
+ /**
+ * Document.getNewLineCharacter() -> String
+ * + (String): If `newLineMode == windows`, `\r\n` is returned.
+ * If `newLineMode == unix`, `\n` is returned.
+ * If `newLineMode == auto`, the value of `autoNewLine` is returned.
+ *
+ * Returns the newline character that's being used, depending on the value of `newLineMode`.
+ *
+ *
+ *
+ **/
this.getNewLineCharacter = function() {
switch (this.$newLineMode) {
case "windows":
@@ -1723,6 +1787,12 @@ var Document = function(text) {
this.$autoNewLine = "\n";
this.$newLineMode = "auto";
+ /**
+ * Document.setNewLineMode(newLineMode) -> Void
+ * - newLineMode(String): [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param}
+ *
+ * [Sets the new line mode.]{: #Document.setNewLineMode.desc}
+ **/
this.setNewLineMode = function(newLineMode) {
if (this.$newLineMode === newLineMode)
return;
@@ -1730,51 +1800,92 @@ var Document = function(text) {
this.$newLineMode = newLineMode;
};
+ /**
+ * Document.getNewLineMode() -> String
+ *
+ * [Returns the type of newlines being used; either `windows`, `unix`, or `auto`]{: #Document.getNewLineMode}
+ *
+ **/
this.getNewLineMode = function() {
return this.$newLineMode;
};
+ /**
+ * Document.isNewLine(text) -> Boolean
+ * - text (String): The text to check
+ *
+ * Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`).
+ *
+ **/
this.isNewLine = function(text) {
return (text == "\r\n" || text == "\r" || text == "\n");
};
/**
- * Get a verbatim copy of the given line as it is in the document
- */
+ * Document.getLine(row) -> String
+ * - row (Number): The row index to retrieve
+ *
+ * Returns a verbatim copy of the given line as it is in the document
+ *
+ **/
this.getLine = function(row) {
return this.$lines[row] || "";
};
+ /**
+ * Document.getLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row index to retrieve
+ * - lastRow (Number): The final row index to retrieve
+ *
+ * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
+ *
+ **/
this.getLines = function(firstRow, lastRow) {
return this.$lines.slice(firstRow, lastRow + 1);
};
/**
- * Returns all lines in the document as string array. Warning: The caller
- * should not modify this array!
- */
+ * Document.getAllLines() -> [String]
+ *
+ * Returns all lines in the document as string array. Warning: The caller should not modify this array!
+ **/
this.getAllLines = function() {
return this.getLines(0, this.getLength());
};
+ /**
+ * Document.getLength() -> Number
+ *
+ * Returns the number of rows in the document.
+ **/
this.getLength = function() {
return this.$lines.length;
};
+ /**
+ * Document.getTextRange(range) -> String
+ * - range (Range): The range to work with
+ *
+ * [Given a range within the document, this function returns all the text within that range as a single string.]{: #Document.getTextRange.desc}
+ **/
this.getTextRange = function(range) {
if (range.start.row == range.end.row) {
return this.$lines[range.start.row].substring(range.start.column,
range.end.column);
}
else {
- var lines = [];
- lines.push(this.$lines[range.start.row].substring(range.start.column));
- lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
- lines.push(this.$lines[range.end.row].substring(0, range.end.column));
+ var lines = this.getLines(range.start.row+1, range.end.row-1);
+ lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
+ lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
return lines.join(this.getNewLineCharacter());
}
};
+ /** internal, hide
+ * Document.$clipPosition(position) -> Number
+ *
+ *
+ **/
this.$clipPosition = function(position) {
var length = this.getLength();
if (position.row >= length) {
@@ -1784,6 +1895,15 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insert(position, text) -> Number
+ * - position (Number): The position to start inserting at
+ * - text (String): A chunk of text to insert
+ * + (Number): The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.
+ * Inserts a block of `text` and the indicated `position`.
+ *
+ *
+ **/
this.insert = function(position, text) {
if (!text || text.length === 0)
return position;
@@ -1807,6 +1927,19 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insertLines(row, lines) -> Object
+ * - row (Number): The index of the row to insert at
+ * - lines (Array): An array of strings
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * If `lines` is empty, this function returns an object containing the current row, and column, like this:
+ * ```{row: row, column: 0}```
+ *
+ * Inserts the elements in `lines` into the document, starting at the row index given by `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.insertLines = function(row, lines) {
if (lines.length == 0)
return {row: row, column: 0};
@@ -1825,6 +1958,17 @@ var Document = function(text) {
return range.end;
};
+ /**
+ * Document.insertNewLine(position) -> Object
+ * - position (String): The position to insert at
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ *
+ * Inserts a new line into the document at the current row's `position`. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertNewLine = function(position) {
position = this.$clipPosition(position);
var line = this.$lines[position.row] || "";
@@ -1847,6 +1991,19 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.insertInLine(position, text) -> Object | Number
+ * - position (Number): The position to insert at
+ * - text (String): A chunk of text
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * + (Number): If `text` is empty, this function returns the value of `position`
+ *
+ * Inserts `text` into the `position` at the current row. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertInLine = function(position, text) {
if (text.length == 0)
return position;
@@ -1871,6 +2028,15 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.remove(range) -> Object
+ * - range (Range): A specified Range to remove
+ * + (Object): Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
+ *
+ * Removes the `range` from the document.
+ *
+ *
+ **/
this.remove = function(range) {
// clip to document
range.start = this.$clipPosition(range.start);
@@ -1903,6 +2069,17 @@ var Document = function(text) {
return range.start;
};
+ /**
+ * Document.removeInLine(row, startColumn, endColumn) -> Object
+ * - row (Number): The row to remove from
+ * - startColumn (Number): The column to start removing at
+ * - endColumn (Number): The column to stop removing at
+ * + (Object): Returns an object containing `startRow` and `startColumn`, indicating the new row and column values. If `startColumn` is equal to `endColumn`, this function returns nothing.
+ *
+ * Removes the specified columns from the `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeInLine = function(row, startColumn, endColumn) {
if (startColumn == endColumn)
return;
@@ -1923,12 +2100,15 @@ var Document = function(text) {
};
/**
- * Removes a range of full lines
- *
- * @param firstRow {Integer} The first row to be removed
- * @param lastRow {Integer} The last row to be removed
- * @return {String[]} The removed lines
- */
+ * Document.removeLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row to be removed
+ * - lastRow (Number): The last row to be removed
+ * + ([String]): Returns all the removed lines.
+ *
+ * Removes a range of full lines. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeLines = function(firstRow, lastRow) {
var range = new Range(firstRow, 0, lastRow + 1, 0);
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
@@ -1943,6 +2123,13 @@ var Document = function(text) {
return removed;
};
+ /**
+ * Document.removeNewLine(row) -> Void
+ * - row (Number): The row to check
+ *
+ * Removes the new line between `row` and the row immediately following it. This method also triggers the `'change'` event.
+ *
+ **/
this.removeNewLine = function(row) {
var firstLine = this.getLine(row);
var secondLine = this.getLine(row+1);
@@ -1960,6 +2147,18 @@ var Document = function(text) {
this._emit("change", { data: delta });
};
+ /**
+ * Document.replace(range, text) -> Object
+ * - range (Range): A specified Range to replace
+ * - text (String): The new text to use as a replacement
+ * + (Object): Returns an object containing the final row and column, like this:
+ * {row: endRow, column: 0}
+ * If the text and range are empty, this function returns an object containing the current `range.start` value.
+ * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
+ *
+ * Replaces a range in the document with the new `text`.
+ *
+ **/
this.replace = function(range, text) {
if (text.length == 0 && range.isEmpty())
return range.start;
@@ -1980,6 +2179,11 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.applyDeltas(deltas) -> Void
+ *
+ * Applies all the changes previously accumulated. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.applyDeltas = function(deltas) {
for (var i=0; i Void
+ *
+ * Reverts any changes previously applied. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.revertDeltas = function(deltas) {
for (var i=deltas.length-1; i>=0; i--) {
var delta = deltas[i];
@@ -2057,6 +2266,23 @@ exports.Document = Document;
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class Range
+ *
+ * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
+ *
+ **/
+
+/**
+ * new Range(startRow, startColumn, endRow, endColumn)
+ * - startRow (Number): The starting row
+ * - startColumn (Number): The starting column
+ * - endRow (Number): The ending row
+ * - endColumn (Number): The ending column
+ *
+ * Creates a new `Range` object with the given starting and ending row and column points.
+ *
+ **/
var Range = function(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
@@ -2070,6 +2296,13 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
(function() {
+ /**
+ * Range.isEqual(range) -> Boolean
+ * - range (Range): A range to check against
+ *
+ * Returns `true` if and only if the starting row and column, and ending tow and column, are equivalent to those given by `range`.
+ *
+ **/
this.isEqual = function(range) {
return this.start.row == range.start.row &&
this.end.row == range.end.row &&
@@ -2077,28 +2310,51 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
this.end.column == range.end.column
};
+ /**
+ * Range.toString() -> String
+ *
+ * Returns a string containing the range's row and column information, given like this:
+ *
+ * [start.row/start.column] -> [end.row/end.column]
+ *
+ **/
+
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
};
+ /** related to: Range.compare
+ * Range.contains(row, column) -> Boolean
+ * - row (Number): A row to check for
+ * - column (Number): A column to check for
+ *
+ * Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:
+ *
+ * this.start.row <= row <= this.end.row &&
+ * this.start.column <= column <= this.end.column
+ *
+ **/
+
this.contains = function(row, column) {
return this.compare(row, column) == 0;
};
- /**
- * Compares this range (A) with another range (B), where B is the passed in
- * range.
+ /** related to: Range.compare
+ * Range.compareRange(range) -> Number
+ * - range (Range): A range to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `-2`: (B) is in front of (A), and doesn't intersect with (A)
+ * * `-1`: (B) begins before (A) but ends inside of (A)
+ * * `0`: (B) is completely inside of (A) OR (A) is completely inside of (B)
+ * * `+1`: (B) begins inside of (A) but ends outside of (A)
+ * * `+2`: (B) is after (A) and doesn't intersect with (A)
+ * * `42`: FTW state: (B) ends in (A) but starts outside of (A)
+ *
+ * Compares `this` range (A) with another range (B).
*
- * Return values:
- * -2: (B) is infront of (A) and doesn't intersect with (A)
- * -1: (B) begins before (A) but ends inside of (A)
- * 0: (B) is completly inside of (A) OR (A) is complety inside of (B)
- * +1: (B) begins inside of (A) but ends outside of (A)
- * +2: (B) is after (A) and doesn't intersect with (A)
- *
- * 42: FTW state: (B) ends in (A) but starts outside of (A)
- */
+ **/
this.compareRange = function(range) {
var cmp,
end = range.end,
@@ -2128,27 +2384,86 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.comparePoint(p) -> Number
+ * - p (Range): A point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points of `p` with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.comparePoint = function(p) {
return this.compare(p.row, p.column);
}
+ /** related to: Range.comparePoint
+ * Range.containsRange(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
+ *
+ **/
this.containsRange = function(range) {
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
}
+ /**
+ * Range.intersects(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Returns `true` if passed in `range` intersects with the one calling this method.
+ *
+ **/
this.intersects = function(range) {
var cmp = this.compareRange(range);
return (cmp == -1 || cmp == 0 || cmp == 1);
}
+ /**
+ * Range.isEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's ending row point is the same as `row`, and if the caller's ending column is the same as `column`.
+ *
+ **/
this.isEnd = function(row, column) {
return this.end.row == row && this.end.column == column;
}
+ /**
+ * Range.isStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's starting row point is the same as `row`, and if the caller's starting column is the same as `column`.
+ *
+ **/
this.isStart = function(row, column) {
return this.start.row == row && this.start.column == column;
}
+ /**
+ * Range.setStart(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setStart = function(row, column) {
if (typeof row == "object") {
this.start.column = row.column;
@@ -2159,6 +2474,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.setEnd(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setEnd = function(row, column) {
if (typeof row == "object") {
this.end.column = row.column;
@@ -2169,6 +2492,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.inside(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range.
+ *
+ **/
this.inside = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column) || this.isStart(row, column)) {
@@ -2180,6 +2511,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's starting points.
+ *
+ **/
this.insideStart = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column)) {
@@ -2191,6 +2530,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's ending points.
+ *
+ **/
this.insideEnd = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isStart(row, column)) {
@@ -2202,6 +2549,27 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /**
+ * Range.compare(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compare = function(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
@@ -2225,8 +2593,28 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
/**
- * Like .compare(), but if isStart is true, return -1;
- */
+ * Range.compareStart(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isStart` is `true`.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareStart = function(row, column) {
if (this.start.row == row && this.start.column == column) {
return -1;
@@ -2236,8 +2624,26 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
/**
- * Like .compare(), but if isEnd is true, return 1;
- */
+ * Range.compareEnd(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isEnd` is `true.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compareEnd = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2246,6 +2652,21 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.compareInside(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`
+ * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`
+ *
+ * Otherwise, it returns the value after calling [[Range.compare `compare()`]].
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareInside = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2256,6 +2677,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.clipRows(firstRow, lastRow) -> Range
+ * - firstRow (Number): The starting row
+ * - lastRow (Number): The ending row
+ *
+ * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
+ *
+ **/
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
var end = {
@@ -2287,6 +2716,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
+ /**
+ * Range.extend(row, column) -> Range
+ * - row (Number): A new row to extend to
+ * - column (Number): A new column to extend to
+ *
+ * Changes the row and column points for the calling range for both the starting and ending points. This method returns that range with a new row.
+ *
+ **/
this.extend = function(row, column) {
var cmp = this.compare(row, column);
@@ -2300,33 +2737,36 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
- this.fixOrientation = function() {
- if (
- this.start.row < this.end.row
- || (this.start.row == this.end.row && this.start.column < this.end.column)
- ) {
- return false;
- }
-
- var temp = this.start;
- this.end = this.start;
- this.start = temp;
- return true;
- };
-
-
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
+ /**
+ * Range.isMultiLine() -> Boolean
+ *
+ * Returns true if the range spans across multiple lines.
+ *
+ **/
this.isMultiLine = function() {
return (this.start.row !== this.end.row);
};
+ /**
+ * Range.clone() -> Range
+ *
+ * Returns a duplicate of the calling range.
+ *
+ **/
this.clone = function() {
return Range.fromPoints(this.start, this.end);
};
+ /**
+ * Range.collapseRows() -> Range
+ *
+ * Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
+ *
+ **/
this.collapseRows = function() {
if (this.end.column == 0)
return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
@@ -2334,6 +2774,12 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return new Range(this.start.row, 0, this.end.row, 0)
};
+ /**
+ * Range.toScreenRange(session) -> Range
+ * - session (EditSession): The `EditSession` to retrieve coordinates from
+ *
+ * Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
+ **/
this.toScreenRange = function(session) {
var screenPosStart =
session.documentToScreenPosition(this.start);
@@ -2348,7 +2794,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}).call(Range.prototype);
-
+/**
+ * Range.fromPoints(start, end) -> Range
+ * - start (Range): A starting point to use
+ * - end (Range): An ending point to use
+ *
+ * Creates and returns a new `Range` based on the row and column of the given parameters.
+ *
+**/
Range.fromPoints = function(start, end) {
return new Range(start.row, start.column, end.row, end.column);
};
@@ -2399,9 +2852,22 @@ var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
/**
- * An Anchor is a floating pointer in the document. Whenever text is inserted or
- * deleted before the cursor, the position of the cursor is updated
- */
+ * class Anchor
+ *
+ * Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated
+ *
+ **/
+
+/**
+ * new Anchor(doc, row, column)
+ * - doc (Document): The document to associate with the anchor
+ * - row (Number): The starting row position
+ * - column (Number): The starting column position
+ *
+ * Creates a new `Anchor` and associates it with a document.
+ *
+ **/
+
var Anchor = exports.Anchor = function(doc, row, column) {
this.document = doc;
@@ -2418,14 +2884,36 @@ var Anchor = exports.Anchor = function(doc, row, column) {
oop.implement(this, EventEmitter);
+ /**
+ * Anchor.getPosition() -> Object
+ *
+ * Returns an object identifying the `row` and `column` position of the current anchor.
+ *
+ **/
+
this.getPosition = function() {
return this.$clipPositionToDocument(this.row, this.column);
};
-
+
+ /**
+ * Anchor.getDocument() -> Document
+ *
+ * Returns the current document.
+ *
+ **/
+
this.getDocument = function() {
return this.document;
};
+ /**
+ * Anchor@onChange(e)
+ * - e (Event): Contains data about the event
+ *
+ * Fires whenever the anchor position changes. Events that can trigger this function include `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ *
+ **/
+
this.onChange = function(e) {
var delta = e.data;
var range = delta.range;
@@ -2491,6 +2979,16 @@ var Anchor = exports.Anchor = function(doc, row, column) {
this.setPosition(row, column, true);
};
+ /**
+ * Anchor.setPosition(row, column, noClip)
+ * - row (Number): The row index to move the anchor to
+ * - column (Number): The column index to move the anchor to
+ * - noClip (Boolean): Identifies if you want the position to be clipped
+ *
+ * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.
+ *
+ **/
+
this.setPosition = function(row, column, noClip) {
var pos;
if (noClip) {
@@ -2519,10 +3017,26 @@ var Anchor = exports.Anchor = function(doc, row, column) {
});
};
+ /**
+ * Anchor.detach()
+ *
+ * When called, the `'change'` event listener is removed.
+ *
+ **/
+
this.detach = function() {
this.document.removeEventListener("change", this.$onChange);
};
+ /** internal, hide
+ * Anchor.clipPositionToDocument(row, column)
+ * - row (Number): The row index to clip the anchor to
+ * - column (Number): The column index to clip the anchor to
+ *
+ * Clips the anchor position to the specified row and column.
+ *
+ **/
+
this.$clipPositionToDocument = function(row, column) {
var pos = {};
@@ -2651,7 +3165,7 @@ exports.arrayToMap = function(arr) {
};
-/**
+/*
* splice out of 'array' anything that === 'value'
*/
exports.arrayRemove = function(array, value) {
diff --git a/build/demo/kitchen-sink/worker-javascript.js b/build/demo/kitchen-sink/worker-javascript.js
index 236565a2..bd77cc7f 100644
--- a/build/demo/kitchen-sink/worker-javascript.js
+++ b/build/demo/kitchen-sink/worker-javascript.js
@@ -154,7 +154,8 @@ define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/rege
require("./regexp");
require("./es5-shim");
-});/**
+});
+/*
* Based on code from:
*
* XRegExp 1.5.0
@@ -292,7 +293,7 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
-/**
+/*
* Brings an environment as close to ECMAScript 5 compliance
* as is possible with the facilities of erstwhile engines.
*
@@ -1322,7 +1323,8 @@ var prepareString = "a"[0] != "a",
}
return Object(o);
};
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -1399,7 +1401,7 @@ EventEmitter._dispatchEvent = function(eventName, e) {
}
if (defaultHandler && !e.defaultPrevented)
- defaultHandler(e);
+ return defaultHandler(e);
};
EventEmitter.setDefaultHandler = function(eventName, callback) {
@@ -1442,7 +1444,8 @@ EventEmitter.removeAllListeners = function(eventName) {
exports.EventEmitter = EventEmitter;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1590,7 +1593,8 @@ oop.inherits(JavaScriptWorker, Mirror);
}).call(JavaScriptWorker.prototype);
-});define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
+});
+define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
"use strict";
var Document = require("../document").Document;
@@ -1632,7 +1636,8 @@ var Mirror = exports.Mirror = function(sender) {
}).call(Mirror.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1677,6 +1682,21 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
var Anchor = require("./anchor").Anchor;
+/**
+ * class Document
+ *
+ * Contains the text of the document. Documents are controlled by a single [[EditSession `EditSession`]]. At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.
+ *
+ *
+ **/
+
+ /**
+ * new Document([text])
+ * - text (String | Array): The starting text
+ *
+ * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.
+ *
+ **/
var Document = function(text) {
this.$lines = [];
@@ -1696,20 +1716,48 @@ var Document = function(text) {
oop.implement(this, EventEmitter);
+ /**
+ * Document.setValue(text) -> Void
+ * - text (String): The text to use
+ *
+ * Replaces all the lines in the current `Document` with the value of `text`.
+ **/
this.setValue = function(text) {
var len = this.getLength();
this.remove(new Range(0, 0, len, this.getLine(len-1).length));
this.insert({row: 0, column:0}, text);
};
+ /**
+ * Document.getValue() -> String
+ *
+ * Returns all the lines in the document as a single string, split by the new line character.
+ **/
this.getValue = function() {
return this.getAllLines().join(this.getNewLineCharacter());
};
+ /**
+ * Document.createAnchor(row, column) -> Anchor
+ * - row (Number): The row number to use
+ * - column (Number): The column number to use
+ *
+ * Creates a new `Anchor` to define a floating point in the document.
+ **/
this.createAnchor = function(row, column) {
return new Anchor(this, row, column);
};
+ /** internal, hide
+ * Document.$split(text) -> [String]
+ * - text (String): The text to work with
+ * + ([String]): A String array, with each index containing a piece of the original `text` string.
+ *
+ * Splits a string of text on any newline (`\n`) or carriage-return ('\r') characters.
+ *
+ *
+ **/
+
// check for IE split bug
if ("aaa".split(/a/).length == 0)
this.$split = function(text) {
@@ -1721,6 +1769,11 @@ var Document = function(text) {
};
+ /** internal, hide
+ * Document.$detectNewLine(text) -> Void
+ *
+ *
+ **/
this.$detectNewLine = function(text) {
var match = text.match(/^.*?(\r\n|\r|\n)/m);
if (match) {
@@ -1730,6 +1783,17 @@ var Document = function(text) {
}
};
+ /**
+ * Document.getNewLineCharacter() -> String
+ * + (String): If `newLineMode == windows`, `\r\n` is returned.
+ * If `newLineMode == unix`, `\n` is returned.
+ * If `newLineMode == auto`, the value of `autoNewLine` is returned.
+ *
+ * Returns the newline character that's being used, depending on the value of `newLineMode`.
+ *
+ *
+ *
+ **/
this.getNewLineCharacter = function() {
switch (this.$newLineMode) {
case "windows":
@@ -1745,6 +1809,12 @@ var Document = function(text) {
this.$autoNewLine = "\n";
this.$newLineMode = "auto";
+ /**
+ * Document.setNewLineMode(newLineMode) -> Void
+ * - newLineMode(String): [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param}
+ *
+ * [Sets the new line mode.]{: #Document.setNewLineMode.desc}
+ **/
this.setNewLineMode = function(newLineMode) {
if (this.$newLineMode === newLineMode)
return;
@@ -1752,51 +1822,92 @@ var Document = function(text) {
this.$newLineMode = newLineMode;
};
+ /**
+ * Document.getNewLineMode() -> String
+ *
+ * [Returns the type of newlines being used; either `windows`, `unix`, or `auto`]{: #Document.getNewLineMode}
+ *
+ **/
this.getNewLineMode = function() {
return this.$newLineMode;
};
+ /**
+ * Document.isNewLine(text) -> Boolean
+ * - text (String): The text to check
+ *
+ * Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`).
+ *
+ **/
this.isNewLine = function(text) {
return (text == "\r\n" || text == "\r" || text == "\n");
};
/**
- * Get a verbatim copy of the given line as it is in the document
- */
+ * Document.getLine(row) -> String
+ * - row (Number): The row index to retrieve
+ *
+ * Returns a verbatim copy of the given line as it is in the document
+ *
+ **/
this.getLine = function(row) {
return this.$lines[row] || "";
};
+ /**
+ * Document.getLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row index to retrieve
+ * - lastRow (Number): The final row index to retrieve
+ *
+ * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
+ *
+ **/
this.getLines = function(firstRow, lastRow) {
return this.$lines.slice(firstRow, lastRow + 1);
};
/**
- * Returns all lines in the document as string array. Warning: The caller
- * should not modify this array!
- */
+ * Document.getAllLines() -> [String]
+ *
+ * Returns all lines in the document as string array. Warning: The caller should not modify this array!
+ **/
this.getAllLines = function() {
return this.getLines(0, this.getLength());
};
+ /**
+ * Document.getLength() -> Number
+ *
+ * Returns the number of rows in the document.
+ **/
this.getLength = function() {
return this.$lines.length;
};
+ /**
+ * Document.getTextRange(range) -> String
+ * - range (Range): The range to work with
+ *
+ * [Given a range within the document, this function returns all the text within that range as a single string.]{: #Document.getTextRange.desc}
+ **/
this.getTextRange = function(range) {
if (range.start.row == range.end.row) {
return this.$lines[range.start.row].substring(range.start.column,
range.end.column);
}
else {
- var lines = [];
- lines.push(this.$lines[range.start.row].substring(range.start.column));
- lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
- lines.push(this.$lines[range.end.row].substring(0, range.end.column));
+ var lines = this.getLines(range.start.row+1, range.end.row-1);
+ lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
+ lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
return lines.join(this.getNewLineCharacter());
}
};
+ /** internal, hide
+ * Document.$clipPosition(position) -> Number
+ *
+ *
+ **/
this.$clipPosition = function(position) {
var length = this.getLength();
if (position.row >= length) {
@@ -1806,6 +1917,15 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insert(position, text) -> Number
+ * - position (Number): The position to start inserting at
+ * - text (String): A chunk of text to insert
+ * + (Number): The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.
+ * Inserts a block of `text` and the indicated `position`.
+ *
+ *
+ **/
this.insert = function(position, text) {
if (!text || text.length === 0)
return position;
@@ -1829,6 +1949,19 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insertLines(row, lines) -> Object
+ * - row (Number): The index of the row to insert at
+ * - lines (Array): An array of strings
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * If `lines` is empty, this function returns an object containing the current row, and column, like this:
+ * ```{row: row, column: 0}```
+ *
+ * Inserts the elements in `lines` into the document, starting at the row index given by `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.insertLines = function(row, lines) {
if (lines.length == 0)
return {row: row, column: 0};
@@ -1847,6 +1980,17 @@ var Document = function(text) {
return range.end;
};
+ /**
+ * Document.insertNewLine(position) -> Object
+ * - position (String): The position to insert at
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ *
+ * Inserts a new line into the document at the current row's `position`. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertNewLine = function(position) {
position = this.$clipPosition(position);
var line = this.$lines[position.row] || "";
@@ -1869,6 +2013,19 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.insertInLine(position, text) -> Object | Number
+ * - position (Number): The position to insert at
+ * - text (String): A chunk of text
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * + (Number): If `text` is empty, this function returns the value of `position`
+ *
+ * Inserts `text` into the `position` at the current row. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertInLine = function(position, text) {
if (text.length == 0)
return position;
@@ -1893,6 +2050,15 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.remove(range) -> Object
+ * - range (Range): A specified Range to remove
+ * + (Object): Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
+ *
+ * Removes the `range` from the document.
+ *
+ *
+ **/
this.remove = function(range) {
// clip to document
range.start = this.$clipPosition(range.start);
@@ -1925,6 +2091,17 @@ var Document = function(text) {
return range.start;
};
+ /**
+ * Document.removeInLine(row, startColumn, endColumn) -> Object
+ * - row (Number): The row to remove from
+ * - startColumn (Number): The column to start removing at
+ * - endColumn (Number): The column to stop removing at
+ * + (Object): Returns an object containing `startRow` and `startColumn`, indicating the new row and column values. If `startColumn` is equal to `endColumn`, this function returns nothing.
+ *
+ * Removes the specified columns from the `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeInLine = function(row, startColumn, endColumn) {
if (startColumn == endColumn)
return;
@@ -1945,12 +2122,15 @@ var Document = function(text) {
};
/**
- * Removes a range of full lines
- *
- * @param firstRow {Integer} The first row to be removed
- * @param lastRow {Integer} The last row to be removed
- * @return {String[]} The removed lines
- */
+ * Document.removeLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row to be removed
+ * - lastRow (Number): The last row to be removed
+ * + ([String]): Returns all the removed lines.
+ *
+ * Removes a range of full lines. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeLines = function(firstRow, lastRow) {
var range = new Range(firstRow, 0, lastRow + 1, 0);
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
@@ -1965,6 +2145,13 @@ var Document = function(text) {
return removed;
};
+ /**
+ * Document.removeNewLine(row) -> Void
+ * - row (Number): The row to check
+ *
+ * Removes the new line between `row` and the row immediately following it. This method also triggers the `'change'` event.
+ *
+ **/
this.removeNewLine = function(row) {
var firstLine = this.getLine(row);
var secondLine = this.getLine(row+1);
@@ -1982,6 +2169,18 @@ var Document = function(text) {
this._emit("change", { data: delta });
};
+ /**
+ * Document.replace(range, text) -> Object
+ * - range (Range): A specified Range to replace
+ * - text (String): The new text to use as a replacement
+ * + (Object): Returns an object containing the final row and column, like this:
+ * {row: endRow, column: 0}
+ * If the text and range are empty, this function returns an object containing the current `range.start` value.
+ * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
+ *
+ * Replaces a range in the document with the new `text`.
+ *
+ **/
this.replace = function(range, text) {
if (text.length == 0 && range.isEmpty())
return range.start;
@@ -2002,6 +2201,11 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.applyDeltas(deltas) -> Void
+ *
+ * Applies all the changes previously accumulated. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.applyDeltas = function(deltas) {
for (var i=0; i Void
+ *
+ * Reverts any changes previously applied. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.revertDeltas = function(deltas) {
for (var i=deltas.length-1; i>=0; i--) {
var delta = deltas[i];
@@ -2079,6 +2288,23 @@ exports.Document = Document;
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class Range
+ *
+ * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
+ *
+ **/
+
+/**
+ * new Range(startRow, startColumn, endRow, endColumn)
+ * - startRow (Number): The starting row
+ * - startColumn (Number): The starting column
+ * - endRow (Number): The ending row
+ * - endColumn (Number): The ending column
+ *
+ * Creates a new `Range` object with the given starting and ending row and column points.
+ *
+ **/
var Range = function(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
@@ -2092,6 +2318,13 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
(function() {
+ /**
+ * Range.isEqual(range) -> Boolean
+ * - range (Range): A range to check against
+ *
+ * Returns `true` if and only if the starting row and column, and ending tow and column, are equivalent to those given by `range`.
+ *
+ **/
this.isEqual = function(range) {
return this.start.row == range.start.row &&
this.end.row == range.end.row &&
@@ -2099,28 +2332,51 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
this.end.column == range.end.column
};
+ /**
+ * Range.toString() -> String
+ *
+ * Returns a string containing the range's row and column information, given like this:
+ *
+ * [start.row/start.column] -> [end.row/end.column]
+ *
+ **/
+
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
};
+ /** related to: Range.compare
+ * Range.contains(row, column) -> Boolean
+ * - row (Number): A row to check for
+ * - column (Number): A column to check for
+ *
+ * Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:
+ *
+ * this.start.row <= row <= this.end.row &&
+ * this.start.column <= column <= this.end.column
+ *
+ **/
+
this.contains = function(row, column) {
return this.compare(row, column) == 0;
};
- /**
- * Compares this range (A) with another range (B), where B is the passed in
- * range.
+ /** related to: Range.compare
+ * Range.compareRange(range) -> Number
+ * - range (Range): A range to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `-2`: (B) is in front of (A), and doesn't intersect with (A)
+ * * `-1`: (B) begins before (A) but ends inside of (A)
+ * * `0`: (B) is completely inside of (A) OR (A) is completely inside of (B)
+ * * `+1`: (B) begins inside of (A) but ends outside of (A)
+ * * `+2`: (B) is after (A) and doesn't intersect with (A)
+ * * `42`: FTW state: (B) ends in (A) but starts outside of (A)
+ *
+ * Compares `this` range (A) with another range (B).
*
- * Return values:
- * -2: (B) is infront of (A) and doesn't intersect with (A)
- * -1: (B) begins before (A) but ends inside of (A)
- * 0: (B) is completly inside of (A) OR (A) is complety inside of (B)
- * +1: (B) begins inside of (A) but ends outside of (A)
- * +2: (B) is after (A) and doesn't intersect with (A)
- *
- * 42: FTW state: (B) ends in (A) but starts outside of (A)
- */
+ **/
this.compareRange = function(range) {
var cmp,
end = range.end,
@@ -2150,27 +2406,86 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.comparePoint(p) -> Number
+ * - p (Range): A point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points of `p` with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.comparePoint = function(p) {
return this.compare(p.row, p.column);
}
+ /** related to: Range.comparePoint
+ * Range.containsRange(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
+ *
+ **/
this.containsRange = function(range) {
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
}
+ /**
+ * Range.intersects(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Returns `true` if passed in `range` intersects with the one calling this method.
+ *
+ **/
this.intersects = function(range) {
var cmp = this.compareRange(range);
return (cmp == -1 || cmp == 0 || cmp == 1);
}
+ /**
+ * Range.isEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's ending row point is the same as `row`, and if the caller's ending column is the same as `column`.
+ *
+ **/
this.isEnd = function(row, column) {
return this.end.row == row && this.end.column == column;
}
+ /**
+ * Range.isStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's starting row point is the same as `row`, and if the caller's starting column is the same as `column`.
+ *
+ **/
this.isStart = function(row, column) {
return this.start.row == row && this.start.column == column;
}
+ /**
+ * Range.setStart(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setStart = function(row, column) {
if (typeof row == "object") {
this.start.column = row.column;
@@ -2181,6 +2496,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.setEnd(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setEnd = function(row, column) {
if (typeof row == "object") {
this.end.column = row.column;
@@ -2191,6 +2514,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.inside(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range.
+ *
+ **/
this.inside = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column) || this.isStart(row, column)) {
@@ -2202,6 +2533,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's starting points.
+ *
+ **/
this.insideStart = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column)) {
@@ -2213,6 +2552,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's ending points.
+ *
+ **/
this.insideEnd = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isStart(row, column)) {
@@ -2224,6 +2571,27 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /**
+ * Range.compare(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compare = function(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
@@ -2247,8 +2615,28 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
/**
- * Like .compare(), but if isStart is true, return -1;
- */
+ * Range.compareStart(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isStart` is `true`.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareStart = function(row, column) {
if (this.start.row == row && this.start.column == column) {
return -1;
@@ -2258,8 +2646,26 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
/**
- * Like .compare(), but if isEnd is true, return 1;
- */
+ * Range.compareEnd(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isEnd` is `true.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compareEnd = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2268,6 +2674,21 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.compareInside(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`
+ * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`
+ *
+ * Otherwise, it returns the value after calling [[Range.compare `compare()`]].
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareInside = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2278,6 +2699,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.clipRows(firstRow, lastRow) -> Range
+ * - firstRow (Number): The starting row
+ * - lastRow (Number): The ending row
+ *
+ * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
+ *
+ **/
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
var end = {
@@ -2309,6 +2738,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
+ /**
+ * Range.extend(row, column) -> Range
+ * - row (Number): A new row to extend to
+ * - column (Number): A new column to extend to
+ *
+ * Changes the row and column points for the calling range for both the starting and ending points. This method returns that range with a new row.
+ *
+ **/
this.extend = function(row, column) {
var cmp = this.compare(row, column);
@@ -2322,33 +2759,36 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
- this.fixOrientation = function() {
- if (
- this.start.row < this.end.row
- || (this.start.row == this.end.row && this.start.column < this.end.column)
- ) {
- return false;
- }
-
- var temp = this.start;
- this.end = this.start;
- this.start = temp;
- return true;
- };
-
-
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
+ /**
+ * Range.isMultiLine() -> Boolean
+ *
+ * Returns true if the range spans across multiple lines.
+ *
+ **/
this.isMultiLine = function() {
return (this.start.row !== this.end.row);
};
+ /**
+ * Range.clone() -> Range
+ *
+ * Returns a duplicate of the calling range.
+ *
+ **/
this.clone = function() {
return Range.fromPoints(this.start, this.end);
};
+ /**
+ * Range.collapseRows() -> Range
+ *
+ * Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
+ *
+ **/
this.collapseRows = function() {
if (this.end.column == 0)
return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
@@ -2356,6 +2796,12 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return new Range(this.start.row, 0, this.end.row, 0)
};
+ /**
+ * Range.toScreenRange(session) -> Range
+ * - session (EditSession): The `EditSession` to retrieve coordinates from
+ *
+ * Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
+ **/
this.toScreenRange = function(session) {
var screenPosStart =
session.documentToScreenPosition(this.start);
@@ -2370,7 +2816,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}).call(Range.prototype);
-
+/**
+ * Range.fromPoints(start, end) -> Range
+ * - start (Range): A starting point to use
+ * - end (Range): An ending point to use
+ *
+ * Creates and returns a new `Range` based on the row and column of the given parameters.
+ *
+**/
Range.fromPoints = function(start, end) {
return new Range(start.row, start.column, end.row, end.column);
};
@@ -2421,9 +2874,22 @@ var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
/**
- * An Anchor is a floating pointer in the document. Whenever text is inserted or
- * deleted before the cursor, the position of the cursor is updated
- */
+ * class Anchor
+ *
+ * Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated
+ *
+ **/
+
+/**
+ * new Anchor(doc, row, column)
+ * - doc (Document): The document to associate with the anchor
+ * - row (Number): The starting row position
+ * - column (Number): The starting column position
+ *
+ * Creates a new `Anchor` and associates it with a document.
+ *
+ **/
+
var Anchor = exports.Anchor = function(doc, row, column) {
this.document = doc;
@@ -2440,14 +2906,36 @@ var Anchor = exports.Anchor = function(doc, row, column) {
oop.implement(this, EventEmitter);
+ /**
+ * Anchor.getPosition() -> Object
+ *
+ * Returns an object identifying the `row` and `column` position of the current anchor.
+ *
+ **/
+
this.getPosition = function() {
return this.$clipPositionToDocument(this.row, this.column);
};
-
+
+ /**
+ * Anchor.getDocument() -> Document
+ *
+ * Returns the current document.
+ *
+ **/
+
this.getDocument = function() {
return this.document;
};
+ /**
+ * Anchor@onChange(e)
+ * - e (Event): Contains data about the event
+ *
+ * Fires whenever the anchor position changes. Events that can trigger this function include `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ *
+ **/
+
this.onChange = function(e) {
var delta = e.data;
var range = delta.range;
@@ -2513,6 +3001,16 @@ var Anchor = exports.Anchor = function(doc, row, column) {
this.setPosition(row, column, true);
};
+ /**
+ * Anchor.setPosition(row, column, noClip)
+ * - row (Number): The row index to move the anchor to
+ * - column (Number): The column index to move the anchor to
+ * - noClip (Boolean): Identifies if you want the position to be clipped
+ *
+ * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.
+ *
+ **/
+
this.setPosition = function(row, column, noClip) {
var pos;
if (noClip) {
@@ -2541,10 +3039,26 @@ var Anchor = exports.Anchor = function(doc, row, column) {
});
};
+ /**
+ * Anchor.detach()
+ *
+ * When called, the `'change'` event listener is removed.
+ *
+ **/
+
this.detach = function() {
this.document.removeEventListener("change", this.$onChange);
};
+ /** internal, hide
+ * Anchor.clipPositionToDocument(row, column)
+ * - row (Number): The row index to clip the anchor to
+ * - column (Number): The column index to clip the anchor to
+ *
+ * Clips the anchor position to the specified row and column.
+ *
+ **/
+
this.$clipPositionToDocument = function(row, column) {
var pos = {};
@@ -2673,7 +3187,7 @@ exports.arrayToMap = function(arr) {
};
-/**
+/*
* splice out of 'array' anything that === 'value'
*/
exports.arrayRemove = function(array, value) {
@@ -7188,7 +7702,8 @@ loop: for (;;) {
if (typeof exports === 'object' && exports)
exports.JSHINT = JSHINT;
-});/* -*- Mode: JS; tab-width: 4; indent-tabs-mode: nil; -*-
+});
+/* -*- Mode: JS; tab-width: 4; indent-tabs-mode: nil; -*-
* vim: set sw=4 ts=4 et tw=78:
* ***** BEGIN LICENSE BLOCK *****
*
@@ -9259,7 +9774,8 @@ exports.Parser = Parser;
exports.Module = Module;
exports.Export = Export;
-});/* vim: set sw=4 ts=4 et tw=78: */
+});
+/* vim: set sw=4 ts=4 et tw=78: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -9856,7 +10372,8 @@ Tokenizer.prototype = {
exports.isIdentifier = isIdentifier;
exports.Tokenizer = Tokenizer;
-});/* vim: set sw=4 ts=4 et tw=78: */
+});
+/* vim: set sw=4 ts=4 et tw=78: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -10551,7 +11068,8 @@ exports.Dict = Dict;
exports.WeakMap = _WeakMap;
exports.Stack = Stack;
-});/* vim: set sw=4 ts=4 et tw=78: */
+});
+/* vim: set sw=4 ts=4 et tw=78: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -10611,4 +11129,4 @@ exports.mozillaMode = true;
// Allow experimental paren-free mode?
exports.parenFreeMode = false;
-});
\ No newline at end of file
+});
diff --git a/build/demo/kitchen-sink/worker-json.js b/build/demo/kitchen-sink/worker-json.js
index b00a47b9..cffed24f 100644
--- a/build/demo/kitchen-sink/worker-json.js
+++ b/build/demo/kitchen-sink/worker-json.js
@@ -154,7 +154,8 @@ define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/rege
require("./regexp");
require("./es5-shim");
-});/**
+});
+/*
* Based on code from:
*
* XRegExp 1.5.0
@@ -292,7 +293,7 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
-/**
+/*
* Brings an environment as close to ECMAScript 5 compliance
* as is possible with the facilities of erstwhile engines.
*
@@ -1322,7 +1323,8 @@ var prepareString = "a"[0] != "a",
}
return Object(o);
};
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -1399,7 +1401,7 @@ EventEmitter._dispatchEvent = function(eventName, e) {
}
if (defaultHandler && !e.defaultPrevented)
- defaultHandler(e);
+ return defaultHandler(e);
};
EventEmitter.setDefaultHandler = function(eventName, callback) {
@@ -1442,7 +1444,8 @@ EventEmitter.removeAllListeners = function(eventName) {
exports.EventEmitter = EventEmitter;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1605,7 +1608,8 @@ oop.inherits(JsonWorker, Mirror);
}).call(JsonWorker.prototype);
-});define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
+});
+define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
"use strict";
var Document = require("../document").Document;
@@ -1647,7 +1651,8 @@ var Mirror = exports.Mirror = function(sender) {
}).call(Mirror.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1692,6 +1697,21 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
var Anchor = require("./anchor").Anchor;
+/**
+ * class Document
+ *
+ * Contains the text of the document. Documents are controlled by a single [[EditSession `EditSession`]]. At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.
+ *
+ *
+ **/
+
+ /**
+ * new Document([text])
+ * - text (String | Array): The starting text
+ *
+ * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.
+ *
+ **/
var Document = function(text) {
this.$lines = [];
@@ -1711,20 +1731,48 @@ var Document = function(text) {
oop.implement(this, EventEmitter);
+ /**
+ * Document.setValue(text) -> Void
+ * - text (String): The text to use
+ *
+ * Replaces all the lines in the current `Document` with the value of `text`.
+ **/
this.setValue = function(text) {
var len = this.getLength();
this.remove(new Range(0, 0, len, this.getLine(len-1).length));
this.insert({row: 0, column:0}, text);
};
+ /**
+ * Document.getValue() -> String
+ *
+ * Returns all the lines in the document as a single string, split by the new line character.
+ **/
this.getValue = function() {
return this.getAllLines().join(this.getNewLineCharacter());
};
+ /**
+ * Document.createAnchor(row, column) -> Anchor
+ * - row (Number): The row number to use
+ * - column (Number): The column number to use
+ *
+ * Creates a new `Anchor` to define a floating point in the document.
+ **/
this.createAnchor = function(row, column) {
return new Anchor(this, row, column);
};
+ /** internal, hide
+ * Document.$split(text) -> [String]
+ * - text (String): The text to work with
+ * + ([String]): A String array, with each index containing a piece of the original `text` string.
+ *
+ * Splits a string of text on any newline (`\n`) or carriage-return ('\r') characters.
+ *
+ *
+ **/
+
// check for IE split bug
if ("aaa".split(/a/).length == 0)
this.$split = function(text) {
@@ -1736,6 +1784,11 @@ var Document = function(text) {
};
+ /** internal, hide
+ * Document.$detectNewLine(text) -> Void
+ *
+ *
+ **/
this.$detectNewLine = function(text) {
var match = text.match(/^.*?(\r\n|\r|\n)/m);
if (match) {
@@ -1745,6 +1798,17 @@ var Document = function(text) {
}
};
+ /**
+ * Document.getNewLineCharacter() -> String
+ * + (String): If `newLineMode == windows`, `\r\n` is returned.
+ * If `newLineMode == unix`, `\n` is returned.
+ * If `newLineMode == auto`, the value of `autoNewLine` is returned.
+ *
+ * Returns the newline character that's being used, depending on the value of `newLineMode`.
+ *
+ *
+ *
+ **/
this.getNewLineCharacter = function() {
switch (this.$newLineMode) {
case "windows":
@@ -1760,6 +1824,12 @@ var Document = function(text) {
this.$autoNewLine = "\n";
this.$newLineMode = "auto";
+ /**
+ * Document.setNewLineMode(newLineMode) -> Void
+ * - newLineMode(String): [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param}
+ *
+ * [Sets the new line mode.]{: #Document.setNewLineMode.desc}
+ **/
this.setNewLineMode = function(newLineMode) {
if (this.$newLineMode === newLineMode)
return;
@@ -1767,51 +1837,92 @@ var Document = function(text) {
this.$newLineMode = newLineMode;
};
+ /**
+ * Document.getNewLineMode() -> String
+ *
+ * [Returns the type of newlines being used; either `windows`, `unix`, or `auto`]{: #Document.getNewLineMode}
+ *
+ **/
this.getNewLineMode = function() {
return this.$newLineMode;
};
+ /**
+ * Document.isNewLine(text) -> Boolean
+ * - text (String): The text to check
+ *
+ * Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`).
+ *
+ **/
this.isNewLine = function(text) {
return (text == "\r\n" || text == "\r" || text == "\n");
};
/**
- * Get a verbatim copy of the given line as it is in the document
- */
+ * Document.getLine(row) -> String
+ * - row (Number): The row index to retrieve
+ *
+ * Returns a verbatim copy of the given line as it is in the document
+ *
+ **/
this.getLine = function(row) {
return this.$lines[row] || "";
};
+ /**
+ * Document.getLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row index to retrieve
+ * - lastRow (Number): The final row index to retrieve
+ *
+ * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
+ *
+ **/
this.getLines = function(firstRow, lastRow) {
return this.$lines.slice(firstRow, lastRow + 1);
};
/**
- * Returns all lines in the document as string array. Warning: The caller
- * should not modify this array!
- */
+ * Document.getAllLines() -> [String]
+ *
+ * Returns all lines in the document as string array. Warning: The caller should not modify this array!
+ **/
this.getAllLines = function() {
return this.getLines(0, this.getLength());
};
+ /**
+ * Document.getLength() -> Number
+ *
+ * Returns the number of rows in the document.
+ **/
this.getLength = function() {
return this.$lines.length;
};
+ /**
+ * Document.getTextRange(range) -> String
+ * - range (Range): The range to work with
+ *
+ * [Given a range within the document, this function returns all the text within that range as a single string.]{: #Document.getTextRange.desc}
+ **/
this.getTextRange = function(range) {
if (range.start.row == range.end.row) {
return this.$lines[range.start.row].substring(range.start.column,
range.end.column);
}
else {
- var lines = [];
- lines.push(this.$lines[range.start.row].substring(range.start.column));
- lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
- lines.push(this.$lines[range.end.row].substring(0, range.end.column));
+ var lines = this.getLines(range.start.row+1, range.end.row-1);
+ lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
+ lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
return lines.join(this.getNewLineCharacter());
}
};
+ /** internal, hide
+ * Document.$clipPosition(position) -> Number
+ *
+ *
+ **/
this.$clipPosition = function(position) {
var length = this.getLength();
if (position.row >= length) {
@@ -1821,6 +1932,15 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insert(position, text) -> Number
+ * - position (Number): The position to start inserting at
+ * - text (String): A chunk of text to insert
+ * + (Number): The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.
+ * Inserts a block of `text` and the indicated `position`.
+ *
+ *
+ **/
this.insert = function(position, text) {
if (!text || text.length === 0)
return position;
@@ -1844,6 +1964,19 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insertLines(row, lines) -> Object
+ * - row (Number): The index of the row to insert at
+ * - lines (Array): An array of strings
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * If `lines` is empty, this function returns an object containing the current row, and column, like this:
+ * ```{row: row, column: 0}```
+ *
+ * Inserts the elements in `lines` into the document, starting at the row index given by `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.insertLines = function(row, lines) {
if (lines.length == 0)
return {row: row, column: 0};
@@ -1862,6 +1995,17 @@ var Document = function(text) {
return range.end;
};
+ /**
+ * Document.insertNewLine(position) -> Object
+ * - position (String): The position to insert at
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ *
+ * Inserts a new line into the document at the current row's `position`. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertNewLine = function(position) {
position = this.$clipPosition(position);
var line = this.$lines[position.row] || "";
@@ -1884,6 +2028,19 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.insertInLine(position, text) -> Object | Number
+ * - position (Number): The position to insert at
+ * - text (String): A chunk of text
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * + (Number): If `text` is empty, this function returns the value of `position`
+ *
+ * Inserts `text` into the `position` at the current row. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertInLine = function(position, text) {
if (text.length == 0)
return position;
@@ -1908,6 +2065,15 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.remove(range) -> Object
+ * - range (Range): A specified Range to remove
+ * + (Object): Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
+ *
+ * Removes the `range` from the document.
+ *
+ *
+ **/
this.remove = function(range) {
// clip to document
range.start = this.$clipPosition(range.start);
@@ -1940,6 +2106,17 @@ var Document = function(text) {
return range.start;
};
+ /**
+ * Document.removeInLine(row, startColumn, endColumn) -> Object
+ * - row (Number): The row to remove from
+ * - startColumn (Number): The column to start removing at
+ * - endColumn (Number): The column to stop removing at
+ * + (Object): Returns an object containing `startRow` and `startColumn`, indicating the new row and column values. If `startColumn` is equal to `endColumn`, this function returns nothing.
+ *
+ * Removes the specified columns from the `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeInLine = function(row, startColumn, endColumn) {
if (startColumn == endColumn)
return;
@@ -1960,12 +2137,15 @@ var Document = function(text) {
};
/**
- * Removes a range of full lines
- *
- * @param firstRow {Integer} The first row to be removed
- * @param lastRow {Integer} The last row to be removed
- * @return {String[]} The removed lines
- */
+ * Document.removeLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row to be removed
+ * - lastRow (Number): The last row to be removed
+ * + ([String]): Returns all the removed lines.
+ *
+ * Removes a range of full lines. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeLines = function(firstRow, lastRow) {
var range = new Range(firstRow, 0, lastRow + 1, 0);
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
@@ -1980,6 +2160,13 @@ var Document = function(text) {
return removed;
};
+ /**
+ * Document.removeNewLine(row) -> Void
+ * - row (Number): The row to check
+ *
+ * Removes the new line between `row` and the row immediately following it. This method also triggers the `'change'` event.
+ *
+ **/
this.removeNewLine = function(row) {
var firstLine = this.getLine(row);
var secondLine = this.getLine(row+1);
@@ -1997,6 +2184,18 @@ var Document = function(text) {
this._emit("change", { data: delta });
};
+ /**
+ * Document.replace(range, text) -> Object
+ * - range (Range): A specified Range to replace
+ * - text (String): The new text to use as a replacement
+ * + (Object): Returns an object containing the final row and column, like this:
+ * {row: endRow, column: 0}
+ * If the text and range are empty, this function returns an object containing the current `range.start` value.
+ * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
+ *
+ * Replaces a range in the document with the new `text`.
+ *
+ **/
this.replace = function(range, text) {
if (text.length == 0 && range.isEmpty())
return range.start;
@@ -2017,6 +2216,11 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.applyDeltas(deltas) -> Void
+ *
+ * Applies all the changes previously accumulated. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.applyDeltas = function(deltas) {
for (var i=0; i Void
+ *
+ * Reverts any changes previously applied. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.revertDeltas = function(deltas) {
for (var i=deltas.length-1; i>=0; i--) {
var delta = deltas[i];
@@ -2094,6 +2303,23 @@ exports.Document = Document;
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class Range
+ *
+ * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
+ *
+ **/
+
+/**
+ * new Range(startRow, startColumn, endRow, endColumn)
+ * - startRow (Number): The starting row
+ * - startColumn (Number): The starting column
+ * - endRow (Number): The ending row
+ * - endColumn (Number): The ending column
+ *
+ * Creates a new `Range` object with the given starting and ending row and column points.
+ *
+ **/
var Range = function(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
@@ -2107,6 +2333,13 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
(function() {
+ /**
+ * Range.isEqual(range) -> Boolean
+ * - range (Range): A range to check against
+ *
+ * Returns `true` if and only if the starting row and column, and ending tow and column, are equivalent to those given by `range`.
+ *
+ **/
this.isEqual = function(range) {
return this.start.row == range.start.row &&
this.end.row == range.end.row &&
@@ -2114,28 +2347,51 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
this.end.column == range.end.column
};
+ /**
+ * Range.toString() -> String
+ *
+ * Returns a string containing the range's row and column information, given like this:
+ *
+ * [start.row/start.column] -> [end.row/end.column]
+ *
+ **/
+
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
};
+ /** related to: Range.compare
+ * Range.contains(row, column) -> Boolean
+ * - row (Number): A row to check for
+ * - column (Number): A column to check for
+ *
+ * Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:
+ *
+ * this.start.row <= row <= this.end.row &&
+ * this.start.column <= column <= this.end.column
+ *
+ **/
+
this.contains = function(row, column) {
return this.compare(row, column) == 0;
};
- /**
- * Compares this range (A) with another range (B), where B is the passed in
- * range.
+ /** related to: Range.compare
+ * Range.compareRange(range) -> Number
+ * - range (Range): A range to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `-2`: (B) is in front of (A), and doesn't intersect with (A)
+ * * `-1`: (B) begins before (A) but ends inside of (A)
+ * * `0`: (B) is completely inside of (A) OR (A) is completely inside of (B)
+ * * `+1`: (B) begins inside of (A) but ends outside of (A)
+ * * `+2`: (B) is after (A) and doesn't intersect with (A)
+ * * `42`: FTW state: (B) ends in (A) but starts outside of (A)
+ *
+ * Compares `this` range (A) with another range (B).
*
- * Return values:
- * -2: (B) is infront of (A) and doesn't intersect with (A)
- * -1: (B) begins before (A) but ends inside of (A)
- * 0: (B) is completly inside of (A) OR (A) is complety inside of (B)
- * +1: (B) begins inside of (A) but ends outside of (A)
- * +2: (B) is after (A) and doesn't intersect with (A)
- *
- * 42: FTW state: (B) ends in (A) but starts outside of (A)
- */
+ **/
this.compareRange = function(range) {
var cmp,
end = range.end,
@@ -2165,27 +2421,86 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.comparePoint(p) -> Number
+ * - p (Range): A point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points of `p` with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.comparePoint = function(p) {
return this.compare(p.row, p.column);
}
+ /** related to: Range.comparePoint
+ * Range.containsRange(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
+ *
+ **/
this.containsRange = function(range) {
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
}
+ /**
+ * Range.intersects(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Returns `true` if passed in `range` intersects with the one calling this method.
+ *
+ **/
this.intersects = function(range) {
var cmp = this.compareRange(range);
return (cmp == -1 || cmp == 0 || cmp == 1);
}
+ /**
+ * Range.isEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's ending row point is the same as `row`, and if the caller's ending column is the same as `column`.
+ *
+ **/
this.isEnd = function(row, column) {
return this.end.row == row && this.end.column == column;
}
+ /**
+ * Range.isStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's starting row point is the same as `row`, and if the caller's starting column is the same as `column`.
+ *
+ **/
this.isStart = function(row, column) {
return this.start.row == row && this.start.column == column;
}
+ /**
+ * Range.setStart(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setStart = function(row, column) {
if (typeof row == "object") {
this.start.column = row.column;
@@ -2196,6 +2511,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.setEnd(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setEnd = function(row, column) {
if (typeof row == "object") {
this.end.column = row.column;
@@ -2206,6 +2529,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.inside(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range.
+ *
+ **/
this.inside = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column) || this.isStart(row, column)) {
@@ -2217,6 +2548,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's starting points.
+ *
+ **/
this.insideStart = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column)) {
@@ -2228,6 +2567,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's ending points.
+ *
+ **/
this.insideEnd = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isStart(row, column)) {
@@ -2239,6 +2586,27 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /**
+ * Range.compare(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compare = function(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
@@ -2262,8 +2630,28 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
/**
- * Like .compare(), but if isStart is true, return -1;
- */
+ * Range.compareStart(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isStart` is `true`.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareStart = function(row, column) {
if (this.start.row == row && this.start.column == column) {
return -1;
@@ -2273,8 +2661,26 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
/**
- * Like .compare(), but if isEnd is true, return 1;
- */
+ * Range.compareEnd(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isEnd` is `true.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compareEnd = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2283,6 +2689,21 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.compareInside(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`
+ * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`
+ *
+ * Otherwise, it returns the value after calling [[Range.compare `compare()`]].
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareInside = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2293,6 +2714,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.clipRows(firstRow, lastRow) -> Range
+ * - firstRow (Number): The starting row
+ * - lastRow (Number): The ending row
+ *
+ * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
+ *
+ **/
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
var end = {
@@ -2324,6 +2753,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
+ /**
+ * Range.extend(row, column) -> Range
+ * - row (Number): A new row to extend to
+ * - column (Number): A new column to extend to
+ *
+ * Changes the row and column points for the calling range for both the starting and ending points. This method returns that range with a new row.
+ *
+ **/
this.extend = function(row, column) {
var cmp = this.compare(row, column);
@@ -2337,33 +2774,36 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
- this.fixOrientation = function() {
- if (
- this.start.row < this.end.row
- || (this.start.row == this.end.row && this.start.column < this.end.column)
- ) {
- return false;
- }
-
- var temp = this.start;
- this.end = this.start;
- this.start = temp;
- return true;
- };
-
-
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
+ /**
+ * Range.isMultiLine() -> Boolean
+ *
+ * Returns true if the range spans across multiple lines.
+ *
+ **/
this.isMultiLine = function() {
return (this.start.row !== this.end.row);
};
+ /**
+ * Range.clone() -> Range
+ *
+ * Returns a duplicate of the calling range.
+ *
+ **/
this.clone = function() {
return Range.fromPoints(this.start, this.end);
};
+ /**
+ * Range.collapseRows() -> Range
+ *
+ * Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
+ *
+ **/
this.collapseRows = function() {
if (this.end.column == 0)
return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
@@ -2371,6 +2811,12 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return new Range(this.start.row, 0, this.end.row, 0)
};
+ /**
+ * Range.toScreenRange(session) -> Range
+ * - session (EditSession): The `EditSession` to retrieve coordinates from
+ *
+ * Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
+ **/
this.toScreenRange = function(session) {
var screenPosStart =
session.documentToScreenPosition(this.start);
@@ -2385,7 +2831,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}).call(Range.prototype);
-
+/**
+ * Range.fromPoints(start, end) -> Range
+ * - start (Range): A starting point to use
+ * - end (Range): An ending point to use
+ *
+ * Creates and returns a new `Range` based on the row and column of the given parameters.
+ *
+**/
Range.fromPoints = function(start, end) {
return new Range(start.row, start.column, end.row, end.column);
};
@@ -2436,9 +2889,22 @@ var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
/**
- * An Anchor is a floating pointer in the document. Whenever text is inserted or
- * deleted before the cursor, the position of the cursor is updated
- */
+ * class Anchor
+ *
+ * Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated
+ *
+ **/
+
+/**
+ * new Anchor(doc, row, column)
+ * - doc (Document): The document to associate with the anchor
+ * - row (Number): The starting row position
+ * - column (Number): The starting column position
+ *
+ * Creates a new `Anchor` and associates it with a document.
+ *
+ **/
+
var Anchor = exports.Anchor = function(doc, row, column) {
this.document = doc;
@@ -2455,14 +2921,36 @@ var Anchor = exports.Anchor = function(doc, row, column) {
oop.implement(this, EventEmitter);
+ /**
+ * Anchor.getPosition() -> Object
+ *
+ * Returns an object identifying the `row` and `column` position of the current anchor.
+ *
+ **/
+
this.getPosition = function() {
return this.$clipPositionToDocument(this.row, this.column);
};
-
+
+ /**
+ * Anchor.getDocument() -> Document
+ *
+ * Returns the current document.
+ *
+ **/
+
this.getDocument = function() {
return this.document;
};
+ /**
+ * Anchor@onChange(e)
+ * - e (Event): Contains data about the event
+ *
+ * Fires whenever the anchor position changes. Events that can trigger this function include `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ *
+ **/
+
this.onChange = function(e) {
var delta = e.data;
var range = delta.range;
@@ -2528,6 +3016,16 @@ var Anchor = exports.Anchor = function(doc, row, column) {
this.setPosition(row, column, true);
};
+ /**
+ * Anchor.setPosition(row, column, noClip)
+ * - row (Number): The row index to move the anchor to
+ * - column (Number): The column index to move the anchor to
+ * - noClip (Boolean): Identifies if you want the position to be clipped
+ *
+ * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.
+ *
+ **/
+
this.setPosition = function(row, column, noClip) {
var pos;
if (noClip) {
@@ -2556,10 +3054,26 @@ var Anchor = exports.Anchor = function(doc, row, column) {
});
};
+ /**
+ * Anchor.detach()
+ *
+ * When called, the `'change'` event listener is removed.
+ *
+ **/
+
this.detach = function() {
this.document.removeEventListener("change", this.$onChange);
};
+ /** internal, hide
+ * Anchor.clipPositionToDocument(row, column)
+ * - row (Number): The row index to clip the anchor to
+ * - column (Number): The column index to clip the anchor to
+ *
+ * Clips the anchor position to the specified row and column.
+ *
+ **/
+
this.$clipPositionToDocument = function(row, column) {
var pos = {};
@@ -2688,7 +3202,7 @@ exports.arrayToMap = function(arr) {
};
-/**
+/*
* splice out of 'array' anything that === 'value'
*/
exports.arrayRemove = function(array, value) {
@@ -3080,4 +3594,4 @@ define('ace/mode/json/json_parse', ['require', 'exports', 'module' ], function(r
return reviver.call(holder, key, value);
}({'': result}, '') : result;
};
-});
\ No newline at end of file
+});
diff --git a/build/demo/kitchen-sink/worker-xquery.js b/build/demo/kitchen-sink/worker-xquery.js
index f056d536..60f818cc 100644
--- a/build/demo/kitchen-sink/worker-xquery.js
+++ b/build/demo/kitchen-sink/worker-xquery.js
@@ -154,7 +154,8 @@ define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/rege
require("./regexp");
require("./es5-shim");
-});/**
+});
+/*
* Based on code from:
*
* XRegExp 1.5.0
@@ -292,7 +293,7 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
-/**
+/*
* Brings an environment as close to ECMAScript 5 compliance
* as is possible with the facilities of erstwhile engines.
*
@@ -1322,7 +1323,8 @@ var prepareString = "a"[0] != "a",
}
return Object(o);
};
-});/* vim:ts=4:sts=4:sw=4:
+});
+/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -1399,7 +1401,7 @@ EventEmitter._dispatchEvent = function(eventName, e) {
}
if (defaultHandler && !e.defaultPrevented)
- defaultHandler(e);
+ return defaultHandler(e);
};
EventEmitter.setDefaultHandler = function(eventName, callback) {
@@ -1442,7 +1444,8 @@ EventEmitter.removeAllListeners = function(eventName) {
exports.EventEmitter = EventEmitter;
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1576,13 +1579,11 @@ oop.inherits(XQueryWorker, Mirror);
type: "error"
});
}
- var tokens = parser.highlighter.getTokens();
- this.sender.emit("highlight", tokens);
- return;
+ } else {
+ this.sender.emit("ok");
}
var tokens = parser.highlighter.getTokens();
this.sender.emit("highlight", tokens);
- this.sender.emit("ok");
};
}).call(XQueryWorker.prototype);
@@ -1630,7 +1631,8 @@ var Mirror = exports.Mirror = function(sender) {
}).call(Mirror.prototype);
-});/* ***** BEGIN LICENSE BLOCK *****
+});
+/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@@ -1675,6 +1677,21 @@ var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Range = require("./range").Range;
var Anchor = require("./anchor").Anchor;
+/**
+ * class Document
+ *
+ * Contains the text of the document. Documents are controlled by a single [[EditSession `EditSession`]]. At its core, `Document`s are just an array of strings, with each row in the document matching up to the array index.
+ *
+ *
+ **/
+
+ /**
+ * new Document([text])
+ * - text (String | Array): The starting text
+ *
+ * Creates a new `Document`. If `text` is included, the `Document` contains those strings; otherwise, it's empty.
+ *
+ **/
var Document = function(text) {
this.$lines = [];
@@ -1694,20 +1711,48 @@ var Document = function(text) {
oop.implement(this, EventEmitter);
+ /**
+ * Document.setValue(text) -> Void
+ * - text (String): The text to use
+ *
+ * Replaces all the lines in the current `Document` with the value of `text`.
+ **/
this.setValue = function(text) {
var len = this.getLength();
this.remove(new Range(0, 0, len, this.getLine(len-1).length));
this.insert({row: 0, column:0}, text);
};
+ /**
+ * Document.getValue() -> String
+ *
+ * Returns all the lines in the document as a single string, split by the new line character.
+ **/
this.getValue = function() {
return this.getAllLines().join(this.getNewLineCharacter());
};
+ /**
+ * Document.createAnchor(row, column) -> Anchor
+ * - row (Number): The row number to use
+ * - column (Number): The column number to use
+ *
+ * Creates a new `Anchor` to define a floating point in the document.
+ **/
this.createAnchor = function(row, column) {
return new Anchor(this, row, column);
};
+ /** internal, hide
+ * Document.$split(text) -> [String]
+ * - text (String): The text to work with
+ * + ([String]): A String array, with each index containing a piece of the original `text` string.
+ *
+ * Splits a string of text on any newline (`\n`) or carriage-return ('\r') characters.
+ *
+ *
+ **/
+
// check for IE split bug
if ("aaa".split(/a/).length == 0)
this.$split = function(text) {
@@ -1719,6 +1764,11 @@ var Document = function(text) {
};
+ /** internal, hide
+ * Document.$detectNewLine(text) -> Void
+ *
+ *
+ **/
this.$detectNewLine = function(text) {
var match = text.match(/^.*?(\r\n|\r|\n)/m);
if (match) {
@@ -1728,6 +1778,17 @@ var Document = function(text) {
}
};
+ /**
+ * Document.getNewLineCharacter() -> String
+ * + (String): If `newLineMode == windows`, `\r\n` is returned.
+ * If `newLineMode == unix`, `\n` is returned.
+ * If `newLineMode == auto`, the value of `autoNewLine` is returned.
+ *
+ * Returns the newline character that's being used, depending on the value of `newLineMode`.
+ *
+ *
+ *
+ **/
this.getNewLineCharacter = function() {
switch (this.$newLineMode) {
case "windows":
@@ -1743,6 +1804,12 @@ var Document = function(text) {
this.$autoNewLine = "\n";
this.$newLineMode = "auto";
+ /**
+ * Document.setNewLineMode(newLineMode) -> Void
+ * - newLineMode(String): [The newline mode to use; can be either `windows`, `unix`, or `auto`]{: #Document.setNewLineMode.param}
+ *
+ * [Sets the new line mode.]{: #Document.setNewLineMode.desc}
+ **/
this.setNewLineMode = function(newLineMode) {
if (this.$newLineMode === newLineMode)
return;
@@ -1750,51 +1817,92 @@ var Document = function(text) {
this.$newLineMode = newLineMode;
};
+ /**
+ * Document.getNewLineMode() -> String
+ *
+ * [Returns the type of newlines being used; either `windows`, `unix`, or `auto`]{: #Document.getNewLineMode}
+ *
+ **/
this.getNewLineMode = function() {
return this.$newLineMode;
};
+ /**
+ * Document.isNewLine(text) -> Boolean
+ * - text (String): The text to check
+ *
+ * Returns `true` if `text` is a newline character (either `\r\n`, `\r`, or `\n`).
+ *
+ **/
this.isNewLine = function(text) {
return (text == "\r\n" || text == "\r" || text == "\n");
};
/**
- * Get a verbatim copy of the given line as it is in the document
- */
+ * Document.getLine(row) -> String
+ * - row (Number): The row index to retrieve
+ *
+ * Returns a verbatim copy of the given line as it is in the document
+ *
+ **/
this.getLine = function(row) {
return this.$lines[row] || "";
};
+ /**
+ * Document.getLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row index to retrieve
+ * - lastRow (Number): The final row index to retrieve
+ *
+ * Returns an array of strings of the rows between `firstRow` and `lastRow`. This function is inclusive of `lastRow`.
+ *
+ **/
this.getLines = function(firstRow, lastRow) {
return this.$lines.slice(firstRow, lastRow + 1);
};
/**
- * Returns all lines in the document as string array. Warning: The caller
- * should not modify this array!
- */
+ * Document.getAllLines() -> [String]
+ *
+ * Returns all lines in the document as string array. Warning: The caller should not modify this array!
+ **/
this.getAllLines = function() {
return this.getLines(0, this.getLength());
};
+ /**
+ * Document.getLength() -> Number
+ *
+ * Returns the number of rows in the document.
+ **/
this.getLength = function() {
return this.$lines.length;
};
+ /**
+ * Document.getTextRange(range) -> String
+ * - range (Range): The range to work with
+ *
+ * [Given a range within the document, this function returns all the text within that range as a single string.]{: #Document.getTextRange.desc}
+ **/
this.getTextRange = function(range) {
if (range.start.row == range.end.row) {
return this.$lines[range.start.row].substring(range.start.column,
range.end.column);
}
else {
- var lines = [];
- lines.push(this.$lines[range.start.row].substring(range.start.column));
- lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1));
- lines.push(this.$lines[range.end.row].substring(0, range.end.column));
+ var lines = this.getLines(range.start.row+1, range.end.row-1);
+ lines.unshift((this.$lines[range.start.row] || "").substring(range.start.column));
+ lines.push((this.$lines[range.end.row] || "").substring(0, range.end.column));
return lines.join(this.getNewLineCharacter());
}
};
+ /** internal, hide
+ * Document.$clipPosition(position) -> Number
+ *
+ *
+ **/
this.$clipPosition = function(position) {
var length = this.getLength();
if (position.row >= length) {
@@ -1804,6 +1912,15 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insert(position, text) -> Number
+ * - position (Number): The position to start inserting at
+ * - text (String): A chunk of text to insert
+ * + (Number): The position of the last line of `text`. If the length of `text` is 0, this function simply returns `position`.
+ * Inserts a block of `text` and the indicated `position`.
+ *
+ *
+ **/
this.insert = function(position, text) {
if (!text || text.length === 0)
return position;
@@ -1827,6 +1944,19 @@ var Document = function(text) {
return position;
};
+ /**
+ * Document.insertLines(row, lines) -> Object
+ * - row (Number): The index of the row to insert at
+ * - lines (Array): An array of strings
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * If `lines` is empty, this function returns an object containing the current row, and column, like this:
+ * ```{row: row, column: 0}```
+ *
+ * Inserts the elements in `lines` into the document, starting at the row index given by `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.insertLines = function(row, lines) {
if (lines.length == 0)
return {row: row, column: 0};
@@ -1845,6 +1975,17 @@ var Document = function(text) {
return range.end;
};
+ /**
+ * Document.insertNewLine(position) -> Object
+ * - position (String): The position to insert at
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ *
+ * Inserts a new line into the document at the current row's `position`. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertNewLine = function(position) {
position = this.$clipPosition(position);
var line = this.$lines[position.row] || "";
@@ -1867,6 +2008,19 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.insertInLine(position, text) -> Object | Number
+ * - position (Number): The position to insert at
+ * - text (String): A chunk of text
+ * + (Object): Returns an object containing the final row and column, like this:
+ * ```{row: endRow, column: 0}```
+ * + (Number): If `text` is empty, this function returns the value of `position`
+ *
+ * Inserts `text` into the `position` at the current row. This method also triggers the `'change'` event.
+ *
+ *
+ *
+ **/
this.insertInLine = function(position, text) {
if (text.length == 0)
return position;
@@ -1891,6 +2045,15 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.remove(range) -> Object
+ * - range (Range): A specified Range to remove
+ * + (Object): Returns the new `start` property of the range, which contains `startRow` and `startColumn`. If `range` is empty, this function returns the unmodified value of `range.start`.
+ *
+ * Removes the `range` from the document.
+ *
+ *
+ **/
this.remove = function(range) {
// clip to document
range.start = this.$clipPosition(range.start);
@@ -1923,6 +2086,17 @@ var Document = function(text) {
return range.start;
};
+ /**
+ * Document.removeInLine(row, startColumn, endColumn) -> Object
+ * - row (Number): The row to remove from
+ * - startColumn (Number): The column to start removing at
+ * - endColumn (Number): The column to stop removing at
+ * + (Object): Returns an object containing `startRow` and `startColumn`, indicating the new row and column values. If `startColumn` is equal to `endColumn`, this function returns nothing.
+ *
+ * Removes the specified columns from the `row`. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeInLine = function(row, startColumn, endColumn) {
if (startColumn == endColumn)
return;
@@ -1943,12 +2117,15 @@ var Document = function(text) {
};
/**
- * Removes a range of full lines
- *
- * @param firstRow {Integer} The first row to be removed
- * @param lastRow {Integer} The last row to be removed
- * @return {String[]} The removed lines
- */
+ * Document.removeLines(firstRow, lastRow) -> [String]
+ * - firstRow (Number): The first row to be removed
+ * - lastRow (Number): The last row to be removed
+ * + ([String]): Returns all the removed lines.
+ *
+ * Removes a range of full lines. This method also triggers the `'change'` event.
+ *
+ *
+ **/
this.removeLines = function(firstRow, lastRow) {
var range = new Range(firstRow, 0, lastRow + 1, 0);
var removed = this.$lines.splice(firstRow, lastRow - firstRow + 1);
@@ -1963,6 +2140,13 @@ var Document = function(text) {
return removed;
};
+ /**
+ * Document.removeNewLine(row) -> Void
+ * - row (Number): The row to check
+ *
+ * Removes the new line between `row` and the row immediately following it. This method also triggers the `'change'` event.
+ *
+ **/
this.removeNewLine = function(row) {
var firstLine = this.getLine(row);
var secondLine = this.getLine(row+1);
@@ -1980,6 +2164,18 @@ var Document = function(text) {
this._emit("change", { data: delta });
};
+ /**
+ * Document.replace(range, text) -> Object
+ * - range (Range): A specified Range to replace
+ * - text (String): The new text to use as a replacement
+ * + (Object): Returns an object containing the final row and column, like this:
+ * {row: endRow, column: 0}
+ * If the text and range are empty, this function returns an object containing the current `range.start` value.
+ * If the text is the exact same as what currently exists, this function returns an object containing the current `range.end` value.
+ *
+ * Replaces a range in the document with the new `text`.
+ *
+ **/
this.replace = function(range, text) {
if (text.length == 0 && range.isEmpty())
return range.start;
@@ -2000,6 +2196,11 @@ var Document = function(text) {
return end;
};
+ /**
+ * Document.applyDeltas(deltas) -> Void
+ *
+ * Applies all the changes previously accumulated. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.applyDeltas = function(deltas) {
for (var i=0; i Void
+ *
+ * Reverts any changes previously applied. These can be either `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ **/
this.revertDeltas = function(deltas) {
for (var i=deltas.length-1; i>=0; i--) {
var delta = deltas[i];
@@ -2077,6 +2283,23 @@ exports.Document = Document;
define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
"use strict";
+/**
+ * class Range
+ *
+ * This object is used in various places to indicate a region within the editor. To better visualize how this works, imagine a rectangle. Each quadrant of the rectangle is analogus to a range, as ranges contain a starting row and starting column, and an ending row, and ending column.
+ *
+ **/
+
+/**
+ * new Range(startRow, startColumn, endRow, endColumn)
+ * - startRow (Number): The starting row
+ * - startColumn (Number): The starting column
+ * - endRow (Number): The ending row
+ * - endColumn (Number): The ending column
+ *
+ * Creates a new `Range` object with the given starting and ending row and column points.
+ *
+ **/
var Range = function(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
@@ -2090,6 +2313,13 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
(function() {
+ /**
+ * Range.isEqual(range) -> Boolean
+ * - range (Range): A range to check against
+ *
+ * Returns `true` if and only if the starting row and column, and ending tow and column, are equivalent to those given by `range`.
+ *
+ **/
this.isEqual = function(range) {
return this.start.row == range.start.row &&
this.end.row == range.end.row &&
@@ -2097,28 +2327,51 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
this.end.column == range.end.column
};
+ /**
+ * Range.toString() -> String
+ *
+ * Returns a string containing the range's row and column information, given like this:
+ *
+ * [start.row/start.column] -> [end.row/end.column]
+ *
+ **/
+
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
};
+ /** related to: Range.compare
+ * Range.contains(row, column) -> Boolean
+ * - row (Number): A row to check for
+ * - column (Number): A column to check for
+ *
+ * Returns `true` if the `row` and `column` provided are within the given range. This can better be expressed as returning `true` if:
+ *
+ * this.start.row <= row <= this.end.row &&
+ * this.start.column <= column <= this.end.column
+ *
+ **/
+
this.contains = function(row, column) {
return this.compare(row, column) == 0;
};
- /**
- * Compares this range (A) with another range (B), where B is the passed in
- * range.
+ /** related to: Range.compare
+ * Range.compareRange(range) -> Number
+ * - range (Range): A range to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `-2`: (B) is in front of (A), and doesn't intersect with (A)
+ * * `-1`: (B) begins before (A) but ends inside of (A)
+ * * `0`: (B) is completely inside of (A) OR (A) is completely inside of (B)
+ * * `+1`: (B) begins inside of (A) but ends outside of (A)
+ * * `+2`: (B) is after (A) and doesn't intersect with (A)
+ * * `42`: FTW state: (B) ends in (A) but starts outside of (A)
+ *
+ * Compares `this` range (A) with another range (B).
*
- * Return values:
- * -2: (B) is infront of (A) and doesn't intersect with (A)
- * -1: (B) begins before (A) but ends inside of (A)
- * 0: (B) is completly inside of (A) OR (A) is complety inside of (B)
- * +1: (B) begins inside of (A) but ends outside of (A)
- * +2: (B) is after (A) and doesn't intersect with (A)
- *
- * 42: FTW state: (B) ends in (A) but starts outside of (A)
- */
+ **/
this.compareRange = function(range) {
var cmp,
end = range.end,
@@ -2148,27 +2401,86 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.comparePoint(p) -> Number
+ * - p (Range): A point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points of `p` with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.comparePoint = function(p) {
return this.compare(p.row, p.column);
}
+ /** related to: Range.comparePoint
+ * Range.containsRange(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Checks the start and end points of `range` and compares them to the calling range. Returns `true` if the `range` is contained within the caller's range.
+ *
+ **/
this.containsRange = function(range) {
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
}
+ /**
+ * Range.intersects(range) -> Boolean
+ * - range (Range): A range to compare with
+ *
+ * Returns `true` if passed in `range` intersects with the one calling this method.
+ *
+ **/
this.intersects = function(range) {
var cmp = this.compareRange(range);
return (cmp == -1 || cmp == 0 || cmp == 1);
}
+ /**
+ * Range.isEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's ending row point is the same as `row`, and if the caller's ending column is the same as `column`.
+ *
+ **/
this.isEnd = function(row, column) {
return this.end.row == row && this.end.column == column;
}
+ /**
+ * Range.isStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the caller's starting row point is the same as `row`, and if the caller's starting column is the same as `column`.
+ *
+ **/
this.isStart = function(row, column) {
return this.start.row == row && this.start.column == column;
}
+ /**
+ * Range.setStart(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setStart = function(row, column) {
if (typeof row == "object") {
this.start.column = row.column;
@@ -2179,6 +2491,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.setEnd(row, column)
+ * - row (Number): A row point to set
+ * - column (Number): A column point to set
+ *
+ * Sets the starting row and column for the range.
+ *
+ **/
this.setEnd = function(row, column) {
if (typeof row == "object") {
this.end.column = row.column;
@@ -2189,6 +2509,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /** related to: Range.compare
+ * Range.inside(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range.
+ *
+ **/
this.inside = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column) || this.isStart(row, column)) {
@@ -2200,6 +2528,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideStart(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's starting points.
+ *
+ **/
this.insideStart = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isEnd(row, column)) {
@@ -2211,6 +2547,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /** related to: Range.compare
+ * Range.insideEnd(row, column) -> Boolean
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ *
+ * Returns `true` if the `row` and `column` are within the given range's ending points.
+ *
+ **/
this.insideEnd = function(row, column) {
if (this.compare(row, column) == 0) {
if (this.isStart(row, column)) {
@@ -2222,6 +2566,27 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return false;
}
+ /**
+ * Range.compare(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compare = function(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
@@ -2245,8 +2610,28 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
/**
- * Like .compare(), but if isStart is true, return -1;
- */
+ * Range.compareStart(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ *
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isStart` is `true`.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareStart = function(row, column) {
if (this.start.row == row && this.start.column == column) {
return -1;
@@ -2256,8 +2641,26 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
/**
- * Like .compare(), but if isEnd is true, return 1;
- */
+ * Range.compareEnd(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `0` if the two points are exactly equal
+ * * `-1` if `p.row` is less then the calling range
+ * * `1` if `p.row` is greater than the calling range, or if `isEnd` is `true.
+ *
+ * If the starting row of the calling range is equal to `p.row`, and:
+ * * `p.column` is greater than or equal to the calling range's starting column, this returns `0`
+ * * Otherwise, it returns -1
+ *
+ * If the ending row of the calling range is equal to `p.row`, and:
+ * * `p.column` is less than or equal to the calling range's ending column, this returns `0`
+ * * Otherwise, it returns 1
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ **/
this.compareEnd = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2266,6 +2669,21 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.compareInside(row, column) -> Number
+ * - row (Number): A row point to compare with
+ * - column (Number): A column point to compare with
+ * + (Number): This method returns one of the following numbers:
+ * * `1` if the ending row of the calling range is equal to `row`, and the ending column of the calling range is equal to `column`
+ * * `-1` if the starting row of the calling range is equal to `row`, and the starting column of the calling range is equal to `column`
+ *
+ * Otherwise, it returns the value after calling [[Range.compare `compare()`]].
+ *
+ * Checks the row and column points with the row and column points of the calling range.
+ *
+ *
+ *
+ **/
this.compareInside = function(row, column) {
if (this.end.row == row && this.end.column == column) {
return 1;
@@ -2276,6 +2694,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}
}
+ /**
+ * Range.clipRows(firstRow, lastRow) -> Range
+ * - firstRow (Number): The starting row
+ * - lastRow (Number): The ending row
+ *
+ * Returns the part of the current `Range` that occurs within the boundaries of `firstRow` and `lastRow` as a new `Range` object.
+ *
+ **/
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
var end = {
@@ -2307,6 +2733,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
+ /**
+ * Range.extend(row, column) -> Range
+ * - row (Number): A new row to extend to
+ * - column (Number): A new column to extend to
+ *
+ * Changes the row and column points for the calling range for both the starting and ending points. This method returns that range with a new row.
+ *
+ **/
this.extend = function(row, column) {
var cmp = this.compare(row, column);
@@ -2320,33 +2754,36 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
- this.fixOrientation = function() {
- if (
- this.start.row < this.end.row
- || (this.start.row == this.end.row && this.start.column < this.end.column)
- ) {
- return false;
- }
-
- var temp = this.start;
- this.end = this.start;
- this.start = temp;
- return true;
- };
-
-
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
+ /**
+ * Range.isMultiLine() -> Boolean
+ *
+ * Returns true if the range spans across multiple lines.
+ *
+ **/
this.isMultiLine = function() {
return (this.start.row !== this.end.row);
};
+ /**
+ * Range.clone() -> Range
+ *
+ * Returns a duplicate of the calling range.
+ *
+ **/
this.clone = function() {
return Range.fromPoints(this.start, this.end);
};
+ /**
+ * Range.collapseRows() -> Range
+ *
+ * Returns a range containing the starting and ending rows of the original range, but with a column value of `0`.
+ *
+ **/
this.collapseRows = function() {
if (this.end.column == 0)
return new Range(this.start.row, 0, Math.max(this.start.row, this.end.row-1), 0)
@@ -2354,6 +2791,12 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return new Range(this.start.row, 0, this.end.row, 0)
};
+ /**
+ * Range.toScreenRange(session) -> Range
+ * - session (EditSession): The `EditSession` to retrieve coordinates from
+ *
+ * Given the current `Range`, this function converts those starting and ending points into screen positions, and then returns a new `Range` object.
+ **/
this.toScreenRange = function(session) {
var screenPosStart =
session.documentToScreenPosition(this.start);
@@ -2368,7 +2811,14 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
}).call(Range.prototype);
-
+/**
+ * Range.fromPoints(start, end) -> Range
+ * - start (Range): A starting point to use
+ * - end (Range): An ending point to use
+ *
+ * Creates and returns a new `Range` based on the row and column of the given parameters.
+ *
+**/
Range.fromPoints = function(start, end) {
return new Range(start.row, start.column, end.row, end.column);
};
@@ -2419,9 +2869,22 @@ var oop = require("./lib/oop");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
/**
- * An Anchor is a floating pointer in the document. Whenever text is inserted or
- * deleted before the cursor, the position of the cursor is updated
- */
+ * class Anchor
+ *
+ * Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated
+ *
+ **/
+
+/**
+ * new Anchor(doc, row, column)
+ * - doc (Document): The document to associate with the anchor
+ * - row (Number): The starting row position
+ * - column (Number): The starting column position
+ *
+ * Creates a new `Anchor` and associates it with a document.
+ *
+ **/
+
var Anchor = exports.Anchor = function(doc, row, column) {
this.document = doc;
@@ -2438,14 +2901,36 @@ var Anchor = exports.Anchor = function(doc, row, column) {
oop.implement(this, EventEmitter);
+ /**
+ * Anchor.getPosition() -> Object
+ *
+ * Returns an object identifying the `row` and `column` position of the current anchor.
+ *
+ **/
+
this.getPosition = function() {
return this.$clipPositionToDocument(this.row, this.column);
};
-
+
+ /**
+ * Anchor.getDocument() -> Document
+ *
+ * Returns the current document.
+ *
+ **/
+
this.getDocument = function() {
return this.document;
};
+ /**
+ * Anchor@onChange(e)
+ * - e (Event): Contains data about the event
+ *
+ * Fires whenever the anchor position changes. Events that can trigger this function include `'includeText'`, `'insertLines'`, `'removeText'`, and `'removeLines'`.
+ *
+ **/
+
this.onChange = function(e) {
var delta = e.data;
var range = delta.range;
@@ -2511,6 +2996,16 @@ var Anchor = exports.Anchor = function(doc, row, column) {
this.setPosition(row, column, true);
};
+ /**
+ * Anchor.setPosition(row, column, noClip)
+ * - row (Number): The row index to move the anchor to
+ * - column (Number): The column index to move the anchor to
+ * - noClip (Boolean): Identifies if you want the position to be clipped
+ *
+ * Sets the anchor position to the specified row and column. If `noClip` is `true`, the position is not clipped.
+ *
+ **/
+
this.setPosition = function(row, column, noClip) {
var pos;
if (noClip) {
@@ -2539,10 +3034,26 @@ var Anchor = exports.Anchor = function(doc, row, column) {
});
};
+ /**
+ * Anchor.detach()
+ *
+ * When called, the `'change'` event listener is removed.
+ *
+ **/
+
this.detach = function() {
this.document.removeEventListener("change", this.$onChange);
};
+ /** internal, hide
+ * Anchor.clipPositionToDocument(row, column)
+ * - row (Number): The row index to clip the anchor to
+ * - column (Number): The column index to clip the anchor to
+ *
+ * Clips the anchor position to the specified row and column.
+ *
+ **/
+
this.$clipPositionToDocument = function(row, column) {
var pos = {};
@@ -2671,7 +3182,7 @@ exports.arrayToMap = function(arr) {
};
-/**
+/*
* splice out of 'array' anything that === 'value'
*/
exports.arrayRemove = function(array, value) {
diff --git a/build/kitchen-sink.html b/build/kitchen-sink.html
index da453fcb..18363d0a 100644
--- a/build/kitchen-sink.html
+++ b/build/kitchen-sink.html
@@ -200,6 +200,14 @@
+
+
+
+
+
+
+
+
diff --git a/build/src/ace-noconflict.js b/build/src/ace-noconflict.js
index f6887cd8..895eba1a 100644
--- a/build/src/ace-noconflict.js
+++ b/build/src/ace-noconflict.js
@@ -1,4 +1,4 @@
-(function(){function g(a){if(typeof requirejs!="undefined"){var e=b.define;b.define=function(a,b,c){return typeof c!="function"?e.apply(this,arguments):ace.define(a,b,function(a,d,e){return b[2]=="module"&&(e.packaged=!0),c.apply(this,arguments)})},b.define.packaged=!0;return}var f=function(a,b){return d("",a,b)};f.packaged=!0;var g=b;a&&(b[a]||(b[a]={}),g=b[a]),g.define&&(c.original=g.define),g.define=c,g.require&&(d.original=g.require),g.require=f}var a="ace",b=function(){return this}(),c=function(a,b,d){if(typeof a!="string"){c.original?c.original.apply(window,arguments):(console.error("dropping module because define wasn't a string."),console.trace());return}arguments.length==2&&(d=b),c.modules||(c.modules={}),c.modules[a]=d},d=function(a,b,c){if(Object.prototype.toString.call(b)==="[object Array]"){var e=[];for(var g=0,h=b.length;g1&&h(b,"")>-1&&(i=RegExp(this.source,d.replace.call(g(this),"g","")),d.replace.call(a.slice(b.index),i,function(){for(var a=1;ab.index&&this.lastIndex--}return b},f||(RegExp.prototype.test=function(a){var b=d.exec.call(this,a);return b&&this.global&&!b[0].length&&this.lastIndex>b.index&&this.lastIndex--,!!b})}),ace.define("ace/lib/es5-shim",["require","exports","module"],function(a,b,c){function p(a){try{return Object.defineProperty(a,"sentinel",{}),"sentinel"in a}catch(b){}}Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=g.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,h=c.apply(f,d.concat(g.call(arguments)));return h!==null&&Object(h)===h?h:f}return c.apply(b,d.concat(g.call(arguments)))};return e});var d=Function.prototype.call,e=Array.prototype,f=Object.prototype,g=e.slice,h=d.bind(f.toString),i=d.bind(f.hasOwnProperty),j,k,l,m,n;if(n=i(f,"__defineGetter__"))j=d.bind(f.__defineGetter__),k=d.bind(f.__defineSetter__),l=d.bind(f.__lookupGetter__),m=d.bind(f.__lookupSetter__);Array.isArray||(Array.isArray=function(b){return h(b)=="[object Array]"}),Array.prototype.forEach||(Array.prototype.forEach=function(b){var c=G(this),d=arguments[1],e=0,f=c.length>>>0;if(h(b)!="[object Function]")throw new TypeError;while(e>>0,e=Array(d),f=arguments[1];if(h(b)!="[object Function]")throw new TypeError;for(var g=0;g>>0,e=[],f=arguments[1];if(h(b)!="[object Function]")throw new TypeError;for(var g=0;g>>0,e=arguments[1];if(h(b)!="[object Function]")throw new TypeError;for(var f=0;f>>0,e=arguments[1];if(h(b)!="[object Function]")throw new TypeError;for(var f=0;f>>0;if(h(b)!="[object Function]")throw new TypeError;if(!d&&arguments.length==1)throw new TypeError;var e=0,f;if(arguments.length>=2)f=arguments[1];else do{if(e in c){f=c[e++];break}if(++e>=d)throw new TypeError}while(!0);for(;e>>0;if(h(b)!="[object Function]")throw new TypeError;if(!d&&arguments.length==1)throw new TypeError;var e,f=d-1;if(arguments.length>=2)e=arguments[1];else do{if(f in c){e=c[f--];break}if(--f<0)throw new TypeError}while(!0);do f in this&&(e=b.call(void 0,e,c[f],f,c));while(f--);return e}),Array.prototype.indexOf||(Array.prototype.indexOf=function(b){var c=G(this),d=c.length>>>0;if(!d)return-1;var e=0;arguments.length>1&&(e=E(arguments[1])),e=e>=0?e:Math.max(0,d+e);for(;e>>0;if(!d)return-1;var e=d-1;arguments.length>1&&(e=Math.min(e,E(arguments[1]))),e=e>=0?e:d-Math.abs(e);for(;e>=0;e--)if(e in c&&b===c[e])return e;return-1}),Object.getPrototypeOf||(Object.getPrototypeOf=function(b){return b.__proto__||(b.constructor?b.constructor.prototype:f)});if(!Object.getOwnPropertyDescriptor){var o="Object.getOwnPropertyDescriptor called on a non-object: ";Object.getOwnPropertyDescriptor=function(b,c){if(typeof b!="object"&&typeof b!="function"||b===null)throw new TypeError(o+b);if(!i(b,c))return;var d,e,g;d={enumerable:!0,configurable:!0};if(n){var h=b.__proto__;b.__proto__=f;var e=l(b,c),g=m(b,c);b.__proto__=h;if(e||g)return e&&(d.get=e),g&&(d.set=g),d}return d.value=b[c],d}}Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(b){return Object.keys(b)}),Object.create||(Object.create=function(b,c){var d;if(b===null)d={__proto__:null};else{if(typeof b!="object")throw new TypeError("typeof prototype["+typeof b+"] != 'object'");var e=function(){};e.prototype=b,d=new e,d.__proto__=b}return c!==void 0&&Object.defineProperties(d,c),d});if(Object.defineProperty){var q=p({}),r=typeof document=="undefined"||p(document.createElement("div"));if(!q||!r)var s=Object.defineProperty}if(!Object.defineProperty||s){var t="Property description must be an object: ",u="Object.defineProperty called on non-object: ",v="getters & setters can not be defined on this javascript engine";Object.defineProperty=function(b,c,d){if(typeof b!="object"&&typeof b!="function"||b===null)throw new TypeError(u+b);if(typeof d!="object"&&typeof d!="function"||d===null)throw new TypeError(t+d);if(s)try{return s.call(Object,b,c,d)}catch(e){}if(i(d,"value"))if(n&&(l(b,c)||m(b,c))){var g=b.__proto__;b.__proto__=f,delete b[c],b[c]=d.value,b.__proto__=g}else b[c]=d.value;else{if(!n)throw new TypeError(v);i(d,"get")&&j(b,c,d.get),i(d,"set")&&k(b,c,d.set)}return b}}Object.defineProperties||(Object.defineProperties=function(b,c){for(var d in c)i(c,d)&&Object.defineProperty(b,d,c[d]);return b}),Object.seal||(Object.seal=function(b){return b}),Object.freeze||(Object.freeze=function(b){return b});try{Object.freeze(function(){})}catch(w){Object.freeze=function(b){return function(c){return typeof c=="function"?c:b(c)}}(Object.freeze)}Object.preventExtensions||(Object.preventExtensions=function(b){return b}),Object.isSealed||(Object.isSealed=function(b){return!1}),Object.isFrozen||(Object.isFrozen=function(b){return!1}),Object.isExtensible||(Object.isExtensible=function(b){if(Object(b)===b)throw new TypeError;var c="";while(i(b,c))c+="?";b[c]=!0;var d=i(b,c);return delete b[c],d});if(!Object.keys){var x=!0,y=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],z=y.length;for(var A in{toString:null})x=!1;Object.keys=function H(a){if(typeof a!="object"&&typeof a!="function"||a===null)throw new TypeError("Object.keys called on a non-object");var H=[];for(var b in a)i(a,b)&&H.push(b);if(x)for(var c=0,d=z;c9999?"+":"")+("00000"+Math.abs(e)).slice(0<=e&&e<=9999?-4:-6),c=b.length;while(c--)d=b[c],d<10&&(b[c]="0"+d);return e+"-"+b.slice(0,2).join("-")+"T"+b.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"};Date.now||(Date.now=function(){return(new Date).getTime()}),Date.prototype.toJSON||(Date.prototype.toJSON=function(b){if(typeof this.toISOString!="function")throw new TypeError;return this.toISOString()}),Date.parse("+275760-09-13T00:00:00.000Z")!==864e13&&(Date=function(a){var b=function e(b,c,d,f,g,h,i){var j=arguments.length;if(this instanceof a){var k=j==1&&String(b)===b?new a(e.parse(b)):j>=7?new a(b,c,d,f,g,h,i):j>=6?new a(b,c,d,f,g,h):j>=5?new a(b,c,d,f,g):j>=4?new a(b,c,d,f):j>=3?new a(b,c,d):j>=2?new a(b,c):j>=1?new a(b):new a;return k.constructor=e,k}return a.apply(this,arguments)},c=new RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{3}))?)?(?:Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$");for(var d in a)b[d]=a[d];return b.now=a.now,b.UTC=a.UTC,b.prototype=a.prototype,b.prototype.constructor=b,b.parse=function(d){var e=c.exec(d);if(e){e.shift();for(var f=1;f<7;f++)e[f]=+(e[f]||(f<3?1:0)),f==1&&e[f]--;var g=+e.pop(),h=+e.pop(),i=e.pop(),j=0;if(i){if(h>23||g>59)return NaN;j=(h*60+g)*6e4*(i=="+"?-1:1)}var k=+e[0];return 0<=k&&k<=99?(e[0]=k+400,a.UTC.apply(this,e)+j-126227808e5):a.UTC.apply(this,e)+j}return a.parse.apply(this,arguments)},b}(Date));var B=" \n\f\r \u2028\u2029";if(!String.prototype.trim||B.trim()){B="["+B+"]";var C=new RegExp("^"+B+B+"*"),D=new RegExp(B+B+"*$");String.prototype.trim=function(){return String(this).replace(C,"").replace(D,"")}}var E=function(a){return a=+a,a!==a?a=0:a!==0&&a!==1/0&&a!==-Infinity&&(a=(a>0||-1)*Math.floor(Math.abs(a))),a},F="a"[0]!="a",G=function(a){if(a==null)throw new TypeError;return F&&typeof a=="string"&&a?a.split(""):Object(a)}}),ace.define("ace/lib/dom",["require","exports","module"],function(a,b,c){"use strict";var d="http://www.w3.org/1999/xhtml";b.createElement=function(a,b){return document.createElementNS?document.createElementNS(b||d,a):document.createElement(a)},b.setText=function(a,b){a.innerText!==undefined&&(a.innerText=b),a.textContent!==undefined&&(a.textContent=b)},b.hasCssClass=function(a,b){var c=a.className.split(/\s+/g);return c.indexOf(b)!==-1},b.addCssClass=function(a,c){b.hasCssClass(a,c)||(a.className+=" "+c)},b.removeCssClass=function(a,b){var c=a.className.split(/\s+/g);for(;;){var d=c.indexOf(b);if(d==-1)break;c.splice(d,1)}a.className=c.join(" ")},b.toggleCssClass=function(a,b){var c=a.className.split(/\s+/g),d=!0;for(;;){var e=c.indexOf(b);if(e==-1)break;d=!1,c.splice(e,1)}return d&&c.push(b),a.className=c.join(" "),d},b.setCssClass=function(a,c,d){d?b.addCssClass(a,c):b.removeCssClass(a,c)},b.hasCssString=function(a,b){var c=0,d;b=b||document;if(b.createStyleSheet&&(d=b.styleSheets)){while(c5||Math.abs(a.clientY-j)>5)h=0;h==d&&(h=0,g(a));if(e)return b.preventDefault(a)};b.addListener(a,"mousedown",k),e.isOldIE&&b.addListener(a,"dblclick",k)},b.addCommandKeyListener=function(a,c){var d=b.addListener;if(e.isOldGecko||e.isOpera){var f=null;d(a,"keydown",function(a){f=a.keyCode}),d(a,"keypress",function(a){return g(c,a,f)})}else{var h=null;d(a,"keydown",function(a){return h=a.keyIdentifier||a.keyCode,g(c,a,a.keyCode)})}};if(window.postMessage){var h=1;b.nextTick=function(a,c){c=c||window;var d="zero-timeout-message-"+h;b.addListener(c,"message",function e(f){f.data==d&&(b.stopPropagation(f),b.removeListener(c,"message",e),a())}),c.postMessage(d,"*")}}else b.nextTick=function(a,b){b=b||window,window.setTimeout(a,0)}}),ace.define("ace/lib/keys",["require","exports","module","ace/lib/oop"],function(a,b,c){"use strict";var d=a("./oop"),e=function(){var a={MODIFIER_KEYS:{16:"Shift",17:"Ctrl",18:"Alt",224:"Meta"},KEY_MODS:{ctrl:1,alt:2,option:2,shift:4,meta:8,command:8},FUNCTION_KEYS:{8:"Backspace",9:"Tab",13:"Return",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock"},PRINTABLE_KEYS:{32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",188:",",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:'"'}};for(var b in a.FUNCTION_KEYS){var c=a.FUNCTION_KEYS[b].toUpperCase();a[c]=parseInt(b,10)}return d.mixin(a,a.MODIFIER_KEYS),d.mixin(a,a.PRINTABLE_KEYS),d.mixin(a,a.FUNCTION_KEYS),a}();d.mixin(b,e),b.keyCodeToString=function(a){return(e[a]||String.fromCharCode(a)).toLowerCase()}}),ace.define("ace/lib/oop",["require","exports","module"],function(a,b,c){"use strict",b.inherits=function(){var a=function(){};return function(b,c){a.prototype=c.prototype,b.super_=c.prototype,b.prototype=new a,b.prototype.constructor=b}}(),b.mixin=function(a,b){for(var c in b)a[c]=b[c]},b.implement=function(a,c){b.mixin(a,c)}}),ace.define("ace/lib/useragent",["require","exports","module"],function(a,b,c){"use strict";var d=(navigator.platform.match(/mac|win|linux/i)||["other"])[0].toLowerCase(),e=navigator.userAgent;b.isWin=d=="win",b.isMac=d=="mac",b.isLinux=d=="linux",b.isIE=navigator.appName=="Microsoft Internet Explorer"&&parseFloat(navigator.userAgent.match(/MSIE ([0-9]+[\.0-9]+)/)[1]),b.isOldIE=b.isIE&&b.isIE<9,b.isGecko=b.isMozilla=window.controllers&&window.navigator.product==="Gecko",b.isOldGecko=b.isGecko&&parseInt((navigator.userAgent.match(/rv\:(\d+)/)||[])[1],10)<4,b.isOpera=window.opera&&Object.prototype.toString.call(window.opera)=="[object Opera]",b.isWebKit=parseFloat(e.split("WebKit/")[1])||undefined,b.isChrome=parseFloat(e.split(" Chrome/")[1])||undefined,b.isAIR=e.indexOf("AdobeAIR")>=0,b.isIPad=e.indexOf("iPad")>=0,b.isTouchPad=e.indexOf("TouchPad")>=0,b.OS={LINUX:"LINUX",MAC:"MAC",WINDOWS:"WINDOWS"},b.getOS=function(){return b.isMac?b.OS.MAC:b.isLinux?b.OS.LINUX:b.OS.WINDOWS}}),ace.define("ace/editor",["require","exports","module","ace/lib/fixoldbrowsers","ace/lib/oop","ace/lib/lang","ace/lib/useragent","ace/keyboard/textinput","ace/mouse/mouse_handler","ace/mouse/fold_handler","ace/keyboard/keybinding","ace/edit_session","ace/search","ace/range","ace/lib/event_emitter","ace/commands/command_manager","ace/commands/default_commands"],function(a,b,c){"use strict",a("./lib/fixoldbrowsers");var d=a("./lib/oop"),e=a("./lib/lang"),f=a("./lib/useragent"),g=a("./keyboard/textinput").TextInput,h=a("./mouse/mouse_handler").MouseHandler,i=a("./mouse/fold_handler").FoldHandler,j=a("./keyboard/keybinding").KeyBinding,k=a("./edit_session").EditSession,l=a("./search").Search,m=a("./range").Range,n=a("./lib/event_emitter").EventEmitter,o=a("./commands/command_manager").CommandManager,p=a("./commands/default_commands").commands,q=function(a,b){var c=a.getContainerElement();this.container=c,this.renderer=a,this.textInput=new g(a.getTextAreaContainer(),this),this.keyBinding=new j(this),f.isIPad||(this.$mouseHandler=new h(this),new i(this)),this.$blockScrolling=0,this.$search=(new l).set({wrap:!0}),this.commands=new o(f.isMac?"mac":"win",p),this.setSession(b||new k(""))};(function(){d.implement(this,n),this.setKeyboardHandler=function(a){this.keyBinding.setKeyboardHandler(a)},this.getKeyboardHandler=function(){return this.keyBinding.getKeyboardHandler()},this.setSession=function(a){if(this.session==a)return;if(this.session){var b=this.session;this.session.removeEventListener("change",this.$onDocumentChange),this.session.removeEventListener("changeMode",this.$onChangeMode),this.session.removeEventListener("tokenizerUpdate",this.$onTokenizerUpdate),this.session.removeEventListener("changeTabSize",this.$onChangeTabSize),this.session.removeEventListener("changeWrapLimit",this.$onChangeWrapLimit),this.session.removeEventListener("changeWrapMode",this.$onChangeWrapMode),this.session.removeEventListener("onChangeFold",this.$onChangeFold),this.session.removeEventListener("changeFrontMarker",this.$onChangeFrontMarker),this.session.removeEventListener("changeBackMarker",this.$onChangeBackMarker),this.session.removeEventListener("changeBreakpoint",this.$onChangeBreakpoint),this.session.removeEventListener("changeAnnotation",this.$onChangeAnnotation),this.session.removeEventListener("changeOverwrite",this.$onCursorChange),this.session.removeEventListener("changeScrollTop",this.$onScrollTopChange),this.session.removeEventListener("changeLeftTop",this.$onScrollLeftChange);var c=this.session.getSelection();c.removeEventListener("changeCursor",this.$onCursorChange),c.removeEventListener("changeSelection",this.$onSelectionChange)}this.session=a,this.$onDocumentChange=this.onDocumentChange.bind(this),a.addEventListener("change",this.$onDocumentChange),this.renderer.setSession(a),this.$onChangeMode=this.onChangeMode.bind(this),a.addEventListener("changeMode",this.$onChangeMode),this.$onTokenizerUpdate=this.onTokenizerUpdate.bind(this),a.addEventListener("tokenizerUpdate",this.$onTokenizerUpdate),this.$onChangeTabSize=this.renderer.updateText.bind(this.renderer),a.addEventListener("changeTabSize",this.$onChangeTabSize),this.$onChangeWrapLimit=this.onChangeWrapLimit.bind(this),a.addEventListener("changeWrapLimit",this.$onChangeWrapLimit),this.$onChangeWrapMode=this.onChangeWrapMode.bind(this),a.addEventListener("changeWrapMode",this.$onChangeWrapMode),this.$onChangeFold=this.onChangeFold.bind(this),a.addEventListener("changeFold",this.$onChangeFold),this.$onChangeFrontMarker=this.onChangeFrontMarker.bind(this),this.session.addEventListener("changeFrontMarker",this.$onChangeFrontMarker),this.$onChangeBackMarker=this.onChangeBackMarker.bind(this),this.session.addEventListener("changeBackMarker",this.$onChangeBackMarker),this.$onChangeBreakpoint=this.onChangeBreakpoint.bind(this),this.session.addEventListener("changeBreakpoint",this.$onChangeBreakpoint),this.$onChangeAnnotation=this.onChangeAnnotation.bind(this),this.session.addEventListener("changeAnnotation",this.$onChangeAnnotation),this.$onCursorChange=this.onCursorChange.bind(this),this.session.addEventListener("changeOverwrite",this.$onCursorChange),this.$onScrollTopChange=this.onScrollTopChange.bind(this),this.session.addEventListener("changeScrollTop",this.$onScrollTopChange),this.$onScrollLeftChange=this.onScrollLeftChange.bind(this),this.session.addEventListener("changeScrollLeft",this.$onScrollLeftChange),this.selection=a.getSelection(),this.selection.addEventListener("changeCursor",this.$onCursorChange),this.$onSelectionChange=this.onSelectionChange.bind(this),this.selection.addEventListener("changeSelection",this.$onSelectionChange),this.onChangeMode(),this.$blockScrolling+=1,this.onCursorChange(),this.$blockScrolling-=1,this.onScrollTopChange(),this.onScrollLeftChange(),this.onSelectionChange(),this.onChangeFrontMarker(),this.onChangeBackMarker(),this.onChangeBreakpoint(),this.onChangeAnnotation(),this.session.getUseWrapMode()&&this.renderer.adjustWrapLimit(),this.renderer.updateFull(),this._emit("changeSession",{session:a,oldSession:b})},this.getSession=function(){return this.session},this.getSelection=function(){return this.selection},this.resize=function(){this.renderer.onResize()},this.setTheme=function(a){this.renderer.setTheme(a)},this.getTheme=function(){return this.renderer.getTheme()},this.setStyle=function(a){this.renderer.setStyle(a)},this.unsetStyle=function(a){this.renderer.unsetStyle(a)},this.setFontSize=function(a){this.container.style.fontSize=a,this.renderer.updateFontSize()},this.$highlightBrackets=function(){this.session.$bracketHighlight&&(this.session.removeMarker(this.session.$bracketHighlight),this.session.$bracketHighlight=null);if(this.$highlightPending)return;var a=this;this.$highlightPending=!0,setTimeout(function(){a.$highlightPending=!1;var b=a.session.findMatchingBracket(a.getCursorPosition());if(b){var c=new m(b.row,b.column,b.row,b.column+1);a.session.$bracketHighlight=a.session.addMarker(c,"ace_bracket","text")}},10)},this.focus=function(){var a=this;setTimeout(function(){a.textInput.focus()}),this.textInput.focus()},this.isFocused=function(){return this.textInput.isFocused()},this.blur=function(){this.textInput.blur()},this.onFocus=function(){this.renderer.showCursor(),this.renderer.visualizeFocus(),this._emit("focus")},this.onBlur=function(){this.renderer.hideCursor(),this.renderer.visualizeBlur(),this._emit("blur")},this.onDocumentChange=function(a){var b=a.data,c=b.range,d;c.start.row==c.end.row&&b.action!="insertLines"&&b.action!="removeLines"?d=c.end.row:d=Infinity,this.renderer.updateLines(c.start.row,d),this._emit("change",a),this.onCursorChange()},this.onTokenizerUpdate=function(a){var b=a.data;this.renderer.updateLines(b.first,b.last)},this.onScrollTopChange=function(){this.renderer.scrollToY(this.session.getScrollTop())},this.onScrollLeftChange=function(){this.renderer.scrollToX(this.session.getScrollLeft())},this.onCursorChange=function(){this.renderer.updateCursor(),this.$blockScrolling||this.renderer.scrollCursorIntoView(),this.renderer.moveTextAreaToCursor(this.textInput.getElement()),this.$highlightBrackets(),this.$updateHighlightActiveLine()},this.$updateHighlightActiveLine=function(){var a=this.getSession();a.$highlightLineMarker&&a.removeMarker(a.$highlightLineMarker),typeof this.$lastrow=="number"&&this.renderer.removeGutterDecoration(this.$lastrow,"ace_gutter_active_line"),a.$highlightLineMarker=null,this.$lastrow=null;if(this.getHighlightActiveLine()){var b=this.getCursorPosition(),c=this.session.getFoldLine(b.row);if(this.getSelectionStyle()!="line"||!this.selection.isMultiLine()){var d;c?d=new m(c.start.row,0,c.end.row+1,0):d=new m(b.row,0,b.row+1,0),a.$highlightLineMarker=a.addMarker(d,"ace_active_line","background")}this.renderer.addGutterDecoration(this.$lastrow=b.row,"ace_gutter_active_line")}},this.onSelectionChange=function(a){var b=this.getSession();b.$selectionMarker&&b.removeMarker(b.$selectionMarker),b.$selectionMarker=null;if(!this.selection.isEmpty()){var c=this.selection.getRange(),d=this.getSelectionStyle();b.$selectionMarker=b.addMarker(c,"ace_selection",d)}else this.$updateHighlightActiveLine();this.$highlightSelectedWord&&this.session.getMode().highlightSelection(this)},this.onChangeFrontMarker=function(){this.renderer.updateFrontMarkers()},this.onChangeBackMarker=function(){this.renderer.updateBackMarkers()},this.onChangeBreakpoint=function(){this.renderer.setBreakpoints(this.session.getBreakpoints())},this.onChangeAnnotation=function(){this.renderer.setAnnotations(this.session.getAnnotations())},this.onChangeMode=function(){this.renderer.updateText()},this.onChangeWrapLimit=function(){this.renderer.updateFull()},this.onChangeWrapMode=function(){this.renderer.onResize(!0)},this.onChangeFold=function(){this.$updateHighlightActiveLine(),this.renderer.updateFull()},this.getCopyText=function(){var a="";return this.selection.isEmpty()||(a=this.session.getTextRange(this.getSelectionRange())),this._emit("copy",a),a},this.onCut=function(){this.commands.exec("cut",this)},this.insert=function(a){var b=this.session,c=b.getMode(),d=this.getCursorPosition();if(this.getBehavioursEnabled()){var e=c.transformAction(b.getState(d.row),"insertion",this,b,a);e&&(a=e.text)}a=a.replace(" ",this.session.getTabString());if(!this.selection.isEmpty())d=this.session.remove(this.getSelectionRange()),this.clearSelection();else if(this.session.getOverwrite()){var f=new m.fromPoints(d,d);f.end.column+=a.length,this.session.remove(f)}this.clearSelection();var g=d.column,h=b.getState(d.row),i=c.checkOutdent(h,b.getLine(d.row),a),j=b.getLine(d.row),k=c.getNextLineIndent(h,j.slice(0,d.column),b.getTabString()),l=b.insert(d,a);e&&e.selection&&(e.selection.length==2?this.selection.setSelectionRange(new m(d.row,g+e.selection[0],d.row,g+e.selection[1])):this.selection.setSelectionRange(new m(d.row+e.selection[0],e.selection[1],d.row+e.selection[2],e.selection[3])));var h=b.getState(d.row);if(b.getDocument().isNewLine(a)){this.moveCursorTo(d.row+1,0);var n=b.getTabSize(),o=Number.MAX_VALUE;for(var p=d.row+1;p<=l.row;++p){var q=0;j=b.getLine(p);for(var r=0;r0;++r)j.charAt(r)==" "?s-=n:j.charAt(r)==" "&&(s-=1);b.remove(new m(p,0,p,r))}b.indentRows(d.row+1,l.row,k)}i&&c.autoOutdent(h,b,d.row)},this.onTextInput=function(a,b){b&&this._emit("paste",a),this.keyBinding.onTextInput(a,b)},this.onCommandKey=function(a,b,c){this.keyBinding.onCommandKey(a,b,c)},this.setOverwrite=function(a){this.session.setOverwrite(a)},this.getOverwrite=function(){return this.session.getOverwrite()},this.toggleOverwrite=function(){this.session.toggleOverwrite()},this.setScrollSpeed=function(a){this.$mouseHandler.setScrollSpeed(a)},this.getScrollSpeed=function(){return this.$mouseHandler.getScrollSpeed()},this.setDragDelay=function(a){this.$mouseHandler.setDragDelay(a)},this.getDragDelay=function(){return this.$mouseHandler.getDragDelay()},this.$selectionStyle="line",this.setSelectionStyle=function(a){if(this.$selectionStyle==a)return;this.$selectionStyle=a,this.onSelectionChange(),this._emit("changeSelectionStyle",{data:a})},this.getSelectionStyle=function(){return this.$selectionStyle},this.$highlightActiveLine=!0,this.setHighlightActiveLine=function(a){if(this.$highlightActiveLine==a)return;this.$highlightActiveLine=a,this.$updateHighlightActiveLine()},this.getHighlightActiveLine=function(){return this.$highlightActiveLine},this.$highlightSelectedWord=!0,this.setHighlightSelectedWord=function(a){if(this.$highlightSelectedWord==a)return;this.$highlightSelectedWord=a,a?this.session.getMode().highlightSelection(this):this.session.getMode().clearSelectionHighlight(this)},this.getHighlightSelectedWord=function(){return this.$highlightSelectedWord},this.setAnimatedScroll=function(a){this.renderer.setAnimatedScroll(a)},this.getAnimatedScroll=function(){return this.renderer.getAnimatedScroll()},this.setShowInvisibles=function(a){if(this.getShowInvisibles()==a)return;this.renderer.setShowInvisibles(a)},this.getShowInvisibles=function(){return this.renderer.getShowInvisibles()},this.setShowPrintMargin=function(a){this.renderer.setShowPrintMargin(a)},this.getShowPrintMargin=function(){return this.renderer.getShowPrintMargin()},this.setPrintMarginColumn=function(a){this.renderer.setPrintMarginColumn(a)},this.getPrintMarginColumn=function(){return this.renderer.getPrintMarginColumn()},this.$readOnly=!1,this.setReadOnly=function(a){this.$readOnly=a},this.getReadOnly=function(){return this.$readOnly},this.$modeBehaviours=!0,this.setBehavioursEnabled=function(a){this.$modeBehaviours=a},this.getBehavioursEnabled=function(){return this.$modeBehaviours},this.setShowFoldWidgets=function(a){var b=this.renderer.$gutterLayer;if(b.getShowFoldWidgets()==a)return;this.renderer.$gutterLayer.setShowFoldWidgets(a),this.$showFoldWidgets=a,this.renderer.updateFull()},this.getShowFoldWidgets=function(){return this.renderer.$gutterLayer.getShowFoldWidgets()},this.remove=function(a){this.selection.isEmpty()&&(a=="left"?this.selection.selectLeft():this.selection.selectRight());var b=this.getSelectionRange();if(this.getBehavioursEnabled()){var c=this.session,d=c.getState(b.start.row),e=c.getMode().transformAction(d,"deletion",this,c,b);e&&(b=e)}this.session.remove(b),this.clearSelection()},this.removeWordRight=function(){this.selection.isEmpty()&&this.selection.selectWordRight(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeWordLeft=function(){this.selection.isEmpty()&&this.selection.selectWordLeft(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineStart=function(){this.selection.isEmpty()&&this.selection.selectLineStart(),this.session.remove(this.getSelectionRange()),this.clearSelection()},this.removeToLineEnd=function(){this.selection.isEmpty()&&this.selection.selectLineEnd();var a=this.getSelectionRange();a.start.column==a.end.column&&a.start.row==a.end.row&&(a.end.column=0,a.end.row++),this.session.remove(a),this.clearSelection()},this.splitLine=function(){this.selection.isEmpty()||(this.session.remove(this.getSelectionRange()),this.clearSelection());var a=this.getCursorPosition();this.insert("\n"),this.moveCursorToPosition(a)},this.transposeLetters=function(){if(!this.selection.isEmpty())return;var a=this.getCursorPosition(),b=a.column;if(b===0)return;var c=this.session.getLine(a.row),d,e;b=this.getFirstVisibleRow()&&a<=this.getLastVisibleRow()},this.isRowFullyVisible=function(a){return a>=this.renderer.getFirstFullyVisibleRow()&&a<=this.renderer.getLastFullyVisibleRow()},this.$getVisibleRowCount=function(){return this.renderer.getScrollBottomRow()-this.renderer.getScrollTopRow()+1},this.$getPageDownRow=function(){return this.renderer.getScrollBottomRow()},this.$getPageUpRow=function(){var a=this.renderer.getScrollTopRow(),b=this.renderer.getScrollBottomRow();return a-(b-a)},this.selectPageDown=function(){var a=this.$getPageDownRow()+Math.floor(this.$getVisibleRowCount()/2);this.scrollPageDown();var b=this.getSelection(),c=this.session.documentToScreenPosition(b.getSelectionLead()),d=this.session.screenToDocumentPosition(a,c.column);b.selectTo(d.row,d.column)},this.selectPageUp=function(){var a=this.renderer.getScrollTopRow()-this.renderer.getScrollBottomRow(),b=this.$getPageUpRow()+Math.round(a/2);this.scrollPageUp();var c=this.getSelection(),d=this.session.documentToScreenPosition(c.getSelectionLead()),e=this.session.screenToDocumentPosition(b,d.column);c.selectTo(e.row,e.column)},this.gotoPageDown=function(){var a=this.$getPageDownRow(),b=this.getCursorPositionScreen().column;this.scrollToRow(a),this.getSelection().moveCursorToScreen(a,b)},this.gotoPageUp=function(){var a=this.$getPageUpRow(),b=this.getCursorPositionScreen().column;this.scrollToRow(a),this.getSelection().moveCursorToScreen(a,b)},this.scrollPageDown=function(){this.scrollToRow(this.$getPageDownRow())},this.scrollPageUp=function(){this.renderer.scrollToRow(this.$getPageUpRow())},this.scrollToRow=function(a){this.renderer.scrollToRow(a)},this.scrollToLine=function(a,b){this.renderer.scrollToLine(a,b)},this.centerSelection=function(){var a=this.getSelectionRange(),b=Math.floor(a.start.row+(a.end.row-a.start.row)/2);this.renderer.scrollToLine(b,!0)},this.getCursorPosition=function(){return this.selection.getCursor()},this.getCursorPositionScreen=function(){return this.session.documentToScreenPosition(this.getCursorPosition())},this.getSelectionRange=function(){return this.selection.getRange()},this.selectAll=function(){this.$blockScrolling+=1,this.selection.selectAll(),this.$blockScrolling-=1},this.clearSelection=function(){this.selection.clearSelection()},this.moveCursorTo=function(a,b){this.selection.moveCursorTo(a,b)},this.moveCursorToPosition=function(a){this.selection.moveCursorToPosition(a)},this.jumpToMatching=function(){var a=this.getCursorPosition(),b=this.session.findMatchingBracket(a);b||(a.column+=1,b=this.session.findMatchingBracket(a)),b||(a.column-=2,b=this.session.findMatchingBracket(a)),b&&(this.clearSelection(),this.moveCursorTo(b.row,b.column))},this.gotoLine=function(a,b){this.selection.clearSelection(),this.session.unfold({row:a-1,column:b||0}),this.$blockScrolling+=1,this.moveCursorTo(a-1,b||0),this.$blockScrolling-=1,this.isRowFullyVisible(this.getCursorPosition().row)||this.scrollToLine(a,!0)},this.navigateTo=function(a,b){this.clearSelection(),this.moveCursorTo(a,b)},this.navigateUp=function(a){this.selection.clearSelection(),a=a||1,this.selection.moveCursorBy(-a,0)},this.navigateDown=function(a){this.selection.clearSelection(),a=a||1,this.selection.moveCursorBy(a,0)},this.navigateLeft=function(a){if(!this.selection.isEmpty()){var b=this.getSelectionRange().start;this.moveCursorToPosition(b)}else{a=a||1;while(a--)this.selection.moveCursorLeft()}this.clearSelection()},this.navigateRight=function(a){if(!this.selection.isEmpty()){var b=this.getSelectionRange().end;this.moveCursorToPosition(b)}else{a=a||1;while(a--)this.selection.moveCursorRight()}this.clearSelection()},this.navigateLineStart=function(){this.selection.moveCursorLineStart(),this.clearSelection()},this.navigateLineEnd=function(){this.selection.moveCursorLineEnd(),this.clearSelection()},this.navigateFileEnd=function(){this.selection.moveCursorFileEnd(),this.clearSelection()},this.navigateFileStart=function(){this.selection.moveCursorFileStart(),this.clearSelection()},this.navigateWordRight=function(){this.selection.moveCursorWordRight(),this.clearSelection()},this.navigateWordLeft=function(){this.selection.moveCursorWordLeft(),this.clearSelection()},this.replace=function(a,b){b&&this.$search.set(b);var c=this.$search.find(this.session),d=0;return c?(this.$tryReplace(c,a)&&(d=1),c!==null&&(this.selection.setSelectionRange(c),this.renderer.scrollSelectionIntoView(c.start,c.end)),d):d},this.replaceAll=function(a,b){b&&this.$search.set(b);var c=this.$search.findAll(this.session),d=0;if(!c.length)return d;this.$blockScrolling+=1;var e=this.getSelectionRange();this.clearSelection(),this.selection.moveCursorTo(0,0);for(var f=c.length-1;f>=0;--f)this.$tryReplace(c[f],a)&&d++;return this.selection.setSelectionRange(e),this.$blockScrolling-=1,d},this.$tryReplace=function(a,b){var c=this.session.getTextRange(a);return b=this.$search.replace(c,b),b!==null?(a.end=this.session.replace(a,b),a):null},this.getLastSearchOptions=function(){return this.$search.getOptions()},this.find=function(a,b){this.clearSelection(),b=b||{},b.needle=a,this.$search.set(b),this.$find()},this.findNext=function(a){a=a||{},typeof a.backwards=="undefined"&&(a.backwards=!1),this.$search.set(a),this.$find()},this.findPrevious=function(a){a=a||{},typeof a.backwards=="undefined"&&(a.backwards=!0),this.$search.set(a),this.$find()},this.$find=function(a){this.selection.isEmpty()||this.$search.set({needle:this.session.getTextRange(this.getSelectionRange())}),typeof a!="undefined"&&this.$search.set({backwards:a});var b=this.$search.find(this.session);if(b){this.session.unfold(b),this.$blockScrolling+=1,this.selection.setSelectionRange(b),this.$blockScrolling-=1;if(this.getAnimatedScroll()){var c=this.getCursorPosition();this.isRowFullyVisible(c.row)||this.scrollToLine(c.row,!0)}else this.renderer.scrollSelectionIntoView(b.start,b.end)}},this.undo=function(){this.session.getUndoManager().undo()},this.redo=function(){this.session.getUndoManager().redo()},this.destroy=function(){this.renderer.destroy()}}).call(q.prototype),b.Editor=q}),ace.define("ace/lib/lang",["require","exports","module"],function(a,b,c){"use strict",b.stringReverse=function(a){return a.split("").reverse().join("")},b.stringRepeat=function(a,b){return(new Array(b+1)).join(a)};var d=/^\s\s*/,e=/\s\s*$/;b.stringTrimLeft=function(a){return a.replace(d,"")},b.stringTrimRight=function(a){return a.replace(e,"")},b.copyObject=function(a){var b={};for(var c in a)b[c]=a[c];return b},b.copyArray=function(a){var b=[];for(var c=0,d=a.length;c128)return;setTimeout(function(){h||m()},0)},p=function(a){h=!0,b.onCompositionStart(),e.isGecko||setTimeout(q,0)},q=function(){if(!h)return;b.onCompositionUpdate(c.value)},r=function(a){h=!1,b.onCompositionEnd()},s=function(a){i=!0;var d=b.getCopyText();d?c.value=d:a.preventDefault(),l(),setTimeout(function(){m()},0)},t=function(a){i=!0;var d=b.getCopyText();d?(c.value=d,b.onCut()):a.preventDefault(),l(),setTimeout(function(){m()},0)};d.addCommandKeyListener(c,b.onCommandKey.bind(b));if(e.isOldIE){var u={13:1,27:1};d.addListener(c,"keyup",function(a){h&&(!c.value||u[a.keyCode])&&setTimeout(r,0);if((c.value.charCodeAt(0)|0)<129)return;h?q():p()})}"onpropertychange"in c&&!("oninput"in c)?d.addListener(c,"propertychange",o):d.addListener(c,"input",n),d.addListener(c,"paste",function(a){j=!0,a.clipboardData&&a.clipboardData.getData?(m(a.clipboardData.getData("text/plain")),a.preventDefault()):o()}),"onbeforecopy"in c&&typeof clipboardData!="undefined"?(d.addListener(c,"beforecopy",function(a){var c=b.getCopyText();c?clipboardData.setData("Text",c):a.preventDefault()}),d.addListener(a,"keydown",function(a){if(a.ctrlKey&&a.keyCode==88){var c=b.getCopyText();c&&(clipboardData.setData("Text",c),b.onCut()),d.preventDefault(a)}})):(d.addListener(c,"copy",s),d.addListener(c,"cut",t)),d.addListener(c,"compositionstart",p),e.isGecko&&d.addListener(c,"text",q),e.isWebKit&&d.addListener(c,"keyup",q),d.addListener(c,"compositionend",r),d.addListener(c,"blur",function(){b.onBlur()}),d.addListener(c,"focus",function(){b.onFocus(),l()}),this.focus=function(){b.onFocus(),l(),c.focus()},this.blur=function(){c.blur()},this.isFocused=v,this.getElement=function(){return c},this.onContextMenu=function(a,b){a&&(k||(k=c.style.cssText),c.style.cssText="position:fixed; z-index:1000;left:"+(a.x-2)+"px; top:"+(a.y-2)+"px;"),b&&(c.value="")},this.onContextMenuClose=function(){setTimeout(function(){k&&(c.style.cssText=k,k=""),m()},0)}};b.TextInput=g}),ace.define("ace/mouse/mouse_handler",["require","exports","module","ace/lib/event","ace/mouse/default_handlers","ace/mouse/default_gutter_handler","ace/mouse/mouse_event"],function(a,b,c){"use strict";var d=a("../lib/event"),e=a("./default_handlers").DefaultHandlers,f=a("./default_gutter_handler").GutterHandler,g=a("./mouse_event").MouseEvent,h=function(a){this.editor=a,new e(a),new f(a),d.addListener(a.container,"mousedown",function(b){return a.focus(),d.preventDefault(b)}),d.addListener(a.container,"selectstart",function(a){return d.preventDefault(a)});var b=a.renderer.getMouseEventTarget();d.addListener(b,"mousedown",this.onMouseEvent.bind(this,"mousedown")),d.addListener(b,"click",this.onMouseEvent.bind(this,"click")),d.addListener(b,"mousemove",this.onMouseMove.bind(this,"mousemove")),d.addMultiMouseDownListener(b,0,2,500,this.onMouseEvent.bind(this,"dblclick")),d.addMultiMouseDownListener(b,0,3,600,this.onMouseEvent.bind(this,"tripleclick")),d.addMultiMouseDownListener(b,0,4,600,this.onMouseEvent.bind(this,"quadclick")),d.addMouseWheelListener(a.container,this.onMouseWheel.bind(this,"mousewheel"));var c=a.renderer.$gutter;d.addListener(c,"mousedown",this.onMouseEvent.bind(this,"guttermousedown")),d.addListener(c,"click",this.onMouseEvent.bind(this,"gutterclick")),d.addListener(c,"dblclick",this.onMouseEvent.bind(this,"gutterdblclick")),d.addListener(c,"mousemove",this.onMouseMove.bind(this,"gutter"))};(function(){this.$scrollSpeed=1,this.setScrollSpeed=function(a){this.$scrollSpeed=a},this.getScrollSpeed=function(){return this.$scrollSpeed},this.onMouseEvent=function(a,b){this.editor._emit(a,new g(b,this.editor))},this.$dragDelay=250,this.setDragDelay=function(a){this.$dragDelay=a},this.getDragDelay=function(){return this.$dragDelay},this.onMouseMove=function(a,b){var c=this.editor._eventRegistry&&this.editor._eventRegistry.mousemove;if(!c||!c.length)return;this.editor._emit(a,new g(b,this.editor))},this.onMouseWheel=function(a,b){var c=new g(b,this.editor);c.speed=this.$scrollSpeed*2,c.wheelX=b.wheelX,c.wheelY=b.wheelY,this.editor._emit(a,c)}}).call(h.prototype),b.MouseHandler=h}),ace.define("ace/mouse/default_handlers",["require","exports","module","ace/lib/event","ace/lib/dom","ace/lib/browser_focus"],function(a,b,c){function k(a){this.editor=a,this.$clickSelection=null,this.browserFocus=new f,a.setDefaultHandler("mousedown",this.onMouseDown.bind(this)),a.setDefaultHandler("dblclick",this.onDoubleClick.bind(this)),a.setDefaultHandler("tripleclick",this.onTripleClick.bind(this)),a.setDefaultHandler("quadclick",this.onQuadClick.bind(this)),a.setDefaultHandler("mousewheel",this.onScroll.bind(this))}function l(a,b,c,d){return Math.sqrt(Math.pow(c-a,2)+Math.pow(d-b,2))}"use strict";var d=a("../lib/event"),e=a("../lib/dom"),f=a("../lib/browser_focus").BrowserFocus,g=0,h=1,i=2,j=5;(function(){this.onMouseDown=function(a){function C(b){a.getShiftKey()?m.selection.selectToPosition(b):n.$clickSelection||(m.moveCursorToPosition(b),m.selection.clearSelection()),q=h}var b=a.inSelection(),c=a.pageX,f=a.pageY,k=a.getDocumentPosition(),m=this.editor,n=this,o=m.getSelectionRange(),p=o.isEmpty(),q=g;if(b&&(!this.browserFocus.isFocused()||(new Date).getTime()-this.browserFocus.lastFocus<20||!m.isFocused())){m.focus();return}var r=a.getButton();if(r!==0){p&&m.moveCursorToPosition(k),r==2&&(m.textInput.onContextMenu({x:a.clientX,y:a.clientY},p),d.capture(m.container,function(){},m.textInput.onContextMenuClose));return}b||C(k);var s=c,t=f,u=(new Date).getTime(),v,w,x,y=function(a){s=d.getDocumentX(a),t=d.getDocumentY(a)},z=function(a){clearInterval(F),q==g?C(k):q==i&&A(a),n.$clickSelection=null,q=g},A=function(a){e.removeCssClass(m.container,"ace_dragging"),m.session.removeMarker(x),m.$mouseHandler.$clickSelection||v||(m.moveCursorToPosition(k),m.selection.clearSelection());if(!v)return;if(w.contains(v.row,v.column)){v=null;return}m.clearSelection();if(a&&(a.ctrlKey||a.altKey))var b=m.session,c=b.insert(v,b.getTextRange(w));else var c=m.moveText(w,v);if(!c){v=null;return}m.selection.setSelectionRange(c)},B=function(){if(q==g){var a=l(c,f,s,t),b=(new Date).getTime();if(a>j){q=h;var d=m.renderer.screenToTextCoordinates(s,t);C(d)}else if(b-u>m.getDragDelay()){q=i,w=m.getSelectionRange();var k=m.getSelectionStyle();x=m.session.addMarker(w,"ace_selection",k),m.clearSelection(),e.addCssClass(m.container,"ace_dragging")}}q==i?E():q==h&&D()},D=function(){var a,b=m.renderer.screenToTextCoordinates(s,t);n.$clickSelection?n.$clickSelection.contains(b.row,b.column)?m.selection.setSelectionRange(n.$clickSelection):(n.$clickSelection.compare(b.row,b.column)==-1?a=n.$clickSelection.end:a=n.$clickSelection.start,m.selection.setSelectionAnchor(a.row,a.column),m.selection.selectToPosition(b)):m.selection.selectToPosition(b),m.renderer.scrollCursorIntoView()},E=function(){v=m.renderer.screenToTextCoordinates(s,t),m.moveCursorToPosition(v)};d.capture(m.container,y,z);var F=setInterval(B,20);return a.preventDefault()},this.onDoubleClick=function(a){var b=a.getDocumentPosition(),c=this.editor;c.moveCursorToPosition(b),c.selection.selectWord(),this.$clickSelection=c.getSelectionRange()},this.onTripleClick=function(a){var b=a.getDocumentPosition(),c=this.editor;c.moveCursorToPosition(b),c.selection.selectLine(),this.$clickSelection=c.getSelectionRange()},this.onQuadClick=function(a){var b=this.editor;b.selectAll(),this.$clickSelection=b.getSelectionRange()},this.onScroll=function(a){var b=this.editor;b.renderer.scrollBy(a.wheelX*a.speed,a.wheelY*a.speed);if(b.renderer.isScrollableBy(a.wheelX*a.speed,a.wheelY*a.speed))return a.preventDefault()}}).call(k.prototype),b.DefaultHandlers=k}),ace.define("ace/lib/browser_focus",["require","exports","module","ace/lib/oop","ace/lib/event","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("./oop"),e=a("./event"),f=a("./event_emitter").EventEmitter,g=function(a){a=a||window,this.lastFocus=(new Date).getTime(),this._isFocused=!0;var b=this;"onfocusin"in a.document?(e.addListener(a.document,"focusin",function(a){b._setFocused(!0)}),e.addListener(a.document,"focusout",function(a){b._setFocused(!!a.toElement)})):(e.addListener(a,"blur",function(a){b._setFocused(!1)}),e.addListener(a,"focus",function(a){b._setFocused(!0)}))};(function(){d.implement(this,f),this.isFocused=function(){return this._isFocused},this._setFocused=function(a){if(this._isFocused==a)return;a&&(this.lastFocus=(new Date).getTime()),this._isFocused=a,this._emit("changeFocus")}}).call(g.prototype),b.BrowserFocus=g}),ace.define("ace/lib/event_emitter",["require","exports","module"],function(a,b,c){"use strict";var d={};d._emit=d._dispatchEvent=function(a,b){this._eventRegistry=this._eventRegistry||{},this._defaultHandlers=this._defaultHandlers||{};var c=this._eventRegistry[a]||[],d=this._defaultHandlers[a];if(!c.length&&!d)return;b=b||{},b.type=a,b.stopPropagation||(b.stopPropagation=function(){this.propagationStopped=!0}),b.preventDefault||(b.preventDefault=function(){this.defaultPrevented=!0});for(var e=0;e=4352&&a<=4447||a>=4515&&a<=4519||a>=4602&&a<=4607||a>=9001&&a<=9002||a>=11904&&a<=11929||a>=11931&&a<=12019||a>=12032&&a<=12245||a>=12272&&a<=12283||a>=12288&&a<=12350||a>=12353&&a<=12438||a>=12441&&a<=12543||a>=12549&&a<=12589||a>=12593&&a<=12686||a>=12688&&a<=12730||a>=12736&&a<=12771||a>=12784&&a<=12830||a>=12832&&a<=12871||a>=12880&&a<=13054||a>=13056&&a<=19903||a>=19968&&a<=42124||a>=42128&&a<=42182||a>=43360&&a<=43388||a>=44032&&a<=55203||a>=55216&&a<=55238||a>=55243&&a<=55291||a>=63744&&a<=64255||a>=65040&&a<=65049||a>=65072&&a<=65106||a>=65108&&a<=65126||a>=65128&&a<=65131||a>=65281&&a<=65376||a>=65504&&a<=65510}e.implement(this,h),this.setDocument=function(a){if(this.doc)throw new Error("Document is already set");this.doc=a,a.on("change",this.onChange.bind(this)),this.on("changeFold",this.onChangeFold.bind(this)),this.bgTokenizer&&(this.bgTokenizer.setDocument(this.getDocument()),this.bgTokenizer.start(0))},this.getDocument=function(){return this.doc},this.$resetRowCache=function(a){if(a==0){this.$rowCache=[];return}var b=this.$rowCache;for(var c=0;c=a){b.splice(c,b.length);return}},this.onChangeFold=function(a){var b=a.data;this.$resetRowCache(b.start.row)},this.onChange=function(a){var b=a.data;this.$modified=!0,this.$resetRowCache(b.range.start.row);var c=this.$updateInternalDataOnChange(a);!this.$fromUndo&&this.$undoManager&&!b.ignore&&(this.$deltasDoc.push(b),c&&c.length!=0&&this.$deltasFold.push({action:"removeFolds",folds:c}),this.$informUndoManager.schedule()),this.bgTokenizer.start(b.range.start.row),this._emit("change",a)},this.setValue=function(a){this.doc.setValue(a),this.selection.moveCursorTo(0,0),this.selection.clearSelection(),this.$resetRowCache(0),this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.getUndoManager().reset()},this.getValue=this.toString=function(){return this.doc.getValue()},this.getSelection=function(){return this.selection},this.getState=function(a){return this.bgTokenizer.getState(a)},this.getTokens=function(a,b){return this.bgTokenizer.getTokens(a,b)},this.getTokenAt=function(a,b){var c=this.bgTokenizer.getTokens(a,a)[0].tokens,d,e=0;if(b==null)f=c.length-1,e=this.getLine(a).length;else for(var f=0;f=b)break}return d=c[f],d?(d.index=f,d.start=e-d.value.length,d):null},this.setUndoManager=function(a){this.$undoManager=a,this.$resetRowCache(0),this.$deltas=[],this.$deltasDoc=[],this.$deltasFold=[],this.$informUndoManager&&this.$informUndoManager.cancel();if(a){var b=this;this.$syncInformUndoManager=function(){b.$informUndoManager.cancel(),b.$deltasFold.length&&(b.$deltas.push({group:"fold",deltas:b.$deltasFold}),b.$deltasFold=[]),b.$deltasDoc.length&&(b.$deltas.push({group:"doc",deltas:b.$deltasDoc}),b.$deltasDoc=[]),b.$deltas.length>0&&a.execute({action:"aceupdate",args:[b.$deltas,b]}),b.$deltas=[]},this.$informUndoManager=f.deferredCall(this.$syncInformUndoManager)}},this.$defaultUndoManager={undo:function(){},redo:function(){},reset:function(){}},this.getUndoManager=function(){return this.$undoManager||this.$defaultUndoManager},this.getTabString=function(){return this.getUseSoftTabs()?f.stringRepeat(" ",this.getTabSize()):" "},this.$useSoftTabs=!0,this.setUseSoftTabs=function(a){if(this.$useSoftTabs===a)return;this.$useSoftTabs=a},this.getUseSoftTabs=function(){return this.$useSoftTabs},this.$tabSize=4,this.setTabSize=function(a){if(isNaN(a)||this.$tabSize===a)return;this.$modified=!0,this.$tabSize=a,this._emit("changeTabSize")},this.getTabSize=function(){return this.$tabSize},this.isTabStop=function(a){return this.$useSoftTabs&&a.column%this.$tabSize==0},this.$overwrite=!1,this.setOverwrite=function(a){if(this.$overwrite==a)return;this.$overwrite=a,this._emit("changeOverwrite")},this.getOverwrite=function(){return this.$overwrite},this.toggleOverwrite=function(){this.setOverwrite(!this.$overwrite)},this.getBreakpoints=function(){return this.$breakpoints},this.setBreakpoints=function(a){this.$breakpoints=[];for(var b=0;b0&&(d=!!c.charAt(b-1).match(this.tokenRe)),d||(d=!!c.charAt(b).match(this.tokenRe));var e=d?this.tokenRe:this.nonTokenRe,f=b;if(f>0){do f--;while(f>=0&&c.charAt(f).match(e));f++}var g=b;while(g=this.doc.getLength()-1)return 0;var c=this.doc.removeLines(a,b);return this.doc.insertLines(a+1,c),1},this.duplicateLines=function(a,b){var a=this.$clipRowToDocument(a),b=this.$clipRowToDocument(b),c=this.getLines(a,b);this.doc.insertLines(a,c);var d=b-a+1;return d},this.$clipRowToDocument=function(a){return Math.max(0,Math.min(a,this.doc.getLength()-1))},this.$clipColumnToRow=function(a,b){return b<0?0:Math.min(this.doc.getLine(a).length,b)},this.$clipPositionToDocument=function(a,b){b=Math.max(0,b);if(a<0)a=0,b=0;else{var c=this.doc.getLength();a>=c?(a=c-1,b=this.doc.getLine(c-1).length):b=Math.min(this.doc.getLine(a).length,b)}return{row:a,column:b}},this.$clipRangeToDocument=function(a){a.start.row<0?(a.start.row=0,a.start.column=0):a.start.column=this.$clipColumnToRow(a.start.row,a.start.column);var b=this.doc.getLength()-1;return a.end.row>b?(a.end.row=b,a.end.column=this.doc.getLine(b).length):a.end.column=this.$clipColumnToRow(a.end.row,a.end.column),a},this.$wrapLimit=80,this.$useWrapMode=!1,this.$wrapLimitRange={min:null,max:null},this.setUseWrapMode=function(a){if(a!=this.$useWrapMode){this.$useWrapMode=a,this.$modified=!0,this.$resetRowCache(0);if(a){var b=this.getLength();this.$wrapData=[];for(var c=0;c0?(this.$wrapLimit=b,this.$modified=!0,this.$useWrapMode&&(this.$updateWrapData(0,this.getLength()-1),this.$resetRowCache(0),this._emit("changeWrapLimit")),!0):!1},this.$constrainWrapLimit=function(a){var b=this.$wrapLimitRange.min;b&&(a=Math.max(b,a));var c=this.$wrapLimitRange.max;return c&&(a=Math.min(c,a)),Math.max(1,a)},this.getWrapLimit=function(){return this.$wrapLimit},this.getWrapLimitRange=function(){return{min:this.$wrapLimitRange.min,max:this.$wrapLimitRange.max}},this.$updateInternalDataOnChange=function(a){var b=this.$useWrapMode,c,d=a.data.action,e=a.data.range.start.row,f=a.data.range.end.row,g=a.data.range.start,h=a.data.range.end,i=null;d.indexOf("Lines")!=-1?(d=="insertLines"?f=e+a.data.lines.length:f=e,c=a.data.lines?a.data.lines.length:f-e):c=f-e;if(c!=0)if(d.indexOf("remove")!=-1){b&&this.$wrapData.splice(e,c);var j=this.$foldData;i=this.getFoldsInRange(a.data.range),this.removeFolds(i);var k=this.getFoldLine(h.row),l=0;if(k){k.addRemoveChars(h.row,h.column,g.column-h.column),k.shiftRow(-c);var m=this.getFoldLine(e);m&&m!==k&&(m.merge(k),k=m),l=j.indexOf(k)+1}for(l;l=h.row&&k.shiftRow(-c)}f=e}else{var n;if(b){n=[e,0];for(var o=0;o=e&&k.shiftRow(c)}}else{c=Math.abs(a.data.range.start.column-a.data.range.end.column),d.indexOf("remove")!=-1&&(i=this.getFoldsInRange(a.data.range),this.removeFolds(i),c=-c);var k=this.getFoldLine(e);k&&k.addRemoveChars(e,g.column,c)}return b&&this.$wrapData.length!=this.doc.getLength()&&console.error("doc.getLength() and $wrapData.length have to be the same!"),b&&this.$updateWrapData(e,f),i},this.$updateWrapData=function(a,b){var c=this.doc.getAllLines(),d=this.getTabSize(),e=this.$wrapData,g=this.$wrapLimit,h,k,l=a;b=Math.min(b,c.length-1);while(l<=b){k=this.getFoldLine(l,k);if(!k)h=this.$getDisplayTokens(f.stringTrimRight(c[l])),e[l]=this.$computeWrapSplits(h,g,d),l++;else{h=[],k.walk(function(a,b,d,e){var f;if(a){f=this.$getDisplayTokens(a,h.length),f[0]=i;for(var g=1;g=n)h.pop();e[k.start.row]=this.$computeWrapSplits(h,g,d),l=k.end.row+1}}};var b=1,c=2,i=3,j=4,l=9,n=10,o=11,p=12;this.$computeWrapSplits=function(a,b){function g(b){var d=a.slice(e,b),g=d.length;d.join("").replace(/12/g,function(){g-=1}).replace(/2/g,function(){g-=1}),f+=g,c.push(f),e=b}if(a.length==0)return[];var c=[],d=a.length,e=0,f=0;while(d-e>b){var h=e+b;if(a[h]>=n){while(a[h]>=n)h++;g(h);continue}if(a[h]==i||a[h]==j){for(h;h!=e-1;h--)if(a[h]==i)break;if(h>e){g(h);continue}h=e+b;for(h;hk&&a[h]k&&a[h]==l)h--;if(h>k){g(++h);continue}h=e+b,g(h)}return c},this.$getDisplayTokens=function(a,d){var e=[],f;d=d||0;for(var g=0;g39&&h<48||h>57&&h<64?e.push(l):h>=4352&&q(h)?e.push(b,c):e.push(b)}return e},this.$getStringScreenWidth=function(a,b,c){if(b==0)return[0,0];b==null&&(b=c+a.length*Math.max(this.getTabSize(),2)),c=c||0;var d,e;for(e=0;e=4352&&q(d)?c+=2:c+=1;if(c>b)break}return[c,e]},this.getRowLength=function(a){return!this.$useWrapMode||!this.$wrapData[a]?1:this.$wrapData[a].length+1},this.getRowHeight=function(a,b){return this.getRowLength(b)*a.lineHeight},this.getScreenLastRowColumn=function(a){var b=this.screenToDocumentPosition(a,Number.MAX_VALUE);return this.documentToScreenColumn(b.row,b.column)},this.getDocumentLastRowColumn=function(a,b){var c=this.documentToScreenRow(a,b);return this.getScreenLastRowColumn(c)},this.getDocumentLastRowColumnPosition=function(a,b){var c=this.documentToScreenRow(a,b);return this.screenToDocumentPosition(c,Number.MAX_VALUE/10)},this.getRowSplitData=function(a){return this.$useWrapMode?this.$wrapData[a]:undefined},this.getScreenTabSize=function(a){return this.$tabSize-a%this.$tabSize},this.screenToDocumentRow=function(a,b){return this.screenToDocumentPosition(a,b).row},this.screenToDocumentColumn=function(a,b){return this.screenToDocumentPosition(a,b).column},this.screenToDocumentPosition=function(a,b){if(a<0)return{row:0,column:0};var c,d=0,e=0,f,g=0,h=0,i=this.$rowCache;for(var j=0;j=a||d>=l)break;g+=h,d++,d>n&&(d=m.end.row+1,m=this.getNextFoldLine(d,m),n=m?m.start.row:Infinity),k&&i.push({docRow:d,screenRow:g})}if(m&&m.start.row<=d)c=this.getFoldDisplayLine(m),d=m.start.row;else{if(g+h<=a||d>l)return{row:l,column:this.getLine(l).length};c=this.getLine(d),m=null}if(this.$useWrapMode){var o=this.$wrapData[d];o&&(f=o[a-g],a>g&&o.length&&(e=o[a-g-1]||o[o.length-1],c=c.substring(e)))}return e+=this.$getStringScreenWidth(c,b)[1],this.$useWrapMode&&e>=f&&(e=f-1),m?m.idxToPosition(e):{row:d,column:e}},this.documentToScreenPosition=function(a,b){if(typeof b=="undefined")var c=this.$clipPositionToDocument(a.row,a.column);else c=this.$clipPositionToDocument(a,b);a=c.row,b=c.column;var d;if(this.$useWrapMode){d=this.$wrapData;if(a>d.length-1)return{row:this.getScreenLength(),column:d.length==0?0:d[d.length-1].length-1}}var e=0,f=null,g=null;g=this.getFoldAt(a,b,1),g&&(a=g.start.row,b=g.start.column);var h,i=0,j=this.$rowCache;for(var k=0;k=n){h=m.end.row+1;if(h>a)break;m=this.getNextFoldLine(h,m),n=m?m.start.row:Infinity}else h=i+1;e+=this.getRowLength(i),i=h,l&&j.push({docRow:i,screenRow:e})}var o="";m&&i>=n?(o=this.getFoldDisplayLine(m,a,b),f=m.start.row):(o=this.getLine(a).substring(0,b),f=a);if(this.$useWrapMode){var p=d[f],q=0;while(o.length>=p[q])e++,q++;o=o.substring(p[q-1]||0,o.length)}return{row:e,column:this.$getStringScreenWidth(o)[0]}},this.documentToScreenColumn=function(a,b){return this.documentToScreenPosition(a,b).column},this.documentToScreenRow=function(a,b){return this.documentToScreenPosition(a,b).row},this.getScreenLength=function(){var a=0,b=null;if(!this.$useWrapMode){a=this.getLength();var c=this.$foldData;for(var d=0;dg&&(f=b.end.row+1,b=this.$foldData[d++],g=b?b.start.row:Infinity)}return a}}).call(n.prototype),a("./edit_session/folding").Folding.call(n.prototype),a("./edit_session/bracket_match").BracketMatch.call(n.prototype),b.EditSession=n}),ace.define("ace/config",["require","exports","module","ace/lib/lang"],function(a,b,c){function g(a){return a.replace(/-(.)/g,function(a,b){return b.toUpperCase()})}"no use strict";var d=a("./lib/lang"),e=function(){return this}(),f={packaged:!1,workerPath:"",modePath:"",themePath:"",suffix:".js"};b.get=function(a){if(!f.hasOwnProperty(a))throw new Error("Unknown confik key: "+a);return f[a]},b.set=function(a,b){if(!f.hasOwnProperty(a))throw new Error("Unknown confik key: "+a);f[a]=b},b.all=function(){return d.copyObject(f)},b.init=function(){f.packaged=a.packaged||c.packaged||e.define&&define.packaged;if(!e.document)return"";var d={},h="",i,j=document.getElementsByTagName("script");for(var k=0;kb.row||a.row==b.row&&a.column>b.column},this.getRange=function(){var a=this.selectionAnchor,b=this.selectionLead;return this.isEmpty()?g.fromPoints(b,b):this.isBackwards()?g.fromPoints(b,a):g.fromPoints(a,b)},this.clearSelection=function(){this.$isEmpty||(this.$isEmpty=!0,this._emit("changeSelection"))},this.selectAll=function(){var a=this.doc.getLength()-1;this.setSelectionAnchor(a,this.doc.getLine(a).length),this.moveCursorTo(0,0)},this.setSelectionRange=function(a,b){b?(this.setSelectionAnchor(a.end.row,a.end.column),this.selectTo(a.start.row,a.start.column)):(this.setSelectionAnchor(a.start.row,a.start.column),this.selectTo(a.end.row,a.end.column)),this.$desiredColumn=null},this.$moveSelection=function(a){var b=this.selectionLead;this.$isEmpty&&this.setSelectionAnchor(b.row,b.column),a.call(this)},this.selectTo=function(a,b){this.$moveSelection(function(){this.moveCursorTo(a,b)})},this.selectToPosition=function(a){this.$moveSelection(function(){this.moveCursorToPosition(a)})},this.selectUp=function(){this.$moveSelection(this.moveCursorUp)},this.selectDown=function(){this.$moveSelection(this.moveCursorDown)},this.selectRight=function(){this.$moveSelection(this.moveCursorRight)},this.selectLeft=function(){this.$moveSelection(this.moveCursorLeft)},this.selectLineStart=function(){this.$moveSelection(this.moveCursorLineStart)},this.selectLineEnd=function(){this.$moveSelection(this.moveCursorLineEnd)},this.selectFileEnd=function(){this.$moveSelection(this.moveCursorFileEnd)},this.selectFileStart=function(){this.$moveSelection(this.moveCursorFileStart)},this.selectWordRight=function(){this.$moveSelection(this.moveCursorWordRight)},this.selectWordLeft=function(){this.$moveSelection(this.moveCursorWordLeft)},this.selectWord=function(){var a=this.getCursor(),b=this.session.getWordRange(a.row,a.column);this.setSelectionRange(b)},this.selectAWord=function(){var a=this.getCursor(),b=this.session.getAWordRange(a.row,a.column);this.setSelectionRange(b)},this.selectLine=function(){var a=this.selectionLead.row,b,c=this.session.getFoldLine(a);c?(a=c.start.row,b=c.end.row):b=a,this.setSelectionAnchor(a,0),this.$moveSelection(function(){this.moveCursorTo(b+1,0)})},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var a=this.selectionLead.getPosition(),b;if(b=this.session.getFoldAt(a.row,a.column,-1))this.moveCursorTo(b.start.row,b.start.column);else if(a.column==0)a.row>0&&this.moveCursorTo(a.row-1,this.doc.getLine(a.row-1).length);else{var c=this.session.getTabSize();this.session.isTabStop(a)&&this.doc.getLine(a.row).slice(a.column-c,a.column).split(" ").length-1==c?this.moveCursorBy(0,-c):this.moveCursorBy(0,-1)}},this.moveCursorRight=function(){var a=this.selectionLead.getPosition(),b;if(b=this.session.getFoldAt(a.row,a.column,1))this.moveCursorTo(b.end.row,b.end.column);else if(this.selectionLead.column==this.doc.getLine(this.selectionLead.row).length)this.selectionLead.row=c.length){this.moveCursorTo(a,c.length),this.moveCursorRight(),a0&&this.moveCursorWordLeft();return}if(g=this.session.tokenRe.exec(f))b-=this.session.tokenRe.lastIndex,this.session.tokenRe.lastIndex=0;this.moveCursorTo(a,b)},this.moveCursorBy=function(a,b){var c=this.session.documentToScreenPosition(this.selectionLead.row,this.selectionLead.column);b===0&&(this.$desiredColumn?c.column=this.$desiredColumn:this.$desiredColumn=c.column);var d=this.session.screenToDocumentPosition(c.row+a,c.column);this.moveCursorTo(d.row,d.column+b,b===0)},this.moveCursorToPosition=function(a){this.moveCursorTo(a.row,a.column)},this.moveCursorTo=function(a,b,c){var d=this.session.getFoldAt(a,b,1);d&&(a=d.start.row,b=d.start.column),this.$keepDesiredColumnOnChange=!0,this.selectionLead.setPosition(a,b),this.$keepDesiredColumnOnChange=!1,c||(this.$desiredColumn=null)},this.moveCursorToScreen=function(a,b,c){var d=this.session.screenToDocumentPosition(a,b);this.moveCursorTo(d.row,d.column,c)},this.detach=function(){this.selectionLead.detach(),this.selectionAnchor.detach(),this.session=this.doc=null},this.fromOrientedRange=function(a){this.setSelectionRange(a,a.cursor==a.start),this.$desiredColumn=a.desiredColumn||this.$desiredColumn},this.toOrientedRange=function(a){var b=this.getRange();return a?(a.start.column=b.start.column,a.start.row=b.start.row,a.end.column=b.end.column,a.end.row=b.end.row):a=b,a.cursor=this.isBackwards()?a.start:a.end,a.desiredColumn=this.$desiredColumn,a}}).call(h.prototype),b.Selection=h}),ace.define("ace/range",["require","exports","module"],function(a,b,c){"use strict";var d=function(a,b,c,d){this.start={row:a,column:b},this.end={row:c,column:d}};(function(){this.isEqual=function(a){return this.start.row==a.start.row&&this.end.row==a.end.row&&this.start.column==a.start.column&&this.end.column==a.end.column},this.toString=function(){return"Range: ["+this.start.row+"/"+this.start.column+"] -> ["+this.end.row+"/"+this.end.column+"]"},this.contains=function(a,b){return this.compare(a,b)==0},this.compareRange=function(a){var b,c=a.end,d=a.start;return b=this.compare(c.row,c.column),b==1?(b=this.compare(d.row,d.column),b==1?2:b==0?1:0):b==-1?-2:(b=this.compare(d.row,d.column),b==-1?-1:b==1?42:0)},this.comparePoint=function(a){return this.compare(a.row,a.column)},this.containsRange=function(a){return this.comparePoint(a.start)==0&&this.comparePoint(a.end)==0},this.intersects=function(a){var b=this.compareRange(a);return b==-1||b==0||b==1},this.isEnd=function(a,b){return this.end.row==a&&this.end.column==b},this.isStart=function(a,b){return this.start.row==a&&this.start.column==b},this.setStart=function(a,b){typeof a=="object"?(this.start.column=a.column,this.start.row=a.row):(this.start.row=a,this.start.column=b)},this.setEnd=function(a,b){typeof a=="object"?(this.end.column=a.column,this.end.row=a.row):(this.end.row=a,this.end.column=b)},this.inside=function(a,b){return this.compare(a,b)==0?this.isEnd(a,b)||this.isStart(a,b)?!1:!0:!1},this.insideStart=function(a,b){return this.compare(a,b)==0?this.isEnd(a,b)?!1:!0:!1},this.insideEnd=function(a,b){return this.compare(a,b)==0?this.isStart(a,b)?!1:!0:!1},this.compare=function(a,b){return!this.isMultiLine()&&a===this.start.row?bthis.end.column?1:0:athis.end.row?1:this.start.row===a?b>=this.start.column?0:-1:this.end.row===a?b<=this.end.column?0:1:0},this.compareStart=function(a,b){return this.start.row==a&&this.start.column==b?-1:this.compare(a,b)},this.compareEnd=function(a,b){return this.end.row==a&&this.end.column==b?1:this.compare(a,b)},this.compareInside=function(a,b){return this.end.row==a&&this.end.column==b?1:this.start.row==a&&this.start.column==b?-1:this.compare(a,b)},this.clipRows=function(a,b){if(this.end.row>b)var c={row:b+1,column:0};if(this.start.row>b)var e={row:b+1,column:0};if(this.start.row=0&&/^[\w\d]/.test(h)||e<=g&&/[\w\d]$/.test(h))return;h=f.substring(c.start.column,c.end.column);if(!/^[\w\d]+$/.test(h))return;var i=a.getCursorPosition(),j={wrap:!0,wholeWord:!0,caseSensitive:!0,needle:h},k=a.$search.getOptions();a.$search.set(j);var l=a.$search.findAll(b);l.forEach(function(a){if(!a.contains(i.row,i.column)){var c=b.addMarker(a,"ace_selected_word","text");b.$selectionOccurrences.push(c)}}),a.$search.set(k)},this.clearSelectionHighlight=function(a){if(!a.session.$selectionOccurrences)return;a.session.$selectionOccurrences.forEach(function(b){a.session.removeMarker(b)}),a.session.$selectionOccurrences=[]},this.createModeDelegates=function(a){if(!this.$embeds)return;this.$modes={};for(var b=0;b1&&e[i].token.length!==j-1)throw new Error("Matching groups and length of the token array don't match in rule #"+i+" of state "+c);h[g]={rule:i,len:j},g+=j,f.push(k)}this.regExps[c]=new RegExp("(?:("+f.join(")|(")+")|(.))",b)}};(function(){this.getLineTokens=function(a,b){var c=b,d=this.rules[c],e=this.matchMappings[c],f=this.regExps[c];f.lastIndex=0;var g,h=[],i=0,j={type:null,value:""};while(g=f.exec(a)){var k="text",l=null,m=[g[0]];for(var n=0;n1&&(m=g.slice(n+2,n+1+e[n].len)),typeof l.token=="function"?k=l.token.apply(this,m):k=l.token,l.next&&(c=l.next,d=this.rules[c],e=this.matchMappings[c],i=f.lastIndex,f=this.regExps[c],f.lastIndex=i);break}if(m[0]){typeof k=="string"&&(m=[m.join("")],k=[k]);for(var n=0;n=b&&(a.row=Math.max(0,b-1),a.column=this.getLine(b-1).length),a},this.insert=function(a,b){if(!b||b.length===0)return a;a=this.$clipPosition(a),this.getLength()<=1&&this.$detectNewLine(b);var c=this.$split(b),d=c.splice(0,1)[0],e=c.length==0?null:c.splice(c.length-1,1)[0];return a=this.insertInLine(a,d),e!==null&&(a=this.insertNewLine(a),a=this.insertLines(a.row,c),a=this.insertInLine(a,e||"")),a},this.insertLines=function(a,b){if(b.length==0)return{row:a,column:0};var c=[a,0];c.push.apply(c,b),this.$lines.splice.apply(this.$lines,c);var d=new f(a,0,a+b.length,0),e={action:"insertLines",range:d,lines:b};return this._emit("change",{data:e}),d.end},this.insertNewLine=function(a){a=this.$clipPosition(a);var b=this.$lines[a.row]||"";this.$lines[a.row]=b.substring(0,a.column),this.$lines.splice(a.row+1,0,b.substring(a.column,b.length));var c={row:a.row+1,column:0},d={action:"insertText",range:f.fromPoints(a,c),text:this.getNewLineCharacter()};return this._emit("change",{data:d}),c},this.insertInLine=function(a,b){if(b.length==0)return a;var c=this.$lines[a.row]||"";this.$lines[a.row]=c.substring(0,a.column)+b+c.substring(a.column);var d={row:a.row,column:a.column+b.length},e={action:"insertText",range:f.fromPoints(a,d),text:b};return this._emit("change",{data:e}),d},this.remove=function(a){a.start=this.$clipPosition(a.start),a.end=this.$clipPosition(a.end);if(a.isEmpty())return a.start;var b=a.start.row,c=a.end.row;if(a.isMultiLine()){var d=a.start.column==0?b:b+1,e=c-1;a.end.column>0&&this.removeInLine(c,0,a.end.column),e>=d&&this.removeLines(d,e),d!=b&&(this.removeInLine(b,a.start.column,this.getLine(b).length),this.removeNewLine(a.start.row))}else this.removeInLine(b,a.start.column,a.end.column);return a.start},this.removeInLine=function(a,b,c){if(b==c)return;var d=new f(a,b,a,c),e=this.getLine(a),g=e.substring(b,c),h=e.substring(0,b)+e.substring(c,e.length);this.$lines.splice(a,1,h);var i={action:"removeText",range:d,text:g};return this._emit("change",{data:i}),d.start},this.removeLines=function(a,b){var c=new f(a,0,b+1,0),d=this.$lines.splice(a,b-a+1),e={action:"removeLines",range:c,nl:this.getNewLineCharacter(),lines:d};return this._emit("change",{data:e}),d},this.removeNewLine=function(a){var b=this.getLine(a),c=this.getLine(a+1),d=new f(a,b.length,a+1,0),e=b+c;this.$lines.splice(a,2,e);var g={action:"removeText",range:d,text:this.getNewLineCharacter()};this._emit("change",{data:g})},this.replace=function(a,b){if(b.length==0&&a.isEmpty())return a.start;if(b==this.getTextRange(a))return a.end;this.remove(a);if(b)var c=this.insert(a.start,b);else c=a.start;return c},this.applyDeltas=function(a){for(var b=0;b=0;b--){var c=a[b],d=f.fromPoints(c.range.start,c.range.end);c.action=="insertLines"?this.removeLines(d.start.row,d.end.row-1):c.action=="insertText"?this.remove(d):c.action=="removeLines"?this.insertLines(d.start.row,c.lines):c.action=="removeText"&&this.insert(d.start,c.text)}}}).call(h.prototype),b.Document=h}),ace.define("ace/anchor",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("./lib/oop"),e=a("./lib/event_emitter").EventEmitter,f=b.Anchor=function(a,b,c){this.document=a,typeof c=="undefined"?this.setPosition(b.row,b.column):this.setPosition(b,c),this.$onChange=this.onChange.bind(this),a.on("change",this.$onChange)};(function(){d.implement(this,e),this.getPosition=function(){return this.$clipPositionToDocument(this.row,this.column)},this.getDocument=function(){return this.document},this.onChange=function(a){var b=a.data,c=b.range;if(c.start.row==c.end.row&&c.start.row!=this.row)return;if(c.start.row>this.row)return;if(c.start.row==this.row&&c.start.column>this.column)return;var d=this.row,e=this.column;b.action==="insertText"?c.start.row===d&&c.start.column<=e?c.start.row===c.end.row?e+=c.end.column-c.start.column:(e-=c.start.column,d+=c.end.row-c.start.row):c.start.row!==c.end.row&&c.start.row=e?e=c.start.column:e=Math.max(0,e-(c.end.column-c.start.column)):c.start.row!==c.end.row&&c.start.row=this.document.getLength()?(c.row=Math.max(0,this.document.getLength()-1),c.column=this.document.getLine(c.row).length):a<0?(c.row=0,c.column=0):(c.row=a,c.column=Math.min(this.document.getLine(c.row).length,Math.max(0,b))),b<0&&(c.column=0),c}}).call(f.prototype)}),ace.define("ace/background_tokenizer",["require","exports","module","ace/lib/oop","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("./lib/oop"),e=a("./lib/event_emitter").EventEmitter,f=function(a,b){this.running=!1,this.lines=[],this.currentLine=0,this.tokenizer=a;var c=this;this.$worker=function(){if(!c.running)return;var a=new Date,b=c.currentLine,d=c.doc,e=0,f=d.getLength();while(c.currentLine20){c.fireUpdateEvent(b,c.currentLine-1),c.running=setTimeout(c.$worker,20);return}}c.running=!1,c.fireUpdateEvent(b,f-1)}};(function(){d.implement(this,e),this.setTokenizer=function(a){this.tokenizer=a,this.lines=[],this.start(0)},this.setDocument=function(a){this.doc=a,this.lines=[],this.stop()},this.fireUpdateEvent=function(a,b){var c={first:a,last:b};this._emit("update",{data:c})},this.start=function(a){this.currentLine=Math.min(a||0,this.currentLine,this.doc.getLength()),this.lines.splice(this.currentLine,this.lines.length),this.stop(),this.running=setTimeout(this.$worker,700)},this.stop=function(){this.running&&clearTimeout(this.running),this.running=!1},this.getTokens=function(a,b){return this.$tokenizeRows(a,b)},this.getState=function(a){return this.$tokenizeRows(a,a)[0].state},this.$tokenizeRows=function(a,b){if(!this.doc||isNaN(a)||isNaN(b))return[{state:"start",tokens:[]}];var c=[],d="start",e=!1;a>0&&this.lines[a-1]?(d=this.lines[a-1].state,e=!0):a==0?(d="start",e=!0):this.lines.length>0&&(d=this.lines[this.lines.length-1].state);var f=this.doc.getLines(a,b);for(var g=a;g<=b;g++)if(!this.lines[g]){var h=this.tokenizer.getLineTokens(f[g-a]||"",d),d=h.state;c.push(h),e&&(this.lines[g]=h)}else{var h=this.lines[g];d=h.state,c.push(h)}return c}}).call(f.prototype),b.BackgroundTokenizer=f}),ace.define("ace/edit_session/folding",["require","exports","module","ace/range","ace/edit_session/fold_line","ace/edit_session/fold","ace/token_iterator"],function(a,b,c){function h(){this.getFoldAt=function(a,b,c){var d=this.getFoldLine(a);if(!d)return null;var e=d.folds;for(var f=0;f=a)return e;if(e.end.row>a)return null}return null},this.getNextFoldLine=function(a,b){var c=this.$foldData,d=0;b&&(d=c.indexOf(b)),d==-1&&(d=0);for(d;d=a)return e}return null},this.getFoldedRowCount=function(a,b){var c=this.$foldData,d=b-a+1;for(var e=0;e=b){h=a?d-=b-h:d=0);break}g>=a&&(h>=a?d-=g-h:d-=g-a+1)}return d},this.$addFoldLine=function(a){return this.$foldData.push(a),this.$foldData.sort(function(a,b){return a.start.row-b.start.row}),a},this.addFold=function(a,b){var c=this.$foldData,d=!1,g;a instanceof f?g=a:g=new f(b,a),this.$clipRangeToDocument(g.range);var h=g.start.row,i=g.start.column,j=g.end.row,k=g.end.column;if(g.placeholder.length<2)throw"Placeholder has to be at least 2 characters";if(h==j&&k-i<2)throw"The range has to be at least 2 characters width";var l=this.getFoldAt(h,i,1),m=this.getFoldAt(j,k,-1);if(l&&m==l)return l.addSubFold(g);if(l&&!l.range.isStart(h,i)||m&&!m.range.isEnd(j,k))throw"A fold can't intersect already existing fold"+g.range+l.range;var n=this.getFoldsInRange(g.range);n.length>0&&(this.removeFolds(n),g.subFolds=n);for(var o=0;othis.endRow)throw"Can't add a fold to this FoldLine as it has no connection";this.folds.push(a),this.folds.sort(function(a,b){return-a.range.compareEnd(b.start.row,b.start.column)}),this.range.compareEnd(a.start.row,a.start.column)>0?(this.end.row=a.end.row,this.end.column=a.end.column):this.range.compareStart(a.end.row,a.end.column)<0&&(this.start.row=a.start.row,this.start.column=a.start.column)}else if(a.start.row==this.end.row)this.folds.push(a),this.end.row=a.end.row,this.end.column=a.end.column;else{if(a.end.row!=this.start.row)throw"Trying to add fold to FoldRow that doesn't have a matching row";this.folds.unshift(a),this.start.row=a.start.row,this.start.column=a.start.column}a.foldLine=this},this.containsRow=function(a){return a>=this.start.row&&a<=this.end.row},this.walk=function(a,b,c){var d=0,e=this.folds,f,g,h,i=!0;b==null&&(b=this.end.row,c=this.end.column);for(var j=0;j=this.$rowTokens.length){this.$row+=1;if(this.$row>=a)return this.$row=a-1,null;this.$rowTokens=this.$session.getTokens(this.$row,this.$row)[0].tokens,this.$tokenIndex=0}return this.$rowTokens[this.$tokenIndex]},this.getCurrentToken=function(){return this.$rowTokens[this.$tokenIndex]},this.getCurrentTokenRow=function(){return this.$row},this.getCurrentTokenColumn=function(){var a=this.$rowTokens,b=this.$tokenIndex,c=a[b].start;if(c!==undefined)return c;c=0;while(b>0)b-=1,c+=a[b].value.length;return c}}).call(d.prototype),b.TokenIterator=d}),ace.define("ace/edit_session/bracket_match",["require","exports","module","ace/token_iterator"],function(a,b,c){function e(){this.findMatchingBracket=function(a){if(a.column==0)return null;var b=this.getLine(a.row).charAt(a.column-1);if(b=="")return null;var c=b.match(/([\(\[\{])|([\)\]\}])/);return c?c[1]?this.$findClosingBracket(c[1],a):this.$findOpeningBracket(c[2],a):null},this.$brackets={")":"(","(":")","]":"[","[":"]","{":"}","}":"{"},this.$findOpeningBracket=function(a,b){var c=this.$brackets[a],e=1,f=new d(this,b.row,b.column),g=f.getCurrentToken();if(!g)return null;var h=new RegExp("(\\.?"+g.type.replace(".","|").replace("rparen","lparen|rparen")+")+"),i=b.column-f.getCurrentTokenColumn()-2,j=g.value;for(;;){while(i>=0){var k=j.charAt(i);if(k==c){e-=1;if(e==0)return{row:f.getCurrentTokenRow(),column:i+f.getCurrentTokenColumn()}}else k==a&&(e+=1);i-=1}do g=f.stepBackward();while(g&&!h.test(g.type));if(g==null)break;j=g.value,i=j.length-1}return null},this.$findClosingBracket=function(a,b){var c=this.$brackets[a],e=1,f=new d(this,b.row,b.column),g=f.getCurrentToken();if(!g)return null;var h=new RegExp("(\\.?"+g.type.replace(".","|").replace("lparen","lparen|rparen")+")+"),i=b.column-f.getCurrentTokenColumn();for(;;){var j=g.value,k=j.length;while(i=0;h--){var i=g[h],j=c.$rangeFromMatch(f,i.offset,i.str.length);if(d(j))return!0}})}}},this.$rangeFromMatch=function(a,b,c){return new f(a,b,a,b+c)},this.$assembleRegExp=function(){if(this.$options.regExp)var a=this.$options.needle;else a=d.escapeRegExp(this.$options.needle);this.$options.wholeWord&&(a="\\b"+a+"\\b");var b="g";this.$options.caseSensitive||(b+="i");var c=new RegExp(a,b);return c},this.$forwardLineIterator=function(a){function k(e){var f=a.getLine(e);return b&&e==c.end.row&&(f=f.substring(0,c.end.column)),j&&e==d.row&&(f=f.substring(0,d.column)),f}var b=this.$options.scope==g.SELECTION,c=this.$options.range||a.getSelection().getRange(),d=this.$options.start||c[b?"start":"end"],e=b?c.start.row:0,f=b?c.start.column:0,h=b?c.end.row:a.getLength()-1,i=this.$options.wrap,j=!1;return{forEach:function(a){var b=d.row,c=k(b),g=d.column,l=!1;j=!1;while(!a(c,g,b)){if(l)return;b++,g=0;if(b>h){if(!i)return;b=e,g=f,j=!0}b==d.row&&(l=!0),c=k(b)}}}},this.$backwardLineIterator=function(a){var b=this.$options.scope==g.SELECTION,c=this.$options.range||a.getSelection().getRange(),d=this.$options.start||c[b?"end":"start"],e=b?c.start.row:0,f=b?c.start.column:0,h=b?c.end.row:a.getLength()-1,i=this.$options.wrap;return{forEach:function(g){var j=d.row,k=a.getLine(j).substring(0,d.column),l=0,m=!1,n=!1;while(!g(k,l,j)){if(m)return;j--,l=0;if(j0},this.hasRedo=function(){return this.$redoStack.length>0}}).call(d.prototype),b.UndoManager=d}),ace.define("ace/virtual_renderer",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/useragent","ace/config","ace/lib/net","ace/layer/gutter","ace/layer/marker","ace/layer/text","ace/layer/cursor","ace/scrollbar","ace/renderloop","ace/lib/event_emitter","text!ace/css/editor.css"],function(a,b,c){"use strict";var d=a("./lib/oop"),e=a("./lib/dom"),f=a("./lib/event"),g=a("./lib/useragent"),h=a("./config"),i=a("./lib/net"),j=a("./layer/gutter").Gutter,k=a("./layer/marker").Marker,l=a("./layer/text").Text,m=a("./layer/cursor").Cursor,n=a("./scrollbar").ScrollBar,o=a("./renderloop").RenderLoop,p=a("./lib/event_emitter").EventEmitter,q=a("text!./css/editor.css");e.importCssString(q,"ace_editor");var r=function(a,b){var c=this;this.container=a,e.addCssClass(a,"ace_editor"),this.setTheme(b),this.$gutter=e.createElement("div"),this.$gutter.className="ace_gutter",this.container.appendChild(this.$gutter),this.scroller=e.createElement("div"),this.scroller.className="ace_scroller",this.container.appendChild(this.scroller),this.content=e.createElement("div"),this.content.className="ace_content",this.scroller.appendChild(this.content),this.$gutterLayer=new j(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onResize.bind(this,!0)),this.$markerBack=new k(this.content);var d=this.$textLayer=new l(this.content);this.canvas=d.element,this.$markerFront=new k(this.content),this.characterWidth=d.getCharacterWidth(),this.lineHeight=d.getLineHeight(),this.$cursorLayer=new m(this.content),this.$cursorPadding=8,this.$horizScroll=!0,this.$horizScrollAlwaysVisible=!0,this.$animatedScroll=!1,this.scrollBar=new n(a),this.scrollBar.addEventListener("scroll",function(a){c.session.setScrollTop(a.data)}),this.scrollTop=0,this.scrollLeft=0,f.addListener(this.scroller,"scroll",function(){var a=c.scroller.scrollLeft;c.scrollLeft=a,c.session.setScrollLeft(a),a==0?c.$gutter.className="ace_gutter":c.$gutter.className="ace_gutter horscroll"}),this.cursorPos={row:0,column:0},this.$textLayer.addEventListener("changeCharacterSize",function(){c.characterWidth=d.getCharacterWidth(),c.lineHeight=d.getLineHeight(),c.$updatePrintMargin(),c.onResize(!0),c.$loop.schedule(c.CHANGE_FULL)}),this.$size={width:0,height:0,scrollerHeight:0,scrollerWidth:0},this.layerConfig={width:1,padding:0,firstRow:0,firstRowScreen:0,lastRow:0,lineHeight:1,characterWidth:1,minHeight:1,maxHeight:1,offset:0,height:1},this.$loop=new o(this.$renderChanges.bind(this),this.container.ownerDocument.defaultView),this.$loop.schedule(this.CHANGE_FULL),this.setPadding(4),this.$updatePrintMargin()};(function(){this.showGutter=!0,this.CHANGE_CURSOR=1,this.CHANGE_MARKER=2,this.CHANGE_GUTTER=4,this.CHANGE_SCROLL=8,this.CHANGE_LINES=16,this.CHANGE_TEXT=32,this.CHANGE_SIZE=64,this.CHANGE_MARKER_BACK=128,this.CHANGE_MARKER_FRONT=256,this.CHANGE_FULL=512,this.CHANGE_H_SCROLL=1024,d.implement(this,p),this.setSession=function(a){this.session=a,this.$cursorLayer.setSession(a),this.$markerBack.setSession(a),this.$markerFront.setSession(a),this.$gutterLayer.setSession(a),this.$textLayer.setSession(a),this.$loop.schedule(this.CHANGE_FULL)},this.updateLines=function(a,b){b===undefined&&(b=Infinity),this.$changedLines?(this.$changedLines.firstRow>a&&(this.$changedLines.firstRow=a),this.$changedLines.lastRowc.lastRow+1)return;if(bd&&this.session.setScrollTop(d),this.scrollTop+this.$size.scrollerHeightc&&(c0)return!0;if(b>0&&this.session.getScrollTop()+this.$size.scrollerHeighth&&(e=g.end.row+1,g=this.session.getNextFoldLine(e,g),h=g?g.start.row:Infinity);if(e>f)break;var j=this.$annotations[e]||b;c.push("
a",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,unknownElems:!!a.getElementsByTagName("nav").length,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",enctype:!!c.createElement("form").enctype,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.lastChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},m&&f.extend(p,{position:"absolute",left:"-999px",top:"-999px"});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="
t
",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;f(function(){var a,b,d,e,g,h,i=1,j="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",l="visibility:hidden;border:0;",n="style='"+j+"border:5px solid #000;padding:0;'",p="