diff --git a/.gitignore b/.gitignore index a589a0c9..b78137a0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,15 +13,7 @@ # A handy place to put stuff that git should ignore: /ignore/ -node_modules/htmlparser/ -node_modules/amd-loader/ -node_modules/asyncjs/ -node_modules/jsdom/ -node_modules/libxml/ -node_modules/mime/ -node_modules/dryice/ -node_modules/uglify-js/ -node_modules/.bin/ +node_modules/ tool/node_modules/ .git-ref diff --git a/Makefile b/Makefile index af99a0ac..54312a73 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +.PHONY : doc build clean dist + build: git rev-parse HEAD > .git-ref mkdir -p build/src @@ -12,6 +14,9 @@ build: ./Makefile.dryice.js demo ./Makefile.dryice.js bm +doc: + cd doc; node build.js + clean: rm -rf build rm -rf ace-* diff --git a/api/ace.html b/api/ace.html new file mode 100644 index 00000000..0aca05f6 --- /dev/null +++ b/api/ace.html @@ -0,0 +1,200 @@ + + + + + + + + + Ace API - ace + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

Ace[edit] +

+ +
+
+
+
+

The main class required to set up an Ace instance in the browser.

+ +
+
+
+

Methods

+
+
+
+
+ +
+
+

This method embeds the Ace editor into the DOM, at the element provided by el. ...

+ +
+

This method embeds the Ace editor into the DOM, at the element provided by el.

+ +
+

   

+
+

Arguments

elString | DOMElementRequired. Either the id of an element, or the element itself
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/anchor.html b/api/anchor.html new file mode 100644 index 00000000..807e17d4 --- /dev/null +++ b/api/anchor.html @@ -0,0 +1,363 @@ + + + + + + + + + Ace API - anchor + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

Anchor[edit] +

+ +
+
+
+
+

Defines the floating pointer in the document. Whenever text is inserted or deleted before the cursor, the position of the cursor is updated

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Creates a new Anchor and associates it with a document. ...

+ +
+

Creates a new Anchor and associates it with a document.

+ +
+

   

+
+

Arguments

docDocumentRequired. The document to associate with the anchor
rowNumberRequired. The starting row position
columnNumberRequired. The starting column position
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • Anchor.on("onChange", function(Event e))
    • +
    +
      +
    +
  • +
+
+
+

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'.

+ +
+

   

+
+

Arguments

eEventRequired. Contains data about the event
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • Anchor.detach()
    • +
    +
      +
    +
  • +
+
+
+

When called, the 'change' event listener is removed. ...

+ +
+

When called, the 'change' event listener is removed.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Anchor.getDocument() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current document. ...

+ +
+

Returns the current document.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Anchor.getPosition() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns an object identifying the row and column position of the current anchor. ...

+ +
+

Returns an object identifying the row and column position of the current anchor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Sets the anchor position to the specified row and column. If noClip is true, the position is not clipped. ...

+ +
+

Sets the anchor position to the specified row and column. If noClip is true, the position is not clipped.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row index to move the anchor to
columnNumberRequired. The column index to move the anchor to
noClipBooleanRequired. Identifies if you want the position to be clipped
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/background_tokenizer.html b/api/background_tokenizer.html new file mode 100644 index 00000000..df856fd5 --- /dev/null +++ b/api/background_tokenizer.html @@ -0,0 +1,462 @@ + + + + + + + + + Ace API - background_tokenizer + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

BackgroundTokenizer[edit] +

+ +
+
+
+
+

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.

+ +
+
+
+

Constructors

+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Creates a new BackgroundTokenizer object. ...

+ +
+

Creates a new BackgroundTokenizer object.

+ +
+

   

+
+

Arguments

tokenizerTokenizerRequired. The tokenizer to use
editorEditorRequired. The editor to associate with
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.$tokenizeRows(Number firstRow, Number lastRow) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Tokenizes all the rows within the specified region. ...

+ +
+

Tokenizes all the rows within the specified region.

+ +
+

   

+
+

Arguments

startRowNumberRequired. The row to start at
lastRowNumberRequired. The row to finish at
+

Returns

Array of ObjectsA list of the tokenized rows. Each item in the list is an object with two properties, state and start.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.fireUpdateEvent(Number firstRow, Number lastRow)
    • +
    +
      +
    +
  • +
+
+
+

Emits the 'update' event. firstRow and lastRow are used to define the boundaries of the region to be updated. ...

+ +
+

Emits the 'update' event. firstRow and lastRow are used to define the boundaries of the region to be updated.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The starting row region
lastRowNumberRequired. The final row region
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.getState(Number row) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the state of tokenization for a row.

+ +
+

Returns the state of tokenization for a row.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to start at
+
+
+
+
+
+
+
+
+
+ +
+
+

Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows. ...

+ +
+

Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The row to start at
lastRowNumberRequired. The row to finish at
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.setDocument(Document doc)
    • +
    +
      +
    +
  • +
+
+
+

Sets a new document to associate with this object. ...

+ +
+

Sets a new document to associate with this object.

+ +
+

   

+
+

Arguments

docDocumentRequired. The new document to associate with
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.setTokenizer(Tokenizer tokenizer)
    • +
    +
      +
    +
  • +
+
+
+

Sets a new tokenizer for this object. ...

+ +
+

Sets a new tokenizer for this object.

+ +
+

   

+
+

Arguments

tokenizerTokenizerRequired. The new tokenizer to use
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.start(Number startRow)
    • +
    +
      +
    +
  • +
+
+
+

Starts tokenizing at the row indicated. ...

+ +
+

Starts tokenizing at the row indicated.

+ +
+

   

+
+

Arguments

startRowNumberRequired. The row to start at
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • BackgroundTokenizer.stop()
    • +
    +
      +
    +
  • +
+
+
+

Stops tokenizing. ...

+ +
+

Stops tokenizing.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/document.html b/api/document.html new file mode 100644 index 00000000..0e236382 --- /dev/null +++ b/api/document.html @@ -0,0 +1,1028 @@ + + + + + + + + + Ace API - document + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+

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.

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Creates a new Document. If text is included, the Document contains those strings; otherwise, it's empty. ...

+ +
+

Creates a new Document. If text is included, the Document contains those strings; otherwise, it's empty.

+ +
+

   

+
+

Arguments

textString | ArrayRequired. The starting text
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • Document.applyDeltas(deltas) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Applies all the changes previously accumulated. These can be either 'includeText', 'insertLines', 'removeText'...

+ +
+

Applies all the changes previously accumulated. These can be either 'includeText', 'insertLines', 'removeText', and 'removeLines'.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Creates a new Anchor to define a floating point in the document. ...

+ +
+

Creates a new Anchor to define a floating point in the document.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row number to use
columnNumberRequired. The column number to use
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.getAllLines() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns all lines in the document as string array. Warning: The caller should not modify this array! ...

+ +
+

Returns all lines in the document as string array. Warning: The caller should not modify this array!

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.getLength() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the number of rows in the document. ...

+ +
+

Returns the number of rows in the document.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns a verbatim copy of the given line as it is in the document ...

+ +
+

Returns a verbatim copy of the given line as it is in the document

+ +
+

   

+
+

Arguments

rowNumberRequired. The row index to retrieve
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns an array of strings of the rows between firstRow and lastRow. This function is inclusive of lastRow. ...

+ +
+

Returns an array of strings of the rows between firstRow and lastRow. This function is inclusive of lastRow.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The first row index to retrieve
lastRowNumberRequired. The final row index to retrieve
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.getNewLineCharacter() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the newline character that's being used, depending on the value of newLineMode. ...

+ +
+

Returns the newline character that's being used, depending on the value of newLineMode.

+ +
+

   

+
+

Returns

StringIf newLineMode == windows, \r\n is returned.
If newLineMode == unix, \n is returned.
If newLineMode == auto, the value of autoNewLine is returned.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.getNewLineMode() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the type of newlines being used; either windows, unix, or auto

+ +
+

Returns the type of newlines being used; either windows, unix, or auto

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.getTextRange(Range range) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

[Given a range within the document, this function returns all the text within that range as a single string.]{: #Doc...

+ +
+

Given a range within the document, this function returns all the text within that range as a single string.

+ +
+

   

+
+

Arguments

rangeRangeRequired. The range to work with
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.getValue() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns all the lines in the document as a single string, split by the new line character. ...

+ +
+

Returns all the lines in the document as a single string, split by the new line character.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

...

+ +
+
+
+

   

+
+

Arguments

positionNumberRequired. The position to start inserting at
textStringRequired. A chunk of text to insert
+

Returns

NumberThe 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.
+
+
+
+
+
+
+
+
+
+ +
+
+

Inserts text into the position at the current row. This method also triggers the 'change' event. ...

+ +
+

Inserts text into the position at the current row. This method also triggers the 'change' event.

+ +
+

   

+
+

Arguments

positionNumberRequired. The position to insert at
textStringRequired. A chunk of text
+

Returns

ObjectReturns an object containing the final row and column, like this:
{row: endRow, column: 0}
NumberIf text is empty, this function returns the value of position
+
+
+
+
+
+
+
+
+
+ +
+
+

Inserts the elements in lines into the document, starting at the row index given by row. This method also trigge...

+ +
+

Inserts the elements in lines into the document, starting at the row index given by row. This method also triggers the 'change' event.

+ +
+

   

+
+

Arguments

rowNumberRequired. The index of the row to insert at
linesArrayRequired. An array of strings
+

Returns

ObjectReturns 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}
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.insertNewLine(String position) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Inserts a new line into the document at the current row's position. This method also triggers the 'change' event. ...

+ +
+

Inserts a new line into the document at the current row's position. This method also triggers the 'change' event.

+ +
+

   

+
+

Arguments

positionStringRequired. The position to insert at
+

Returns

ObjectReturns an object containing the final row and column, like this:
{row: endRow, column: 0}
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns true if text is a newline character (either \r\n, \r, or \n). ...

+ +
+

Returns true if text is a newline character (either \r\n, \r, or \n).

+ +
+

   

+
+

Arguments

textStringRequired. The text to check
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Removes the range from the document. ...

+ +
+

Removes the range from the document.

+ +
+

   

+
+

Arguments

rangeRangeRequired. A specified Range to remove
+

Returns

ObjectReturns 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 specified columns from the row. This method also triggers the 'change' event. ...

+ +
+

Removes the specified columns from the row. This method also triggers the 'change' event.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to remove from
startColumnNumberRequired. The column to start removing at
endColumnNumberRequired. The column to stop removing at
+

Returns

ObjectReturns an object containing startRow and startColumn, indicating the new row and column values.
If startColumn is equal to endColumn, this function returns nothing.
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Removes a range of full lines. This method also triggers the 'change' event. ...

+ +
+

Removes a range of full lines. This method also triggers the 'change' event.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The first row to be removed
lastRowNumberRequired. The last row to be removed
+

Returns

Array of StringsReturns all the removed lines.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.removeNewLine(Number row) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Removes the new line between row and the row immediately following it. This method also triggers the 'change' event. ...

+ +
+

Removes the new line between row and the row immediately following it. This method also triggers the 'change' event.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to check
+
+
+
+
+
+
+
+
+
+ +
+
+

Replaces a range in the document with the new text. ...

+ +
+

Replaces a range in the document with the new text.

+ +
+

   

+
+

Arguments

rangeRangeRequired. A specified Range to replace
textStringRequired. The new text to use as a replacement
+

Returns

ObjectReturns 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'.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.setNewLineMode(String newLineMode) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Sets the new line mode.

+ +
+

Sets the new line mode.

+ +
+

   

+
+

Arguments

newLineModeStringRequired. The newline mode to use; can be either windows, unix, or auto
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Document.setValue(String text) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Replaces all the lines in the current Document with the value of text. ...

+ +
+

Replaces all the lines in the current Document with the value of text.

+ +
+

   

+
+

Arguments

textStringRequired. The text to use
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/edit_session.html b/api/edit_session.html new file mode 100644 index 00000000..b8c34034 --- /dev/null +++ b/api/edit_session.html @@ -0,0 +1,2767 @@ + + + + + + + + + Ace API - edit_session + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+

Stores various states related to a Document. A single EditSession can be in charge of several Documents.

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Sets up a new EditSession and associates it with the given Document and TextMode. ...

+ +
+

Sets up a new EditSession and associates it with the given Document and TextMode.

+ +
+

   

+
+

Arguments

textDocument | StringRequired. If text is a Document, it associates the EditSession with it. Otherwise, a new Document is created, with the initial text
modeTextModeRequired. 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.

+ +
+

   

+
+
+
+
+
+
+

Methods

+
+
+
+
+ +
+
+

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.

+ +
+

   

+
+

Arguments

rangeRangeRequired. Define the range of the marker
clazzStringRequired. Set the CSS class for the marker
typeFunction | StringRequired. Identify the type of the marker
inFrontBooleanRequired. Set to true to establish a front marker
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.clearAnnotations()
    • +
    +
      +
    +
  • +
+
+
+

Clears all the annotations for this session. This function also triggers the 'changeAnnotation' event. ...

+ +
+

Clears all the annotations for this session. This function also triggers the 'changeAnnotation' event.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.clearBreakpoint(Number row)
    • +
    +
      +
    +
  • +
+
+
+

Removes a breakpoint on the row number given by rows. This function also emites the 'changeBreakpoint' event. ...

+ +
+

Removes a breakpoint on the row number given by rows. This function also emites the 'changeBreakpoint' event.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row index
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.clearBreakpoints()
    • +
    +
      +
    +
  • +
+
+
+

Removes all breakpoints on the rows. This function also emites the 'changeBreakpoint' event. ...

+ +
+

Removes all breakpoints on the rows. This function also emites the 'changeBreakpoint' event.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

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.

+ +
+

   

+
+

Arguments

docRowNumberRequired. The document row to check
docColumnNumberRequired. The document column to check
+

Returns

ObjectThe object returned by this method has two properties: row and column.
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Duplicates all the text between firstRow and lastRow. ...

+ +
+

Duplicates all the text between firstRow and lastRow.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The starting row to duplicate
lastRowNumberRequired. The final row to duplicate
+

Returns

NumberReturns the number of new rows added; in other words, lastRow - firstRow + 1.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getAnnotations() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the annotations for the EditSession. ...

+ +
+

Returns the annotations for the EditSession.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Gets the range of a word, including its right whitespace. ...

+ +
+

Gets the range of a word, including its right whitespace.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row number to start from
columnNumberRequired. The column number to start from
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getBreakpoints() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns an array of numbers, indicating which rows have breakpoints. ...

+ +
+

Returns an array of numbers, indicating which rows have breakpoints.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getDocument() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the Document associated with this session. ...

+ +
+

Returns the Document associated with this session.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the number of rows in the document. ...

+ +
+

Returns the number of rows in the document.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns a verbatim copy of the given line as it is in the document ...

+ +
+

Returns a verbatim copy of the given line as it is in the document

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to retrieve from
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns an array of strings of the rows between firstRow and lastRow. This function is inclusive of lastRow. ...

+ +
+

Returns an array of strings of the rows between firstRow and lastRow. This function is inclusive of lastRow.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The first row index to retrieve
lastRowNumberRequired. The final row index to retrieve
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getMarkers(Boolean inFront) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns an array containing the IDs of all the markers, either front or back. ...

+ +
+

Returns an array containing the IDs of all the markers, either front or back.

+ +
+

   

+
+

Arguments

inFrontBooleanRequired. If true, indicates you only want front markers; false indicates only back markers
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getMode() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current text mode. ...

+ +
+

Returns the current text mode.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the current new line mode. ...

+ +
+

Returns the current new line mode.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getOverwrite() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if overwrites are enabled; false otherwise. ...

+ +
+

Returns true if overwrites are enabled; false otherwise.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the height of the indicated row. This is mostly relevant for situations where wrapping occurs, and a single ...

+ +
+

Returns the height of the indicated row. This is mostly relevant for situations where wrapping occurs, and a single line spans across multiple rows.

+ +
+

   

+
+

Arguments

configObjectRequired. An object containing a parameter indicating the lineHeight.
rowNumberRequired. The row number to check
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns the length of the indicated row. ...

+ +
+

Returns the length of the indicated row.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row number to check
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getScreenLength() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the length of the screen. ...

+ +
+

Returns the length of the screen.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getScreenTabSize(Number screenColumn) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

The distance to the next tab stop at the specified screen column. ...

+ +
+

The distance to the next tab stop at the specified screen column.

+ +
+

   

+
+

Arguments

screenColumnNumberRequired. The screen column to check
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getScreenWidth() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the width of the screen. ...

+ +
+

Returns the width of the screen.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getScrollLeft() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

[Returns the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #...

+ +
+

Returns the value of the distance between the left of the editor and the leftmost part of the visible content.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getScrollTop() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

[Returns the value of the distance between the top of the editor and the topmost part of the visible content.]{: #Ed...

+ +
+

Returns the value of the distance between the top of the editor and the topmost part of the visible content.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getSelection() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the string of the current selection. ...

+ +
+

Returns the string of the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the state of tokenization for a row. ...

+ +
+

Returns the state of tokenization for a row.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to start at
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getTabSize() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current tab size. ...

+ +
+

Returns the current tab size.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getTabString() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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'.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Given a range within the document, this function returns all the text within that range as a single string. ...

+ +
+

Given a range within the document, this function returns all the text within that range as a single string.

+ +
+

   

+
+

Arguments

rangeStringRequired. The range to work with
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns an array of tokens at the indicated row and column. ...

+ +
+

Returns an array of tokens at the indicated row and column.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row number to retrieve from
columnNumberRequired. The column number to retrieve from
+
+
+
+
+
+
+
+
+
+ +
+
+

Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows. ...

+ +
+

Starts tokenizing at the row indicated. Returns a list of objects of the tokenized rows.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The row to start at
lastRowNumberRequired. The row to finish at
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getUndoManager() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current undo manager. ...

+ +
+

Returns the current undo manager.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getUseSoftTabs() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if soft tabs are being used, false otherwise. ...

+ +
+

Returns true if soft tabs are being used, false otherwise.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getUseWorker() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if workers are being used. ...

+ +
+

Returns true if workers are being used.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getUseWrapMode() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if wrap mode is being used; false otherwise. ...

+ +
+

Returns true if wrap mode is being used; false otherwise.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the current Document as a string. ...

+ +
+

Returns the current Document as a string.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getWidth() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the width of the document. ...

+ +
+

Returns the width of the document.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Given a starting row and column, this method returns the Range of the first word boundary it finds. ...

+ +
+

Given a starting row and column, this method returns the Range of the first word boundary it finds.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to start at
columnNumberRequired. The column to start at
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getWrapLimit() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the value of wrap limit. ...

+ +
+

Returns the value of wrap limit.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.getWrapLimitRange() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this: + ...

+ +
+

Returns an object that defines the minimum and maximum of the wrap limit; it looks something like this: +

+ +
+

   

+
{ min: wrapLimitRange_min, max: wrapLimitRange_max }
+ +
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Indents all the rows, from startRow to endRow (inclusive), by prefixing each row with the token in indentString. + ...

+ +
+

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 getTabString.

+ +

Arguments

startRowNumberRequired. Starting row
endRowNumberRequired. Ending row
indentStringStringRequired. The indent token
+
+
+
+
+
+
+
+
+
+ +
+
+

Inserts a block of text and the indicated position. ...

+ +
+

Inserts a block of text and the indicated position.

+ +
+

   

+
+

Arguments

positionNumberRequired. The position to start inserting at
textStringRequired. A chunk of text to insert
+

Returns

NumberThe position of the last line of text. If the length of text is 0, this function simply returns position.
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns true if the character at the position is a soft tab. ...

+ +
+

Returns true if the character at the position is a soft tab.

+ +
+

   

+
+

Arguments

positionObjectRequired. The position to check
+
+
+
+
+
+
+
+
+
+ +
+
+

...

+ +
+
+
+

   

+
+

Arguments

firstRowNumberRequired. The starting row to move down
lastRowNumberRequired. The final row to move down
+

Returns

NumberIf 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. ...

+ +
+

Shifts all the lines in the document up one, starting from firstRow and ending at lastRow.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The starting row to move up
lastRowNumberRequired. The final row to move up
+

Returns

NumberIf firstRow is less-than or equal to 0, this function returns 0. Otherwise, on success, it returns -1.
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

{ row: newRowLocation, column: newColumnLocation } ...

+ +
+

{ row: newRowLocation, column: newColumnLocation }

+ +
+

   

+
+

Arguments

fromRangeRangeRequired. The range of text you want moved within the document
toPositionObjectRequired. The location (row and column) where you want to move the text to
+

Returns

RangeThe 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:
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.outdentRows(Range range)
    • +
    +
      +
    +
  • +
+
+
+

Outdents all the rows defined by the start and end properties of range. ...

+ +
+

Outdents all the rows defined by the start and end properties of range.

+ +
+

   

+
+

Arguments

rangeRangeRequired. A range of rows
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Re-implements a previously undone change to your document. ...

+ +
+

Re-implements a previously undone change to your document.

+ +
+

   

+
+

Arguments

deltasArrayRequired. An array of previous changes
dontSelectBooleanRequired. If true, doesn't select the range of where the change occured
+
+
+
+
+
+
+
+
+
+ +
+
+

Removes the range from the document. ...

+ +
+

Removes the range from the document.

+ +
+

   

+
+

Arguments

rangeRangeRequired. A specified Range to remove
+

Returns

ObjectThe new start property of the range, which contains startRow and startColumn. If range is empty, this function returns the unmodified value of range.start.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.removeMarker(Number markerId)
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+

Arguments

markerIdNumberRequired. A number representing a marker
+
+
+
+
+
+
+
+
+
+ +
+
+

Replaces a range in the document with the new text. ...

+ +
+

Replaces a range in the document with the new text.

+ +
+

   

+
+

Arguments

rangeRangeRequired. A specified Range to replace
textStringRequired. The new text to use as a replacement
+

Returns

ObjectReturns 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.
+
+
+
+
+
+
+
+
+
+ +
+
+

Converts characters coordinates on the screen to characters coordinates within the document. [This takes into accoun...

+ +
+

This takes into account code folding, word wrap, tab size, and any other visual modifications.

+ +
+

   

+
+

Arguments

screenRowNumberRequired. The screen row to check
screenColumnNumberRequired. The screen column to check
+

Returns

ObjectThe object returned has two properties: row and column.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setAnnotations(Array annotations)
    • +
    +
      +
    +
  • +
+
+
+

Sets annotations for the EditSession. This functions emits the 'changeAnnotation' event. ...

+ +
+

Sets annotations for the EditSession. This functions emits the 'changeAnnotation' event.

+ +
+

   

+
+

Arguments

annotationsArrayRequired. A list of annotations
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setBreakpoint(Number row)
    • +
    +
      +
    +
  • +
+
+
+

Sets a breakpoint on the row number given by rows. This function also emites the 'changeBreakpoint' event. ...

+ +
+

Sets a breakpoint on the row number given by rows. This function also emites the 'changeBreakpoint' event.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row index
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setBreakpoints(Array rows)
    • +
    +
      +
    +
  • +
+
+
+

Sets a breakpoint on every row number given by rows. This function also emites the 'changeBreakpoint' event. ...

+ +
+

Sets a breakpoint on every row number given by rows. This function also emites the 'changeBreakpoint' event.

+ +
+

   

+
+

Arguments

rowsArrayRequired. An array of row indicies
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setDocument(Document doc)
    • +
    +
      +
    +
  • +
+
+
+

Sets the EditSession to point to a new Document. If a BackgroundTokenizer exists, it also points to doc. ...

+ +
+

Sets the EditSession to point to a new Document. If a BackgroundTokenizer exists, it also points to doc.

+ +
+

   

+
+

Arguments

docDocumentRequired. The new Document to use
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setMode(TextMode mode)
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+

Arguments

modeTextModeRequired. Set a new text mode
+
+
+
+
+
+
+
+
+
+ +
+
+

Sets the new line mode. ...

+ +
+

Sets the new line mode.

+ +
+

   

+
+

Arguments

newLineModeStringRequired. The newline mode to use; can be either windows, unix, or auto
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setOverwrite(Boolean overwrite)
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+

Arguments

overwriteBooleanRequired. Defines wheter or not to set overwrites
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setScrollLeft(scrollLeft)
    • +
    +
      +
    +
  • +
+
+
+

[Sets the value of the distance between the left of the editor and the leftmost part of the visible content.]{: #Edi...

+ +
+

Sets the value of the distance between the left of the editor and the leftmost part of the visible content.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setScrollTop(Number scrollTop)
    • +
    +
      +
    +
  • +
+
+
+

This function sets the scroll top value. It also emits the 'changeScrollTop' event. ...

+ +
+

This function sets the scroll top value. It also emits the 'changeScrollTop' event.

+ +
+

   

+
+

Arguments

scrollTopNumberRequired. The new scroll top value
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setTabSize(Number tabSize)
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+

Arguments

tabSizeNumberRequired. The new tab size
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setUndoManager(UndoManager undoManager)
    • +
    +
      +
    +
  • +
+
+
+

Sets the undo manager. ...

+ +
+

Sets the undo manager.

+ +
+

   

+
+

Arguments

undoManagerUndoManagerRequired. The new undo manager
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setUndoSelect(Boolean enable)
    • +
    +
      +
    +
  • +
+
+
+

ENables or disables highlighting of the range where an undo occured. ...

+ +
+

ENables or disables highlighting of the range where an undo occured.

+ +
+

   

+
+

Arguments

enableBooleanRequired. If true, selects the range of the reinserted change
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setUseSoftTabs(Boolean useSoftTabs)
    • +
    +
      +
    +
  • +
+
+
+

Pass true to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character ('\t'). ...

+ +
+

Pass true to enable the use of soft tabs. Soft tabs means you're using spaces instead of the tab character ('\t').

+ +
+

   

+
+

Arguments

useSoftTabsBooleanRequired. Value indicating whether or not to use soft tabs
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setUseWorker(Boolean useWorker)
    • +
    +
      +
    +
  • +
+
+
+

Identifies if you want to use a worker for the EditSession. ...

+ +
+

Identifies if you want to use a worker for the EditSession.

+ +
+

   

+
+

Arguments

useWorkerBooleanRequired. Set to true to use a worker
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setUseWrapMode(Boolean useWrapMode)
    • +
    +
      +
    +
  • +
+
+
+

Sets whether or not line wrapping is enabled. If useWrapMode is different than the current value, the `'changeWrap...

+ +
+

Sets whether or not line wrapping is enabled. If useWrapMode is different than the current value, the 'changeWrapMode' event is emitted.

+ +
+

   

+
+

Arguments

useWrapModeBooleanRequired. Enable (or disable) wrap mode
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.setValue(String text)
    • +
    +
      +
    +
  • +
+
+
+

Sets the session text. ...

+ +
+

Sets the session text.

+ +
+

   

+
+

Arguments

textStringRequired. The new text to place
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+

Arguments

minNumberRequired. The minimum wrap value (the left side wrap)
maxNumberRequired. The maximum wrap value (the right side wrap)
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • EditSession.toggleOverwrite()
    • +
    +
      +
    +
  • +
+
+
+

Sets the value of overwrite to the opposite of whatever it currently is. ...

+ +
+

Sets the value of overwrite to the opposite of whatever it currently is.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the current Document as a string. ...

+ +
+

Returns the current Document as a string.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Reverts previous changes to your document. ...

+ +
+

Reverts previous changes to your document.

+ +
+

   

+
+

Arguments

deltasArrayRequired. An array of previous changes
dontSelectBooleanRequired. If true, doesn't select the range of where the change occured
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/editor.html b/api/editor.html new file mode 100644 index 00000000..93b91c84 --- /dev/null +++ b/api/editor.html @@ -0,0 +1,4397 @@ + + + + + + + + + Ace API - editor + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

Editor[edit] +

+ +
+
+
+
+

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.

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Creates a new Editor object. ...

+ +
+

Creates a new Editor object.

+ +
+

   

+
+

Arguments

rendererVirtualRendererRequired. Associated VirtualRenderer that draws everything
sessionEditSessionRequired. The EditSession to refer to
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • Editor.on("onBlur", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted once the editor has been blurred. ...

+ +
+

Emitted once the editor has been blurred.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onChangeAnnotation", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when an annotation changes. ...

+ +
+

Emitted when an annotation changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onChangeBackMarker", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when a back marker changes. ...

+ +
+

Emitted when a back marker changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onChangeBreakpoint", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when a breakpoint changes. ...

+ +
+

Emitted when a breakpoint changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onChangeFold", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the code folds change. ...

+ +
+

Emitted when the code folds change.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onChangeFrontMarker", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when a front marker changes. ...

+ +
+

Emitted when a front marker changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onChangeMode", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the mode changes. ...

+ +
+

Emitted when the mode changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onChangeWrapLimit", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the wrap limit changes. ...

+ +
+

Emitted when the wrap limit changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onChangeWrapMode", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the wrap mode changes. ...

+ +
+

Emitted when the wrap mode changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onCommandKey", function(e, hashId, keyCode))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the command-key is pressed. ...

+ +
+

Emitted when the command-key is pressed.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onCursorChange", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the cursor changes. ...

+ +
+

Emitted when the cursor changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onDocumentChange", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Emitted whenever the document is changed. ...

+ +
+

Emitted whenever the document is changed.

+ +
+

   

+
+

Arguments

eObjectRequired. Contains a single property, data, which has the delta of changes
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onFocus", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted once the editor comes into focus. ...

+ +
+

Emitted once the editor comes into focus.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onScrollLeftChange", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the scroll left changes. ...

+ +
+

Emitted when the scroll left changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onScrollTopChange", function())
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the scroll top changes. ...

+ +
+

Emitted when the scroll top changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onSelectionChange", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when a selection has changed. ...

+ +
+

Emitted when a selection has changed.

+ +
+

   

+
+

Arguments

eObjectRequired. Contains a single property, data, which has the delta of changes
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onTextInput", function(String text, Boolean pasted))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when text is entered. ...

+ +
+

Emitted when text is entered.

+ +
+

   

+
+

Arguments

textStringRequired. The text entered
pastedBooleanRequired. Identifies whether the text was pasted (true) or not
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.on("onTokenizerUpdate", function(Object e))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the a tokenizer is updated. ...

+ +
+

Emitted when the a tokenizer is updated.

+ +
+

   

+
+

Arguments

eObjectRequired. Contains a single property, data, which indicates the changed rows
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • Editor.$getSelectedRows() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns an object indicating the currently selected rows. The object looks like this: + ...

+ +
+

Returns an object indicating the currently selected rows. The object looks like this: +

+ +
+

   

+

{ first: range.start.row, last: range.end.row }

+ +
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.$getVisibleRowCount() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the number of currently visibile rows. ...

+ +
+

Returns the number of currently visibile rows.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Executes a specific function, which can be anything that manipulates selected lines, such as copying them, duplicati...

+ +
+

Executes a specific function, which can be anything that manipulates selected lines, such as copying them, duplicating them, or shifting them.

+ +
+

   

+
+

Arguments

moverFunctionRequired. A method to call on each selected row
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.addSelectionMarker(Range orientedRange) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Adds the selection and cursor. ...

+ +
+

Adds the selection and cursor.

+ +
+

   

+
+

Arguments

orientedRangeRangeRequired. A range containing a cursor
+
+
+
+
+
+
+
+
+
+ +
+
+

Outdents the current line. ...

+ +
+

Outdents the current line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.blur()
    • +
    +
      +
    +
  • +
+
+
+

Blurs the current textInput. ...

+ +
+

Blurs the current textInput.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.centerSelection()
    • +
    +
      +
    +
  • +
+
+
+

Attempts to center the current selection on the screen. ...

+ +
+

Attempts to center the current selection on the screen.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Empties the selection (by de-selecting it). This function also emits the 'changeSelection' event. ...

+ +
+

Empties the selection (by de-selecting it). This function also emits the 'changeSelection' event.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Copies all the selected lines down one row. ...

+ +
+

Copies all the selected lines down one row.

+ +
+

   

+
+

Returns

NumberOn success, returns the number of new rows added; in other words, lastRow - firstRow + 1.
+
+
+
+
+
+
+
+
+
+ +
+
+

Copies all the selected lines up one row. ...

+ +
+

Copies all the selected lines up one row.

+ +
+

   

+
+

Returns

NumberOn success, returns 0.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.destroy()
    • +
    +
      +
    +
  • +
+
+
+

Cleans up the entire editor. ...

+ +
+

Cleans up the entire editor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.exitMultiSelectMode()
    • +
    +
      +
    +
  • +
+
+
+

Removes all the selections except the last added one. ...

+ +
+

Removes all the selections except the last added one.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Attempts to find needle within the document. For more information on options, see Search. ...

+ +
+

Attempts to find needle within the document. For more information on options, see Search.

+ +
+

   

+
+

Arguments

needleStringRequired. The text to search for
optionsObjectRequired. An object defining various search properties
+
+
+
+
+
+
+
+
+
+ +
+
+

Finds and selects all the occurences of needle. ...

+ +
+

Finds and selects all the occurences of needle.

+ +
+

   

+
+

Arguments

needleStringRequired. The text to find
optionsObjectRequired. Any of the additional search options
additiveBooleanRequired. TODO
+

Returns

NumberThe number of found ranges.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.findNext(options)
    • +
    + +
  • +
+
+
+

Performs another search for needle in the document. For more information on options, see Search. ...

+ +
+

Performs another search for needle in the document. For more information on options, see Search.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.findPrevious(options)
    • +
    + +
  • +
+
+
+

Performs a search for needle backwards. For more information on options, see Search. ...

+ +
+

Performs a search for needle backwards. For more information on options, see Search.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.focus()
    • +
    +
      +
    +
  • +
+
+
+

Brings the current textInput into focus. ...

+ +
+

Brings the current textInput into focus.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Executes a command for each selection range. ...

+ +
+

Executes a command for each selection range.

+ +
+

   

+
+

Arguments

cmdStringRequired. The command to execute
argsStringRequired. Any arguments for the command
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getBehavioursEnabled() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getCopyText() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the string of text currently highlighted. ...

+ +
+

Returns the string of text currently highlighted.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Gets the current position of the cursor. ...

+ +
+

Gets the current position of the cursor.

+ +
+

   

+
+

Returns

ObjectThis returns an object that looks something like this:
{ row: currRow, column: currCol }
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the screen position of the cursor. ...

+ +
+

Returns the screen position of the cursor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getDragDelay() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current mouse drag delay. ...

+ +
+

Returns the current mouse drag delay.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the index of the first visible row. ...

+ +
+

Returns the index of the first visible row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getHighlightActiveLine() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if current lines are always highlighted. ...

+ +
+

Returns true if current lines are always highlighted.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getHighlightSelectedWord() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if currently highlighted words are to be highlighted. ...

+ +
+

Returns true if currently highlighted words are to be highlighted.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getKeyboardHandler() +
    • + +
    • +
    + +
  • +
+
+
+

Returns the keyboard handler. ...

+ +
+

Returns the keyboard handler.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns an object containing all the search options. For more information on options, see Search. ...

+ +
+

Returns an object containing all the search options. For more information on options, see Search.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the index of the last visible row. ...

+ +
+

Returns the index of the last visible row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns true if overwrites are enabled; false otherwise. ...

+ +
+

Returns true if overwrites are enabled; false otherwise.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getPrintMarginColumn() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the column number of where the print margin is. ...

+ +
+

Returns the column number of where the print margin is.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getReadOnly() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the editor is set to read-only mode. ...

+ +
+

Returns true if the editor is set to read-only mode.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getScrollSpeed() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the value indicating how fast the mouse scroll speed is. ...

+ +
+

Returns the value indicating how fast the mouse scroll speed is.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getSelection() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the currently highlighted selection. ...

+ +
+

Returns the currently highlighted selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the Range for the selected text. ...

+ +
+

Returns the Range for the selected text.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getSelectionStyle() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current selection style. ...

+ +
+

Returns the current selection style.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns the current session being used. ...

+ +
+

Returns the current session being used.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getShowFoldWidgets() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the fold widgets are shown. ...

+ +
+

Returns true if the fold widgets are shown.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getShowInvisibles() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if invisible characters are being shown. ...

+ +
+

Returns true if invisible characters are being shown.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.getShowPrintMargin() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the print margin is being shown. ...

+ +
+

Returns true if the print margin is being shown.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the path of the current theme. ...

+ +
+

Returns the path of the current theme.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Moves the cursor to the specified line number, and also into the indiciated column. ...

+ +
+

Moves the cursor to the specified line number, and also into the indiciated column.

+ +
+

   

+
+

Arguments

lineNumberNumberRequired. The line number to go to
columnNumberRequired. A column number to go to
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.gotoPageDown()
    • +
    +
      +
    +
  • +
+
+
+

Shifts the document to wherever "page down" is, as well as moving the cursor position. ...

+ +
+

Shifts the document to wherever "page down" is, as well as moving the cursor position.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.gotoPageUp()
    • +
    +
      +
    +
  • +
+
+
+

Shifts the document to wherever "page up" is, as well as moving the cursor position. ...

+ +
+

Shifts the document to wherever "page up" is, as well as moving the cursor position.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Indents the current line. ...

+ +
+

Indents the current line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.insert(String text)
    • +
    +
      +
    +
  • +
+
+
+

Inserts text into wherever the cursor is pointing. ...

+ +
+

Inserts text into wherever the cursor is pointing.

+ +
+

   

+
+

Arguments

textStringRequired. The new text to add
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.isFocused() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the current textInput is in focus. ...

+ +
+

Returns true if the current textInput is in focus.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Indicates if the entire row is currently visible on the screen. ...

+ +
+

Indicates if the entire row is currently visible on the screen.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to check
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Indicates if the row is currently visible on the screen. ...

+ +
+

Indicates if the row is currently visible on the screen.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to check
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.jumpToMatching()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor's row and column to the next matching bracket. ...

+ +
+

Moves the cursor's row and column to the next matching bracket.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Moves the cursor to the specified row and column. Note that this does not de-select the current selection. ...

+ +
+

Moves the cursor to the specified row and column. Note that this does not de-select the current selection.

+ +
+

   

+
+

Arguments

rowNumberRequired. The new row number
columnNumberRequired. The new column number
+
+
+
+
+
+
+
+
+
+ +
+
+

Moves the cursor to the position indicated by pos.row and pos.column. ...

+ +
+

Moves the cursor to the position indicated by pos.row and pos.column.

+ +
+

   

+
+

Arguments

posObjectRequired. An object with two properties, row and column
+
+
+
+
+
+
+
+
+
+ +
+
+

Shifts all the selected lines down one row. ...

+ +
+

Shifts all the selected lines down one row.

+ +
+

   

+
+

Returns

NumberOn success, it returns -1.
+
+
+
+
+
+
+
+
+
+ +
+
+

Shifts all the selected lines up one row. ...

+ +
+

Shifts all the selected lines up one row.

+ +
+

   

+
+

Returns

NumberOn success, it returns -1.
+
+
+
+
+
+
+
+
+
+ +
+
+

Moves a range of text from the given range to the given position. toPosition is an object that looks like this: + ...

+ +
+

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 }

+ +

Arguments

fromRangeRangeRequired. The range of text you want moved within the document
toPositionObjectRequired. The location (row and column) where you want to move the text to
+

Returns

RangeThe new range where the text was moved to.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateDown(Number times)
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor down in the document the specified number of times. Note that this does de-select the current selec...

+ +
+

Moves the cursor down in the document the specified number of times. Note that this does de-select the current selection.

+ +
+

   

+
+

Arguments

timesNumberRequired. The number of times to change navigation
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateFileEnd()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the end of the current file. Note that this does de-select the current selection. ...

+ +
+

Moves the cursor to the end of the current file. Note that this does de-select the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateFileStart()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the start of the current file. Note that this does de-select the current selection. ...

+ +
+

Moves the cursor to the start of the current file. Note that this does de-select the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateLeft(Number times)
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor left in the document the specified number of times. Note that this does de-select the current selec...

+ +
+

Moves the cursor left in the document the specified number of times. Note that this does de-select the current selection.

+ +
+

   

+
+

Arguments

timesNumberRequired. The number of times to change navigation
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateLineEnd()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the end of the current line. Note that this does de-select the current selection. ...

+ +
+

Moves the cursor to the end of the current line. Note that this does de-select the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateLineStart()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the start of the current line. Note that this does de-select the current selection. ...

+ +
+

Moves the cursor to the start of the current line. Note that this does de-select the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateRight(Number times)
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor right in the document the specified number of times. Note that this does de-select the current sele...

+ +
+

Moves the cursor right in the document the specified number of times. Note that this does de-select the current selection.

+ +
+

   

+
+

Arguments

timesNumberRequired. The number of times to change navigation
+
+
+
+
+
+
+
+
+
+ +
+
+

Moves the cursor to the specified row and column. Note that this does de-select the current selection. ...

+ +
+

Moves the cursor to the specified row and column. Note that this does de-select the current selection.

+ +
+

   

+
+

Arguments

rowNumberRequired. The new row number
columnNumberRequired. The new column number
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateUp(Number times)
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection. ...

+ +
+

Moves the cursor up in the document the specified number of times. Note that this does de-select the current selection.

+ +
+

   

+
+

Arguments

timesNumberRequired. The number of times to change navigation
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateWordLeft()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the curr...

+ +
+

Moves the cursor to the word immediately to the left of the current position. Note that this does de-select the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.navigateWordRight()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the cur...

+ +
+

Moves the cursor to the word immediately to the right of the current position. Note that this does de-select the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.removeSelectionMarker(Range range)
    • +
    +
      +
    +
  • +
+
+
+

Removes the selection marker. ...

+ +
+

Removes the selection marker.

+ +
+

   

+
+

Arguments

rangeRangeRequired. The selection range added with addSelectionMarker().
+
+
+
+
+
+
+
+
+
+ +
+
+

Finds the next occurence of text in an active selection and adds it to the selections. ...

+ +
+

Finds the next occurence of text in an active selection and adds it to the selections.

+ +
+

   

+
+

Arguments

dirNumberRequired. The direction of lines to select: -1 for up, 1 for down
skipBooleanRequired. If true, removes the active selection range
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Adds a cursor above or below the active cursor. ...

+ +
+

Adds a cursor above or below the active cursor.

+ +
+

   

+
+

Arguments

dirNumberRequired. The direction of lines to select: -1 for up, 1 for down
skipBooleanRequired. If true, removes the active selection range
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.transposeSelections(Number dir)
    • +
    +
      +
    +
  • +
+
+
+

Transposes the selected ranges. ...

+ +
+

Transposes the selected ranges.

+ +
+

   

+
+

Arguments

dirNumberRequired. The direction to rotate selections
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.onCut()
    • +
    +
      +
    +
  • +
+
+
+

Emitted whenever a text "cut" happens. ...

+ +
+

Emitted whenever a text "cut" happens.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Perform a redo operation on the document, reimplementing the last change. ...

+ +
+

Perform a redo operation on the document, reimplementing the last change.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.remove(String dir)
    • +
    +
      +
    +
  • +
+
+
+

Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace. ...

+ +
+

Removes words of text from the editor. A "word" is defined as a string of characters bookended by whitespace.

+ +
+

   

+
+

Arguments

dirStringRequired. The direction of the deletion to occur, either "left" or "right"
+
+
+
+
+
+
+
+
+
+ +
+
+

Removes all the lines in the current selection ...

+ +
+

Removes all the lines in the current selection

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.removeToLineEnd()
    • +
    +
      +
    +
  • +
+
+
+

Removes all the words to the right of the current selection, until the end of the line. ...

+ +
+

Removes all the words to the right of the current selection, until the end of the line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.removeToLineStart()
    • +
    +
      +
    +
  • +
+
+
+

Removes all the words to the left of the current selection, until the start of the line. ...

+ +
+

Removes all the words to the left of the current selection, until the start of the line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.removeWordLeft()
    • +
    +
      +
    +
  • +
+
+
+

Removes the word directly to the left of the current selection. ...

+ +
+

Removes the word directly to the left of the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.removeWordRight()
    • +
    +
      +
    +
  • +
+
+
+

Removes the word directly to the right of the current selection. ...

+ +
+

Removes the word directly to the right of the current selection.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Replaces the first occurance of options.needle with the value in replacement. ...

+ +
+

Replaces the first occurance of options.needle with the value in replacement.

+ +
+

   

+
+

Arguments

replacementStringRequired. The text to replace with
optionsObjectRequired. The Search options to use
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Replaces all occurances of options.needle with the value in replacement. ...

+ +
+

Replaces all occurances of options.needle with the value in replacement.

+ +
+

   

+
+

Arguments

replacementStringRequired. The text to replace with
optionsObjectRequired. The Search options to use
+
+
+
+
+
+
+
+
+
+ +
+
+

Triggers a resize of the editor. ...

+ +
+

Triggers a resize of the editor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.scrollPageDown()
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the document to wherever "page down" is, without changing the cursor position. ...

+ +
+

Scrolls the document to wherever "page down" is, without changing the cursor position.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.scrollPageUp()
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the document to wherever "page up" is, without changing the cursor position. ...

+ +
+

Scrolls the document to wherever "page up" is, without changing the cursor position.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

TODO scrollsa to line, if center == true, puts line in middle of screen or attempts to) ...

+ +
+

TODO scrollsa to line, if center == true, puts line in middle of screen or attempts to)

+ +
+

   

+
+

Arguments

lineNumberRequired. The line to scroll to
centerBooleanRequired. If true
+
+
+
+
+
+
+
+
+
+ +
+
+

Moves the editor to the specified row. ...

+ +
+

Moves the editor to the specified row.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to move to
+
+
+
+
+
+
+
+
+
+ +
+
+

Selects all the text in editor. ...

+ +
+

Selects all the text in editor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.selectPageDown()
    • +
    +
      +
    +
  • +
+
+
+

Selects the text from the current position of the document until where a "page down" finishes. ...

+ +
+

Selects the text from the current position of the document until where a "page down" finishes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.selectPageUp()
    • +
    +
      +
    +
  • +
+
+
+

Selects the text from the current position of the document until where a "page up" finishes. ...

+ +
+

Selects the text from the current position of the document until where a "page up" finishes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setBehavioursEnabled()
    • +
    +
      +
    +
  • +
+
+
+

Specifies whether to use behaviors or not. ["Behaviors" in this case is the auto-pairing of special characters, like...

+ +
+

"Behaviors" in this case is the auto-pairing of special characters, like quotation marks, parenthesis, or brackets.

+ +
+

   

+
+

Arguments

enabledBooleanRequired. Enables or disables behaviors
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setDragDelay(Number dragDelay)
    • +
    +
      +
    +
  • +
+
+
+

Sets the delay (in milliseconds) of the mouse drag. ...

+ +
+

Sets the delay (in milliseconds) of the mouse drag.

+ +
+

   

+
+

Arguments

dragDelayNumberRequired. A value indicating the new delay
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setFontSize(Number size)
    • +
    +
      +
    +
  • +
+
+
+

Set a new font size (in pixels) for the editor text. ...

+ +
+

Set a new font size (in pixels) for the editor text.

+ +
+

   

+
+

Arguments

sizeNumberRequired. A font size
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setHighlightActiveLine(Boolean shouldHighlight)
    • +
    +
      +
    +
  • +
+
+
+

Determines whether or not the current line should be highlighted. ...

+ +
+

Determines whether or not the current line should be highlighted.

+ +
+

   

+
+

Arguments

shouldHighlightBooleanRequired. Set to true to highlight the current line
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setHighlightSelectedWord(Boolean shouldHighlight)
    • +
    +
      +
    +
  • +
+
+
+

Determines if the currently selected word should be highlighted. ...

+ +
+

Determines if the currently selected word should be highlighted.

+ +
+

   

+
+

Arguments

shouldHighlightBooleanRequired. Set to true to highlight the currently selected word
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setKeyboardHandler(keyboardHandler)
    • +
    +
      +
    +
  • +
+
+
+

Sets a new keyboard handler. ...

+ +
+

Sets a new keyboard handler.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

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.

+ +
+

   

+
+

Arguments

overwriteBooleanRequired. Defines wheter or not to set overwrites
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setPrintMarginColumn(Number showPrintMargin)
    • +
    +
      +
    +
  • +
+
+
+

Sets the column defining where the print margin should be. ...

+ +
+

Sets the column defining where the print margin should be.

+ +
+

   

+
+

Arguments

showPrintMarginNumberRequired. Specifies the new print margin
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setReadOnly(Boolean readOnly)
    • +
    +
      +
    +
  • +
+
+
+

If readOnly is true, then the editor is set to read-only mode, and none of the content can change. ...

+ +
+

If readOnly is true, then the editor is set to read-only mode, and none of the content can change.

+ +
+

   

+
+

Arguments

readOnlyBooleanRequired. Specifies whether the editor can be modified or not
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setScrollSpeed(Number speed)
    • +
    +
      +
    +
  • +
+
+
+

Sets how fast the mouse scrolling should do. ...

+ +
+

Sets how fast the mouse scrolling should do.

+ +
+

   

+
+

Arguments

speedNumberRequired. A value indicating the new speed
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setSelectionStyle(String style)
    • +
    +
      +
    +
  • +
+
+
+

Indicates how selections should occur. By default, selections are set to "line". This function also emits the `'chan...

+ +
+

Indicates how selections should occur. By default, selections are set to "line". This function also emits the 'changeSelectionStyle' event.

+ +
+

   

+
+

Arguments

styleStringRequired. The new selection style
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Sets a new editsession to use. This method also emits the 'changeSession' event. ...

+ +
+

Sets a new editsession to use. This method also emits the 'changeSession' event.

+ +
+

   

+
+

Arguments

sessionEditSessionRequired. The new session to use
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setShowFoldWidgets(Boolean show)
    • +
    +
      +
    +
  • +
+
+
+

Indicates whether the fold widgets are shown or not. ...

+ +
+

Indicates whether the fold widgets are shown or not.

+ +
+

   

+
+

Arguments

showBooleanRequired. Specifies whether the fold widgets are shown
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setShowInvisibles(Boolean showInvisibles)
    • +
    +
      +
    +
  • +
+
+
+

If showInvisibiles is set to true, invisible characters—like spaces or new lines—are show in the editor. ...

+ +
+

If showInvisibiles is set to true, invisible characters—like spaces or new lines—are show in the editor.

+ +
+

   

+
+

Arguments

showInvisiblesBooleanRequired. Specifies whether or not to show invisible characters
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setShowPrintMargin(Boolean showPrintMargin)
    • +
    +
      +
    +
  • +
+
+
+

If showPrintMargin is set to true, the print margin is shown in the editor. ...

+ +
+

If showPrintMargin is set to true, the print margin is shown in the editor.

+ +
+

   

+
+

Arguments

showPrintMarginBooleanRequired. Specifies whether or not to show the print margin
+
+
+
+
+
+
+
+
+
+ +
+
+

Adds a new class, style, to the editor. ...

+ +
+

Adds a new class, style, to the editor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.setTheme(theme)
    • +
    +
      +
    +
  • +
+
+
+

Sets a new theme for the editor. theme should exist, and be a directory path, like ace/theme/textmate. ...

+ +
+

Sets a new theme for the editor. theme should exist, and be a directory path, like ace/theme/textmate.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.splitLine()
    • +
    +
      +
    +
  • +
+
+
+

Splits the line at the current selection (by inserting an '\n'). ...

+ +
+

Splits the line at the current selection (by inserting an '\n').

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.toggleCommentLines()
    • +
    +
      +
    +
  • +
+
+
+

Given the currently selected range, this function either comments all lines or uncomments all lines (depending on wh...

+ +
+

Given the currently selected range, this function either comments all lines or uncomments all lines (depending on whether it's commented or not).

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Sets the value of overwrite to the opposite of whatever it currently is. ...

+ +
+

Sets the value of overwrite to the opposite of whatever it currently is.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.toLowerCase()
    • +
    +
      +
    +
  • +
+
+
+

Converts the current selection entirely into lowercase. ...

+ +
+

Converts the current selection entirely into lowercase.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.toUpperCase()
    • +
    +
      +
    +
  • +
+
+
+

Converts the current selection entirely into uppercase. ...

+ +
+

Converts the current selection entirely into uppercase.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Editor.transposeLetters()
    • +
    +
      +
    +
  • +
+
+
+

Transposes current line. ...

+ +
+

Transposes current line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Perform an undo operation on the document, reverting the last change. Returns the range of the undo. ...

+ +
+

Perform an undo operation on the document, reverting the last change. Returns the range of the undo.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Removes the class style from the editor. ...

+ +
+

Removes the class style from the editor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/index.html b/api/index.html new file mode 100644 index 00000000..3323640b --- /dev/null +++ b/api/index.html @@ -0,0 +1,134 @@ + + + + + + + + + Ace API + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+

Ace API Reference

+

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 + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/placeholder.html b/api/placeholder.html new file mode 100644 index 00000000..21bca776 --- /dev/null +++ b/api/placeholder.html @@ -0,0 +1,411 @@ + + + + + + + + + Ace API - placeholder + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

PlaceHolder[edit] +

+ +
+
+
+
+

TODO

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

TODO ...

+ +
+

TODO

+ +
+

   

+
+

Arguments

sessionDocumentRequired. The document to associate with the anchor
lengthNumberRequired. The starting row position
posNumberRequired. The starting column position
othersStringRequired.
mainClassStringRequired.
othersClassStringRequired.
+
+
+
+
+
+

Events

+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.on("onCursorChange", function(e))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the cursor changes. ...

+ +
+

Emitted when the cursor changes.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.on("onUpdate", function(e))
    • +
    +
      +
    +
  • +
+
+
+

Emitted when the place holder updates. ...

+ +
+

Emitted when the place holder updates.

+ +
+

   

+
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.cancel()
    • +
    +
      +
    +
  • +
+
+
+

TODO ...

+ +
+

TODO

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.detach()
    • +
    +
      +
    +
  • +
+
+
+

TODO ...

+ +
+

TODO

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.hideOtherMarkers()
    • +
    +
      +
    +
  • +
+
+
+

Hides all over markers in the EditSession that are not the currently selected one. ...

+ +
+

Hides all over markers in the EditSession that are not the currently selected one.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.setup()
    • +
    +
      +
    +
  • +
+
+
+

TODO ...

+ +
+

TODO

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • PlaceHolder.showOtherMarkers()
    • +
    +
      +
    +
  • +
+
+
+

TODO ...

+ +
+

TODO

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/range.html b/api/range.html new file mode 100644 index 00000000..48f4b467 --- /dev/null +++ b/api/range.html @@ -0,0 +1,1103 @@ + + + + + + + + + Ace API - range + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

Range[edit] +

+ +
+
+
+
+

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.

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Creates a new Range object with the given starting and ending row and column points. ...

+ +
+

Creates a new Range object with the given starting and ending row and column points.

+ +
+

   

+
+

Arguments

startRowNumberRequired. The starting row
startColumnNumberRequired. The starting column
endRowNumberRequired. The ending row
endColumnNumberRequired. The ending column
+
+
+
+
+
+

Methods

+
+
+
+
+ +
+
+

Returns the part of the current Range that occurs within the boundaries of firstRow and lastRow as a new `Rang...

+ +
+

Returns the part of the current Range that occurs within the boundaries of firstRow and lastRow as a new Range object.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The starting row
lastRowNumberRequired. The ending row
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Range.clone() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns a duplicate of the calling range. ...

+ +
+

Returns a duplicate of the calling range.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Range.collapseRows() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns a range containing the starting and ending rows of the original range, but with a column value of 0. ...

+ +
+

Returns a range containing the starting and ending rows of the original range, but with a column value of 0.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Checks the row and column points with the row and column points of the calling range. ...

+ +
+

Checks the row and column points with the row and column points of the calling range.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+

Returns

NumberThis 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. ...

+ +
+

Checks the row and column points with the row and column points of the calling range.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+

Returns

NumberThis 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
+
+
+
+
+
+
+
+
+
+ +
+
+

Checks the row and column points with the row and column points of the calling range. ...

+ +
+

Checks the row and column points with the row and column points of the calling range.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+

Returns

NumberThis 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.
+
+
+
+
+
+
+
+
+
+ +
+
+

Checks the row and column points of p with the row and column points of the calling range. ...

+ +
+

Checks the row and column points of p with the row and column points of the calling range.

+ +
+

   

+
+

Arguments

pRangeRequired. A point to compare with
+

Returns

NumberThis 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
+
+
+
+
+
+
+
+
+
+ +
+
+

Compares this range (A) with another range (B). ...

+ +
+

Compares this range (A) with another range (B).

+ +
+

   

+
+

Arguments

rangeRangeRequired. A range to compare with
+

Returns

NumberThis 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)
+
+
+
+
+
+
+
+
+
+ +
+
+

Checks the row and column points with the row and column points of the calling range. ...

+ +
+

Checks the row and column points with the row and column points of the calling range.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+

Returns

NumberThis 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
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns true if the row and column provided are within the given range. This can better be expressed as return...

+ +
+

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

+ +

Arguments

rowNumberRequired. A row to check for
columnNumberRequired. A column to check for
+
+
+
+
+
+
+
+
+
+ +
+
+

Checks the start and end points of range and compares them to the calling range. Returns true if the range is ...

+ +
+

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.

+ +
+

   

+
+

Arguments

rangeRangeRequired. A range to compare with
+
+
+
+
+
+
+
+
+
+ +
+
+

Changes the row and column points for the calling range for both the starting and ending points. This method returns...

+ +
+

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.

+ +
+

   

+
+

Arguments

rowNumberRequired. A new row to extend to
columnNumberRequired. A new column to extend to
+
+
+
+
+
+
+
+
+
+ +
+
+

Creates and returns a new Range based on the row and column of the given parameters. ...

+ +
+

Creates and returns a new Range based on the row and column of the given parameters.

+ +
+

   

+
+

Arguments

startRangeRequired. A starting point to use
endRangeRequired. An ending point to use
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns true if the row and column are within the given range. ...

+ +
+

Returns true if the row and column are within the given range.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns true if the row and column are within the given range's ending points. ...

+ +
+

Returns true if the row and column are within the given range's ending points.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns true if the row and column are within the given range's starting points. ...

+ +
+

Returns true if the row and column are within the given range's starting points.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns true if passed in range intersects with the one calling this method. ...

+ +
+

Returns true if passed in range intersects with the one calling this method.

+ +
+

   

+
+

Arguments

rangeRangeRequired. A range 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 ...

+ +
+

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.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns true if and only if the starting row and column, and ending tow and column, are equivalent to those given ...

+ +
+

Returns true if and only if the starting row and column, and ending tow and column, are equivalent to those given by range.

+ +
+

   

+
+

Arguments

rangeRangeRequired. A range to check against
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Range.isMultiLine() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the range spans across multiple lines. ...

+ +
+

Returns true if the range spans across multiple lines.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns true if the caller's starting row point is the same as row, and if the caller's starting column is the s...

+ +
+

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.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to compare with
columnNumberRequired. A column point to compare with
+
+
+
+
+
+
+
+
+
+ +
+
+

Sets the starting row and column for the range. ...

+ +
+

Sets the starting row and column for the range.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to set
columnNumberRequired. A column point to set
+
+
+
+
+
+
+
+
+
+ +
+
+

Sets the starting row and column for the range. ...

+ +
+

Sets the starting row and column for the range.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row point to set
columnNumberRequired. A column point to set
+
+
+
+
+
+
+
+
+
+ +
+
+

Given the current Range, this function converts those starting and ending points into screen positions, and then r...

+ +
+

Given the current Range, this function converts those starting and ending points into screen positions, and then returns a new Range object.

+ +
+

   

+
+

Arguments

sessionEditSessionRequired. The EditSession to retrieve coordinates from
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Range.toString() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns a string containing the range's row and column information, given like this: + ...

+ +
+

Returns a string containing the range's row and column information, given like this: +

+ +
+

   

+

[start.row/start.column] -> [end.row/end.column]

+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/resources/csses/ace_api.css b/api/resources/csses/ace_api.css new file mode 100644 index 00000000..6deac5d0 --- /dev/null +++ b/api/resources/csses/ace_api.css @@ -0,0 +1,1027 @@ +/* + Generic "affects everything" stuff +*/ +body { + min-width: 1010px; + color: #2D2D2D; + background: #EDF5FA url(../images/main_bg.png) 0 0 repeat; +} + +ul { + font-size: 13px; +} + +li { + color: black; +} + +a, a:hover { + color : #00438a; +} + +code { + font-size: 12px; + line-height: 16px; + font-family: 'Ubuntu Mono',Monaco,Consolas,monospace !important; + background-color: #F9F9F9; + border-radius: 3px 3px 3px 3px; + box-shadow: 0 0 2px #888888; + display: inline-block; + padding: 0 4px; + margin: 2px 1px; + color: inherit; +} + +pre { + margin-top: 10px; + border-radius: none; + box-shadow: none; + background : white; + /*background : #f5f5f5; + border: 0;*/ + + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; + + padding: 5px; +} + +.method pre, .event pre, .property pre { + background : white; +} + +pre code { + background-color: transparent; + border-radius: none; + box-shadow: none; +} + +a code { + color: #00438a; +} + +h2 { + font-size: 26px; +} +p { + font-size: 13px; + line-height : 20px; + margin-bottom : 13px; +} +li p:last-child { + margin-bottom : 5px; +} + +blockquote p{ + font-size: 14px; + font-weight: 500; + line-height: 23px; + font-style: italic; +} + +.alert-message{ + margin-bottom : 13px; +} +/* + Header and shoulders +*/ + +.navbar .nav > li { + float:none; + display:inline-block; + *display:inline; /* ie7 fix */ + zoom:1; /* hasLayout ie7 trigger */ +} + +.navbar { + text-align:center; +} + +.small_win #topSection { + width: 100%; +} +.small_win #topSection .dropdown { + margin-right: 40%; +} +.brand { + background: transparent url(../images/ace_logo_menu.png) no-repeat 13px 5px; + width: 105px; + outline: none; + height: 40px; + padding: 0 10px !important; + border: none; +} +.brand.dropdown-toggle:after { + content: none; + display: block; + height: 40px; + border: none; +} + +.ace_logo { + position: absolute; + top: 45px; + z-index: 20000; + left: 210px; +} + +.masthead { + background: #101010 url(../images/dashed_back.png) repeat 0 0; +} +.masthead .container { + /*width: 680px;*/ + padding-left: 285px; + margin: 0 auto; + color: white; +} +.jumbotron { + min-width: 1000px; + padding-top: 40px; + position: relative; +} + +.jumbotron .inner { +/* background: transparent url(../images/header-back.png) top center;*/ + padding: 45px 0; +/* -webkit-box-shadow: inset 0 10px 30px rgba(0,0,0,.3); + -moz-box-shadow: inset 0 10px 30px rgba(0,0,0,.3);*/ +} + +.headerTitle { + position: relative; + top: 100px; + left: 250px; +} + +/* + Menu venue +*/ + +ul.menu { + margin-left: 16px; +} + +.menu li { + list-style-image: url(../images/menu_disc.png); + margin-bottom: 3px; + font-weight : 700; +} + +.menu li .menu-item a.menuLink, .menu li .menu-item span.menuLink { + color: #262626; +} +.menuTwo { + margin-bottom: 5px; + margin-top: 2px; +} +.menuTwo li .menu-item a.menuLink { + color: #262626; +} + +/* need specificity to "beat" the above colors */ +.menu li .menu-item a.currentItem, .menuTwo li .menu-item { + color: #0072bc; +} + +/* + Members and the tabs that represent them +*/ + +.members { +/* width: 800px; */ + /*width: 700px;*/ +/* margin: 0 10px;*/ + + height: 42px; + left: 0; +/* position: fixed;*/ + top: 0; +/* transition-duration: 300ms, 300ms; + transition-property: box-shadow, height; + transition-timing-function: ease-out, ease-out; + -moz-transition-duration: 300ms, 300ms; + -moz-transition-property: -moz-box-shadow, height; + -moz-transition-timing-function: ease-out, ease-out; + -o-transition-duration: 300ms, 300ms; + -o-transition-property: -o-box-shadow, height; + -o-transition-timing-function: ease-out, ease-out; + -webkit-transition-duration: 300ms, 300ms; + -webkit-transition-property: -webkit-box-shadow, height; + -webkit-transition-timing-function: ease-out, ease-out;*/ +/* width: 100%;*/ + /*transition-duration: 300ms; + transition-property: box-shadow; + transition-timing-function: ease-out; + -moz-transition-duration: 300ms, 300ms; + -moz-transition-property: -moz-box-shadow, height; + -moz-transition-timing-function: ease-out, ease-out; + -o-transition-duration: 300ms; + -o-transition-property: -o-box-shadow; + -o-transition-timing-function: ease-out;*/ + -webkit-transition-duration: 400ms, 0ms; + -webkit-transition-property: -webkit-box-shadow, background; + -webkit-transition-timing-function: ease-out, ease-out; + z-index: 100; + padding-bottom : 5px; + overflow: visible !important; + +/* background: #FFF; + width: 100%; + padding-bottom: 13px; + top: 40px; + position: fixed;*/ +} +.srolled .members { + width: 100%; +/* -webkit-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); + -moz-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); + box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); */ + padding-bottom: 15px; +/* height: 31px;*/ + top: 40px; + position: fixed; +} +.shadow.members{ + background: #edf8fd; + box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); + -moz-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); + -o-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); + -webkit-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); +} + +.membersContent { + +/* border-bottom: 0.1em solid #FFF;*/ + height: 3em; + padding-top: 4px; +/* line-height: 4;*/ +/* margin-top: -0.1em;*/ + position: relative; +/* transition-property: border-color, line-height; + transition-duration: 125ms, 250ms; + transition-timing-function: ease-out, ease-out; + -moz-transition-property: border-color, line-height; + -moz-transition-duration: 125ms, 250ms; + -moz-transition-timing-function: ease-out, ease-out; + -o-transition-property: border-color, line-height; + -o-transition-duration: 125ms, 250ms; + -o-transition-timing-function: ease-out, ease-out; + -webkit-transition-property: border-color, line-height; + -webkit-transition-duration: 125ms, 250ms; + -webkit-transition-timing-function: ease-out, ease-out;*/ + + /*transition-duration: 125ms; + transition-property: top; + transition-timing-function: ease-out; + + top : 11px;*/ + z-index: 103; + /*width: 700px;*/ +} +.srolledHeader .membersContent { + line-height: 3; +} +.srolled .membersContent { + /*top : 0;*/ + width : 695px; + padding-left : 305px; + margin : 0 auto 0 auto; +} +.membersBackground { +/* background-color: white; + position: fixed; + z-index: 2; + top: 40px; + left: 0px; + right: 0px; + width: 100%; + height: 55px; + opacity: 0; + display: none; + box-shadow: rgba(0, 0, 0, 0.398438) 1px 4px 6px;*/ + + background-color: transparent; + height: 47px; + /*width: 700px;*/ + position: absolute; +} +.srolled .membersBackground { + position: relative; +} +.srolledHeader .membersBackground { +/* display: block;*/ +} +.memberHeader { + float: left; + padding-right: 10px; + margin-bottom: 5px; + position: absolute; + padding-top: 4px; + +} + +.tabs a.menu:after, .tabs .dropdown-toggle:after { + margin-top: 22px; +} + +.dropdown .caret { + margin-top: 14px; + color: #6D8CA0; +} + +li.dropdown { + color: #2D2D2D; + font-weight: bold; +} + + +.backToMDN, .editInC9 { + font-size: 11px; + color: #657383; + margin : 0 0 0 5px; +} + +.backToMDN a, .editInC9 a { + color: #657383; + font-weight: normal; + position : relative; + top : -2px; +} + +.tabs { + padding-top: 10px; + /*border-bottom: 1px solid #848484;*/ + min-height : 27px; + padding-bottom : 5px; +} +.tabsSansBorder { + border: 0; +} +.tabs, .pills { + margin-bottom: 0; +} +.srolledHeader .members .tabs { + background-color: white; +} + +li.dropdown { + color: #2D2D2D; + font-weight: bold; +} + +.members .tabs .dropdown a, +.members .tabs a.menu:after, +.members .tabs .dropdown-toggle:after { + margin-right: 0; + margin-left: 6px; +} + +.members .tabs ul li { + font-weight: bold; +} + +.memberLink a { + margin-left: 0 !important; +} +.menu-dropdown, .dropdown-menu { + min-width : 105px; + max-height: 350px; + overflow: auto; + border-color : rgba(0, 0, 0, 0.1); +} +.topbar div > ul .menu-dropdown li a:hover, +.nav .menu-dropdown li a:hover, +.topbar div > ul .dropdown-menu li a:hover, +.nav .dropdown-menu li a:hover { + background-color: #ffffff; + color: #000000; +} +.dropdown-menu { + border-top: none; +} + +.tabs a.menu:after, .tabs .dropdown-toggle:after { + margin-top: 13px; + line-height: 28px; +} +.open .menu, .dropdown.open .menu, .open .dropdown-toggle, .dropdown.open .dropdown-toggle { + background: transparent; + color: black; +/* font-weight: bold;*/ +} +#topSection .open .menu, #topSection .dropdown.open .menu, #topSection .open .dropdown-toggle, +#topSection .dropdown.open .dropdown-toggle { + color: #bfbfbf; +} + +.tabs > li { + font-weight: bold; +} + +.tabs > li > a { + border: none; + outline: none; + line-height: 28px; + font-size: 11px; + padding: 0 5px; +} +.tabs > li > a:hover { + color: #000000; + text-decoration: none; + background-color: transparent; + border: none; +} +.tabs > li, .pills > li { + float: right; +} +.topbar .dropdown-menu a, .dropdown-menu a { + font-size: 11px; +/* padding: 2px 12px;*/ + line-height: 14px; +} +.tabs .active > a, .tabs .active > a:hover { + color: #000000; + border: none; + cursor: default; +} +.tabs .menu-dropdown, .tabs .dropdown-menu { + border-radius: 0 0 6px 6px; + top: 32px; + right: 0px; + width: 150px; +} +.srolled .tabs .menu-dropdown, .srolled .tabs .dropdown-menu { + top: 32px; +} +.dropdown-toggle { + color: #6D8CA0; +} + +ul.tabs .double ul, ul.tabs .triple ul, ul.tabs .quad ul{ + width:760px; + margin-bottom:20px; + overflow:hidden; + border-top:1px solid #ccc; +} +/*ul.tabs .double li, ul.tabs .triple li, ul.tabs .quad li{ + line-height:1.5em; + border-bottom:1px solid #ccc; + float:left; + display:inline; +}*/ + +/* + Center content (the "real stuff") +*/ + +.content .row { + width: 1000px; + margin-left: auto; + margin-right: auto; +} + +.content .centerpiece { + background: url(../images/sidebar_border.png) repeat-y 180px 0; + padding-bottom: 9em; +} + +header.filler { + position: relative; + height: 50px; + width: 100%; +} + +.container { + width: 100%; +} + +/* +.container-fluid .row-fluid { + width: 1000px; + margin-left: auto; + margin-right: auto; +}*/ + +.divider { + height: 3px; + background-color: #BEDAEA; + margin-bottom: 3px; +} + +.sidebarContainer { + width: 280px; + margin-left: 0px; +} + +#sidebar { + margin-top: 9px; + /*background: url(../images/sidebar-border.png) repeat-y right 0;*/ + margin-left: 12px; +/* width: 280px;*/ +/* overflow: auto;*/ + padding-right : 10px; +} + +#sidebar h3 a, +#sidebar h3 a:hover { + color: #404040; +} + +.mainContent .hero-unit { + background: rgba(255, 255, 255, 0.5); +} + +#documentation { + padding-bottom: 10px; +} + +#documentation article.article { +/* border-bottom: 1px solid #e9e9e9;*/ + border-top: 1px solid #e9e9e9; + padding: 16px 10px 2px; +} +div#documentation article:last-child { + border-bottom: 1px solid #e9e9e9; + padding-bottom: 40px; +} +#documentation article.article.methodToggleOpen { + background: rgba(255, 255, 255, 0.5); + padding: 20px; + font-size: 13px; + line-height: 24px; + margin: 0 0 10px 0; +} + +#documentation article:first-child { + border:none; +} + +.site_logo { + display: block; + margin-left: auto; + margin-right: auto; +} +/* + Edit in Cloud9, sucka +*/ + +.snippet pre { + margin-bottom: 0; +} + +.snippet .toolbar { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + + text-align: right; + padding: 3px 10px; + margin-top : -1px; +} + +.snippet .filename, .snippet .toolbar { + font-family: Ubuntu, sans-serif; + font-size: 12px; + color: #EEE; +} + +.snippet .filename { + padding: 0 5px 2px 5px; + font-size: 10px; + background: rgba(230,230,230,0.5); + padding: 0 5px 2px 5px; + border-radius: 0 6px 0 6px; + margin : 1px; + position : absolute; + right : 0; + top : 0; +} + +.snippet .filename span{ + color : #666; +} + +.snippet .toolbar { + background-color: rgba(30,30,30,0.5); +} + +div.snippet { + margin-bottom: 18px; + position : relative; +} + +div.snippet a, div.toolbar a { + color: #FFF; +} + +/* + All about signatures +*/ + +.signatures { +/* width: 800px;*/ + margin-left: 20px; + margin-bottom: 5px; +} +.sideToggler { + padding-left: 20px; +} +ul.signatures ul { + list-style: none; + display: inline; +} + +li.signature { + list-style: none; +} + +.signature ul { + padding: 0; + margin: 0; +} + +.signature li { + display: inline; +} + +.signature ul.argument-types::before { + content: '→'; + margin: 0 5px; +} + +.signature li.argument-type::after { + content: '|'; + padding: 0 5px 0 5px; +} + +.signature li.argument-type:last-child:after { + content: ''; + padding: 0 5px 0 5px; +} + +.member-name { + color: #4397cd; + font-weight: bold; + text-decoration: none; + cursor: pointer; + padding-right: 3px; +} + +.signature-call { + cursor: pointer; +} +.signature-call a { + color: #8e487e; +} + +.sigClassName { + display: none; +} + +.eventObjName { + font-style: italic; +} +.eventListenerStart, .eventFunctionOpen, .eventFunctionClose { + color: #999999; +} +.eventMember { + padding-right: 0px; +} + +.metaInfo { + float: right; + z-index: 1; + position: relative; +} + +.chainable { + background-color: #0072bc; + color: #ffffff; +} + +.deprecated { + background-color: #f7941d; + color: #ffffff; +} + +.alias { + background-color: #6c951e; + color: #ffffff; +} + +.related-to { + background-color: #89289a; + color: #ffffff; + font-size: 10px; + padding: 2px 5px 3px; + text-transform: capitalize; +} + +.alias a, .related-to a { + color: #ffffff; + /* text-decoration: underline; */ +} +.alias a:hover, .related-to a:hover { + text-decoration: none; +} +.alias:hover, .related-to:hover { + opacity: 0.8; + cursor: pointer; +} +.memberContent .title { + +} +.memberContent .description { + position:relative; + /*top: -13px;*/ + display: none; +} +.snip-container .actions .toggle-plaintext label { + margin-top: 1px; + padding-top: 0; + text-align: left; +} +.snip-container .actions .toggle-plaintext input { + margin-top: 4px !important; +} +.snip-container label { + color: #ffffff; +} +.description h4 { + font-size: 18px; + margin: 20px 0 10px; + line-height : 18px; +} + +.table-striped tbody tr:nth-child(odd) td, .table-striped tbody tr:nth-child(odd) th { + background-color: #F9F9F9; +} +.table-striped tbody tr:nth-child(even) td, .table-striped tbody tr:nth-child(even) th { + background-color: #fbfbfb; +} +.table-striped tbody tr:hover td, .table-striped tbody tr:hover th { +} + +.argument-list { + margin-bottom : 13px; +} +.argName { + font-style: italic; +} + + +/* + Everyday I'm togglin' +*/ +.mainContent { + padding-top: 10px; + float: right; + margin-left: 0px; + width: 695px; + padding-left: 5px; +} + +#documentation h3 { + font-size: 24px; + margin-top: 5px; +} +#documentation h3.methodToggle { + margin: 0; +} +#documentation h3.sectionHeader { + margin: 10px 0 17px 0; + line-height : 24px; +} + +div.method { + position: relative; +} + +.methodToggle a { + color: #fff; + border-bottom: 0px; + text-decoration: none; +} + +h3.methodToggle { + height : 13px; + width : 8px; + background-position : 0px 0px; + position: absolute; + top: -20px; + background-image : url(../images/member-sprites.png); + background-color : transparent; + background-repeat : no-repeat; + overflow: hidden; + left: 0px; +} + +h3.methodToggleHover { + /* background-position : 0px -28px; */ +} + +h3.methodToggle.inactive { + top: 4px; +} + +h3.methodToggle.active { + top: 6px; + height : 13px; + width : 8px; + background-position : 0px -59px; +} + +.hidden { + display: none; + visibility: hidden; +} + +.hiddenSpan { + display: none; +} + +.ellipsis_description, .short_description { +/* width: 800px;*/ +} +.methodToggleOpen .ellipsis_description { + display: none; +} +.sideToggler .short_description, +.sideToggler .description{ + display: none; +} +.methodToggleOpen .short_description, +.methodToggleOpen .description { + display: block; +} +.description td p { + margin: 0; +} +/* + Footer? I hardly know her +*/ + +#footer { + left:0px; + bottom:0px; + padding-top: 0; + width:100%; + background: #101010 url(../images/dashed_back.png) repeat 0 0; + font-size: 12px; + color: white; + border-top: none; + margin-top: 0; +} +#footer .container { + width: 710px; + padding-left: 300px; + margin-left: auto; + margin-right: auto; + min-height: 60px; +} +#footer .footer-text { + display: block; + float: right; + margin-right: 10px; + margin-top: 24px; +} +#footer .sponsors { + display: inline-block; + margin-top: 18px; +} + +#footer .sponsors .sponsor { + padding-right: 22px; +} + +#footer a, #footer a:hover { + color: #8DD0FF; +} +#footer .c9-logo { + width: 141px; + height: 20px; + background: url(../images/c9-log-footer.png) no-repeat 0 0; + display: inline-block; + padding-right: 10px; +} +#footer .joyent-logo { + width: 70px; + height: 19px; + background: url(../images/joyent-logo-footer.png) no-repeat 0 0; + display: inline-block; + padding-right: 10px; +} +#footer .mozilla-logo { + width: 78px; + height: 24px; + background: url(../images/mozilla-logo-footer.png) no-repeat 0 0; + display: inline-block; + padding-right: 10px; +} +#footer .debuggable-logo { + width: 119px; + height: 25px; + background: url(../images/debuggable-logo-footer.png) no-repeat 0 0; + display: inline-block; + padding-right: 0 !important; + margin-bottom : -3px; +} +#footer .span11 { + margin-left: 0; +} + +.logoText, .logoImg { + /*position: absolute;*/ + margin-bottom: 5px; +} + +.logoImg { + top: 40px; +} +.topbar div > ul .menu-dropdown li a:hover, +.nav .menu-dropdown li a:hover, +.topbar div > ul .dropdown-menu li a:hover, +.nav .dropdown-menu li a:hover { + background-color: #191919; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919)); + background-image: -moz-linear-gradient(top, #292929, #191919); + background-image: -ms-linear-gradient(top, #292929, #191919); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919)); + background-image: -webkit-linear-gradient(top, #292929, #191919); + background-image: -o-linear-gradient(top, #292929, #191919); + background-image: linear-gradient(top, #292929, #191919); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0); + color: #ffffff; +} + +.alert-message.block-message { + background: #fefaca; + border-color : #fefaca; + padding : 8px 14px 8px 14px; +} + +body .dsq-reply{ + margin-top : 10px; +} + +#disqus_thread{ + border-top : 1px solid #ddd; + margin-top : 30px; +} + +#disqus_thread h3, body #dsq-content h3 { + font-size : 12px; + margin : 0 0 20px 0; + line-height : 12px; +} +body #dsq-reply h3{ + font-size : 18px; + line-height : 18px; + margin : 15px 0 20px 0; +} + +#disqus_thread select{ + font-size : 11px; + height : 20px; + color : #444; +} + +#dsq-global-toolbar, #dsq-pagination, .dsq-trackback-url{ + display : none; +} + +/* Sticky footer stuff */ + +html +{ +height: 100%; +} + +body +{ +height: 100%; +} + +#nonFooter +{ +position: relative; +min-height: 100%; +} + +* html #nonFooter +{ +height: 100%; +} + +#wrapper +{ + +} + +#footer +{ +position: relative; +margin-top: -3.5em; +} \ No newline at end of file diff --git a/api/resources/csses/bootstrap.min.css b/api/resources/csses/bootstrap.min.css new file mode 100644 index 00000000..c9514677 --- /dev/null +++ b/api/resources/csses/bootstrap.min.css @@ -0,0 +1,689 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;} +audio,canvas,video{display:inline-block;*display:inline;*zoom:1;} +audio:not([controls]){display:none;} +html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;} +a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +a:hover,a:active{outline:0;} +sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;} +sup{top:-0.5em;} +sub{bottom:-0.25em;} +img{height:auto;border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;} +button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;} +button,input{*overflow:visible;line-height:normal;} +button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;} +button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;} +input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;} +input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;} +textarea{overflow:auto;vertical-align:top;} +.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";} +.clearfix:after{clear:both;} +.hide-text{overflow:hidden;text-indent:100%;white-space:nowrap;} +.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} +body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333333;background-color:#ffffff;} +a{color:#0088cc;text-decoration:none;} +a:hover{color:#005580;text-decoration:underline;} +.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} +.row:after{clear:both;} +[class*="span"]{float:left;margin-left:20px;} +.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.span12{width:940px;} +.span11{width:860px;} +.span10{width:780px;} +.span9{width:700px;} +.span8{width:620px;} +.span7{width:540px;} +.span6{width:460px;} +.span5{width:380px;} +.span4{width:300px;} +.span3{width:220px;} +.span2{width:140px;} +.span1{width:60px;} +.offset12{margin-left:980px;} +.offset11{margin-left:900px;} +.offset10{margin-left:820px;} +.offset9{margin-left:740px;} +.offset8{margin-left:660px;} +.offset7{margin-left:580px;} +.offset6{margin-left:500px;} +.offset5{margin-left:420px;} +.offset4{margin-left:340px;} +.offset3{margin-left:260px;} +.offset2{margin-left:180px;} +.offset1{margin-left:100px;} +.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} +.row-fluid:after{clear:both;} +.row-fluid>[class*="span"]{float:left;margin-left:2.127659574%;} +.row-fluid>[class*="span"]:first-child{margin-left:0;} +.row-fluid > .span12{width:99.99999998999999%;} +.row-fluid > .span11{width:91.489361693%;} +.row-fluid > .span10{width:82.97872339599999%;} +.row-fluid > .span9{width:74.468085099%;} +.row-fluid > .span8{width:65.95744680199999%;} +.row-fluid > .span7{width:57.446808505%;} +.row-fluid > .span6{width:48.93617020799999%;} +.row-fluid > .span5{width:40.425531911%;} +.row-fluid > .span4{width:31.914893614%;} +.row-fluid > .span3{width:23.404255317%;} +.row-fluid > .span2{width:14.89361702%;} +.row-fluid > .span1{width:6.382978723%;} +.container{margin-left:auto;margin-right:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";} +.container:after{clear:both;} +.container-fluid{padding-left:20px;padding-right:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";} +.container-fluid:after{clear:both;} +p{margin:0 0 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;}p small{font-size:11px;color:#999999;} +.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px;} +h1,h2,h3,h4,h5,h6{margin:0;font-family:inherit;font-weight:bold;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999999;} +h1{font-size:30px;line-height:36px;}h1 small{font-size:18px;} +h2{font-size:24px;line-height:36px;}h2 small{font-size:18px;} +h3{line-height:27px;font-size:18px;}h3 small{font-size:14px;} +h4,h5,h6{line-height:18px;} +h4{font-size:14px;}h4 small{font-size:12px;} +h5{font-size:12px;} +h6{font-size:11px;color:#999999;text-transform:uppercase;} +.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eeeeee;} +.page-header h1{line-height:1;} +ul,ol{padding:0;margin:0 0 9px 25px;} +ul ul,ul ol,ol ol,ol ul{margin-bottom:0;} +ul{list-style:disc;} +ol{list-style:decimal;} +li{line-height:18px;} +ul.unstyled,ol.unstyled{margin-left:0;list-style:none;} +dl{margin-bottom:18px;} +dt,dd{line-height:18px;} +dt{font-weight:bold;line-height:17px;} +dd{margin-left:9px;} +.dl-horizontal dt{float:left;clear:left;width:120px;text-align:right;} +.dl-horizontal dd{margin-left:130px;} +hr{margin:18px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;} +strong{font-weight:bold;} +em{font-style:italic;} +.muted{color:#999999;} +abbr[title]{border-bottom:1px dotted #ddd;cursor:help;} +abbr.initialism{font-size:90%;text-transform:uppercase;} +blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px;} +blockquote small{display:block;line-height:18px;color:#999999;}blockquote small:before{content:'\2014 \00A0';} +blockquote.pull-right{float:right;padding-left:0;padding-right:15px;border-left:0;border-right:5px solid #eeeeee;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;} +q:before,q:after,blockquote:before,blockquote:after{content:"";} +address{display:block;margin-bottom:18px;line-height:18px;font-style:normal;} +small{font-size:100%;} +cite{font-style:normal;} +code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;} +pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12.025px;line-height:18px;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;white-space:pre;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;}pre.prettyprint{margin-bottom:18px;} +pre code{padding:0;color:inherit;background-color:transparent;border:0;} +.pre-scrollable{max-height:340px;overflow-y:scroll;} +form{margin:0 0 18px;} +fieldset{padding:0;margin:0;border:0;} +legend{display:block;width:100%;padding:0;margin-bottom:27px;font-size:19.5px;line-height:36px;color:#333333;border:0;border-bottom:1px solid #eee;}legend small{font-size:13.5px;color:#999999;} +label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:18px;} +input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;} +label{display:block;margin-bottom:5px;color:#333333;} +input,textarea,select,.uneditable-input{display:inline-block;width:210px;height:18px;padding:4px;margin-bottom:9px;font-size:13px;line-height:18px;color:#555555;border:1px solid #cccccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.uneditable-textarea{width:auto;height:auto;} +label input,label textarea,label select{display:block;} +input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border:0 \9;} +input[type="image"]{border:0;} +input[type="file"]{width:auto;padding:initial;line-height:initial;border:initial;background-color:#ffffff;background-color:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;} +select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px;} +input[type="file"]{line-height:18px \9;} +select{width:220px;background-color:#ffffff;} +select[multiple],select[size]{height:auto;} +input[type="image"]{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +textarea{height:auto;} +input[type="hidden"]{display:none;} +.radio,.checkbox{padding-left:18px;} +.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px;} +.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;} +.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;} +.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;} +input,textarea{-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-ms-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s;} +input:focus,textarea:focus{border-color:rgba(82, 168, 236, 0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);outline:0;outline:thin dotted \9;} +input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.input-mini{width:60px;} +.input-small{width:90px;} +.input-medium{width:150px;} +.input-large{width:210px;} +.input-xlarge{width:270px;} +.input-xxlarge{width:530px;} +input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{float:none;margin-left:0;} +input,textarea,.uneditable-input{margin-left:0;} +input.span12, textarea.span12, .uneditable-input.span12{width:930px;} +input.span11, textarea.span11, .uneditable-input.span11{width:850px;} +input.span10, textarea.span10, .uneditable-input.span10{width:770px;} +input.span9, textarea.span9, .uneditable-input.span9{width:690px;} +input.span8, textarea.span8, .uneditable-input.span8{width:610px;} +input.span7, textarea.span7, .uneditable-input.span7{width:530px;} +input.span6, textarea.span6, .uneditable-input.span6{width:450px;} +input.span5, textarea.span5, .uneditable-input.span5{width:370px;} +input.span4, textarea.span4, .uneditable-input.span4{width:290px;} +input.span3, textarea.span3, .uneditable-input.span3{width:210px;} +input.span2, textarea.span2, .uneditable-input.span2{width:130px;} +input.span1, textarea.span1, .uneditable-input.span1{width:50px;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{background-color:#eeeeee;border-color:#ddd;cursor:not-allowed;} +.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;} +.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853;}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:0 0 6px #dbc59e;-moz-box-shadow:0 0 6px #dbc59e;box-shadow:0 0 6px #dbc59e;} +.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} +.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} +.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48;}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:0 0 6px #d59392;-moz-box-shadow:0 0 6px #d59392;box-shadow:0 0 6px #d59392;} +.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} +.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} +.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847;}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:0 0 6px #7aba7b;-moz-box-shadow:0 0 6px #7aba7b;box-shadow:0 0 6px #7aba7b;} +.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} +input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} +.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#eeeeee;border-top:1px solid #ddd;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";} +.form-actions:after{clear:both;} +.uneditable-input{display:block;background-color:#ffffff;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;} +:-moz-placeholder{color:#999999;} +::-webkit-input-placeholder{color:#999999;} +.help-block,.help-inline{color:#555555;} +.help-block{display:block;margin-bottom:9px;} +.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;} +.input-prepend,.input-append{margin-bottom:5px;}.input-prepend input,.input-append input,.input-prepend select,.input-append select,.input-prepend .uneditable-input,.input-append .uneditable-input{*margin-left:0;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}.input-prepend input:focus,.input-append input:focus,.input-prepend select:focus,.input-append select:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus{position:relative;z-index:2;} +.input-prepend .uneditable-input,.input-append .uneditable-input{border-left-color:#ccc;} +.input-prepend .add-on,.input-append .add-on{display:inline-block;width:auto;min-width:16px;height:18px;padding:4px 5px;font-weight:normal;line-height:18px;text-align:center;text-shadow:0 1px 0 #ffffff;vertical-align:middle;background-color:#eeeeee;border:1px solid #ccc;} +.input-prepend .add-on,.input-append .add-on,.input-prepend .btn,.input-append .btn{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-prepend .active,.input-append .active{background-color:#a9dba9;border-color:#46a546;} +.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;} +.input-append input,.input-append select .uneditable-input{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-append .uneditable-input{border-left-color:#eee;border-right-color:#ccc;} +.input-append .add-on,.input-append .btn{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.search-query{padding-left:14px;padding-right:14px;margin-bottom:0;-webkit-border-radius:14px;-moz-border-radius:14px;border-radius:14px;} +.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;margin-bottom:0;} +.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;} +.form-search label,.form-inline label{display:inline-block;} +.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;} +.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;} +.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-left:0;margin-right:3px;} +.control-group{margin-bottom:9px;} +legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate;} +.form-horizontal .control-group{margin-bottom:18px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";} +.form-horizontal .control-group:after{clear:both;} +.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right;} +.form-horizontal .controls{margin-left:160px;*display:inline-block;*margin-left:0;*padding-left:20px;} +.form-horizontal .help-block{margin-top:9px;margin-bottom:0;} +.form-horizontal .form-actions{padding-left:160px;} +table{max-width:100%;border-collapse:collapse;border-spacing:0;background-color:transparent;} +.table{width:100%;margin-bottom:18px;}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #dddddd;} +.table th{font-weight:bold;} +.table thead th{vertical-align:bottom;} +.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0;} +.table tbody+tbody{border-top:2px solid #dddddd;} +.table-condensed th,.table-condensed td{padding:4px 5px;} +.table-bordered{border:1px solid #dddddd;border-left:0;border-collapse:separate;*border-collapse:collapsed;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th,.table-bordered td{border-left:1px solid #dddddd;} +.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;} +.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-radius:4px 0 0 0;-moz-border-radius:4px 0 0 0;border-radius:4px 0 0 0;} +.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-radius:0 4px 0 0;-moz-border-radius:0 4px 0 0;border-radius:0 4px 0 0;} +.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;} +.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-radius:0 0 4px 0;-moz-border-radius:0 0 4px 0;border-radius:0 0 4px 0;} +.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;} +.table tbody tr:hover td,.table tbody tr:hover th{background-color:#f5f5f5;} +table .span1{float:none;width:44px;margin-left:0;} +table .span2{float:none;width:124px;margin-left:0;} +table .span3{float:none;width:204px;margin-left:0;} +table .span4{float:none;width:284px;margin-left:0;} +table .span5{float:none;width:364px;margin-left:0;} +table .span6{float:none;width:444px;margin-left:0;} +table .span7{float:none;width:524px;margin-left:0;} +table .span8{float:none;width:604px;margin-left:0;} +table .span9{float:none;width:684px;margin-left:0;} +table .span10{float:none;width:764px;margin-left:0;} +table .span11{float:none;width:844px;margin-left:0;} +table .span12{float:none;width:924px;margin-left:0;} +table .span13{float:none;width:1004px;margin-left:0;} +table .span14{float:none;width:1084px;margin-left:0;} +table .span15{float:none;width:1164px;margin-left:0;} +table .span16{float:none;width:1244px;margin-left:0;} +table .span17{float:none;width:1324px;margin-left:0;} +table .span18{float:none;width:1404px;margin-left:0;} +table .span19{float:none;width:1484px;margin-left:0;} +table .span20{float:none;width:1564px;margin-left:0;} +table .span21{float:none;width:1644px;margin-left:0;} +table .span22{float:none;width:1724px;margin-left:0;} +table .span23{float:none;width:1804px;margin-left:0;} +table .span24{float:none;width:1884px;margin-left:0;} +[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;*margin-right:.3em;}[class^="icon-"]:last-child,[class*=" icon-"]:last-child{*margin-left:0;} +.icon-white{background-image:url("../img/glyphicons-halflings-white.png");} +.icon-glass{background-position:0 0;} +.icon-music{background-position:-24px 0;} +.icon-search{background-position:-48px 0;} +.icon-envelope{background-position:-72px 0;} +.icon-heart{background-position:-96px 0;} +.icon-star{background-position:-120px 0;} +.icon-star-empty{background-position:-144px 0;} +.icon-user{background-position:-168px 0;} +.icon-film{background-position:-192px 0;} +.icon-th-large{background-position:-216px 0;} +.icon-th{background-position:-240px 0;} +.icon-th-list{background-position:-264px 0;} +.icon-ok{background-position:-288px 0;} +.icon-remove{background-position:-312px 0;} +.icon-zoom-in{background-position:-336px 0;} +.icon-zoom-out{background-position:-360px 0;} +.icon-off{background-position:-384px 0;} +.icon-signal{background-position:-408px 0;} +.icon-cog{background-position:-432px 0;} +.icon-trash{background-position:-456px 0;} +.icon-home{background-position:0 -24px;} +.icon-file{background-position:-24px -24px;} +.icon-time{background-position:-48px -24px;} +.icon-road{background-position:-72px -24px;} +.icon-download-alt{background-position:-96px -24px;} +.icon-download{background-position:-120px -24px;} +.icon-upload{background-position:-144px -24px;} +.icon-inbox{background-position:-168px -24px;} +.icon-play-circle{background-position:-192px -24px;} +.icon-repeat{background-position:-216px -24px;} +.icon-refresh{background-position:-240px -24px;} +.icon-list-alt{background-position:-264px -24px;} +.icon-lock{background-position:-287px -24px;} +.icon-flag{background-position:-312px -24px;} +.icon-headphones{background-position:-336px -24px;} +.icon-volume-off{background-position:-360px -24px;} +.icon-volume-down{background-position:-384px -24px;} +.icon-volume-up{background-position:-408px -24px;} +.icon-qrcode{background-position:-432px -24px;} +.icon-barcode{background-position:-456px -24px;} +.icon-tag{background-position:0 -48px;} +.icon-tags{background-position:-25px -48px;} +.icon-book{background-position:-48px -48px;} +.icon-bookmark{background-position:-72px -48px;} +.icon-print{background-position:-96px -48px;} +.icon-camera{background-position:-120px -48px;} +.icon-font{background-position:-144px -48px;} +.icon-bold{background-position:-167px -48px;} +.icon-italic{background-position:-192px -48px;} +.icon-text-height{background-position:-216px -48px;} +.icon-text-width{background-position:-240px -48px;} +.icon-align-left{background-position:-264px -48px;} +.icon-align-center{background-position:-288px -48px;} +.icon-align-right{background-position:-312px -48px;} +.icon-align-justify{background-position:-336px -48px;} +.icon-list{background-position:-360px -48px;} +.icon-indent-left{background-position:-384px -48px;} +.icon-indent-right{background-position:-408px -48px;} +.icon-facetime-video{background-position:-432px -48px;} +.icon-picture{background-position:-456px -48px;} +.icon-pencil{background-position:0 -72px;} +.icon-map-marker{background-position:-24px -72px;} +.icon-adjust{background-position:-48px -72px;} +.icon-tint{background-position:-72px -72px;} +.icon-edit{background-position:-96px -72px;} +.icon-share{background-position:-120px -72px;} +.icon-check{background-position:-144px -72px;} +.icon-move{background-position:-168px -72px;} +.icon-step-backward{background-position:-192px -72px;} +.icon-fast-backward{background-position:-216px -72px;} +.icon-backward{background-position:-240px -72px;} +.icon-play{background-position:-264px -72px;} +.icon-pause{background-position:-288px -72px;} +.icon-stop{background-position:-312px -72px;} +.icon-forward{background-position:-336px -72px;} +.icon-fast-forward{background-position:-360px -72px;} +.icon-step-forward{background-position:-384px -72px;} +.icon-eject{background-position:-408px -72px;} +.icon-chevron-left{background-position:-432px -72px;} +.icon-chevron-right{background-position:-456px -72px;} +.icon-plus-sign{background-position:0 -96px;} +.icon-minus-sign{background-position:-24px -96px;} +.icon-remove-sign{background-position:-48px -96px;} +.icon-ok-sign{background-position:-72px -96px;} +.icon-question-sign{background-position:-96px -96px;} +.icon-info-sign{background-position:-120px -96px;} +.icon-screenshot{background-position:-144px -96px;} +.icon-remove-circle{background-position:-168px -96px;} +.icon-ok-circle{background-position:-192px -96px;} +.icon-ban-circle{background-position:-216px -96px;} +.icon-arrow-left{background-position:-240px -96px;} +.icon-arrow-right{background-position:-264px -96px;} +.icon-arrow-up{background-position:-289px -96px;} +.icon-arrow-down{background-position:-312px -96px;} +.icon-share-alt{background-position:-336px -96px;} +.icon-resize-full{background-position:-360px -96px;} +.icon-resize-small{background-position:-384px -96px;} +.icon-plus{background-position:-408px -96px;} +.icon-minus{background-position:-433px -96px;} +.icon-asterisk{background-position:-456px -96px;} +.icon-exclamation-sign{background-position:0 -120px;} +.icon-gift{background-position:-24px -120px;} +.icon-leaf{background-position:-48px -120px;} +.icon-fire{background-position:-72px -120px;} +.icon-eye-open{background-position:-96px -120px;} +.icon-eye-close{background-position:-120px -120px;} +.icon-warning-sign{background-position:-144px -120px;} +.icon-plane{background-position:-168px -120px;} +.icon-calendar{background-position:-192px -120px;} +.icon-random{background-position:-216px -120px;} +.icon-comment{background-position:-240px -120px;} +.icon-magnet{background-position:-264px -120px;} +.icon-chevron-up{background-position:-288px -120px;} +.icon-chevron-down{background-position:-313px -119px;} +.icon-retweet{background-position:-336px -120px;} +.icon-shopping-cart{background-position:-360px -120px;} +.icon-folder-close{background-position:-384px -120px;} +.icon-folder-open{background-position:-408px -120px;} +.icon-resize-vertical{background-position:-432px -119px;} +.icon-resize-horizontal{background-position:-456px -118px;} +.dropdown{position:relative;} +.dropdown-toggle{*margin-bottom:-3px;} +.dropdown-toggle:active,.open .dropdown-toggle{outline:0;} +.caret{display:inline-block;width:0;height:0;vertical-align:top;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000000;opacity:0.3;filter:alpha(opacity=30);content:"";} +.dropdown .caret{margin-top:8px;margin-left:2px;} +.dropdown:hover .caret,.open.dropdown .caret{opacity:1;filter:alpha(opacity=100);} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;float:left;display:none;min-width:160px;padding:4px 0;margin:0;list-style:none;background-color:#ffffff;border-color:#ccc;border-color:rgba(0, 0, 0, 0.2);border-style:solid;border-width:1px;-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;*border-right-width:2px;*border-bottom-width:2px;}.dropdown-menu.pull-right{right:0;left:auto;} +.dropdown-menu .divider{height:1px;margin:8px 1px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;*width:100%;*margin:-5px 0 5px;} +.dropdown-menu a{display:block;padding:3px 15px;clear:both;font-weight:normal;line-height:18px;color:#333333;white-space:nowrap;} +.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#ffffff;text-decoration:none;background-color:#0088cc;} +.dropdown.open{*z-index:1000;}.dropdown.open .dropdown-toggle{color:#ffffff;background:#ccc;background:rgba(0, 0, 0, 0.3);} +.dropdown.open .dropdown-menu{display:block;} +.pull-right .dropdown-menu{left:auto;right:0;} +.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"\2191";} +.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;} +.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} +.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.fade{-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-ms-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;opacity:0;}.fade.in{opacity:1;} +.collapse{-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-ms-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;position:relative;overflow:hidden;height:0;}.collapse.in{height:auto;} +.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;opacity:0.4;filter:alpha(opacity=40);cursor:pointer;} +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 10px 4px;margin-bottom:0;font-size:13px;line-height:18px;color:#333333;text-align:center;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);vertical-align:middle;background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-ms-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(top, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);border:1px solid #cccccc;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);cursor:pointer;*margin-left:.3em;}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{background-color:#e6e6e6;} +.btn:active,.btn.active{background-color:#cccccc \9;} +.btn:first-child{*margin-left:0;} +.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-ms-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} +.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.btn.active,.btn:active{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);background-color:#e6e6e6;background-color:#d9d9d9 \9;outline:0;} +.btn.disabled,.btn[disabled]{cursor:default;background-image:none;background-color:#e6e6e6;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.btn-large [class^="icon-"]{margin-top:1px;} +.btn-small{padding:5px 9px;font-size:11px;line-height:16px;} +.btn-small [class^="icon-"]{margin-top:-1px;} +.btn-mini{padding:2px 6px;font-size:11px;line-height:14px;} +.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover,.btn-inverse,.btn-inverse:hover{text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);color:#ffffff;} +.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);} +.btn-primary{background-color:#0074cc;background-image:-moz-linear-gradient(top, #0088cc, #0055cc);background-image:-ms-linear-gradient(top, #0088cc, #0055cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0055cc));background-image:-webkit-linear-gradient(top, #0088cc, #0055cc);background-image:-o-linear-gradient(top, #0088cc, #0055cc);background-image:linear-gradient(top, #0088cc, #0055cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0055cc', GradientType=0);border-color:#0055cc #0055cc #003580;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{background-color:#0055cc;} +.btn-primary:active,.btn-primary.active{background-color:#004099 \9;} +.btn-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{background-color:#f89406;} +.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} +.btn-danger{background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-ms-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(top, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{background-color:#bd362f;} +.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} +.btn-success{background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-ms-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(top, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{background-color:#51a351;} +.btn-success:active,.btn-success.active{background-color:#408140 \9;} +.btn-info{background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-ms-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(top, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{background-color:#2f96b4;} +.btn-info:active,.btn-info.active{background-color:#24748c \9;} +.btn-inverse{background-color:#414141;background-image:-moz-linear-gradient(top, #555555, #222222);background-image:-ms-linear-gradient(top, #555555, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222));background-image:-webkit-linear-gradient(top, #555555, #222222);background-image:-o-linear-gradient(top, #555555, #222222);background-image:linear-gradient(top, #555555, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{background-color:#222222;} +.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;} +button.btn,input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;} +button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;} +button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;} +button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;} +.btn-group{position:relative;*zoom:1;*margin-left:.3em;}.btn-group:before,.btn-group:after{display:table;content:"";} +.btn-group:after{clear:both;} +.btn-group:first-child{*margin-left:0;} +.btn-group+.btn-group{margin-left:5px;} +.btn-toolbar{margin-top:9px;margin-bottom:9px;}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1;} +.btn-group .btn{position:relative;float:left;margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group .btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.btn-group .btn:last-child,.btn-group .dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.btn-group .btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.btn-group .btn.large:last-child,.btn-group .large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.btn-group .btn:hover,.btn-group .btn:focus,.btn-group .btn:active,.btn-group .btn.active{z-index:2;} +.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;} +.btn-group .dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);*padding-top:3px;*padding-bottom:3px;} +.btn-group .btn-mini.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:1px;*padding-bottom:1px;} +.btn-group .btn-small.dropdown-toggle{*padding-top:4px;*padding-bottom:4px;} +.btn-group .btn-large.dropdown-toggle{padding-left:12px;padding-right:12px;} +.btn-group.open{*z-index:1000;}.btn-group.open .dropdown-menu{display:block;margin-top:1px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);} +.btn .caret{margin-top:7px;margin-left:0;} +.btn:hover .caret,.open.btn-group .caret{opacity:1;filter:alpha(opacity=100);} +.btn-mini .caret{margin-top:5px;} +.btn-small .caret{margin-top:6px;} +.btn-large .caret{margin-top:6px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:0.75;filter:alpha(opacity=75);} +.alert{padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;} +.alert-heading{color:inherit;} +.alert .close{position:relative;top:-2px;right:-21px;line-height:18px;} +.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;} +.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;} +.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;} +.alert-block{padding-top:14px;padding-bottom:14px;} +.alert-block>p,.alert-block>ul{margin-bottom:0;} +.alert-block p+p{margin-top:5px;} +.nav{margin-left:0;margin-bottom:18px;list-style:none;} +.nav>li>a{display:block;} +.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} +.nav .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:18px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;} +.nav li+.nav-header{margin-top:9px;} +.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;} +.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} +.nav-list>li>a{padding:3px 15px;} +.nav-list>.active>a,.nav-list>.active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;} +.nav-list [class^="icon-"]{margin-right:2px;} +.nav-list .divider{height:1px;margin:8px 1px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;*width:100%;*margin:-5px 0 5px;} +.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";} +.nav-tabs:after,.nav-pills:after{clear:both;} +.nav-tabs>li,.nav-pills>li{float:left;} +.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} +.nav-tabs{border-bottom:1px solid #ddd;} +.nav-tabs>li{margin-bottom:-1px;} +.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:18px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#0088cc;} +.nav-stacked>li{float:none;} +.nav-stacked>li>a{margin-right:0;} +.nav-tabs.nav-stacked{border-bottom:0;} +.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} +.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} +.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;} +.nav-pills.nav-stacked>li>a{margin-bottom:3px;} +.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;} +.nav-tabs .dropdown-menu,.nav-pills .dropdown-menu{margin-top:1px;border-width:1px;} +.nav-pills .dropdown-menu{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;} +.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;} +.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret{border-top-color:#333333;border-bottom-color:#333333;} +.nav>.dropdown.active>a:hover{color:#000000;cursor:pointer;} +.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;} +.nav .open .caret,.nav .open.active .caret,.nav .open a:hover .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);} +.tabs-stacked .open>a:hover{border-color:#999999;} +.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";} +.tabbable:after{clear:both;} +.tab-content{display:table;width:100%;} +.tabs-below .nav-tabs,.tabs-right .nav-tabs,.tabs-left .nav-tabs{border-bottom:0;} +.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;} +.tab-content>.active,.pill-content>.active{display:block;} +.tabs-below .nav-tabs{border-top:1px solid #ddd;} +.tabs-below .nav-tabs>li{margin-top:-1px;margin-bottom:0;} +.tabs-below .nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below .nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;} +.tabs-below .nav-tabs .active>a,.tabs-below .nav-tabs .active>a:hover{border-color:transparent #ddd #ddd #ddd;} +.tabs-left .nav-tabs>li,.tabs-right .nav-tabs>li{float:none;} +.tabs-left .nav-tabs>li>a,.tabs-right .nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;} +.tabs-left .nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;} +.tabs-left .nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.tabs-left .nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;} +.tabs-left .nav-tabs .active>a,.tabs-left .nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;} +.tabs-right .nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;} +.tabs-right .nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.tabs-right .nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;} +.tabs-right .nav-tabs .active>a,.tabs-right .nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} +.navbar{*position:relative;*z-index:2;overflow:visible;margin-bottom:18px;} +.navbar-inner{padding-left:20px;padding-right:20px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);} +.navbar .container{width:auto;} +.btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);}.btn-navbar:hover,.btn-navbar:active,.btn-navbar.active,.btn-navbar.disabled,.btn-navbar[disabled]{background-color:#222222;} +.btn-navbar:active,.btn-navbar.active{background-color:#080808 \9;} +.btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);} +.btn-navbar .icon-bar+.icon-bar{margin-top:3px;} +.nav-collapse.collapse{height:auto;} +.navbar{color:#999999;}.navbar .brand:hover{text-decoration:none;} +.navbar .brand{float:left;display:block;padding:8px 20px 12px;margin-left:-20px;font-size:20px;font-weight:200;line-height:1;color:#ffffff;} +.navbar .navbar-text{margin-bottom:0;line-height:40px;} +.navbar .btn,.navbar .btn-group{margin-top:5px;} +.navbar .btn-group .btn{margin-top:0;} +.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";} +.navbar-form:after{clear:both;} +.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;} +.navbar-form input,.navbar-form select{display:inline-block;margin-bottom:0;} +.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;} +.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;} +.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0;}.navbar-search .search-query{padding:4px 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#ffffff;background-color:#626262;border:1px solid #151515;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.navbar-search .search-query:-moz-placeholder{color:#cccccc;} +.navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;} +.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;} +.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;} +.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.navbar-fixed-top{top:0;} +.navbar-fixed-bottom{bottom:0;} +.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} +.navbar .nav.pull-right{float:right;} +.navbar .nav>li{display:block;float:left;} +.navbar .nav>li>a{float:none;padding:10px 10px 11px;line-height:19px;color:#999999;text-decoration:none;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);} +.navbar .nav>li>a:hover{background-color:transparent;color:#ffffff;text-decoration:none;} +.navbar .nav .active>a,.navbar .nav .active>a:hover{color:#ffffff;text-decoration:none;background-color:#222222;} +.navbar .divider-vertical{height:40px;width:1px;margin:0 9px;overflow:hidden;background-color:#222222;border-right:1px solid #333333;} +.navbar .nav.pull-right{margin-left:10px;margin-right:0;} +.navbar .dropdown-menu{margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.navbar .dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;} +.navbar .dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;} +.navbar-fixed-bottom .dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;} +.navbar-fixed-bottom .dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;} +.navbar .nav .dropdown-toggle .caret,.navbar .nav .open.dropdown .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.navbar .nav .active .caret{opacity:1;filter:alpha(opacity=100);} +.navbar .nav .open>.dropdown-toggle,.navbar .nav .active>.dropdown-toggle,.navbar .nav .open.active>.dropdown-toggle{background-color:transparent;} +.navbar .nav .active>.dropdown-toggle:hover{color:#ffffff;} +.navbar .nav.pull-right .dropdown-menu,.navbar .nav .dropdown-menu.pull-right{left:auto;right:0;}.navbar .nav.pull-right .dropdown-menu:before,.navbar .nav .dropdown-menu.pull-right:before{left:auto;right:12px;} +.navbar .nav.pull-right .dropdown-menu:after,.navbar .nav .dropdown-menu.pull-right:after{left:auto;right:13px;} +.breadcrumb{padding:7px 14px;margin:0 0 18px;list-style:none;background-color:#fbfbfb;background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);background-image:linear-gradient(top, #ffffff, #f5f5f5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#999999;} +.breadcrumb .active a{color:#333333;} +.pagination{height:36px;margin:18px 0;} +.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} +.pagination li{display:inline;} +.pagination a{float:left;padding:0 14px;line-height:34px;text-decoration:none;border:1px solid #ddd;border-left-width:0;} +.pagination a:hover,.pagination .active a{background-color:#f5f5f5;} +.pagination .active a{color:#999999;cursor:default;} +.pagination .disabled span,.pagination .disabled a,.pagination .disabled a:hover{color:#999999;background-color:transparent;cursor:default;} +.pagination li:first-child a{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.pagination li:last-child a{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.pagination-centered{text-align:center;} +.pagination-right{text-align:right;} +.pager{margin-left:0;margin-bottom:18px;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";} +.pager:after{clear:both;} +.pager li{display:inline;} +.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.pager a:hover{text-decoration:none;background-color:#f5f5f5;} +.pager .next a{float:right;} +.pager .previous a{float:left;} +.pager .disabled a,.pager .disabled a:hover{color:#999999;background-color:#fff;cursor:default;} +.modal-open .dropdown-menu{z-index:2050;} +.modal-open .dropdown.open{*z-index:2050;} +.modal-open .popover{z-index:2060;} +.modal-open .tooltip{z-index:2070;} +.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;} +.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);} +.modal{position:fixed;top:50%;left:50%;z-index:1050;overflow:auto;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-ms-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} +.modal.fade.in{top:50%;} +.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;} +.modal-body{overflow-y:auto;max-height:400px;padding:15px;} +.modal-form{margin-bottom:0;} +.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";} +.modal-footer:after{clear:both;} +.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;} +.modal-footer .btn-group .btn+.btn{margin-left:-1px;} +.tooltip{position:absolute;z-index:1020;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);} +.tooltip.top{margin-top:-2px;} +.tooltip.right{margin-left:2px;} +.tooltip.bottom{margin-top:2px;} +.tooltip.left{margin-left:-2px;} +.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} +.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} +.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} +.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.tooltip-arrow{position:absolute;width:0;height:0;} +.popover{position:absolute;top:0;left:0;z-index:1010;display:none;padding:5px;}.popover.top{margin-top:-5px;} +.popover.right{margin-left:5px;} +.popover.bottom{margin-top:5px;} +.popover.left{margin-left:-5px;} +.popover.top .arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} +.popover.bottom .arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} +.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} +.popover .arrow{position:absolute;width:0;height:0;} +.popover-inner{padding:3px;width:280px;overflow:hidden;background:#000000;background:rgba(0, 0, 0, 0.8);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);} +.popover-title{padding:9px 15px;line-height:1;background-color:#f5f5f5;border-bottom:1px solid #eee;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;} +.popover-content{padding:14px;background-color:#ffffff;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} +.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";} +.thumbnails:after{clear:both;} +.thumbnails>li{float:left;margin:0 0 18px 20px;} +.thumbnail{display:block;padding:4px;line-height:1;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);} +a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} +.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;} +.thumbnail .caption{padding:9px;} +.label{padding:1px 4px 2px;font-size:10.998px;font-weight:bold;line-height:13px;color:#ffffff;vertical-align:middle;white-space:nowrap;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.label:hover{color:#ffffff;text-decoration:none;} +.label-important{background-color:#b94a48;} +.label-important:hover{background-color:#953b39;} +.label-warning{background-color:#f89406;} +.label-warning:hover{background-color:#c67605;} +.label-success{background-color:#468847;} +.label-success:hover{background-color:#356635;} +.label-info{background-color:#3a87ad;} +.label-info:hover{background-color:#2d6987;} +.label-inverse{background-color:#333333;} +.label-inverse:hover{background-color:#1a1a1a;} +.badge{padding:1px 9px 2px;font-size:12.025px;font-weight:bold;white-space:nowrap;color:#ffffff;background-color:#999999;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;} +.badge:hover{color:#ffffff;text-decoration:none;cursor:pointer;} +.badge-error{background-color:#b94a48;} +.badge-error:hover{background-color:#953b39;} +.badge-warning{background-color:#f89406;} +.badge-warning:hover{background-color:#c67605;} +.badge-success{background-color:#468847;} +.badge-success:hover{background-color:#356635;} +.badge-info{background-color:#3a87ad;} +.badge-info:hover{background-color:#2d6987;} +.badge-inverse{background-color:#333333;} +.badge-inverse:hover{background-color:#1a1a1a;} +@-webkit-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}.progress{overflow:hidden;height:18px;margin-bottom:18px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-ms-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(top, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.progress .bar{width:0%;height:18px;color:#ffffff;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-ms-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(top, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-ms-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} +.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;} +.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;} +.progress-danger .bar{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);} +.progress-danger.progress-striped .bar{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-success .bar{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-ms-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(top, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);} +.progress-success.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-info .bar{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(top, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);} +.progress-info.progress-striped .bar{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-warning .bar{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);} +.progress-warning.progress-striped .bar{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.accordion{margin-bottom:18px;} +.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion-heading{border-bottom:0;} +.accordion-heading .accordion-toggle{display:block;padding:8px 15px;} +.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;} +.carousel{position:relative;margin-bottom:18px;line-height:1;} +.carousel-inner{overflow:hidden;width:100%;position:relative;} +.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-ms-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;} +.carousel .item>img{display:block;line-height:1;} +.carousel .active,.carousel .next,.carousel .prev{display:block;} +.carousel .active{left:0;} +.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;} +.carousel .next{left:100%;} +.carousel .prev{left:-100%;} +.carousel .next.left,.carousel .prev.right{left:0;} +.carousel .active.left{left:-100%;} +.carousel .active.right{left:100%;} +.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;} +.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);} +.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:10px 15px 5px;background:#333333;background:rgba(0, 0, 0, 0.75);} +.carousel-caption h4,.carousel-caption p{color:#ffffff;} +.hero-unit{padding:60px;margin-bottom:30px;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;} +.hero-unit p{font-size:18px;font-weight:200;line-height:27px;color:inherit;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.invisible{visibility:hidden;} diff --git a/api/resources/csses/prettify.css b/api/resources/csses/prettify.css new file mode 100644 index 00000000..2cd13649 --- /dev/null +++ b/api/resources/csses/prettify.css @@ -0,0 +1,52 @@ +/* Pretty printing styles. Used with prettify.js. */ + +/* SPAN elements with the classes below are added by prettyprint. */ +.pln { color: #000 } /* plain text */ + +@media screen { + .str { color: #2e6a40 } /* string content */ + .kwd { color: #214afc } /* a keyword */ + .com { color: #4c886b } /* a comment */ + .typ { color: #1130ad } /* a type name */ + .lit { color: #1130ad } /* a literal value */ + /* punctuation, lisp open bracket, lisp close bracket */ + .pun, .opn, .clo { color: #2d0603 } + .tag { color: #008 } /* a markup tag name */ + .atn { color: #606 } /* a markup attribute name */ + .atv { color: #080 } /* a markup attribute value */ + .dec, .var { color: #606 } /* a declaration; a variable name */ + .fun { color: #1130ad } /* a function name */ +} + +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { color: #060 } + .kwd { color: #006; font-weight: bold } + .com { color: #600; font-style: italic } + .typ { color: #404; font-weight: bold } + .lit { color: #044 } + .pun, .opn, .clo { color: #440 } + .tag { color: #006; font-weight: bold } + .atn { color: #404 } + .atv { color: #060 } +} + +/* Put a border around prettyprinted code snippets. */ +/*pre.prettyprint { padding: 2px; }*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */` +li.L0, +li.L1, +li.L2, +li.L3, +li.L5, +li.L6, +li.L7, +li.L8 { list-style-type: none } +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { background: #eee } diff --git a/api/resources/images/Ace_ERD.svg b/api/resources/images/Ace_ERD.svg new file mode 100644 index 00000000..ba386287 --- /dev/null +++ b/api/resources/images/Ace_ERD.svg @@ -0,0 +1,4 @@ + + + + diff --git a/api/resources/images/ace_logo.png b/api/resources/images/ace_logo.png new file mode 100644 index 00000000..4dab4f66 Binary files /dev/null and b/api/resources/images/ace_logo.png differ diff --git a/api/resources/images/ace_logo_menu.png b/api/resources/images/ace_logo_menu.png new file mode 100644 index 00000000..b011fadd Binary files /dev/null and b/api/resources/images/ace_logo_menu.png differ diff --git a/api/resources/images/c9-log-footer.png b/api/resources/images/c9-log-footer.png new file mode 100644 index 00000000..f3bcb4d7 Binary files /dev/null and b/api/resources/images/c9-log-footer.png differ diff --git a/api/resources/images/c9-sponsor.png b/api/resources/images/c9-sponsor.png new file mode 100644 index 00000000..599d3b49 Binary files /dev/null and b/api/resources/images/c9-sponsor.png differ diff --git a/api/resources/images/cloud9-logo.png b/api/resources/images/cloud9-logo.png new file mode 100644 index 00000000..912524a9 Binary files /dev/null and b/api/resources/images/cloud9-logo.png differ diff --git a/api/resources/images/content-top.png b/api/resources/images/content-top.png new file mode 100644 index 00000000..ec4ccad0 Binary files /dev/null and b/api/resources/images/content-top.png differ diff --git a/api/resources/images/content_bg.png b/api/resources/images/content_bg.png new file mode 100644 index 00000000..928f81e4 Binary files /dev/null and b/api/resources/images/content_bg.png differ diff --git a/api/resources/images/content_top_bg.png b/api/resources/images/content_top_bg.png new file mode 100644 index 00000000..42039338 Binary files /dev/null and b/api/resources/images/content_top_bg.png differ diff --git a/api/resources/images/dashed_back.png b/api/resources/images/dashed_back.png new file mode 100644 index 00000000..c6ee9313 Binary files /dev/null and b/api/resources/images/dashed_back.png differ diff --git a/api/resources/images/favicon.ico b/api/resources/images/favicon.ico new file mode 100644 index 00000000..e97c70f6 Binary files /dev/null and b/api/resources/images/favicon.ico differ diff --git a/api/resources/images/footer-bg.png b/api/resources/images/footer-bg.png new file mode 100644 index 00000000..0d572c28 Binary files /dev/null and b/api/resources/images/footer-bg.png differ diff --git a/api/resources/images/main_bg.png b/api/resources/images/main_bg.png new file mode 100644 index 00000000..f26aefc2 Binary files /dev/null and b/api/resources/images/main_bg.png differ diff --git a/api/resources/images/member-sprites.png b/api/resources/images/member-sprites.png new file mode 100644 index 00000000..96b0520f Binary files /dev/null and b/api/resources/images/member-sprites.png differ diff --git a/api/resources/images/menu_disc.png b/api/resources/images/menu_disc.png new file mode 100644 index 00000000..1d3925b3 Binary files /dev/null and b/api/resources/images/menu_disc.png differ diff --git a/api/resources/images/method_bg.png b/api/resources/images/method_bg.png new file mode 100644 index 00000000..b0189557 Binary files /dev/null and b/api/resources/images/method_bg.png differ diff --git a/api/resources/images/scrolled-heading-shadow.png b/api/resources/images/scrolled-heading-shadow.png new file mode 100644 index 00000000..aed814ee Binary files /dev/null and b/api/resources/images/scrolled-heading-shadow.png differ diff --git a/api/resources/images/sidebar-top-bg.png b/api/resources/images/sidebar-top-bg.png new file mode 100644 index 00000000..c0a800e1 Binary files /dev/null and b/api/resources/images/sidebar-top-bg.png differ diff --git a/api/resources/images/sidebar_border.png b/api/resources/images/sidebar_border.png new file mode 100644 index 00000000..ea6cd700 Binary files /dev/null and b/api/resources/images/sidebar_border.png differ diff --git a/api/resources/images/swirl_divider.png b/api/resources/images/swirl_divider.png new file mode 100644 index 00000000..f3e9f6c6 Binary files /dev/null and b/api/resources/images/swirl_divider.png differ diff --git a/api/resources/javascripts/bootstrap-dropdown.js b/api/resources/javascripts/bootstrap-dropdown.js new file mode 100644 index 00000000..54b61c5e --- /dev/null +++ b/api/resources/javascripts/bootstrap-dropdown.js @@ -0,0 +1,92 @@ +/* ============================================================ + * bootstrap-dropdown.js v2.0.2 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function( $ ){ + + "use strict" + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle="dropdown"]' + , Dropdown = function ( element ) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function ( e ) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + , isActive + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + $parent.length || ($parent = $this.parent()) + + isActive = $parent.hasClass('open') + + clearMenus() + !isActive && $parent.toggleClass('open') + + return false + } + + } + + function clearMenus() { + $(toggle).parent().removeClass('open') + } + + + /* DROPDOWN PLUGIN DEFINITION + * ========================== */ + + $.fn.dropdown = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('dropdown') + if (!data) $this.data('dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.dropdown.Constructor = Dropdown + + + /* APPLY TO STANDARD DROPDOWN ELEMENTS + * =================================== */ + + $(function () { + $('html').on('click.dropdown.data-api', clearMenus) + $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) + }) + +}( window.jQuery ); \ No newline at end of file diff --git a/api/resources/javascripts/clicker.js b/api/resources/javascripts/clicker.js new file mode 100644 index 00000000..5fe3dca2 --- /dev/null +++ b/api/resources/javascripts/clicker.js @@ -0,0 +1,35 @@ +$(function() { + // when hovering over arrow, add highlight (only if inactive) + $("h3.methodToggle").hover(function () { + if (!$("h3.methodToggle").hasClass('active')) + $(this).addClass("methodToggleHover"); + }, + function () { + $(this).removeClass("methodToggleHover"); + } + ); + + // after expanding the hidden description, hide the ellipsis + $('.signature-call, .signature-returns', '.signature').click(function() { + var $article = $(this).closest('.article'), + $arrow = $('h3.methodClicker', $article); + + if (!$article.hasClass('methodToggleOpen') || this.force) { + $article.addClass('methodToggleOpen'); + $arrow.removeClass('inactive').addClass('active'); + + var data = location.hash = $arrow[0].id.replace(/^js_/, ""); + scrollTo(null, data); + } + else { + $article.removeClass('methodToggleOpen'); + $arrow.removeClass('active').addClass('inactive'); + } + + }); + + $('.related-to', '.metaInfo').click(function(){ + location.hash = $(this).find('a').attr('href').split('#')[1]; + }); +}); + diff --git a/api/resources/javascripts/disqus-ext.js b/api/resources/javascripts/disqus-ext.js new file mode 100644 index 00000000..6f966cc6 --- /dev/null +++ b/api/resources/javascripts/disqus-ext.js @@ -0,0 +1,12 @@ +var disqus_shortname = 'aceapi'; + +var paths = window.location.pathname.split("/"); +var fileName = paths[paths.length - 2] + "/" + paths[paths.length - 1]; + +var disqus_identifier = fileName; + + (function() { + var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; + dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js'; + (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); + })(); \ No newline at end of file diff --git a/api/resources/javascripts/ga.js b/api/resources/javascripts/ga.js new file mode 100644 index 00000000..f0035835 --- /dev/null +++ b/api/resources/javascripts/ga.js @@ -0,0 +1,9 @@ + var _gaq = _gaq || []; + _gaq.push(['_setAccount', 'UA-18736001-1']); + _gaq.push(['_trackPageview']); + + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + })(); \ No newline at end of file diff --git a/api/resources/javascripts/jquery-scrollspy.js b/api/resources/javascripts/jquery-scrollspy.js new file mode 100644 index 00000000..71b4a363 --- /dev/null +++ b/api/resources/javascripts/jquery-scrollspy.js @@ -0,0 +1,98 @@ +/*! + * jQuery Scrollspy Plugin + * Author: @sxalexander + * Licensed under the MIT license + */ + + +;(function ( $, window, document, undefined ) { + + $.fn.extend({ + scrollspy: function ( options ) { + + var defaults = { + min: 0, + max: 0, + mode: 'vertical', + buffer: 0, + container: window, + onEnter: options.onEnter ? options.onEnter : [], + onLeave: options.onLeave ? options.onLeave : [], + onTick: options.onTick ? options.onTick : [] + } + + var options = $.extend( {}, defaults, options ); + + return this.each(function (i) { + + var element = this; + var o = options; + var $container = $(o.container); + var mode = o.mode; + var buffer = o.buffer; + var enters = leaves = 0; + var inside = false; + + /* add listener to container */ + $container.bind('scroll', function(e){ + var position = {top: $(this).scrollTop(), left: $(this).scrollLeft()}; + var xy = (mode == 'vertical') ? position.top + buffer : position.left + buffer; + var max = o.max; + var min = o.min; + + /* fix max */ + if($.isFunction(o.max)){ + max = o.max(); + } + + /* fix max */ + if($.isFunction(o.min)){ + min = o.min(); + } + + if(max == 0){ + max = (mode == 'vertical') ? $container.height() : $container.outerWidth() + $(element).outerWidth(); + } + + /* if we have reached the minimum bound but are below the max ... */ + if(xy >= o.min && xy <= max){ + /* trigger enter event */ + if(!inside){ + inside = true; + enters++; + + /* fire enter event */ + $(element).trigger('scrollEnter', {position: position}) + if($.isFunction(o.onEnter)){ + o.onEnter(element, position); + } + + } + + /* triger tick event */ + $(element).trigger('scrollTick', {position: position, inside: inside, enters: enters, leaves: leaves}) + if($.isFunction(o.onTick)){ + o.onTick(element, position, inside, enters, leaves); + } + }else{ + + if(inside){ + inside = false; + leaves++; + /* trigger leave event */ + $(element).trigger('scrollLeave', {position: position, leaves:leaves}) + + if($.isFunction(o.onLeave)){ + o.onLeave(element, position); + } + } + } + }); + + }); + } + + }) + + +})( jQuery, window ); diff --git a/api/resources/javascripts/jquery.collapse.js b/api/resources/javascripts/jquery.collapse.js new file mode 100644 index 00000000..427ee5fa --- /dev/null +++ b/api/resources/javascripts/jquery.collapse.js @@ -0,0 +1,151 @@ +/*! + * Collapse plugin for jQuery + * http://github.com/danielstocks/jQuery-Collapse/ + * + * @author Daniel Stocks (http://webcloud.se) + * @version 0.9.1 + * @updated 17-AUG-2010 + * + * Copyright 2010, Daniel Stocks + * Released under the MIT, BSD, and GPL Licenses. + */ + +(function($) { + + // Use a cookie counter to allow multiple instances of the plugin + var cookieCounter = 0; + + $.fn.extend({ + collapse: function(options) { + + var defaults = { + head : "h3", + group : "div, ul", + cookieName : "collapse", + // Default function for showing content + show: function() { + this.show(); + }, + // Default function for hiding content + hide: function() { + this.hide(); + } + }; + var op = $.extend(defaults, options); + + // Default CSS classes + var active = "active", + inactive = "inactive"; + + return this.each(function() { + + // Increment coookie counter to ensure cookie name integrity + cookieCounter++; + var obj = $(this), + // Find all headers and wrap them in for accessibility. + sections = obj.find(op.head).wrapInner(''), + l = sections.length, + cookie = op.cookieName + "_" + cookieCounter; + // Locate all panels directly following a header + var panel = obj.find(op.head).map(function() { + var head = $(this) + if(!head.hasClass(active)) { + return head.next(op.group).hide()[0]; + } + return head.next(op.group)[0]; + }); + + // Bind event for showing content + obj.bind("show", function(e, bypass) { + var obj = $(e.target); + // ARIA attribute + obj.attr('aria-hidden', false) + .prev() + .removeClass(inactive) + .addClass(active); + // Bypass method for instant display + if(bypass) { + obj.show(); + } else { + op.show.call(obj); + } + }); + + // Bind event for hiding content + obj.bind("hide", function(e, bypass) { + var obj = $(e.target); + obj.attr('aria-hidden', true) + .prev() + .removeClass(active) + .addClass(inactive); + if(bypass) { + obj.hide(); + } else { + op.hide.call(obj); + } + }); + + // Look for existing cookies + if(cookieSupport) { + for (var c=0;c<=l;c++) { + var val = $.cookie(cookie + c); + // Show content if associating cookie is found + if ( val == c + "open" ) { + panel.eq(c).trigger('show', [true]); + // Hide content + } else if ( val == c + "closed") { + panel.eq(c).trigger('hide', [true]); + } + } + } + + // Delegate click event to show/hide content. + obj.bind("click", function(e) { + var t = $(e.target); + // Check if header was clicked + if(!t.is(op.head)) { + // What about link inside header. + if ( t.parent().is(op.head) ) { + t = t.parent(); + } else { + return; + } + e.preventDefault(); + } + // Figure out what position the clicked header has. + var num = sections.index(t), + cookieName = cookie + num, + cookieVal = num, + content = t.next(op.group); + // If content is already active, hide it. + if(t.hasClass(active)) { + content.trigger('hide'); + cookieVal += 'closed'; + if(cookieSupport) { + $.cookie(cookieName, cookieVal, { path: '/', expires: 10 }); + } + return; + } + // Otherwise show it. + content.trigger('show'); + cookieVal += 'open'; + if(cookieSupport) { + $.cookie(cookieName, cookieVal, { path: '/', expires: 10 }); + } + }); + }); + } + }); + + // Make sure can we eat cookies without getting into trouble. + var cookieSupport = (function() { + try { + $.cookie('x', 'x', { path: '/', expires: 10 }); + $.cookie('x', null); + } + catch(e) { + return false; + } + return true; + })(); +})(jQuery); \ No newline at end of file diff --git a/api/resources/javascripts/jquery.cookie.js b/api/resources/javascripts/jquery.cookie.js new file mode 100644 index 00000000..6df1faca --- /dev/null +++ b/api/resources/javascripts/jquery.cookie.js @@ -0,0 +1,96 @@ +/** + * Cookie plugin + * + * Copyright (c) 2006 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ + +/** + * Create a cookie with the given name and value and other optional parameters. + * + * @example $.cookie('the_cookie', 'the_value'); + * @desc Set the value of a cookie. + * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); + * @desc Create a cookie with all available options. + * @example $.cookie('the_cookie', 'the_value'); + * @desc Create a session cookie. + * @example $.cookie('the_cookie', null); + * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain + * used when the cookie was set. + * + * @param String name The name of the cookie. + * @param String value The value of the cookie. + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. + * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. + * If set to null or omitted, the cookie will be a session cookie and will not be retained + * when the the browser exits. + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will + * require a secure protocol (like HTTPS). + * @type undefined + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ + +/** + * Get the value of a cookie with the given name. + * + * @example $.cookie('the_cookie'); + * @desc Get the value of a cookie. + * + * @param String name The name of the cookie. + * @return The value of the cookie. + * @type String + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ +jQuery.cookie = function(name, value, options) { + if (typeof value != 'undefined') { // name and value given, set cookie + options = options || {}; + if (value === null) { + value = ''; + options.expires = -1; + } + var expires = ''; + if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { + var date; + if (typeof options.expires == 'number') { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else { + date = options.expires; + } + expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE + } + // CAUTION: Needed to parenthesize options.path and options.domain + // in the following expressions, otherwise they evaluate to undefined + // in the packed version for some reason... + var path = options.path ? '; path=' + (options.path) : ''; + var domain = options.domain ? '; domain=' + (options.domain) : ''; + var secure = options.secure ? '; secure' : ''; + document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); + } else { // only name given, get cookie + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } +}; \ No newline at end of file diff --git a/api/resources/javascripts/jquery.js b/api/resources/javascripts/jquery.js new file mode 100644 index 00000000..3ca5e0f5 --- /dev/null +++ b/api/resources/javascripts/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7 jquery.com | jquery.org/license */ +(function(a,b){function cA(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cx(a){if(!cm[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cn||(cn=c.createElement("iframe"),cn.frameBorder=cn.width=cn.height=0),b.appendChild(cn);if(!co||!cn.createElement)co=(cn.contentWindow||cn.contentDocument).document,co.write((c.compatMode==="CSS1Compat"?"":"")+""),co.close();d=co.createElement(a),co.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cn)}cm[a]=e}return cm[a]}function cw(a,b){var c={};f.each(cs.concat.apply([],cs.slice(0,b)),function(){c[this]=a});return c}function cv(){ct=b}function cu(){setTimeout(cv,0);return ct=f.now()}function cl(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ck(){try{return new a.XMLHttpRequest}catch(b){}}function ce(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bB(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function br(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bi,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bq(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bp(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bp)}function bp(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bo(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bn(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bm(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(){return!0}function M(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.add(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return a!=null&&m.test(a)&&!isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
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="
"+""+"
";m=c.getElementsByTagName("body")[0];!m||(a=c.createElement("div"),a.style.cssText=l+"width:0;height:0;position:static;top:0;margin-top:"+i+"px",m.insertBefore(a,m.firstChild),o=c.createElement("div"),o.style.cssText=j+l,o.innerHTML=p,a.appendChild(o),b=o.firstChild,d=b.firstChild,g=b.nextSibling.firstChild.firstChild,h={doesNotAddBorder:d.offsetTop!==5,doesAddBorderForTableAndCells:g.offsetTop===5},d.style.position="fixed",d.style.top="20px",h.fixedPosition=d.offsetTop===20||d.offsetTop===15,d.style.position=d.style.top="",b.style.overflow="hidden",b.style.position="relative",h.subtractsBorderForOverflowNotVisible=d.offsetTop===-5,h.doesNotIncludeMarginInBodyOffset=m.offsetTop!==i,m.removeChild(a),o=a=null,f.extend(k,h))}),o.innerHTML="",n.removeChild(o),o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[f.expando]:a[f.expando]&&f.expando,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[f.expando]=n=++f.uuid:n=f.expando),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[f.expando]:f.expando;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)?b=b:b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" "));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];if(!arguments.length){if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}return b}e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!a||j===3||j===8||j===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g},removeAttr:function(a,b){var c,d,e,g,h=0;if(a.nodeType===1){d=(b||"").split(p),g=d.length;for(;h=0}})});var z=/\.(.*)$/,A=/^(?:textarea|input|select)$/i,B=/\./g,C=/ /g,D=/[^\w\s.|`]/g,E=/^([^\.]*)?(?:\.(.+))?$/,F=/\bhover(\.\S+)?/,G=/^key/,H=/^(?:mouse|contextmenu)|click/,I=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,J=function(a){var b=I.exec(a);b&& +(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},K=function(a,b){return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||a.id===b[2])&&(!b[3]||b[3].test(a.className))},L=function(a){return f.event.special.hover?a:a.replace(F,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=L(c).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"",(g||!e)&&c.preventDefault();if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,n=null;for(m=e.parentNode;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l=0:t===b&&(t=o[s]=r.quick?K(m,r.quick):f(m).is(s)),t&&q.push(r);q.length&&j.push({elem:m,matches:q})}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),G.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),H.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y="abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",Z=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,_=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,ba=/<([\w:]+)/,bb=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bk=X(c);bj.optgroup=bj.option,bj.tbody=bj.tfoot=bj.colgroup=bj.caption=bj.thead,bj.th=bj.td,f.support.htmlSerialize||(bj._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after" +,arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Z,""):null;if(typeof a=="string"&&!bd.test(a)&&(f.support.leadingWhitespace||!$.test(a))&&!bj[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(_,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bn(a,d),e=bo(a),g=bo(d);for(h=0;e[h];++h)g[h]&&bn(e[h],g[h])}if(b){bm(a,d);if(c){e=bo(a),g=bo(d);for(h=0;e[h];++h)bm(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bc.test(k))k=b.createTextNode(k);else{k=k.replace(_,"<$1>");var l=(ba.exec(k)||["",""])[1].toLowerCase(),m=bj[l]||bj._default,n=m[0],o=b.createElement("div");b===c?bk.appendChild(o):X(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=bb.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&$.test(k)&&o.insertBefore(b.createTextNode($.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bt.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bs,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bs.test(g)?g.replace(bs,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bB(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bC=function(a,c){var d,e,g;c=c.replace(bu,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bD=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bv.test(f)&&bw.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bB=bC||bD,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bF=/%20/g,bG=/\[\]$/,bH=/\r?\n/g,bI=/#.*$/,bJ=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bK=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bL=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bM=/^(?:GET|HEAD)$/,bN=/^\/\//,bO=/\?/,bP=/)<[^<]*)*<\/script>/gi,bQ=/^(?:select|textarea)/i,bR=/\s+/,bS=/([?&])_=[^&]*/,bT=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bU=f.fn.load,bV={},bW={},bX,bY,bZ=["*/"]+["*"];try{bX=e.href}catch(b$){bX=c.createElement("a"),bX.href="",bX=bX.href}bY=bT.exec(bX.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bU)return bU.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bP,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bQ.test(this.nodeName)||bK.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bH,"\r\n")}}):{name:b.name,value:c.replace(bH,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?cb(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),cb(a,b);return a},ajaxSettings:{url:bX,isLocal:bL.test(bY[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bZ},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:b_(bV),ajaxTransport:b_(bW),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cd(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=ce(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bJ.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bI,"").replace(bN,bY[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bR),d.crossDomain==null&&(r=bT.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bY[1]&&r[2]==bY[2]&&(r[3]||(r[1]==="http:"?80:443))==(bY[3]||(bY[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),ca(bV,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bM.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bO.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bS,"$1_="+x);d.url=y+(y===d.url?(bO.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bZ+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=ca(bW,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)cc(g,a[g],c,e);return d.join("&").replace(bF,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cf=f.now(),cg=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cf++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cg.test(b.url)||e&&cg.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cg,l),b.url===j&&(e&&(k=k.replace(cg,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ch=a.ActiveXObject?function(){for(var a in cj)cj[a](0,1)}:!1,ci=0,cj;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ck()||cl()}:ck,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ch&&delete cj[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++ci,ch&&(cj||(cj={},f(a).unload(ch)),cj[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cm={},cn,co,cp=/^(?:toggle|show|hide)$/,cq=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cr,cs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],ct;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cw("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cz.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cz.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cA(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cA(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/api/resources/javascripts/plugins.js b/api/resources/javascripts/plugins.js new file mode 100644 index 00000000..efda459c --- /dev/null +++ b/api/resources/javascripts/plugins.js @@ -0,0 +1,13 @@ +window.log=function(){log.history=log.history||[];log.history.push(arguments);if(this.console){arguments.callee=arguments.callee.caller;var a=[].slice.call(arguments);(typeof console.log==="object"?log.apply.call(console.log,console,a):console.log.apply(console,a))}}; +(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try +{console.log();return window.console;}catch(err){return window.console={};}})()); + +/* + * jQuery throttle / debounce - v1.1 - 3/7/2010 + * http://benalman.com/projects/jquery-throttle-debounce-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this); diff --git a/api/resources/javascripts/prettify-extension.js b/api/resources/javascripts/prettify-extension.js new file mode 100644 index 00000000..ca8458dc --- /dev/null +++ b/api/resources/javascripts/prettify-extension.js @@ -0,0 +1,24 @@ +// Stolen from StackOverflow. Find all
 
+// elements on the page and add the "prettyprint" style. If at least one 
+// prettyprint element was found, call the Google Prettify prettyPrint() API.
+//http://sstatic.net/so/js/master.js?v=6523
+function styleCode() 
+{
+    if (typeof disableStyleCode != "undefined") 
+    {
+        return;
+    }
+
+    var a = false;
+
+    $("pre code").parent().each(function() 
+    {
+        if (!$(this).hasClass("prettyprint")) 
+        {
+            $(this).addClass("prettyprint");
+            a = true
+        }
+    });
+    
+    if (a) { prettyPrint() } 
+}
\ No newline at end of file
diff --git a/api/resources/javascripts/prettify.js b/api/resources/javascripts/prettify.js
new file mode 100644
index 00000000..eef5ad7e
--- /dev/null
+++ b/api/resources/javascripts/prettify.js
@@ -0,0 +1,28 @@
+var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
+(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
+[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
+l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
+q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
+q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
+"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
+a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
+for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
+"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
+H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
+J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
+I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
+["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
+/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
+["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
+hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b=
+!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p= 0) $('li#node_js_ref').addClass("active");
+    else if (pathName.indexOf("nodejs_dev_guide") >= 0) $('li#nodejs_dev_guide').addClass("active");
+    else if (pathName.indexOf("js_doc") >= 0) $('li#js_doc').addClass("active");
+
+    function loadCallback(evt) {
+        var form = document.getElementById("searchbox");
+        var input = form.query;
+        form.onsubmit = function (evt) {
+            var query = input.value;
+            if (query) {
+                input.value = "";
+                input.blur();
+                var currentVersion = $('#currentVersion').text();
+                var url = "https://www.google.com/search?q=" + encodeURIComponent("site:ace.ajax.org/api" + " " + query);
+                window.open(url);
+            }
+            return false;
+        };
+    }
+
+    var fileNameRE = new RegExp("^" + fileName, "i");
+
+    $('a.menuLink').each(function (index) {
+        if ($(this).attr("href").match(fileNameRE)) {
+            $(this).addClass("currentItem");
+            return false;
+        }
+    });
+
+    // init search
+    $('#search')
+    // prevent from form submit
+    .on('submit', function () {
+        return false;
+    }).find('input');
+
+    // init prettyprint
+    $('pre > code').addClass('prettyprint');
+    prettyPrint();
+    
+});
+
+$(document).ready(function () {
+    var d = 'a.menu, .dropdown-toggle'
+
+    function clearMenus() {
+        $(d).parent('li').each(function () {
+            $(this).removeClass('open')
+        });
+    }
+
+    var s, sx;
+
+    // scrolling offset calculation via www.quirksmode.org
+    if (window.pageYOffset || window.pageXOffset) {
+        s = window.pageYOffset;
+        sx = window.pageXOffset;
+    }
+    else if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)) {
+        s = document.documentElement.scrollTop;
+        sx = document.documentElement.scrollLeft;
+    }
+    else if (document.body) {
+        s = document.body.scrollTop;
+        sx = document.body.scrollLeft;
+    }
+
+    if (document.documentElement.offsetWidth < 1010) {
+        if (sx <= 0) sx = 0;
+        else if (sx + document.documentElement.offsetWidth > 1010) sx = 1010 - document.documentElement.offsetWidth;
+    }
+    else sx = 0;
+
+    $('.members').each(function (i) {
+        var position = $(this).position();
+        var $classContent = $(this).closest('.classContent');
+        
+        $(this).scrollspy({
+            min: $classContent.position().top - 35,
+            max: $classContent.position().top + $classContent.height(),
+            onEnter: function (element, position) {
+                var $pagination = $(element);
+                var $paginationContent = $('.membersContent pos' + i);
+                var $tabs = $('.tabs pos' + i);
+
+                $paginationContent.css('left', -1 * sx);
+                $paginationContent.css('top', 0);
+
+                $pagination.addClass('shadow').stop().css({
+                    height: 31,
+                    'top': 33
+                }).closest('.classContent').addClass('srolled');
+
+                $tabs.addClass('tabsSansBorder');
+            },
+            onLeave: function (element, position) {
+                var $pagination = $(element);
+                var $paginationContent = $('.membersContent pos' + i);
+                var $tabs = $('.tabs pos' + i);
+
+                $paginationContent.stop().css({
+                    top: 11
+                }); 
+                $pagination.css({
+                    'position': 'absolute',
+                    'top': 193
+                });
+                $pagination.stop().removeClass('shadow').css({
+                    height: 42
+                });
+
+                $paginationContent.css('left', 0);
+               // setTimeout(function () {
+                    $paginationContent.css({
+                        'top': ''
+                    });
+                    $pagination.css({
+                        'position': '',
+                        'top': ''
+                    });
+                    $paginationContent.css('left', 0);
+                    $pagination.closest('.classContent').removeClass('srolled')
+                    $tabs.removeClass('tabsSansBorder');
+               // }, 300);
+            }
+        });
+    });
+    
+    $('span.methodClicker, article.article, h3.methodClicker').each(function () {
+        var a = $(this);
+        var constructorPos = a.attr("id").indexOf("new ");
+
+        var objName = a.attr("id");
+        if (constructorPos >= 0) {
+            objName = objName.substring(constructorPos + 4);
+            objName += ".new";
+        }
+
+        a.attr("id", objName);
+    });
+
+    $('.brand').parent('.dropdown').hover(
+
+    function () {
+        $(this).addClass('open');
+    }, function () {
+        clearMenus();
+    });
+
+    $('.versions').hover(
+
+    function () {
+        $(this).addClass('open');
+    }, function () {
+        clearMenus();
+    });
+
+    function showMethodContent() {
+        if (!location.hash) return;
+
+        var $clickerEl = $('span#' + location.hash.replace(/^#/, '').replace(/\./g, '\\.'));
+        if ($clickerEl.length > 0 && $clickerEl.hasClass('methodClicker')) {
+            var p = $clickerEl.parent();
+            p[0].force = true;
+            p.trigger('click');
+            p[0].force = false;
+        }
+    }
+
+    if (location.hash) {
+        showMethodContent();
+        var data = location.hash;
+        scrollTo(null, data.substr(1));
+    }
+
+    window.onhashchange = function () {
+        showMethodContent();
+    }
+});
+
+function scrollTo(el, data) {
+    if (!data) {
+        data = el.getAttribute("data-id");
+        location.hash = data;
+    }
+    var el = $("span#" + data.replace(/\./g, "\\."))[0];
+    if (!el) return;
+
+    var article = $(el).closest('.article')[0];
+
+    var top = article.offsetTop - 100;
+
+    if (document.body.scrollTop > top || document.body.scrollTop != top && document.body.scrollTop + (window.innerHeight || document.documentElement.offsetHeight) < top + article.offsetHeight) {
+        $('body').animate({
+            scrollTop: top
+        }, {
+            duration: 200,
+            easing: "swing"
+        });
+    }
+}
\ No newline at end of file
diff --git a/api/scrollbar.html b/api/scrollbar.html
new file mode 100644
index 00000000..8c503554
--- /dev/null
+++ b/api/scrollbar.html
@@ -0,0 +1,348 @@
+
+
+
+  
+
+  
+    
+    
+    Ace API - scrollbar
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+  
+    
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

ScrollBar[edit] +

+ +
+
+
+
+

A set of methods for setting and retrieving the editor's scrollbar.

+ +
+
+
+

Constructors

+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Creates a new ScrollBar. parent is the owner of the scroll bar. ...

+ +
+

Creates a new ScrollBar. parent is the owner of the scroll bar.

+ +
+

   

+
+

Arguments

parentDOMElementRequired. A DOM element
+ + + + + +

Events

+
+
+
+
+

Emitted when the scroll bar, well, scrolls. ...

+ +
+

Emitted when the scroll bar, well, scrolls.

+ +
+

   

+
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • ScrollBar.getWidth() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the width of the scroll bar. ...

+ +
+

Returns the width of the scroll bar.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • ScrollBar.setHeight(Number height)
    • +
    +
      +
    +
  • +
+
+
+

Sets the height of the scroll bar, in pixels. ...

+ +
+

Sets the height of the scroll bar, in pixels.

+ +
+

   

+
+

Arguments

heightNumberRequired. The new height
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • ScrollBar.setInnerHeight(Number height)
    • +
    +
      +
    +
  • +
+
+
+

Sets the inner height of the scroll bar, in pixels. ...

+ +
+

Sets the inner height of the scroll bar, in pixels.

+ +
+

   

+
+

Arguments

heightNumberRequired. The new inner height
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • ScrollBar.setScrollTop(Number scrollTop)
    • +
    +
      +
    +
  • +
+
+
+

Sets the scroll top of the scroll bar. ...

+ +
+

Sets the scroll top of the scroll bar.

+ +
+

   

+
+

Arguments

scrollTopNumberRequired. The new scroll top
+
+
+
+
+
+ + +
+ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/search.html b/api/search.html new file mode 100644 index 00000000..15c5e63b --- /dev/null +++ b/api/search.html @@ -0,0 +1,388 @@ + + + + + + + + + Ace API - search + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

Search[edit] +

+ +
+
+
+
+

A class designed to handle all sorts of text searches within a Document.

+ +
+
+
+

Constructors

+
+
+
+
+
    +
  • +
      +
    • new Search()
    • +
    +
      +
    +
  • +
+
+
+ + + +
    +
  • needle: ""
  • +
  • backwards: false
  • +
  • wrap: false
  • +
  • caseSensitive: false
  • +
  • wholeWord: false
  • +
  • scope: ALL
  • +
  • regExp: false
  • +
+ +
+
+
+
+
+

Methods

+
+
+
+
+ +
+
+

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.

+ +
+

   

+
+

Arguments

sessionEditSessionRequired. The session to search with
+
+
+
+
+
+
+
+
+
+ +
+
+

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.

+ +
+

   

+
+

Arguments

sessionEditSessionRequired. The session to search with
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Search.getOptions() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns an object containing all the search options.

+ +
+

Returns an object containing all the search options.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Searches for options.needle in input, and, if found, replaces it with replacement. ...

+ +
+

Searches for options.needle in input, and, if found, replaces it with replacement.

+ +
+

   

+
+

Arguments

inputStringRequired. The text to search in
replacementStringRequired. The replacing text
+

Returns

StringIf 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.
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Sets the search options via the options parameter. ...

+ +
+

Sets the search options via the options parameter.

+ +
+

   

+
+

Arguments

optionsObjectRequired. An object containing all the new search properties
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/selection.html b/api/selection.html new file mode 100644 index 00000000..1573a0df --- /dev/null +++ b/api/selection.html @@ -0,0 +1,1692 @@ + + + + + + + + + Ace API - selection + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+

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.

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Creates a new Selection object. ...

+ +
+

Creates a new Selection object.

+ +
+

   

+
+

Arguments

sessionEditSessionRequired. The session to use
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • Selection.addRange(Range range, Boolean $blockChangeEvents)
    • +
    +
      +
    +
  • +
+
+
+

Adds a range to a selection by entering multiselect mode, if necessary. ...

+ +
+

Adds a range to a selection by entering multiselect mode, if necessary.

+ +
+

   

+
+

Arguments

rangeRangeRequired. The new range to add
$blockChangeEventsBooleanRequired. Whether or not to block changing events
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.clearSelection()
    • +
    +
      +
    +
  • +
+
+
+

[Empties the selection (by de-selecting it). This function also emits the 'changeSelection' event.]{: #Selection.c...

+ +
+

Empties the selection (by de-selecting it). This function also emits the 'changeSelection' event.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.getCursor() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Gets the current position of the cursor. ...

+ +
+

Gets the current position of the cursor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.getRange() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the Range for the selected text.

+ +
+

Returns the Range for the selected text.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns an object containing the row and column of the calling selection anchor. ...

+ +
+

Returns an object containing the row and column of the calling selection anchor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.getSelectionLead() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns an object containing the row and column of the calling selection lead. ...

+ +
+

Returns an object containing the row and column of the calling selection lead.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.isBackwards() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the selection is going backwards in the document. ...

+ +
+

Returns true if the selection is going backwards in the document.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.isEmpty() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the selection is empty. ...

+ +
+

Returns true if the selection is empty.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.isMultiLine() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the selection is a multi-line. ...

+ +
+

Returns true if the selection is a multi-line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.mergeOverlappingRanges()
    • +
    +
      +
    +
  • +
+
+
+

Merges overlapping ranges ensuring consistency after changes ...

+ +
+

Merges overlapping ranges ensuring consistency after changes

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Moves the cursor to position indicated by the parameters. Negative numbers move the cursor backwards in the document. ...

+ +
+

Moves the cursor to position indicated by the parameters. Negative numbers move the cursor backwards in the document.

+ +
+

   

+
+

Arguments

rowsNumberRequired. The number of rows to move by
charsNumberRequired. The number of characters to move by
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorDown()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor down one row. ...

+ +
+

Moves the cursor down one row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorFileEnd()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the end of the file. ...

+ +
+

Moves the cursor to the end of the file.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorFileStart()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the start of the file. ...

+ +
+

Moves the cursor to the start of the file.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorLeft()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor left one column. ...

+ +
+

Moves the cursor left one column.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorLineEnd()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the end of the line. ...

+ +
+

Moves the cursor to the end of the line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorLineStart()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the start of the line. ...

+ +
+

Moves the cursor to the start of the line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorRight()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor right one column. ...

+ +
+

Moves the cursor right one column.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Moves the cursor to the row and column provided. [If preventUpdateDesiredColumn is true, then the cursor stays i...

+ +
+

If preventUpdateDesiredColumn is true, then the cursor stays in the same column position as its original point.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to move to
columnNumberRequired. The column to move to
keepDesiredColumnBooleanRequired. If true, the cursor move does not respect the previous column
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorToPosition(Object position)
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection to the position indicated by its row and column. ...

+ +
+

Moves the selection to the position indicated by its row and column.

+ +
+

   

+
+

Arguments

positionObjectRequired. The position to move to
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to move to
columnNumberRequired. The column to move to
keepDesiredColumnBooleanRequired. If true, the cursor move does not respect the previous column
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorUp()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor up one row. ...

+ +
+

Moves the cursor up one row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorWordLeft()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the word on the left. ...

+ +
+

Moves the cursor to the word on the left.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.moveCursorWordRight()
    • +
    +
      +
    +
  • +
+
+
+

Moves the cursor to the word on the right. ...

+ +
+

Moves the cursor to the word on the right.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.rectangularRangeBlock(Cursor screenCursor, Anchor screenAnchor, Boolean includeEmptyLines) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Gets list of ranges composing rectangular block on the screen + ...

+ +
+

Gets list of ranges composing rectangular block on the screen +

+ +
+

   

+

/ + this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) { + var rectSel = []; + +

+
   var xBackwards = screenCursor.column < screenAnchor.column;
+   if (xBackwards) {
+       var startColumn = screenCursor.column;
+       var endColumn = screenAnchor.column;
+   } else {
+       var startColumn = screenAnchor.column;
+       var endColumn = screenCursor.column;
+   }
+
+   var yBackwards = screenCursor.row < screenAnchor.row;
+   if (yBackwards) {
+       var startRow = screenCursor.row;
+       var endRow = screenAnchor.row;
+   } else {
+       var startRow = screenAnchor.row;
+       var endRow = screenCursor.row;
+   }
+
+   if (startColumn < 0)
+       startColumn = 0;
+   if (startRow < 0)
+       startRow = 0;
+
+   if (startRow == endRow)
+       includeEmptyLines = true;
+
+   for (var row = startRow; row <= endRow; row++) {
+       var range = Range.fromPoints(
+           this.session.screenToDocumentPosition(row, startColumn),
+           this.session.screenToDocumentPosition(row, endColumn)
+       );
+       if (range.isEmpty()) {
+           if (docEnd && isSamePoint(range.end, docEnd))
+               break;
+           var docEnd = range.end;
+       }
+       range.cursor = xBackwards ? range.start : range.end;
+       rectSel.push(range);
+   }
+
+   if (yBackwards)
+       rectSel.reverse();
+
+   if (!includeEmptyLines) {
+       var end = rectSel.length - 1;
+       while (rectSel[end].isEmpty() && end > 0)
+           end--;
+       if (end > 0) {
+           var start = 0;
+           while (rectSel[start].isEmpty())
+               start++;
+       }
+       for (var i = end; i >= start; i--) {
+           if (rectSel[i].isEmpty())
+               rectSel.splice(i, 1);
+       }
+   }
+
+   return rectSel;
+

}; +}).call(Selection.prototype); + +

+

// extend Editor +var Editor = require("./editor").Editor; +(function() { + +

+

/** extension +Editor.updateSelectionMarkers() + +

+

Updates the cursor and marker layers.

+ +

Arguments

screenCursorCursorRequired. The cursor to use
screenAnchorAnchorRequired. The anchor to use
includeEmptyLinsBooleanRequired. If true, this includes ranges inside the block which are empty due to clipping
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.substractPoint(Range pos) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Removes a Range containing pos (if it exists). ...

+ +
+

Removes a Range containing pos (if it exists).

+ +
+

   

+
+

Arguments

posRangeRequired. The position to remove, as a {row, column} object
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectAll()
    • +
    +
      +
    +
  • +
+
+
+

Selects all the text in the document. ...

+ +
+

Selects all the text in the document.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Selects a word, including its right whitespace. ...

+ +
+

Selects a word, including its right whitespace.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectDown()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection down one row. ...

+ +
+

Moves the selection down one row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectFileEnd()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection to the end of the file. ...

+ +
+

Moves the selection to the end of the file.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectFileStart()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection to the start of the file. ...

+ +
+

Moves the selection to the start of the file.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectLeft()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection left one column. ...

+ +
+

Moves the selection left one column.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectLine()
    • +
    +
      +
    +
  • +
+
+
+

Selects the entire line. ...

+ +
+

Selects the entire line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectLineEnd()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection to the end of the current line. ...

+ +
+

Moves the selection to the end of the current line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectLineStart()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection to the beginning of the current line. ...

+ +
+

Moves the selection to the beginning of the current line.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectRight()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection right one column. ...

+ +
+

Moves the selection right one column.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Moves the selection cursor to the indicated row and column. ...

+ +
+

Moves the selection cursor to the indicated row and column.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row to select to
columnNumberRequired. The column to select to
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectToPosition(Object pos)
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection cursor to the row and column indicated by pos. ...

+ +
+

Moves the selection cursor to the row and column indicated by pos.

+ +
+

   

+
+

Arguments

posObjectRequired. An object containing the row and column
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectUp()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection up one row. ...

+ +
+

Moves the selection up one row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Moves the selection to highlight the entire word. ...

+ +
+

Moves the selection to highlight the entire word.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectWordLeft()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection to the first word on the left. ...

+ +
+

Moves the selection to the first word on the left.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.selectWordRight()
    • +
    +
      +
    +
  • +
+
+
+

Moves the selection to the first word on the right. ...

+ +
+

Moves the selection to the first word on the right.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.setSelectionAnchor(Number row, Number column)
    • +
    +
      +
    +
  • +
+
+
+

Sets the row and column position of the anchor. This function also emits the 'changeSelection' event. ...

+ +
+

Sets the row and column position of the anchor. This function also emits the 'changeSelection' event.

+ +
+

   

+
+

Arguments

rowNumberRequired. The new row
columnNumberRequired. The new column
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.setSelectionRange(Range range, Boolean reverse)
    • +
    +
      +
    +
  • +
+
+
+

Sets the selection to the provided range. ...

+ +
+

Sets the selection to the provided range.

+ +
+

   

+
+

Arguments

rangeRangeRequired. The range of text to select
reverseBooleanRequired. Indicates if the range should go backwards (true) or not
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • Selection.shiftSelection(Number columns)
    • +
    +
      +
    +
  • +
+
+
+

Shifts the selection up (or down, if isBackwards is true) the given number of columns. ...

+ +
+

Shifts the selection up (or down, if isBackwards is true) the given number of columns.

+ +
+

   

+
+

Arguments

columnsNumberRequired. The number of columns to shift by
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/split.html b/api/split.html new file mode 100644 index 00000000..9af27f5e --- /dev/null +++ b/api/split.html @@ -0,0 +1,718 @@ + + + + + + + + + Ace API - split + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

Split.blur[edit] +

+ +
+
+
+
+
+
+
    +
  • +
      +
    • Split.blur() +
    • +
        +
      • Void
      • +
      +
    • +
    + +
  • +
+
+
+

Blurs the current editor. ...

+ +
+

Blurs the current editor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
+

Split.focus[edit] +

+ +
+
+
+
+
+
+
    +
  • +
      +
    • Split.focus() +
    • +
        +
      • Void
      • +
      +
    • +
    + +
  • +
+
+
+

Focuses the current editor. ...

+ +
+

Focuses the current editor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
+

Split.getCurrentEditor[edit] +

+ +
+
+
+
+
+
+
    +
  • +
      +
    • Split.getCurrentEditor() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current editor. ...

+ +
+

Returns the current editor.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
+

Split.getEditor[edit] +

+ +
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns the editor identified by the index idx. ...

+ +
+

Returns the editor identified by the index idx.

+ +
+

   

+
+

Arguments

idxNumberRequired. The index of the editor you want
+
+
+
+
+
+
+
+
+
+
+

Split.getSplits[edit] +

+ +
+
+
+
+
+
+
    +
  • +
      +
    • Split.getSplits() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the number of splits. ...

+ +
+

Returns the number of splits.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
+

Split.resize[edit] +

+ +
+
+
+
+
+
+
    +
  • +
      +
    • Split.resize() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    • Internal
    • +
    +
  • +
+
+
+

...

+ +
+
+
+

   

+
+
+
+
+
+
+
+
+
+
+
+

Split.setFontSize[edit] +

+ +
+
+
+
+
+
+ +
+
+

Sets the font size, in pixels, for all the available editors. ...

+ +
+

Sets the font size, in pixels, for all the available editors.

+ +
+

   

+
+

Arguments

sizeNumberRequired. The new font size
+
+
+
+
+
+
+
+
+
+
+

Split.setSession[edit] +

+ +
+
+
+
+
+
+ +
+
+

Sets a new EditSession for the indicated editor. ...

+ +
+

Sets a new EditSession for the indicated editor.

+ +
+

   

+
+

Arguments

sessionEditSessionRequired. The new edit session
idxNumberRequired. The editor's index you're interested in
+
+
+
+
+
+
+
+
+
+
+

Split.setTheme[edit] +

+ +
+
+
+
+
+
+ +
+
+

Sets a theme for each of the available editors. ...

+ +
+

Sets a theme for each of the available editors.

+ +
+

   

+
+

Arguments

themeStringRequired. The name of the theme to set
+
+
+
+
+
+
+
+
+
+
+

Split.UndoManagerProxy[edit] +

+ +
+
+
+
+
+
+
    +
  • +
      +
    • Split.UndoManagerProxy() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    • Internal
    • +
    +
  • +
+
+
+

...

+ +
+
+
+

   

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/token_iterator.html b/api/token_iterator.html new file mode 100644 index 00000000..a3770534 --- /dev/null +++ b/api/token_iterator.html @@ -0,0 +1,374 @@ + + + + + + + + + Ace API - token_iterator + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

TokenIterator[edit] +

+ +
+
+
+
+

This class provides an essay way to treat the document as a stream of tokens, and provides methods to iterate over these tokens.

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Creates a new token iterator object. The inital token index is set to the provided row and column coordinates. ...

+ +
+

Creates a new token iterator object. The inital token index is set to the provided row and column coordinates.

+ +
+

   

+
+

Arguments

sessionEditSessionRequired. The session to associate with
initialRowNumberRequired. The row to start the tokenizing at
initialColumnNumberRequired. The column to start the tokenizing at
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • TokenIterator.getCurrentToken() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current tokenized string. ...

+ +
+

Returns the current tokenized string.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • TokenIterator.getCurrentTokenColumn() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current column. ...

+ +
+

Returns the current column.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • TokenIterator.getCurrentTokenRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the current row. ...

+ +
+

Returns the current row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • TokenIterator.stepBackward() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Tokenizes all the items from the current point to the row prior in the document. ...

+ +
+

Tokenizes all the items from the current point to the row prior in the document.

+ +
+

   

+
+

Returns

StringIf the current point is not at the top of the file, this function returns null. Otherwise, it returns an array of the tokenized strings.
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • TokenIterator.stepForward() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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 + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

Tokenizer[edit] +

+ +
+
+ +

Constructors

+
+
+
+
+ +
+
+

Constructs a new tokenizer based on the given rules and flags. ...

+ +
+

Constructs a new tokenizer based on the given rules and flags.

+ +
+

   

+
+

Arguments

rulesObjectRequired. The highlighting rules
flagStringRequired. Any additional regular expression flags to pass (like "i" for case insensitive)
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • Tokenizer.getLineTokens() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns an object containing two properties: tokens, which contains all the tokens; and state, the current state. ...

+ +
+

Returns an object containing two properties: tokens, which contains all the tokens; and state, the current state.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/undefined.html b/api/undefined.html new file mode 100644 index 00000000..09ccafe0 --- /dev/null +++ b/api/undefined.html @@ -0,0 +1,129 @@ + + + + + + + + + Ace API - + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/undomanager.html b/api/undomanager.html new file mode 100644 index 00000000..e3e8053c --- /dev/null +++ b/api/undomanager.html @@ -0,0 +1,412 @@ + + + + + + + + + Ace API - undomanager + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+

UndoManager[edit] +

+ +
+
+
+
+

This object maintains the undo stack for an EditSession.

+ +
+
+
+

Constructors

+
+
+
+
+
    +
  • +
      +
    • new UndoManager()
    • +
    +
      +
    +
  • +
+
+
+

Resets the current undo state and creates a new UndoManager. ...

+ +
+

Resets the current undo state and creates a new UndoManager.

+ +
+

   

+
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • UndoManager.execute(Object options) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

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

+ +
+

   

+
+

Arguments

optionsObjectRequired. Contains additional properties
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • UndoManager.hasRedo() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if there are redo operations left to perform. ...

+ +
+

Returns true if there are redo operations left to perform.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • UndoManager.hasUndo() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if there are undo operations left to perform. ...

+ +
+

Returns true if there are undo operations left to perform.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • UndoManager.redo(Boolean dontSelect) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Perform a redo operation on the document, reimplementing the last change.

+ +
+

Perform a redo operation on the document, reimplementing the last change.

+ +
+

   

+
+

Arguments

dontSelectBooleanRequired. If true, doesn't select the range of where the change occured
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • UndoManager.reset() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Destroys the stack of undo and redo redo operations. ...

+ +
+

Destroys the stack of undo and redo redo operations.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

[Perform an undo operation on the document, reverting the last change. Returns the range of the undo.]{: #UndoManage...

+ +
+

Perform an undo operation on the document, reverting the last change. Returns the range of the undo.

+ +
+

   

+
+

Arguments

dontSelectBooleanRequired. If true, doesn't select the range of where the change occured
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + \ No newline at end of file diff --git a/api/virtual_renderer.html b/api/virtual_renderer.html new file mode 100644 index 00000000..7067c9d1 --- /dev/null +++ b/api/virtual_renderer.html @@ -0,0 +1,2241 @@ + + + + + + + + + Ace API - virtual_renderer + + + + + + + + + + + + + + + + + +
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+

The class that is responsible for drawing everything you see on the screen!

+ +
+
+
+

Constructors

+
+
+
+
+ +
+
+

Constructs a new VirtualRenderer within the container specified, applying the given theme. ...

+ +
+

Constructs a new VirtualRenderer within the container specified, applying the given theme.

+ +
+

   

+
+

Arguments

containerDOMElementRequired. The root element of the editor
themeStringRequired. The starting theme
+
+
+
+
+
+

Methods

+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.addGutterDecoration(Number row, String className) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Adds className to the row, to be used for CSS stylings and whatnot. ...

+ +
+

Adds className to the row, to be used for CSS stylings and whatnot.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row number
classNameStringRequired. The class to add
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • 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. ...

+ +
+

Adjusts the wrap limit, which is the number of characters that can fit within the width of the edit area on screen.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.destroy()
    • +
    +
      +
    +
  • +
+
+
+

Destroys the text and cursor layers for this renderer. ...

+ +
+

Destroys the text and cursor layers for this renderer.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getAnimatedScroll() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns whether an animated scroll happens or not. ...

+ +
+

Returns whether an animated scroll happens or not.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getContainerElement() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the root element containing this renderer. ...

+ +
+

Returns the root element containing this renderer.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getFirstFullyVisibleRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getFirstVisibleRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the index of the first visible row.

+ +
+

Returns the index of the first visible row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getHScrollBarAlwaysVisible() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns whether the horizontal scrollbar is set to be always visible. ...

+ +
+

Returns whether the horizontal scrollbar is set to be always visible.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getLastFullyVisibleRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

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.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getLastVisibleRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the index of the last visible row.

+ +
+

Returns the index of the last visible row.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getMouseEventTarget() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the element that the mouse events are attached to ...

+ +
+

Returns the element that the mouse events are attached to

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getPrintMarginColumn() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns whether the print margin column is being shown or not. ...

+ +
+

Returns whether the print margin column is being shown or not.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getScrollBottomRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the last visible row, regardless of whether it's fully visible or not. ...

+ +
+

Returns the last visible row, regardless of whether it's fully visible or not.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the value of the distance between the left of the editor and the leftmost part of the visible content. ...

+ +
+

Returns the value of the distance between the left of the editor and the leftmost part of the visible content.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+ +
+
+

Returns the value of the distance between the top of the editor and the topmost part of the visible content. ...

+ +
+

Returns the value of the distance between the top of the editor and the topmost part of the visible content.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getScrollTopRow() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the first visible row, regardless of whether it's fully visible or not. ...

+ +
+

Returns the first visible row, regardless of whether it's fully visible or not.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getShowGutter() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns true if the gutter is being shown. ...

+ +
+

Returns true if the gutter is being shown.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getShowInvisibles() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns whether invisible characters are being shown or not. ...

+ +
+

Returns whether invisible characters are being shown or not.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getShowPrintMargin() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns whetherthe print margin is being shown or not. ...

+ +
+

Returns whetherthe print margin is being shown or not.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getTextAreaContainer() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the element to which the hidden text area is added. ...

+ +
+

Returns the element to which the hidden text area is added.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.getTheme() +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Returns the path of the current theme.

+ +
+

Returns the path of the current theme.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.hideComposition() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Hides the current composition. ...

+ +
+

Hides the current composition.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.hideCursor() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Hides the cursor icon. ...

+ +
+

Hides the cursor icon.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns true if you can still scroll by either parameter; in other words, you haven't reached the end of the file ...

+ +
+

Returns true if you can still scroll by either parameter; in other words, you haven't reached the end of the file or line.

+ +
+

   

+
+

Arguments

deltaXNumberRequired. The x value to scroll by
deltaYNumberRequired. The y value to scroll by
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.moveTextAreaToCursor(DOMElement textarea) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Changes the position of textarea to where the cursor is pointing. ...

+ +
+

Changes the position of textarea to where the cursor is pointing.

+ +
+

   

+
+

Arguments

textareaDOMElementRequired. A text area to work with
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.onResize(Boolean force) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Triggers a resize of the editor.

+ +
+

Triggers a resize of the editor.

+ +
+

   

+
+

Arguments

forceBooleanRequired. If true, recomputes the size, even if the height and width haven't changed
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.removeGutterDecoration(Number row, String className) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Removes className from the row. ...

+ +
+

Removes className from the row.

+ +
+

   

+
+

Arguments

rowNumberRequired. The row number
classNameStringRequired. The class to add
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollBy(Number deltaX, Number deltaY) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the editor across both x- and y-axes. ...

+ +
+

Scrolls the editor across both x- and y-axes.

+ +
+

   

+
+

Arguments

deltaXNumberRequired. The x value to scroll by
deltaYNumberRequired. The y value to scroll by
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollCursorIntoView() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the cursor into the first visibile area of the editor ...

+ +
+

Scrolls the cursor into the first visibile area of the editor

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollToLine(Number line, Boolean center) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Gracefully scrolls the editor to the row indicated. ...

+ +
+

Gracefully scrolls the editor to the row indicated.

+ +
+

   

+
+

Arguments

lineNumberRequired. A line number
centerBooleanRequired. If true, centers the editor the to indicated line
+
+
+
+
+
+
+
+
+
+ +
+
+

Gracefully scrolls the top of the editor to the row indicated. ...

+ +
+

Gracefully scrolls the top of the editor to the row indicated.

+ +
+

   

+
+

Arguments

rowNumberRequired. A row id
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollToX(Number scrollLeft) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the editor to the x pixel indicated. ...

+ +
+

Scrolls the editor to the x pixel indicated.

+ +
+

   

+
+

Arguments

scrollLeftNumberRequired. The position to scroll to
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.scrollToY(Number scrollTop) +
    • + +
    • +
    +
      +
    +
  • +
+
+
+

Scrolls the editor to the y pixel indicated. ...

+ +
+

Scrolls the editor to the y pixel indicated.

+ +
+

   

+
+

Arguments

scrollTopNumberRequired. The position to scroll to
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setAnimatedScroll(Boolean shouldAnimate) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to have an animated scroll or not. ...

+ +
+

Identifies whether you want to have an animated scroll or not.

+ +
+

   

+
+

Arguments

shouldAnimateBooleanRequired. Set to true to show animated scrolls
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setAnnotations(Array annotations) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Sets annotations for the gutter. ...

+ +
+

Sets annotations for the gutter.

+ +
+

   

+
+

Arguments

annotationsArrayRequired. An array containing annotations
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setBreakpoints(Array rows) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Sets a breakpoint for every row number indicated on rows. ...

+ +
+

Sets a breakpoint for every row number indicated on rows.

+ +
+

   

+
+

Arguments

rowsArrayRequired. An array containg row numbers
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setCompositionText(String text) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Sets the inner text of the current composition to text. ...

+ +
+

Sets the inner text of the current composition to text.

+ +
+

   

+
+

Arguments

textStringRequired. A string of text to use
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setHScrollBarAlwaysVisible(Boolean alwaysVisible) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to show the horizontal scrollbar or not. ...

+ +
+

Identifies whether you want to show the horizontal scrollbar or not.

+ +
+

   

+
+

Arguments

alwaysVisibleBooleanRequired. Set to true to make the horizontal scroll bar visible
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setPadding(Number padding) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Sets the padding for all the layers. ...

+ +
+

Sets the padding for all the layers.

+ +
+

   

+
+

Arguments

paddingNumberRequired. A new padding value (in pixels)
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setPrintMarginColumn(Boolean showPrintMargin)
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to show the print margin column or not. ...

+ +
+

Identifies whether you want to show the print margin column or not.

+ +
+

   

+
+

Arguments

showPrintMarginBooleanRequired. Set to true to show the print margin column
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setSession(session) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Associates an EditSession. ...

+ +
+

Associates an EditSession.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setShowGutter(Boolean show) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to show the gutter or not. ...

+ +
+

Identifies whether you want to show the gutter or not.

+ +
+

   

+
+

Arguments

showBooleanRequired. Set to true to show the gutter
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setShowInvisibles(Boolean showInvisibles) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to show invisible characters or not. ...

+ +
+

Identifies whether you want to show invisible characters or not.

+ +
+

   

+
+

Arguments

showInvisiblesBooleanRequired. Set to true to show invisibles
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setShowPrintMargin(Boolean showPrintMargin)
    • +
    +
      +
    +
  • +
+
+
+

Identifies whether you want to show the print margin or not. ...

+ +
+

Identifies whether you want to show the print margin or not.

+ +
+

   

+
+

Arguments

showPrintMarginBooleanRequired. Set to true to show the print margin
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setStyle(String style) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Adds a new class, style, to the editor.

+ +
+

Adds a new class, style, to the editor.

+ +
+

   

+
+

Arguments

styleStringRequired. A class name
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.setTheme(String theme) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

[Sets a new theme for the editor. theme should exist, and be a directory path, like ace/theme/textmate.]{: #Virt...

+ +
+

Sets a new theme for the editor. theme should exist, and be a directory path, like ace/theme/textmate.

+ +
+

   

+
+

Arguments

themeStringRequired. The path to a theme
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.showCursor() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Shows the cursor icon. ...

+ +
+

Shows the cursor icon.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • + +
      +
    +
  • +
+
+
+

Returns an object containing the pageX and pageY coordinates of the document position. ...

+ +
+

Returns an object containing the pageX and pageY coordinates of the document position.

+ +
+

   

+
+

Arguments

rowNumberRequired. The document row position
columnNumberRequired. The document column position
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.unsetStyle(String style) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Removes the class style from the editor.

+ +
+

Removes the class style from the editor.

+ +
+

   

+
+

Arguments

styleStringRequired. A class name
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateBackMarkers() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Schedules an update to all the back markers in the document. ...

+ +
+

Schedules an update to all the back markers in the document.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateCursor() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Updates the cursor icon. ...

+ +
+

Updates the cursor icon.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateFontSize() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Updates the font size. ...

+ +
+

Updates the font size.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateFrontMarkers() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Schedules an update to all the front markers in the document. ...

+ +
+

Schedules an update to all the front markers in the document.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateFull() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Triggers a full update of all the layers, for all the rows. ...

+ +
+

Triggers a full update of all the layers, for all the rows.

+ +
+

   

+
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateLines(Number firstRow, Number lastRow) +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

Triggers a partial update of the text, from the range given by the two parameters. ...

+ +
+

Triggers a partial update of the text, from the range given by the two parameters.

+ +
+

   

+
+

Arguments

firstRowNumberRequired. The first row to update
lastRowNumberRequired. The last row to update
+
+
+
+
+
+
+
+
+
+
    +
  • +
      +
    • VirtualRenderer.updateText() +
    • +
        +
      • Void
      • +
      +
    • +
    +
      +
    +
  • +
+
+
+

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("
",e+1);if(i){var k=i[e];k==null&&(k=i[e]=this.session.getFoldWidget(e)),k&&c.push("")}var l=this.session.getRowLength(e)-1;while(l--)c.push("
¦");c.push("
"),e++}this.element=d.setInnerHtml(this.element,c.join("")),this.element.style.height=a.minHeight+"px";var m=this.element.offsetWidth;m!==this.gutterWidth&&(this.gutterWidth=m,this._emit("changeGutterWidth",m))},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(a){a?d.addCssClass(this.element,"ace_folding-enabled"):d.removeCssClass(this.element,"ace_folding-enabled"),this.$showFoldWidgets=a},this.getShowFoldWidgets=function(){return this.$showFoldWidgets}}).call(g.prototype),b.Gutter=g}),ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(a,b,c){"use strict";var d=a("../range").Range,e=a("../lib/dom"),f=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_marker-layer",a.appendChild(this.element)};(function(){this.$padding=0,this.setPadding=function(a){this.$padding=a},this.setSession=function(a){this.session=a},this.setMarkers=function(a){this.markers=a},this.update=function(a){var a=a||this.config;if(!a)return;this.config=a;var b=[];for(var c in this.markers){var d=this.markers[c],f=d.range.clipRows(a.firstRow,a.lastRow);if(f.isEmpty())continue;f=f.toScreenRange(this.session);if(d.renderer){var g=this.$getTop(f.start.row,a),h=Math.round(this.$padding+f.start.column*a.characterWidth);d.renderer(b,f,h,g,a)}else f.isMultiLine()?d.type=="text"?this.drawTextMarker(b,f,d.clazz,a):this.drawMultiLineMarker(b,f,d.clazz,a,d.type):this.drawSingleLineMarker(b,f,d.clazz+" start",a,null,d.type)}this.element=e.setInnerHtml(this.element,b.join(""))},this.$getTop=function(a,b){return(a-b.firstRowScreen)*b.lineHeight},this.drawTextMarker=function(a,b,c,e){var f=b.start.row,g=new d(f,b.start.column,f,this.session.getScreenLastRowColumn(f));this.drawSingleLineMarker(a,g,c+" start",e,1,"text"),f=b.end.row,g=new d(f,0,f,b.end.column),this.drawSingleLineMarker(a,g,c,e,0,"text");for(f=b.start.row+1;f
"),j=this.$getTop(b.end.row,d),i=Math.round(b.end.column*d.characterWidth),a.push("
"),h=(b.end.row-b.start.row-1)*d.lineHeight;if(h<0)return;j=this.$getTop(b.start.row+1,d),a.push("
")},this.drawSingleLineMarker=function(a,b,c,d,e,f){var g=f==="background"?0:this.$padding,h=d.lineHeight;if(f==="background")var i=d.width;else i=Math.round((b.end.column+(e||0)-b.start.column)*d.characterWidth);var j=this.$getTop(b.start.row,d),k=Math.round(g+b.start.column*d.characterWidth);a.push("
")}}).call(f.prototype),b.Marker=f}),ace.define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("../lib/oop"),e=a("../lib/dom"),f=a("../lib/lang"),g=a("../lib/useragent"),h=a("../lib/event_emitter").EventEmitter,i=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_text-layer",a.appendChild(this.element),this.$characterSize=this.$measureSizes()||{width:0,height:0},this.$pollSizeChanges()};(function(){d.implement(this,h),this.EOF_CHAR="¶",this.EOL_CHAR="¬",this.TAB_CHAR="→",this.SPACE_CHAR="·",this.$padding=0,this.setPadding=function(a){this.$padding=a,this.element.style.padding="0 "+a+"px"},this.getLineHeight=function(){return this.$characterSize.height||1},this.getCharacterWidth=function(){return this.$characterSize.width||1},this.checkForSizeChanges=function(){var a=this.$measureSizes();a&&(this.$characterSize.width!==a.width||this.$characterSize.height!==a.height)&&(this.$characterSize=a,this._emit("changeCharacterSize",{data:a}))},this.$pollSizeChanges=function(){var a=this;this.$pollSizeChangesTimer=setInterval(function(){a.checkForSizeChanges()},500)},this.$fontStyles={fontFamily:1,fontSize:1,fontWeight:1,fontStyle:1,lineHeight:1},this.$measureSizes=g.isIE||g.isOldGecko?function(){var a=1e3;if(!this.$measureNode){var b=this.$measureNode=e.createElement("div"),c=b.style;c.width=c.height="auto",c.left=c.top=-a*40+"px",c.visibility="hidden",c.position="fixed",c.overflow="visible",c.whiteSpace="nowrap",b.innerHTML=f.stringRepeat("Xy",a);if(this.element.ownerDocument.body)this.element.ownerDocument.body.appendChild(b);else{var d=this.element.parentNode;while(!e.hasCssClass(d,"ace_editor"))d=d.parentNode;d.appendChild(b)}}if(!this.element.offsetWidth)return null;var c=this.$measureNode.style,g=e.computedStyle(this.element);for(var h in this.$fontStyles)c[h]=g[h];var i={height:this.$measureNode.offsetHeight,width:this.$measureNode.offsetWidth/(a*2)};return i.width==0||i.height==0?null:i}:function(){if(!this.$measureNode){var a=this.$measureNode=e.createElement("div"),b=a.style;b.width=b.height="auto",b.left=b.top="-100px",b.visibility="hidden",b.position="fixed",b.overflow="visible",b.whiteSpace="nowrap",a.innerHTML="X";var c=this.element.parentNode;while(c&&!e.hasCssClass(c,"ace_editor"))c=c.parentNode;if(!c)return this.$measureNode=null;c.appendChild(a)}var d=this.$measureNode.getBoundingClientRect(),f={height:d.height,width:d.width};return f.width==0||f.height==0?null:f},this.setSession=function(a){this.session=a},this.showInvisibles=!1,this.setShowInvisibles=function(a){return this.showInvisibles==a?!1:(this.showInvisibles=a,!0)},this.$tabStrings=[],this.$computeTabString=function(){var a=this.session.getTabSize(),b=this.$tabStrings=[0];for(var c=1;c"+this.TAB_CHAR+(new Array(c)).join(" ")+"
"):b.push((new Array(c+1)).join(" "))},this.updateLines=function(a,b,c){this.$computeTabString(),(this.config.lastRow!=a.lastRow||this.config.firstRow!=a.firstRow)&&this.scrollLines(a),this.config=a;var d=Math.max(b,a.firstRow),f=Math.min(c,a.lastRow),g=this.element.childNodes,h=0;for(var i=a.firstRow;i0;d--)c.removeChild(c.firstChild);if(b.lastRow>a.lastRow)for(var d=this.session.getFoldedRowCount(a.lastRow+1,b.lastRow);d>0;d--)c.removeChild(c.lastChild);if(a.firstRowb.lastRow){var e=this.$renderLinesFragment(a,b.lastRow+1,a.lastRow);c.appendChild(e)}},this.$renderLinesFragment=function(a,b,c){var d=this.element.ownerDocument.createDocumentFragment(),f=b,g=this.session.getNextFoldLine(f),h=g?g.start.row:Infinity;for(;;){f>h&&(f=g.end.row+1,g=this.session.getNextFoldLine(f,g),h=g?g.start.row:Infinity);if(f>c)break;var i=e.createElement("div"),j=[],k=this.session.getTokens(f,f);k.length==1&&this.$renderLine(j,f,k[0].tokens,!1),i.innerHTML=j.join("");if(this.$useLineGroups())i.className="ace_line_group",d.appendChild(i);else{var l=i.childNodes;while(l.length)d.appendChild(l[0])}f++}return d},this.update=function(a){this.$computeTabString(),this.config=a;var b=[],c=a.firstRow,d=a.lastRow,f=c,g=this.session.getNextFoldLine(f),h=g?g.start.row:Infinity;for(;;){f>h&&(f=g.end.row+1,g=this.session.getNextFoldLine(f,g),h=g?g.start.row:Infinity);if(f>d)break;this.$useLineGroups()&&b.push("
");var i=this.session.getTokens(f,f);i.length==1&&this.$renderLine(b,f,i[0].tokens,!1),this.$useLineGroups()&&b.push("
"),f++}this.element=e.setInnerHtml(this.element,b.join(""))},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(a,b,c,d){var e=this,f=/\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,h=function(a,c,d,f,h){if(a.charCodeAt(0)==32)return(new Array(a.length+1)).join(" ");if(a==" "){var i=e.session.getScreenTabSize(b+f);return b+=i-1,e.$tabStrings[i]}if(a=="&")return g.isOldGecko?"&":"&";if(a=="<")return"<";if(a==" "){var j=e.showInvisibles?"ace_cjk ace_invisible":"ace_cjk",k=e.showInvisibles?e.SPACE_CHAR:"";return b+=1,""+k+""}if(a.match(/[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/)){if(e.showInvisibles){var k=(new Array(a.length+1)).join(e.SPACE_CHAR);return""+k+""}return" "}return b+=1,""+a+""},i=d.replace(f,h);if(!this.$textToken[c.type]){var j="ace_"+c.type.replace(/\./g," ace_"),k="";c.type=="fold"&&(k=" style='width:"+c.value.length*this.config.characterWidth+"px;' "),a.push("",i,"")}else a.push(i);return b+d.length},this.$renderLineCore=function(a,b,c,d,e){var f=0,g=0,h,i=0,j=this;!d||d.length==0?h=Number.MAX_VALUE:h=d[0],e||a.push("
");for(var k=0;k=h)i=j.$renderToken(a,i,l,m.substring(0,h-f)),m=m.substring(h-f),f=h,e||a.push("
","
"),g++,i=0,h=d[g]||Number.MAX_VALUE;m.length!=0&&(f+=m.length,i=j.$renderToken(a,i,l,m))}}this.showInvisibles&&(b!==this.session.getLength()-1?a.push(""+this.EOL_CHAR+""):a.push(""+this.EOF_CHAR+"")),e||a.push("
")},this.$renderLine=function(a,b,c,d){if(!this.session.isRowFolded(b)){var e=this.session.getRowSplitData(b);this.$renderLineCore(a,b,c,e,d)}else this.$renderFoldLine(a,b,c,d)},this.$renderFoldLine=function(a,b,c,d){function h(a,b,c){var d=0,e=0;while(e+a[d].value.lengthc-b&&(f=f.substring(0,c-b)),g.push({type:a[d].type,value:f}),e=b+f.length,d+=1}while(ec&&(f=f.substring(0,c-e)),g.push({type:a[d].type,value:f}),e+=f.length,d+=1}}var e=this.session,f=e.getFoldLine(b),g=[];f.walk(function(a,b,d,e,f){a?g.push({type:"fold",value:a}):(f&&(c=this.session.getTokens(b,b)[0].tokens),c.length!=0&&h(c,e,d))}.bind(this),f.end.row,this.session.getLine(f.end.row).length);var i=this.session.$useWrapMode?this.session.$wrapData[b]:null;this.$renderLineCore(a,b,g,i,d)},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(i.prototype),b.Text=i}),ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(a,b,c){"use strict";var d=a("../lib/dom"),e=function(a){this.element=d.createElement("div"),this.element.className="ace_layer ace_cursor-layer",a.appendChild(this.element),this.isVisible=!1,this.cursors=[],this.cursor=this.addCursor()};(function(){this.$padding=0,this.setPadding=function(a){this.$padding=a},this.setSession=function(a){this.session=a},this.addCursor=function(){var a=d.createElement("div"),b="ace_cursor";return this.isVisible||(b+=" ace_hidden"),this.overwrite&&(b+=" ace_overwrite"),a.className=b,this.element.appendChild(a),this.cursors.push(a),a},this.removeCursor=function(){if(this.cursors.length>1){var a=this.cursors.pop();return a.parentNode.removeChild(a),a}},this.hideCursor=function(){this.isVisible=!1;for(var a=this.cursors.length;a--;)d.addCssClass(this.cursors[a],"ace_hidden");clearInterval(this.blinkId)},this.showCursor=function(){this.isVisible=!0;for(var a=this.cursors.length;a--;)d.removeCssClass(this.cursors[a],"ace_hidden");this.element.style.visibility="",this.restartTimer()},this.restartTimer=function(){clearInterval(this.blinkId);if(!this.isVisible)return;var a=this.cursors.length==1?this.cursor:this.element;this.blinkId=setInterval(function(){a.style.visibility="hidden",setTimeout(function(){a.style.visibility=""},400)},1e3)},this.getPixelPosition=function(a,b){if(!this.config||!this.session)return{left:0,top:0};a||(a=this.session.selection.getCursor());var c=this.session.documentToScreenPosition(a),d=Math.round(this.$padding+c.column*this.config.characterWidth),e=(c.row-(b?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:d,top:e}},this.update=function(a){this.config=a;if(this.session.selectionMarkerCount>0){var b=this.session.$selectionMarkers,c=0,d,e=0;for(var c=b.length;c--;){d=b[c];var f=this.getPixelPosition(d.cursor,!0),g=(this.cursors[e++]||this.addCursor()).style;g.left=f.left+"px",g.top=f.top+"px",g.width=a.characterWidth+"px",g.height=a.lineHeight+"px"}if(e>1)while(this.cursors.length>e)this.removeCursor()}else{var f=this.getPixelPosition(null,!0),g=this.cursor.style;g.left=f.left+"px",g.top=f.top+"px",g.width=a.characterWidth+"px",g.height=a.lineHeight+"px";while(this.cursors.length>1)this.removeCursor()}var h=this.session.getOverwrite();h!=this.overwrite&&this.$setOverite(h),this.restartTimer()},this.$setOverite=function(a){this.overwrite=a;for(var b=this.cursors.length;b--;)a?d.addCssClass(this.cursors[b],"ace_overwrite"):d.removeCssClass(this.cursors[b],"ace_overwrite")},this.destroy=function(){clearInterval(this.blinkId)}}).call(e.prototype),b.Cursor=e}),ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("./lib/oop"),e=a("./lib/dom"),f=a("./lib/event"),g=a("./lib/event_emitter").EventEmitter,h=function(a){this.element=e.createElement("div"),this.element.className="ace_sb",this.inner=e.createElement("div"),this.element.appendChild(this.inner),a.appendChild(this.element),this.width=e.scrollbarWidth(a.ownerDocument),this.element.style.width=(this.width||15)+5+"px",f.addListener(this.element,"scroll",this.onScroll.bind(this))};(function(){d.implement(this,g),this.onScroll=function(){this._emit("scroll",{data:this.element.scrollTop})},this.getWidth=function(){return this.width},this.setHeight=function(a){this.element.style.height=a+"px"},this.setInnerHeight=function(a){this.inner.style.height=a+"px"},this.setScrollTop=function(a){this.element.scrollTop=a}}).call(h.prototype),b.ScrollBar=h}),ace.define("ace/renderloop",["require","exports","module","ace/lib/event"],function(a,b,c){"use strict";var d=a("./lib/event"),e=function(a,b){this.onRender=a,this.pending=!1,this.changes=0,this.window=b||window};(function(){this.schedule=function(a){this.changes=this.changes|a;if(!this.pending){this.pending=!0;var b=this;d.nextTick(function(){b.pending=!1;var a;while(a=b.changes)b.changes=0,b.onRender(a)},this.window)}}}).call(e.prototype),b.RenderLoop=e}),ace.define("text!ace/css/editor.css",[],"@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono);\n\n.ace_editor {\n position: absolute;\n overflow: hidden;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Droid Sans Mono', 'Consolas', monospace;\n font-size: 12px;\n}\n\n.ace_scroller {\n position: absolute;\n overflow-x: scroll;\n overflow-y: hidden;\n}\n\n.ace_content {\n position: absolute;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n cursor: text;\n}\n\n.ace_composition {\n position: absolute;\n background: #555;\n color: #DDD;\n z-index: 4;\n}\n\n.ace_gutter {\n position: absolute;\n overflow : hidden;\n height: 100%;\n width: auto;\n cursor: default;\n z-index: 1000;\n}\n\n.ace_gutter.horscroll {\n box-shadow: 0px 0px 20px rgba(0,0,0,0.4);\n}\n\n.ace_gutter-cell {\n padding-left: 19px;\n padding-right: 6px;\n}\n\n.ace_gutter-cell.ace_error {\n background-image: url(\"data:image/gif,GIF89a%10%00%10%00%D5%00%00%F5or%F5%87%88%F5nr%F4ns%EBmq%F5z%7F%DDJT%DEKS%DFOW%F1Yc%F2ah%CE(7%CE)8%D18E%DD%40M%F2KZ%EBU%60%F4%60m%DCir%C8%16(%C8%19*%CE%255%F1%3FR%F1%3FS%E6%AB%B5%CA%5DI%CEn%5E%F7%A2%9A%C9G%3E%E0a%5B%F7%89%85%F5yy%F6%82%80%ED%82%80%FF%BF%BF%E3%C4%C4%FF%FF%FF%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%25%00%2C%00%00%00%00%10%00%10%00%00%06p%C0%92pH%2C%1A%8F%C8%D2H%93%E1d4%23%E4%88%D3%09mB%1DN%B48%F5%90%40%60%92G%5B%94%20%3E%22%D2%87%24%FA%20%24%C5%06A%00%20%B1%07%02B%A38%89X.v%17%82%11%13q%10%0Fi%24%0F%8B%10%7BD%12%0Ei%09%92%09%0EpD%18%15%24%0A%9Ci%05%0C%18F%18%0B%07%04%01%04%06%A0H%18%12%0D%14%0D%12%A1I%B3%B4%B5IA%00%3B\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_warning {\n background-image: url(\"data:image/gif,GIF89a%10%00%10%00%D5%00%00%FF%DBr%FF%DE%81%FF%E2%8D%FF%E2%8F%FF%E4%96%FF%E3%97%FF%E5%9D%FF%E6%9E%FF%EE%C1%FF%C8Z%FF%CDk%FF%D0s%FF%D4%81%FF%D5%82%FF%D5%83%FF%DC%97%FF%DE%9D%FF%E7%B8%FF%CCl%7BQ%13%80U%15%82W%16%81U%16%89%5B%18%87%5B%18%8C%5E%1A%94d%1D%C5%83-%C9%87%2F%C6%84.%C6%85.%CD%8B2%C9%871%CB%8A3%CD%8B5%DC%98%3F%DF%9BB%E0%9CC%E1%A5U%CB%871%CF%8B5%D1%8D6%DB%97%40%DF%9AB%DD%99B%E3%B0p%E7%CC%AE%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%2F%00%2C%00%00%00%00%10%00%10%00%00%06a%C0%97pH%2C%1A%8FH%A1%ABTr%25%87%2B%04%82%F4%7C%B9X%91%08%CB%99%1C!%26%13%84*iJ9(%15G%CA%84%14%01%1A%97%0C%03%80%3A%9A%3E%81%84%3E%11%08%B1%8B%20%02%12%0F%18%1A%0F%0A%03'F%1C%04%0B%10%16%18%10%0B%05%1CF%1D-%06%07%9A%9A-%1EG%1B%A0%A1%A0U%A4%A5%A6BA%00%3B\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_info {\n background-image: url(\"data:image/gif;base64,R0lGODlhEAAQAMQAAAAAAEFBQVJSUl5eXmRkZGtra39/f4WFhYmJiZGRkaampry8vMPDw8zMzNXV1dzc3OTk5Orq6vDw8P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABQALAAAAAAQABAAAAUuICWOZGmeaBml5XGwFCQSBGyXRSAwtqQIiRuiwIM5BoYVbEFIyGCQoeJGrVptIQA7\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_editor .ace_sb {\n position: absolute;\n overflow-x: hidden;\n overflow-y: scroll;\n right: 0;\n}\n\n.ace_editor .ace_sb div {\n position: absolute;\n width: 1px;\n left: 0;\n}\n\n.ace_editor .ace_print_margin_layer {\n z-index: 0;\n position: absolute;\n overflow: hidden;\n margin: 0;\n left: 0;\n height: 100%;\n width: 100%;\n}\n\n.ace_editor .ace_print_margin {\n position: absolute;\n height: 100%;\n}\n\n.ace_editor textarea {\n position: fixed;\n z-index: 0;\n width: 10px;\n height: 30px;\n opacity: 0;\n background: transparent;\n appearance: none;\n -moz-appearance: none;\n border: none;\n resize: none;\n outline: none;\n overflow: hidden;\n}\n\n.ace_layer {\n z-index: 1;\n position: absolute;\n overflow: hidden;\n white-space: nowrap;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n /* setting pointer-events: auto; on node under the mouse, which changes\n during scroll, will break mouse wheel scrolling in Safari */\n pointer-events: none;\n}\n\n.ace_gutter .ace_layer {\n position: relative;\n min-width: 40px;\n text-align: right;\n pointer-events: auto;\n}\n\n.ace_text-layer {\n color: black;\n}\n\n.ace_cjk {\n display: inline-block;\n text-align: center;\n}\n\n.ace_cursor-layer {\n z-index: 4;\n}\n\n.ace_cursor {\n z-index: 4;\n position: absolute;\n}\n\n.ace_cursor.ace_hidden {\n opacity: 0.2;\n}\n\n.ace_editor.multiselect .ace_cursor {\n border-left-width: 1px;\n}\n\n.ace_line {\n white-space: nowrap;\n}\n\n.ace_marker-layer .ace_step {\n position: absolute;\n z-index: 3;\n}\n\n.ace_marker-layer .ace_selection {\n position: absolute;\n z-index: 5;\n}\n\n.ace_marker-layer .ace_bracket {\n position: absolute;\n z-index: 6;\n}\n\n.ace_marker-layer .ace_active_line {\n position: absolute;\n 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 box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n}\n\n.ace_line .ace_fold {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n \n display: inline-block;\n height: 11px;\n margin-top: -2px;\n vertical-align: middle;\n\n background-image: \n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%3AIDAT8%11c%FC%FF%FF%7F%18%03%1A%60%01%F2%3F%A0%891%80%04%FF%11-%F8%17%9BJ%E2%05%B1ZD%81v%26t%E7%80%F8%A3%82h%A12%1A%20%A3%01%02%0F%01%BA%25%06%00%19%C0%0D%AEF%D5%3ES%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat, repeat-x;\n background-position: center center, top left;\n color: transparent;\n\n border: 1px solid black;\n -moz-border-radius: 2px;\n -webkit-border-radius: 2px;\n border-radius: 2px;\n \n cursor: pointer;\n pointer-events: auto;\n}\n\n.ace_dark .ace_fold {\n}\n\n.ace_fold:hover{\n background-image: \n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%003IDAT8%11c%FC%FF%FF%7F%3E%03%1A%60%01%F2%3F%A3%891%80%04%FFQ%26%F8w%C0%B43%A1%DB%0C%E2%8F%0A%A2%85%CAh%80%8C%06%08%3C%04%E8%96%18%00%A3S%0D%CD%CF%D8%C1%9D%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat, repeat-x;\n background-position: center center, top left;\n}\n\n.ace_dragging .ace_content {\n cursor: move;\n}\n\n.ace_folding-enabled > .ace_gutter-cell {\n padding-right: 13px;\n}\n\n.ace_fold-widget {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n\n margin: 0 -12px 1px 1px;\n display: inline-block;\n height: 14px;\n width: 11px;\n vertical-align: text-bottom;\n \n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAe%8A%B1%0D%000%0C%C2%F2%2CK%96%BC%D0%8F9%81%88H%E9%D0%0E%96%C0%10%92%3E%02%80%5E%82%E4%A9*-%EEsw%C8%CC%11%EE%96w%D8%DC%E9*Eh%0C%151(%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat;\n background-position: center 5px;\n\n border-radius: 3px;\n}\n\n.ace_fold-widget.end {\n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAm%C7%C1%09%000%08C%D1%8C%ECE%C8E(%8E%EC%02)%1EZJ%F1%C1'%04%07I%E1%E5%EE%CAL%F5%A2%99%99%22%E2%D6%1FU%B5%FE0%D9x%A7%26Wz5%0E%D5%00%00%00%00IEND%AEB%60%82\");\n}\n\n.ace_fold-widget.closed {\n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%03%00%00%00%06%08%06%00%00%00%06%E5%24%0C%00%00%009IDATx%DA5%CA%C1%09%000%08%03%C0%AC*(%3E%04%C1%0D%BA%B1%23%A4Uh%E0%20%81%C0%CC%F8%82%81%AA%A2%AArGfr%88%08%11%11%1C%DD%7D%E0%EE%5B%F6%F6%CB%B8%05Q%2F%E9tai%D9%00%00%00%00IEND%AEB%60%82\");\n}\n\n.ace_fold-widget:hover {\n border: 1px solid rgba(0, 0, 0, 0.3);\n background-color: rgba(255, 255, 255, 0.2);\n -moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n -moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n -webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n -webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n background-position: center 4px;\n}\n\n.ace_fold-widget:active {\n border: 1px solid rgba(0, 0, 0, 0.4);\n background-color: rgba(0, 0, 0, 0.05);\n -moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n -moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n -webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n -webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n}\n\n.ace_fold-widget.invalid {\n background-color: #FFB4B4;\n border-color: #DE5555;\n}\n"),ace.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(a,b,c){function j(a,b,c){return i.$options.wrap=!0,i.$options.needle=b,i.$options.backwards=c==-1,i.find(a)}function m(a,b){return a.row==b.row&&a.column==b.column}function n(a){a.$onAddRange=a.$onAddRange.bind(a),a.$onRemoveRange=a.$onRemoveRange.bind(a),a.$onMultiSelect=a.$onMultiSelect.bind(a),a.$onSingleSelect=a.$onSingleSelect.bind(a),b.onSessionChange.call(a,a),a.on("changeSession",b.onSessionChange.bind(a)),a.on("mousedown",g),a.commands.addCommands(b.commands.defaultCommands),o(a)}function o(a){function e(){c&&(d.style.cursor="",c=!1)}var b=a.textInput.getElement(),c=!1,d=a.renderer.content;b.addEventListener("keydown",function(a){a.keyCode==18&&!(a.ctrlKey||a.shiftKey||a.metaKey)?c||(d.style.cursor="crosshair",c=!0):c&&(d.style.cursor="")}),b.addEventListener("keyup",e),b.addEventListener("blur",e)}var d=a("./range_list").RangeList,e=a("./range").Range,f=a("./selection").Selection,g=a("./mouse/multi_select_handler").onMouseDown;b.commands=a("./commands/multi_select_commands");var h=a("./search").Search,i=new h,k=a("./edit_session").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(k.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(a,b){if(!a)return;if(!this.inMultiSelectMode&&this.rangeCount==0){var c=this.toOrientedRange();if(a.intersects(c))return b||this.fromOrientedRange(a);this.rangeList.add(c),this.$onAddRange(c)}a.cursor||(a.cursor=a.end);var d=this.rangeList.add(a);return this.$onAddRange(a),d.length&&this.$onRemoveRange(d),this.rangeCount>1&&!this.inMultiSelectMode&&(this._emit("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),b||this.fromOrientedRange(a)},this.toSingleRange=function(a){a=a||this.ranges[0];var b=this.rangeList.removeAll();b.length&&this.$onRemoveRange(b),a&&this.fromOrientedRange(a)},this.substractPoint=function(a){var b=this.rangeList.substractPoint(a);if(b)return this.$onRemoveRange(b),b[0]},this.mergeOverlappingRanges=function(){var a=this.rangeList.merge();a.length?this.$onRemoveRange(a):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(a){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(a),this._emit("addRange",{range:a})},this.$onRemoveRange=function(a){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var b=this.rangeList.ranges.pop();a.push(b),this.rangeCount=0}for(var c=a.length;c--;){var d=this.ranges.indexOf(a[c]);this.ranges.splice(d,1)}this._emit("removeRange",{ranges:a}),this.rangeCount==0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._emit("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),b=b||this.ranges[0],b&&!b.isEqual(this.getRange())&&this.fromOrientedRange(b)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new d,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeList.ranges.concat()},this.splitIntoLines=function(){if(this.rangeCount>1){var a=this.rangeList.ranges,b=a[a.length-1],c=e.fromPoints(a[0].start,b.end);this.toSingleRange(),this.setSelectionRange(c,b.cursor==b.start)}else{var d=this.session.documentToScreenPosition(this.selectionLead),f=this.session.documentToScreenPosition(this.selectionAnchor),g=this.rectangularRangeBlock(d,f);g.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(a,b,c){var d=[],f=a.column0)p--;if(p>0){var q=0;while(d[q].isEmpty())q++}for(var r=p;r>=q;r--)d[r].isEmpty()&&d.splice(r,1)}return d}}.call(f.prototype);var l=a("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(a){a.cursor||(a.cursor=a.end);var b=this.getSelectionStyle();return a.marker=this.session.addMarker(a,"ace_selection",b),this.session.$selectionMarkers.push(a),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,a},this.removeSelectionMarker=function(a){if(!a.marker)return;this.session.removeMarker(a.marker);var b=this.session.$selectionMarkers.indexOf(a);b!=-1&&this.session.$selectionMarkers.splice(b,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(a){var b=this.session.$selectionMarkers;for(var c=a.length;c--;){var d=a[c];if(!d.marker)continue;this.session.removeMarker(d.marker);var e=b.indexOf(d);e!=-1&&b.splice(e,1)}this.session.selectionMarkerCount=b.length},this.$onAddRange=function(a){this.addSelectionMarker(a.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(a){this.removeSelectionMarkers(a.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(a){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("multiselect"),this.keyBinding.addKeyboardHandler(b.commands.keyboardHandler),this.commands.on("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(a){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("multiselect"),this.keyBinding.removeKeyboardHandler(b.commands.keyboardHandler),this.commands.removeEventListener("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelectExec=function(a){var b=a.command,c=a.editor;b.multiSelectAction?b.multiSelectAction=="forEach"?c.forEachSelection(b,a.args):b.multiSelectAction=="single"?(c.exitMultiSelectMode(),b.exec(c,a.args||{})):b.multiSelectAction(c,a.args||{}):(b.exec(c,a.args||{}),c.multiSelect.addRange(c.multiSelect.toOrientedRange()),c.multiSelect.mergeOverlappingRanges()),a.preventDefault()},this.forEachSelection=function(a,b){if(this.inVirtualSelectionMode)return;var c=this.session,d=this.selection,e=d.rangeList,g=d._eventRegistry;d._eventRegistry={};var h=new f(c);this.inVirtualSelectionMode=!0;for(var i=e.ranges.length;i--;)h.fromOrientedRange(e.ranges[i]),this.selection=c.selection=h,a.exec(this,b||{}),h.toOrientedRange(e.ranges[i]);h.detach(),this.selection=c.selection=d,this.inVirtualSelectionMode=!1,d._eventRegistry=g,d.mergeOverlappingRanges(),this.onCursorChange(),this.onSelectionChange()},this.exitMultiSelectMode=function(){if(this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getCopyText=function(){var a="";if(this.inMultiSelectMode){var b=this.multiSelect.rangeList.ranges;a=[];for(var c=0;c0)continue;return f==0?d:(f=this.comparePoints(a,e.start),f>=0?d:-d-1)}return-d-1},this.add=function(a){var b=this.pointIndex(a.start);b<0&&(b=-b-1);var c=this.pointIndex(a.end,b);return c<0?c=-c-1:c++,this.ranges.splice(b,c-b,a)},this.addList=function(a){var b=[];for(var c=a.length;c--;)b.push.call(b,this.add(a[c]));return b},this.substractPoint=function(a){var b=this.pointIndex(a);if(b>=0)return this.ranges.splice(b,1)},this.merge=function(){var a=[],b=this.ranges,c=b[0],d;for(var e=1;e=0},this.containsPoint=function(a){return this.pointIndex(a)>=0},this.rangeAtPoint=function(a){var b=this.pointIndex(a);if(b>=0)return this.ranges[b]},this.clipRows=function(a,b){var c=this.ranges;if(c[0].start.row>b||c[c.length-1].start.rowe)break;l.start.row==e&&l.start.column>=c.column&&(l.start.column+=h,l.start.row+=g),l.end.row==e&&l.end.column>=c.column&&(l.end.column+=h,l.end.row+=g)}if(g!=0&&j=this.pos.column&&c.start.column<=this.pos.column+this.length+1){var f=c.start.column-this.pos.column;this.length+=e;if(!this.session.$fromUndo){if(b.action==="insertText")for(var g=this.others.length-1;g>=0;g--){var h=this.others[g],i={row:h.row,column:h.column+f};h.row===c.start.row&&c.start.column=0;g--){var h=this.others[g],i={row:h.row,column:h.column+f};h.row===c.start.row&&c.start.column=this.pos.column&&b.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",a)):(this.hideOtherMarkers(),this._emit("cursorLeave",a))},this.detach=function(){this.session.removeMarker(this.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.pos.detach();for(var a=0;a1&&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.commands=new o(f.isMac?"mac":"win",p),this.textInput=new g(a.getTextAreaContainer(),this),this.renderer.textarea=this.textInput.getElement(),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.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.$cursorChange=function(){this.renderer.updateCursor()},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.$cursorChange()},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.$cursorChange(),this.$blockScrolling||this.renderer.scrollCursorIntoView(),this.$highlightBrackets(),this.$updateHighlightActiveLine()},this.$updateHighlightActiveLine=function(){var a=this.getSession();a.$highlightLineMarker&&a.removeMarker(a.$highlightLineMarker),a.$highlightLineMarker=null;if(this.$highlightActiveLine){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.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.onCopy=function(){this.commands.exec("copy",this)},this.onCut=function(){this.commands.exec("cut",this)},this.onPaste=function(a){this._emit("paste",a),this.insert(a)},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){this.keyBinding.onTextInput(a)},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.$highlightGutterLine=!0,this.setHighlightGutterLine=function(a){if(this.$highlightGutterLine==a)return;this.renderer.setHighlightGutterLine(a)},this.getHighlightGutterLine=function(){return this.$highlightGutterLine},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.setFadeFoldWidgets=function(a){this.renderer.setFadeFoldWidgets(a)},this.getFadeFoldWidgets=function(){return this.renderer.getFadeFoldWidgets()},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.$moveByPage=function(a,b){var c=this.renderer,d=this.renderer.layerConfig,e=a*Math.floor(d.height/d.lineHeight);this.$blockScrolling++,b==1?this.selection.$moveSelection(function(){this.moveCursorBy(e,0)}):b==0&&(this.selection.moveCursorBy(e,0),this.selection.clearSelection()),this.$blockScrolling--;var f=c.scrollTop;c.scrollBy(0,e*d.lineHeight),b!=null&&c.scrollCursorIntoView(null,.5),c.animateScrolling(f)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(a){this.renderer.scrollToRow(a)},this.scrollToLine=function(a,b,c,d){this.renderer.scrollToLine(a,b,c,d)},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,c){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(a-1)||this.scrollToLine(a-1,!0,c)},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(){var a=this.renderer.scrollTop;this.selection.moveCursorFileEnd(),this.clearSelection(),this.renderer.animateScrolling(a)},this.navigateFileStart=function(){var a=this.renderer.scrollTop;this.selection.moveCursorFileStart(),this.clearSelection(),this.renderer.animateScrolling(a)},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,c){this.clearSelection(),b=b||{},b.needle=a,this.$search.set(b),this.$find(!1,c)},this.findNext=function(a,b){a=a||{},this.$search.set(a),this.$find(!1,b)},this.findPrevious=function(a,b){a=a||{},this.$search.set(a),this.$find(!0,b)},this.$find=function(a,b){this.selection.isEmpty()||this.$search.set({needle:this.session.getTextRange(this.getSelectionRange())}),typeof a!="undefined"&&this.$search.set({backwards:a});var c=this.$search.find(this.session);if(c){this.$blockScrolling+=1,this.session.unfold(c),this.selection.setSelectionRange(c),this.$blockScrolling-=1;var d=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(c.start,c.end,.5),this.renderer.animateScrolling(d)}},this.undo=function(){this.$blockScrolling++,this.session.getUndoManager().undo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.$blockScrolling++,this.session.getUndoManager().redo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},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;c1&&(d.charAt(0)==g?d=d.substr(1):d.charAt(d.length-1)==g&&(d=d.slice(0,-1))),d&&d!=g&&(j?b.onPaste(d):b.onTextInput(d));if(!v())return!1}}i=!1,j=!1,c.value=g,l()}function v(){return document.activeElement===c}var c=f.createElement("textarea");e.isTouchPad&&c.setAttribute("x-palm-disable-auto-cap",!0),c.setAttribute("wrap","off"),c.style.left="-10000px",c.style.position="fixed",a.insertBefore(c,a.firstChild);var g=String.fromCharCode(0);m();var h=!1,i=!1,j=!1,k="",n=function(a){setTimeout(function(){h||m(a.data)},0)},o=function(a){if(e.isOldIE&&c.value.charCodeAt(0)>128)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(this),new f(this),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)},this.setState=function(a){this.state=a},this.captureMouse=function(a,b){b&&this.setState(b),this.x=a.x,this.y=a.y;var c=this.editor.renderer.$keepTextAreaAtCursor;this.editor.renderer.$keepTextAreaAtCursor=!1;var e=this,f=function(a){e.x=a.clientX,e.y=a.clientY},g=function(a){clearInterval(i),e[e.state+"End"]&&e[e.state+"End"](a),e.$clickSelection=null,e.editor.renderer.$keepTextAreaAtCursor=c,e.editor.renderer.$moveTextAreaToCursor()},h=function(){e[e.state]&&e[e.state]()};d.capture(this.editor.container,f,g);var i=setInterval(h,20);a.preventDefault()}}).call(h.prototype),b.MouseHandler=h}),ace.define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/browser_focus"],function(a,b,c){function g(a){a.$clickSelection=null,a.browserFocus=new e;var b=a.editor;b.setDefaultHandler("mousedown",this.onMouseDown.bind(a)),b.setDefaultHandler("dblclick",this.onDoubleClick.bind(a)),b.setDefaultHandler("tripleclick",this.onTripleClick.bind(a)),b.setDefaultHandler("quadclick",this.onQuadClick.bind(a)),b.setDefaultHandler("mousewheel",this.onScroll.bind(a));var c=["select","startSelect","drag","dragEnd","dragWait","dragWaitEnd","startDrag"];c.forEach(function(b){a[b]=this[b]},this),a.selectByLines=this.extendSelectionBy.bind(a,"getLineRange"),a.selectByWords=this.extendSelectionBy.bind(a,"getWordRange")}function h(a,b,c,d){return Math.sqrt(Math.pow(c-a,2)+Math.pow(d-b,2))}"use strict";var d=a("../lib/dom"),e=a("../lib/browser_focus").BrowserFocus,f=5;(function(){this.onMouseDown=function(a){this.mousedownEvent=a;var b=a.inSelection(),c=a.getDocumentPosition(),d=this.editor,e=this;this.ev=a;var f=d.getSelectionRange(),g=f.isEmpty(),h=a.getButton();if(h!==0){g&&(d.moveCursorToPosition(c),d.selection.clearSelection()),this.moveTextarea=function(){d.textInput.onContextMenu({x:e.x,y:e.y})},this.moveTextareaEnd=d.textInput.onContextMenuClose,d.textInput.onContextMenu({x:this.x,y:this.y},g),this.captureMouse(a,"moveTextarea");return}if(b&&!d.isFocused()){d.focus();return}if(!b||this.$clickSelection||a.getShiftKey())this.startSelect(c);else if(b){var i=a.domEvent;i.ctrlKey||i.altKey?this.startDrag():(this.mousedownEvent.time=(new Date).getTime(),this.setState("dragWait"))}this.captureMouse(a)},this.startSelect=function(a){a=a||this.editor.renderer.screenToTextCoordinates(this.x,this.y),this.mousedownEvent.getShiftKey()?this.editor.selection.selectToPosition(a):this.$clickSelection||(this.editor.moveCursorToPosition(a),this.editor.selection.clearSelection()),this.setState("select")},this.select=function(){var a,b=this.editor,c=b.renderer.screenToTextCoordinates(this.x,this.y);if(this.$clickSelection){var d=this.$clickSelection.comparePoint(c);d==-1?a=this.$clickSelection.end:d==1?a=this.$clickSelection.start:(c=this.$clickSelection.end,a=this.$clickSelection.start),b.selection.setSelectionAnchor(a.row,a.column)}b.selection.selectToPosition(c),b.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(a){var b,c=this.editor,d=c.renderer.screenToTextCoordinates(this.x,this.y),e=c.selection[a](d.row,d.column);if(this.$clickSelection){var f=this.$clickSelection.comparePoint(e.start),g=this.$clickSelection.comparePoint(e.end);f==-1&&g<=0?(b=this.$clickSelection.end,d=e.start):g==1&&f>=0?(b=this.$clickSelection.start,d=e.end):f==-1&&g==1?(d=e.end,b=e.start):(d=this.$clickSelection.end,b=this.$clickSelection.start),c.selection.setSelectionAnchor(b.row,b.column)}c.selection.selectToPosition(d),c.renderer.scrollCursorIntoView()},this.startDrag=function(){var a=this.editor;this.setState("drag"),this.dragRange=a.getSelectionRange();var b=a.getSelectionStyle();this.dragSelectionMarker=a.session.addMarker(this.dragRange,"ace_selection",b),a.clearSelection(),d.addCssClass(a.container,"ace_dragging"),this.$dragKeybinding||(this.$dragKeybinding={handleKeyboard:function(a,b,c,d){if(c=="esc")return{command:this.command}},command:{exec:function(a){var b=a.$mouseHandler;b.dragCursor=null,b.dragEnd(),b.startSelect()}}}),a.keyBinding.addKeyboardHandler(this.$dragKeybinding)},this.dragWait=function(){var a=h(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),b=(new Date).getTime(),c=this.editor;a>f?this.startSelect():b-this.mousedownEvent.time>c.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(a){this.mousedownEvent.domEvent=a,this.startSelect()},this.drag=function(){var a=this.editor;this.dragCursor=a.renderer.screenToTextCoordinates(this.x,this.y),a.moveCursorToPosition(this.dragCursor),a.renderer.scrollCursorIntoView()},this.dragEnd=function(a){var b=this.editor,c=this.dragCursor,e=this.dragRange;d.removeCssClass(b.container,"ace_dragging"),b.session.removeMarker(this.dragSelectionMarker),b.keyBinding.removeKeyboardHandler(this.$dragKeybinding);if(!c)return;b.clearSelection();if(a&&(a.ctrlKey||a.altKey)){var f=b.session,g=e;g.end=f.insert(c,f.getTextRange(e)),g.start=c}else{if(e.contains(c.row,c.column))return;var g=b.moveText(e,c)}if(!g)return;b.selection.setSelectionRange(g)},this.onDoubleClick=function(a){var b=a.getDocumentPosition(),c=this.editor;this.setState("selectByWords"),c.moveCursorToPosition(b),c.selection.selectWord(),this.$clickSelection=c.getSelectionRange()},this.onTripleClick=function(a){var b=a.getDocumentPosition(),c=this.editor;this.setState("selectByLines"),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.setState("select")},this.onScroll=function(a){var b=this.editor,c=b.renderer.isScrollableBy(a.wheelX*a.speed,a.wheelY*a.speed);if(c)this.$passScrollEvent=!1;else{if(this.$passScrollEvent)return;if(!this.$scrollStopTimeout){var d=this;this.$scrollStopTimeout=setTimeout(function(){d.$passScrollEvent=!0,d.$scrollStopTimeout=null},200)}}return b.renderer.scrollBy(a.wheelX*a.speed,a.wheelY*a.speed),a.preventDefault()}}).call(g.prototype),b.DefaultHandlers=g}),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,j,k=a;b=Math.min(b,c.length-1);while(k<=b){j=this.getFoldLine(k,j);if(!j)h=this.$getDisplayTokens(f.stringTrimRight(c[k])),e[k]=this.$computeWrapSplits(h,g,d),k++;else{h=[],j.walk(function(a,b,d,e){var f;if(a){f=this.$getDisplayTokens(a,h.length),f[0]=i;for(var g=1;g=o)h.pop();e[j.start.row]=this.$computeWrapSplits(h,g,d),k=j.end.row+1}}};var b=1,c=2,i=3,l=4,n=9,o=10,p=11,q=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]>=o){while(a[h]>=o)h++;g(h);continue}if(a[h]==i||a[h]==l){for(h;h!=e-1;h--)if(a[h]==i)break;if(h>e){g(h);continue}h=e+b;for(h;hj&&a[h]j&&a[h]==n)h--;if(h>j){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(n):h>=4352&&r(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&&r(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.anchor,b=this.lead;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.lead;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.getWordRange=function(a,b){if(typeof b=="undefined"){var c=a||this.lead;a=c.row,b=c.column}return this.session.getWordRange(a,b)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var a=this.getCursor(),b=this.session.getAWordRange(a.row,a.column);this.setSelectionRange(b)},this.getLineRange=function(a,b){var c=typeof a=="number"?a:this.lead.row,d,e=this.session.getFoldLine(c);return e?(c=e.start.row,d=e.end.row):d=c,b?new g(c,0,d,this.session.getLine(d).length):new g(c,0,d+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var a=this.lead.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.lead.getPosition(),b;if(b=this.session.getFoldAt(a.row,a.column,1))this.moveCursorTo(b.end.row,b.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.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.$shortWordEndIndex=function(a){var b,c=0,d,e=/\s/,f=this.session.tokenRe;f.lastIndex=0;if(b=this.session.tokenRe.exec(a))c=this.session.tokenRe.lastIndex;else{while((d=a[c])&&e.test(d))c++;if(c<=1){f.lastIndex=0;while((d=a[c])&&!f.test(d)){f.lastIndex=0,c++;if(e.test(d)){if(c>2){c--;break}while((d=a[c])&&e.test(d))c++;if(c>2)break}}}}return f.lastIndex=0,c},this.moveCursorShortWordRight=function(){var a=this.lead.row,b=this.lead.column,c=this.doc.getLine(a),d=c.substring(b),e=this.session.getFoldAt(a,b,1);if(e)return this.moveCursorTo(e.end.row,e.end.column);if(b==c.length)return this.moveCursorRight();var f=this.$shortWordEndIndex(d);this.moveCursorTo(a,b+f)},this.moveCursorShortWordLeft=function(){var a=this.lead.row,b=this.lead.column,c;if(c=this.session.getFoldAt(a,b,-1))return this.moveCursorTo(c.start.row,c.start.column);if(b==0)return this.moveCursorLeft();var d=this.session.getLine(a).substring(0,b),f=e.stringReverse(d),g=this.$shortWordEndIndex(f);return this.moveCursorTo(a,b-g)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(a,b){var c=this.session.documentToScreenPosition(this.lead.row,this.lead.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.lead.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.lead.detach(),this.anchor.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,this.$keepTextAreaAtCursor=!g.isIE,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.setHighlightGutterLine(!0),this.$gutterLayer=new j(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onResize.bind(this,!0)),this.setFadeFoldWidgets(!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=!1,this.$horizScrollAlwaysVisible=!1,this.$animatedScroll=!1,this.scrollBar=new n(a),this.scrollBar.addEventListener("scroll",function(a){c.$inScrollAnimation||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),c.scroller.className=a==0?"ace_scroller":"ace_scroller 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.scroller.className="ace_scroller",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.lastRowthis.layerConfig.height)return;b+=(this.showGutter?this.$gutterLayer.gutterWidth:0)-this.scrollLeft;var c=this.container.getBoundingClientRect();this.textarea.style.left=c.left+b+"px",this.textarea.style.top=c.top+a+"px"},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var a=Math.floor((this.layerConfig.height+this.layerConfig.offset)/this.layerConfig.lineHeight);return this.layerConfig.firstRow-1+a},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(a){this.$padding=a,this.$textLayer.setPadding(a),this.$cursorLayer.setPadding(a),this.$markerFront.setPadding(a),this.$markerBack.setPadding(a),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.getHScrollBarAlwaysVisible=function(){return this.$horizScrollAlwaysVisible},this.setHScrollBarAlwaysVisible=function(a){this.$horizScrollAlwaysVisible!=a&&(this.$horizScrollAlwaysVisible=a,(!this.$horizScrollAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL))},this.$updateScrollBar=function(){this.scrollBar.setInnerHeight(this.layerConfig.maxHeight),this.scrollBar.setScrollTop(this.scrollTop)},this.$renderChanges=function(a){if(!a||!this.session||!this.container.offsetWidth)return;(a&this.CHANGE_FULL||a&this.CHANGE_SIZE||a&this.CHANGE_TEXT||a&this.CHANGE_LINES||a&this.CHANGE_SCROLL)&&this.$computeLayerConfig();if(a&this.CHANGE_H_SCROLL){this.scroller.scrollLeft=this.scrollLeft;var b=this.scroller.scrollLeft;this.scrollLeft=b,this.session.setScrollLeft(b)}if(a&this.CHANGE_FULL){this.$textLayer.checkForSizeChanges(),this.$updateScrollBar(),this.$textLayer.update(this.layerConfig),this.showGutter&&this.$gutterLayer.update(this.layerConfig),this.$markerBack.update(this.layerConfig),this.$markerFront.update(this.layerConfig),this.$cursorLayer.update(this.layerConfig),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight();return}if(a&this.CHANGE_SCROLL){this.$updateScrollBar(),a&this.CHANGE_TEXT||a&this.CHANGE_LINES?this.$textLayer.update(this.layerConfig):this.$textLayer.scrollLines(this.layerConfig),this.showGutter&&this.$gutterLayer.update(this.layerConfig),this.$markerBack.update(this.layerConfig),this.$markerFront.update(this.layerConfig),this.$cursorLayer.update(this.layerConfig),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight();return}a&this.CHANGE_TEXT?(this.$textLayer.update(this.layerConfig),this.showGutter&&this.$gutterLayer.update(this.layerConfig)):a&this.CHANGE_LINES?this.$updateLines()&&(this.$updateScrollBar(),this.showGutter&&this.$gutterLayer.update(this.layerConfig)):a&this.CHANGE_GUTTER&&this.showGutter&&this.$gutterLayer.update(this.layerConfig),a&this.CHANGE_CURSOR&&(this.$cursorLayer.update(this.layerConfig),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight()),a&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(this.layerConfig),a&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(this.layerConfig),a&this.CHANGE_SIZE&&this.$updateScrollBar()},this.$computeLayerConfig=function(){var a=this.session,b=this.scrollTop%this.lineHeight,c=this.$size.scrollerHeight+this.lineHeight,d=this.$getLongestLine(),e=this.$horizScrollAlwaysVisible||this.$size.scrollerWidth-d<0,f=this.$horizScroll!==e;this.$horizScroll=e,f&&(this.scroller.style.overflowX=e?"scroll":"hidden",e||this.session.setScrollLeft(0));var g=this.session.getScreenLength()*this.lineHeight;this.session.setScrollTop(Math.max(0,Math.min(this.scrollTop,g-this.$size.scrollerHeight)));var h=Math.ceil(c/this.lineHeight)-1,i=Math.max(0,Math.round((this.scrollTop-b)/this.lineHeight)),j=i+h,k,l,m={lineHeight:this.lineHeight};i=a.screenToDocumentRow(i,0);var n=a.getFoldLine(i);n&&(i=n.start.row),k=a.documentToScreenRow(i,0),l=a.getRowHeight(m,i),j=Math.min(a.screenToDocumentRow(j,0),a.getLength()-1),c=this.$size.scrollerHeight+a.getRowHeight(m,j)+l,b=this.scrollTop-k*this.lineHeight,this.layerConfig={width:d,padding:this.$padding,firstRow:i,firstRowScreen:k,lastRow:j,lineHeight:this.lineHeight,characterWidth:this.characterWidth,minHeight:c,maxHeight:g,offset:b,height:this.$size.scrollerHeight},this.$gutter.style.marginTop=-b+"px",this.content.style.marginTop=-b+"px",this.content.style.width=d+2*this.$padding+"px",this.content.style.height=c+"px",f&&this.onResize(!0)},this.$updateLines=function(){var a=this.$changedLines.firstRow,b=this.$changedLines.lastRow;this.$changedLines=null;var c=this.layerConfig;if(c.width!=this.$getLongestLine())return this.$textLayer.update(c);if(a>c.lastRow+1)return;if(be?(b&&(e-=b*this.$size.scrollerHeight),this.session.setScrollTop(e)):this.scrollTop+this.$size.scrollerHeightd?(d0)return!0;if(b>0&&this.session.getScrollTop()+this.$size.scrollerHeight0?1:-1}},this.screenToTextCoordinates=function(a,b){var c=this.scroller.getBoundingClientRect(),d=Math.round((a+this.scrollLeft-c.left-this.$padding)/this.characterWidth),e=Math.floor((b+this.scrollTop-c.top)/this.lineHeight);return this.session.screenToDocumentPosition(e,Math.max(d,0))},this.textToScreenCoordinates=function(a,b){var c=this.scroller.getBoundingClientRect(),d=this.session.documentToScreenPosition(a,b),e=this.$padding+Math.round(d.column*this.characterWidth),f=d.row*this.lineHeight;return{pageX:c.left+e-this.scrollLeft,pageY:c.top+f-this.scrollTop}},this.visualizeFocus=function(){e.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){e.removeCssClass(this.container,"ace_focus")},this.showComposition=function(a){this.$composition||(this.$composition=e.createElement("div"),this.$composition.className="ace_composition",this.content.appendChild(this.$composition)),this.$composition.innerHTML=" ";var b=this.$cursorLayer.getPixelPosition(),c=this.$composition.style;c.top=b.top+"px",c.left=b.left+this.$padding+"px",c.height=this.lineHeight+"px",this.hideCursor()},this.setCompositionText=function(a){e.setInnerText(this.$composition,a)},this.hideComposition=function(){this.showCursor();if(!this.$composition)return;var a=this.$composition.style;a.top="-10000px",a.left="-10000px"},this._loadTheme=function(a,b){if(!h.get("packaged"))return b();var c=a.split("/").pop(),d=h.get("themePath")+"/theme-"+c+h.get("suffix");i.loadScript(d,b)},this.setTheme=function(b){function h(a){e.importCssString(a.cssText,a.cssClass,c.container.ownerDocument),c.$theme&&e.removeCssClass(c.container,c.$theme),c.$theme=a?a.cssClass:null,c.$theme&&e.addCssClass(c.container,c.$theme),a&&a.isDark?e.addCssClass(c.container,"ace_dark"):e.removeCssClass(c.container,"ace_dark"),c.$size&&(c.$size.width=0,c.onResize())}var c=this;this.$themeValue=b;if(!b||typeof b=="string"){var d=b||"ace/theme/textmate",f;try{f=a(d)}catch(g){}if(f)return h(f);c._loadTheme(d,function(){a([d],function(a){if(c.$themeValue!==b)return;h(a)})})}else h(b)},this.getTheme=function(){return this.$themeValue},this.setStyle=function(b){e.addCssClass(this.container,b)},this.unsetStyle=function(b){e.removeCssClass(this.container,b)},this.destroy=function(){this.$textLayer.destroy(),this.$cursorLayer.destroy()}}).call(r.prototype),b.VirtualRenderer=r}),ace.define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("../lib/dom"),e=a("../lib/oop"),f=a("../lib/event_emitter").EventEmitter,g=function(a){this.element=d.createElement("div"),this.element.className="ace_layer ace_gutter-layer",a.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$breakpoints=[],this.$annotations=[],this.$decorations=[]};(function(){e.implement(this,f),this.setSession=function(a){this.session=a},this.addGutterDecoration=function(a,b){this.$decorations[a]||(this.$decorations[a]=""),this.$decorations[a]+=" "+b},this.removeGutterDecoration=function(a,b){this.$decorations[a]=this.$decorations[a].replace(" "+b,"")},this.setBreakpoints=function(a){this.$breakpoints=a.concat()},this.setAnnotations=function(a){this.$annotations=[];for(var b in a)if(a.hasOwnProperty(b)){var c=a[b];if(!c)continue;var d=this.$annotations[b]={text:[]};for(var e=0;eh&&(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("
",e+1);if(i){var k=i[e];k==null&&(k=i[e]=this.session.getFoldWidget(e)),k&&c.push("")}var l=this.session.getRowLength(e)-1;while(l--)c.push("
¦");c.push("
"),e++}this.element=d.setInnerHtml(this.element,c.join("")),this.element.style.height=a.minHeight+"px";var m=this.element.offsetWidth;m!==this.gutterWidth&&(this.gutterWidth=m,this._emit("changeGutterWidth",m))},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(a){a?d.addCssClass(this.element,"ace_folding-enabled"):d.removeCssClass(this.element,"ace_folding-enabled"),this.$showFoldWidgets=a},this.getShowFoldWidgets=function(){return this.$showFoldWidgets}}).call(g.prototype),b.Gutter=g}),ace.define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(a,b,c){"use strict";var d=a("../range").Range,e=a("../lib/dom"),f=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_marker-layer",a.appendChild(this.element)};(function(){this.$padding=0,this.setPadding=function(a){this.$padding=a},this.setSession=function(a){this.session=a},this.setMarkers=function(a){this.markers=a},this.update=function(a){var a=a||this.config;if(!a)return;this.config=a;var b=[];for(var c in this.markers){var d=this.markers[c],f=d.range.clipRows(a.firstRow,a.lastRow);if(f.isEmpty())continue;f=f.toScreenRange(this.session);if(d.renderer){var g=this.$getTop(f.start.row,a),h=Math.round(this.$padding+f.start.column*a.characterWidth);d.renderer(b,f,h,g,a)}else f.isMultiLine()?d.type=="text"?this.drawTextMarker(b,f,d.clazz,a):this.drawMultiLineMarker(b,f,d.clazz,a,d.type):this.drawSingleLineMarker(b,f,d.clazz+" start",a,null,d.type)}this.element=e.setInnerHtml(this.element,b.join(""))},this.$getTop=function(a,b){return(a-b.firstRowScreen)*b.lineHeight},this.drawTextMarker=function(a,b,c,e){var f=b.start.row,g=new d(f,b.start.column,f,this.session.getScreenLastRowColumn(f));this.drawSingleLineMarker(a,g,c+" start",e,1,"text"),f=b.end.row,g=new d(f,0,f,b.end.column),this.drawSingleLineMarker(a,g,c,e,0,"text");for(f=b.start.row+1;f"),j=this.$getTop(b.end.row,d),i=Math.round(b.end.column*d.characterWidth),a.push("
"),h=(b.end.row-b.start.row-1)*d.lineHeight;if(h<0)return;j=this.$getTop(b.start.row+1,d),a.push("
")},this.drawSingleLineMarker=function(a,b,c,d,e,f){var g=f==="background"?0:this.$padding,h=d.lineHeight;if(f==="background")var i=d.width;else i=Math.round((b.end.column+(e||0)-b.start.column)*d.characterWidth);var j=this.$getTop(b.start.row,d),k=Math.round(g+b.start.column*d.characterWidth);a.push("
")}}).call(f.prototype),b.Marker=f}),ace.define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("../lib/oop"),e=a("../lib/dom"),f=a("../lib/lang"),g=a("../lib/useragent"),h=a("../lib/event_emitter").EventEmitter,i=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_text-layer",a.appendChild(this.element),this.$characterSize=this.$measureSizes()||{width:0,height:0},this.$pollSizeChanges()};(function(){d.implement(this,h),this.EOF_CHAR="¶",this.EOL_CHAR="¬",this.TAB_CHAR="→",this.SPACE_CHAR="·",this.$padding=0,this.setPadding=function(a){this.$padding=a,this.element.style.padding="0 "+a+"px"},this.getLineHeight=function(){return this.$characterSize.height||1},this.getCharacterWidth=function(){return this.$characterSize.width||1},this.checkForSizeChanges=function(){var a=this.$measureSizes();a&&(this.$characterSize.width!==a.width||this.$characterSize.height!==a.height)&&(this.$characterSize=a,this._emit("changeCharacterSize",{data:a}))},this.$pollSizeChanges=function(){var a=this;this.$pollSizeChangesTimer=setInterval(function(){a.checkForSizeChanges()},500)},this.$fontStyles={fontFamily:1,fontSize:1,fontWeight:1,fontStyle:1,lineHeight:1},this.$measureSizes=g.isIE||g.isOldGecko?function(){var a=1e3;if(!this.$measureNode){var b=this.$measureNode=e.createElement("div"),c=b.style;c.width=c.height="auto",c.left=c.top=-a*40+"px",c.visibility="hidden",c.position="fixed",c.overflow="visible",c.whiteSpace="nowrap",b.innerHTML=f.stringRepeat("Xy",a);if(this.element.ownerDocument.body)this.element.ownerDocument.body.appendChild(b);else{var d=this.element.parentNode;while(!e.hasCssClass(d,"ace_editor"))d=d.parentNode;d.appendChild(b)}}if(!this.element.offsetWidth)return null;var c=this.$measureNode.style,g=e.computedStyle(this.element);for(var h in this.$fontStyles)c[h]=g[h];var i={height:this.$measureNode.offsetHeight,width:this.$measureNode.offsetWidth/(a*2)};return i.width==0||i.height==0?null:i}:function(){if(!this.$measureNode){var a=this.$measureNode=e.createElement("div"),b=a.style;b.width=b.height="auto",b.left=b.top="-100px",b.visibility="hidden",b.position="fixed",b.overflow="visible",b.whiteSpace="nowrap",a.innerHTML="X";var c=this.element.parentNode;while(c&&!e.hasCssClass(c,"ace_editor"))c=c.parentNode;if(!c)return this.$measureNode=null;c.appendChild(a)}var d=this.$measureNode.getBoundingClientRect(),f={height:d.height,width:d.width};return f.width==0||f.height==0?null:f},this.setSession=function(a){this.session=a},this.showInvisibles=!1,this.setShowInvisibles=function(a){return this.showInvisibles==a?!1:(this.showInvisibles=a,!0)},this.$tabStrings=[],this.$computeTabString=function(){var a=this.session.getTabSize(),b=this.$tabStrings=[0];for(var c=1;c"+this.TAB_CHAR+(new Array(c)).join(" ")+""):b.push((new Array(c+1)).join(" "))},this.updateLines=function(a,b,c){this.$computeTabString(),(this.config.lastRow!=a.lastRow||this.config.firstRow!=a.firstRow)&&this.scrollLines(a),this.config=a;var d=Math.max(b,a.firstRow),f=Math.min(c,a.lastRow),g=this.element.childNodes,h=0;for(var i=a.firstRow;i0;d--)c.removeChild(c.firstChild);if(b.lastRow>a.lastRow)for(var d=this.session.getFoldedRowCount(a.lastRow+1,b.lastRow);d>0;d--)c.removeChild(c.lastChild);if(a.firstRowb.lastRow){var e=this.$renderLinesFragment(a,b.lastRow+1,a.lastRow);c.appendChild(e)}},this.$renderLinesFragment=function(a,b,c){var d=this.element.ownerDocument.createDocumentFragment(),f=b,g=this.session.getNextFoldLine(f),h=g?g.start.row:Infinity;for(;;){f>h&&(f=g.end.row+1,g=this.session.getNextFoldLine(f,g),h=g?g.start.row:Infinity);if(f>c)break;var i=e.createElement("div"),j=[],k=this.session.getTokens(f,f);k.length==1&&this.$renderLine(j,f,k[0].tokens,!1),i.innerHTML=j.join("");if(this.$useLineGroups())i.className="ace_line_group",d.appendChild(i);else{var l=i.childNodes;while(l.length)d.appendChild(l[0])}f++}return d},this.update=function(a){this.$computeTabString(),this.config=a;var b=[],c=a.firstRow,d=a.lastRow,f=c,g=this.session.getNextFoldLine(f),h=g?g.start.row:Infinity;for(;;){f>h&&(f=g.end.row+1,g=this.session.getNextFoldLine(f,g),h=g?g.start.row:Infinity);if(f>d)break;this.$useLineGroups()&&b.push("
");var i=this.session.getTokens(f,f);i.length==1&&this.$renderLine(b,f,i[0].tokens,!1),this.$useLineGroups()&&b.push("
"),f++}this.element=e.setInnerHtml(this.element,b.join(""))},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(a,b,c,d){var e=this,f=/\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,g=function(a,c,d,f,g){if(c)return(new Array(a.length+1)).join(" ");if(a=="&")return"&";if(a=="<")return"<";if(a==" "){var h=e.session.getScreenTabSize(b+f);return b+=h-1,e.$tabStrings[h]}if(a==" "){var i=e.showInvisibles?"ace_cjk ace_invisible":"ace_cjk",j=e.showInvisibles?e.SPACE_CHAR:"";return b+=1,""+j+""}return d?""+e.SPACE_CHAR+"":(b+=1,""+a+"")},h=d.replace(f,g);if(!this.$textToken[c.type]){var i="ace_"+c.type.replace(/\./g," ace_"),j="";c.type=="fold"&&(j=" style='width:"+c.value.length*this.config.characterWidth+"px;' "),a.push("",h,"")}else a.push(h);return b+d.length},this.$renderLineCore=function(a,b,c,d,e){var f=0,g=0,h,i=0,j=this;!d||d.length==0?h=Number.MAX_VALUE:h=d[0],e||a.push("
");for(var k=0;k=h)i=j.$renderToken(a,i,l,m.substring(0,h-f)),m=m.substring(h-f),f=h,e||a.push("
","
"),g++,i=0,h=d[g]||Number.MAX_VALUE;m.length!=0&&(f+=m.length,i=j.$renderToken(a,i,l,m))}}this.showInvisibles&&(b!==this.session.getLength()-1?a.push(""+this.EOL_CHAR+""):a.push(""+this.EOF_CHAR+"")),e||a.push("
")},this.$renderLine=function(a,b,c,d){if(!this.session.isRowFolded(b)){var e=this.session.getRowSplitData(b);this.$renderLineCore(a,b,c,e,d)}else this.$renderFoldLine(a,b,c,d)},this.$renderFoldLine=function(a,b,c,d){function h(a,b,c){var d=0,e=0;while(e+a[d].value.lengthc-b&&(f=f.substring(0,c-b)),g.push({type:a[d].type,value:f}),e=b+f.length,d+=1}while(ec&&(f=f.substring(0,c-e)),g.push({type:a[d].type,value:f}),e+=f.length,d+=1}}var e=this.session,f=e.getFoldLine(b),g=[];f.walk(function(a,b,d,e,f){a?g.push({type:"fold",value:a}):(f&&(c=this.session.getTokens(b,b)[0].tokens),c.length!=0&&h(c,e,d))}.bind(this),f.end.row,this.session.getLine(f.end.row).length);var i=this.session.$useWrapMode?this.session.$wrapData[b]:null;this.$renderLineCore(a,b,g,i,d)},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(i.prototype),b.Text=i}),ace.define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(a,b,c){"use strict";var d=a("../lib/dom"),e=function(a){this.element=d.createElement("div"),this.element.className="ace_layer ace_cursor-layer",a.appendChild(this.element),this.isVisible=!1,this.cursors=[],this.cursor=this.addCursor()};(function(){this.$padding=0,this.setPadding=function(a){this.$padding=a},this.setSession=function(a){this.session=a},this.addCursor=function(){var a=d.createElement("div"),b="ace_cursor";return this.isVisible||(b+=" ace_hidden"),this.overwrite&&(b+=" ace_overwrite"),a.className=b,this.element.appendChild(a),this.cursors.push(a),a},this.removeCursor=function(){if(this.cursors.length>1){var a=this.cursors.pop();return a.parentNode.removeChild(a),a}},this.hideCursor=function(){this.isVisible=!1;for(var a=this.cursors.length;a--;)d.addCssClass(this.cursors[a],"ace_hidden");clearInterval(this.blinkId)},this.showCursor=function(){this.isVisible=!0;for(var a=this.cursors.length;a--;)d.removeCssClass(this.cursors[a],"ace_hidden");this.element.style.visibility="",this.restartTimer()},this.restartTimer=function(){clearInterval(this.blinkId);if(!this.isVisible)return;var a=this.cursors.length==1?this.cursor:this.element;this.blinkId=setInterval(function(){a.style.visibility="hidden",setTimeout(function(){a.style.visibility=""},400)},1e3)},this.getPixelPosition=function(a,b){if(!this.config||!this.session)return{left:0,top:0};a||(a=this.session.selection.getCursor());var c=this.session.documentToScreenPosition(a),d=Math.round(this.$padding+c.column*this.config.characterWidth),e=(c.row-(b?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:d,top:e}},this.update=function(a){this.config=a;if(this.session.selectionMarkerCount>0){var b=this.session.$selectionMarkers,c=0,d,e=0;for(var c=b.length;c--;){d=b[c];var f=this.getPixelPosition(d.cursor,!0),g=(this.cursors[e++]||this.addCursor()).style;g.left=f.left+"px",g.top=f.top+"px",g.width=a.characterWidth+"px",g.height=a.lineHeight+"px"}if(e>1)while(this.cursors.length>e)this.removeCursor()}else{var f=this.getPixelPosition(null,!0),g=this.cursor.style;g.left=f.left+"px",g.top=f.top+"px",g.width=a.characterWidth+"px",g.height=a.lineHeight+"px";while(this.cursors.length>1)this.removeCursor()}var h=this.session.getOverwrite();h!=this.overwrite&&this.$setOverite(h),this.$pixelPos=f,this.restartTimer()},this.$setOverite=function(a){this.overwrite=a;for(var b=this.cursors.length;b--;)a?d.addCssClass(this.cursors[b],"ace_overwrite"):d.removeCssClass(this.cursors[b],"ace_overwrite")},this.destroy=function(){clearInterval(this.blinkId)}}).call(e.prototype),b.Cursor=e}),ace.define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("./lib/oop"),e=a("./lib/dom"),f=a("./lib/event"),g=a("./lib/event_emitter").EventEmitter,h=function(a){this.element=e.createElement("div"),this.element.className="ace_sb",this.inner=e.createElement("div"),this.element.appendChild(this.inner),a.appendChild(this.element),this.width=e.scrollbarWidth(a.ownerDocument),this.element.style.width=(this.width||15)+5+"px",f.addListener(this.element,"scroll",this.onScroll.bind(this))};(function(){d.implement(this,g),this.onScroll=function(){this._emit("scroll",{data:this.element.scrollTop})},this.getWidth=function(){return this.width},this.setHeight=function(a){this.element.style.height=a+"px"},this.setInnerHeight=function(a){this.inner.style.height=a+"px"},this.setScrollTop=function(a){this.element.scrollTop=a}}).call(h.prototype),b.ScrollBar=h}),ace.define("ace/renderloop",["require","exports","module","ace/lib/event"],function(a,b,c){"use strict";var d=a("./lib/event"),e=function(a,b){this.onRender=a,this.pending=!1,this.changes=0,this.window=b||window};(function(){this.schedule=function(a){this.changes=this.changes|a;if(!this.pending){this.pending=!0;var b=this;d.nextTick(function(){b.pending=!1;var a;while(a=b.changes)b.changes=0,b.onRender(a)},this.window)}}}).call(e.prototype),b.RenderLoop=e}),ace.define("text!ace/css/editor.css",[],"\n.ace_editor {\n position: absolute;\n overflow: hidden;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Droid Sans Mono', 'Consolas', monospace;\n font-size: 12px;\n}\n\n.ace_scroller {\n position: absolute;\n overflow-x: scroll;\n overflow-y: hidden;\n}\n\n.ace_content {\n position: absolute;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n cursor: text;\n}\n\n.ace_composition {\n position: absolute;\n background: #555;\n color: #DDD;\n z-index: 4;\n}\n\n.ace_gutter {\n position: absolute;\n overflow : hidden;\n height: 100%;\n width: auto;\n cursor: default;\n 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\n.ace_gutter-cell {\n padding-left: 19px;\n padding-right: 6px;\n}\n\n.ace_gutter-cell.ace_error {\n background-image: url(\"data:image/gif,GIF89a%10%00%10%00%D5%00%00%F5or%F5%87%88%F5nr%F4ns%EBmq%F5z%7F%DDJT%DEKS%DFOW%F1Yc%F2ah%CE(7%CE)8%D18E%DD%40M%F2KZ%EBU%60%F4%60m%DCir%C8%16(%C8%19*%CE%255%F1%3FR%F1%3FS%E6%AB%B5%CA%5DI%CEn%5E%F7%A2%9A%C9G%3E%E0a%5B%F7%89%85%F5yy%F6%82%80%ED%82%80%FF%BF%BF%E3%C4%C4%FF%FF%FF%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%25%00%2C%00%00%00%00%10%00%10%00%00%06p%C0%92pH%2C%1A%8F%C8%D2H%93%E1d4%23%E4%88%D3%09mB%1DN%B48%F5%90%40%60%92G%5B%94%20%3E%22%D2%87%24%FA%20%24%C5%06A%00%20%B1%07%02B%A38%89X.v%17%82%11%13q%10%0Fi%24%0F%8B%10%7BD%12%0Ei%09%92%09%0EpD%18%15%24%0A%9Ci%05%0C%18F%18%0B%07%04%01%04%06%A0H%18%12%0D%14%0D%12%A1I%B3%B4%B5IA%00%3B\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_warning {\n background-image: url(\"data:image/gif,GIF89a%10%00%10%00%D5%00%00%FF%DBr%FF%DE%81%FF%E2%8D%FF%E2%8F%FF%E4%96%FF%E3%97%FF%E5%9D%FF%E6%9E%FF%EE%C1%FF%C8Z%FF%CDk%FF%D0s%FF%D4%81%FF%D5%82%FF%D5%83%FF%DC%97%FF%DE%9D%FF%E7%B8%FF%CCl%7BQ%13%80U%15%82W%16%81U%16%89%5B%18%87%5B%18%8C%5E%1A%94d%1D%C5%83-%C9%87%2F%C6%84.%C6%85.%CD%8B2%C9%871%CB%8A3%CD%8B5%DC%98%3F%DF%9BB%E0%9CC%E1%A5U%CB%871%CF%8B5%D1%8D6%DB%97%40%DF%9AB%DD%99B%E3%B0p%E7%CC%AE%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%2F%00%2C%00%00%00%00%10%00%10%00%00%06a%C0%97pH%2C%1A%8FH%A1%ABTr%25%87%2B%04%82%F4%7C%B9X%91%08%CB%99%1C!%26%13%84*iJ9(%15G%CA%84%14%01%1A%97%0C%03%80%3A%9A%3E%81%84%3E%11%08%B1%8B%20%02%12%0F%18%1A%0F%0A%03'F%1C%04%0B%10%16%18%10%0B%05%1CF%1D-%06%07%9A%9A-%1EG%1B%A0%A1%A0U%A4%A5%A6BA%00%3B\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_info {\n background-image: url(\"data:image/gif;base64,R0lGODlhEAAQAMQAAAAAAEFBQVJSUl5eXmRkZGtra39/f4WFhYmJiZGRkaampry8vMPDw8zMzNXV1dzc3OTk5Orq6vDw8P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABQALAAAAAAQABAAAAUuICWOZGmeaBml5XGwFCQSBGyXRSAwtqQIiRuiwIM5BoYVbEFIyGCQoeJGrVptIQA7\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_editor .ace_sb {\n position: absolute;\n overflow-x: hidden;\n overflow-y: scroll;\n right: 0;\n}\n\n.ace_editor .ace_sb div {\n position: absolute;\n width: 1px;\n left: 0;\n}\n\n.ace_editor .ace_print_margin_layer {\n z-index: 0;\n position: absolute;\n overflow: hidden;\n margin: 0;\n left: 0;\n height: 100%;\n width: 100%;\n}\n\n.ace_editor .ace_print_margin {\n position: absolute;\n height: 100%;\n}\n\n.ace_editor textarea {\n position: fixed;\n z-index: 0;\n width: 0.5em;\n height: 1em;\n opacity: 0;\n background: transparent;\n appearance: none;\n -moz-appearance: none;\n border: none;\n resize: none;\n outline: none;\n overflow: hidden;\n}\n\n.ace_layer {\n z-index: 1;\n position: absolute;\n overflow: hidden;\n white-space: nowrap;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n /* setting pointer-events: auto; on node under the mouse, which changes\n during scroll, will break mouse wheel scrolling in Safari */\n pointer-events: none;\n}\n\n.ace_gutter .ace_layer {\n position: relative;\n min-width: 40px;\n text-align: right;\n pointer-events: auto;\n}\n\n.ace_text-layer {\n color: black;\n font: inherit !important;\n}\n\n.ace_cjk {\n display: inline-block;\n text-align: center;\n}\n\n.ace_cursor-layer {\n z-index: 4;\n}\n\n.ace_cursor {\n z-index: 4;\n position: absolute;\n}\n\n.ace_cursor.ace_hidden {\n opacity: 0.2;\n}\n\n.ace_editor.multiselect .ace_cursor {\n border-left-width: 1px;\n}\n\n.ace_line {\n white-space: nowrap;\n}\n\n.ace_marker-layer .ace_step {\n position: absolute;\n z-index: 3;\n}\n\n.ace_marker-layer .ace_selection {\n position: absolute;\n z-index: 5;\n}\n\n.ace_marker-layer .ace_bracket {\n position: absolute;\n z-index: 6;\n}\n\n.ace_marker-layer .ace_active_line {\n position: absolute;\n z-index: 2;\n}\n\n.ace_marker-layer .ace_selected_word {\n position: absolute;\n z-index: 4;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n}\n\n.ace_line .ace_fold {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n \n display: inline-block;\n height: 11px;\n margin-top: -2px;\n vertical-align: middle;\n\n background-image: \n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%3AIDAT8%11c%FC%FF%FF%7F%18%03%1A%60%01%F2%3F%A0%891%80%04%FF%11-%F8%17%9BJ%E2%05%B1ZD%81v%26t%E7%80%F8%A3%82h%A12%1A%20%A3%01%02%0F%01%BA%25%06%00%19%C0%0D%AEF%D5%3ES%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat, repeat-x;\n background-position: center center, top left;\n color: transparent;\n\n border: 1px solid black;\n -moz-border-radius: 2px;\n -webkit-border-radius: 2px;\n border-radius: 2px;\n \n cursor: pointer;\n pointer-events: auto;\n}\n\n.ace_dark .ace_fold {\n}\n\n.ace_fold:hover{\n background-image: \n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%003IDAT8%11c%FC%FF%FF%7F%3E%03%1A%60%01%F2%3F%A3%891%80%04%FFQ%26%F8w%C0%B43%A1%DB%0C%E2%8F%0A%A2%85%CAh%80%8C%06%08%3C%04%E8%96%18%00%A3S%0D%CD%CF%D8%C1%9D%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat, repeat-x;\n background-position: center center, top left;\n}\n\n.ace_dragging .ace_content {\n cursor: move;\n}\n\n.ace_folding-enabled > .ace_gutter-cell {\n padding-right: 13px;\n}\n\n.ace_fold-widget {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n\n margin: 0 -12px 1px 1px;\n display: inline-block;\n height: 14px;\n width: 11px;\n vertical-align: text-bottom;\n \n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAe%8A%B1%0D%000%0C%C2%F2%2CK%96%BC%D0%8F9%81%88H%E9%D0%0E%96%C0%10%92%3E%02%80%5E%82%E4%A9*-%EEsw%C8%CC%11%EE%96w%D8%DC%E9*Eh%0C%151(%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat;\n background-position: center 5px;\n\n border-radius: 3px;\n}\n\n.ace_fold-widget.end {\n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAm%C7%C1%09%000%08C%D1%8C%ECE%C8E(%8E%EC%02)%1EZJ%F1%C1'%04%07I%E1%E5%EE%CAL%F5%A2%99%99%22%E2%D6%1FU%B5%FE0%D9x%A7%26Wz5%0E%D5%00%00%00%00IEND%AEB%60%82\");\n}\n\n.ace_fold-widget.closed {\n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%03%00%00%00%06%08%06%00%00%00%06%E5%24%0C%00%00%009IDATx%DA5%CA%C1%09%000%08%03%C0%AC*(%3E%04%C1%0D%BA%B1%23%A4Uh%E0%20%81%C0%CC%F8%82%81%AA%A2%AArGfr%88%08%11%11%1C%DD%7D%E0%EE%5B%F6%F6%CB%B8%05Q%2F%E9tai%D9%00%00%00%00IEND%AEB%60%82\");\n}\n\n.ace_fold-widget:hover {\n border: 1px solid rgba(0, 0, 0, 0.3);\n background-color: rgba(255, 255, 255, 0.2);\n -moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n -moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n -webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n -webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n background-position: center 4px;\n}\n\n.ace_fold-widget:active {\n border: 1px solid rgba(0, 0, 0, 0.4);\n background-color: rgba(0, 0, 0, 0.05);\n -moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n -moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n -webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n -webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n}\n\n.ace_fold-widget.invalid {\n 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"),ace.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(a,b,c){function k(a,b,c){return j.$options.wrap=!0,j.$options.needle=b,j.$options.backwards=c==-1,j.find(a)}function n(a,b){return a.row==b.row&&a.column==b.column}function o(a){a.$onAddRange=a.$onAddRange.bind(a),a.$onRemoveRange=a.$onRemoveRange.bind(a),a.$onMultiSelect=a.$onMultiSelect.bind(a),a.$onSingleSelect=a.$onSingleSelect.bind(a),b.onSessionChange.call(a,a),a.on("changeSession",b.onSessionChange.bind(a)),a.on("mousedown",g),a.commands.addCommands(b.commands.defaultCommands),p(a)}function p(a){function e(){c&&(d.style.cursor="",c=!1)}var b=a.textInput.getElement(),c=!1,d=a.renderer.content;h.addListener(b,"keydown",function(a){a.keyCode==18&&!(a.ctrlKey||a.shiftKey||a.metaKey)?c||(d.style.cursor="crosshair",c=!0):c&&(d.style.cursor="")}),h.addListener(b,"keyup",e),h.addListener(b,"blur",e)}var d=a("./range_list").RangeList,e=a("./range").Range,f=a("./selection").Selection,g=a("./mouse/multi_select_handler").onMouseDown,h=a("./lib/event");b.commands=a("./commands/multi_select_commands");var i=a("./search").Search,j=new i,l=a("./edit_session").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(l.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(a,b){if(!a)return;if(!this.inMultiSelectMode&&this.rangeCount==0){var c=this.toOrientedRange();if(a.intersects(c))return b||this.fromOrientedRange(a);this.rangeList.add(c),this.$onAddRange(c)}a.cursor||(a.cursor=a.end);var d=this.rangeList.add(a);return this.$onAddRange(a),d.length&&this.$onRemoveRange(d),this.rangeCount>1&&!this.inMultiSelectMode&&(this._emit("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),b||this.fromOrientedRange(a)},this.toSingleRange=function(a){a=a||this.ranges[0];var b=this.rangeList.removeAll();b.length&&this.$onRemoveRange(b),a&&this.fromOrientedRange(a)},this.substractPoint=function(a){var b=this.rangeList.substractPoint(a);if(b)return this.$onRemoveRange(b),b[0]},this.mergeOverlappingRanges=function(){var a=this.rangeList.merge();a.length?this.$onRemoveRange(a):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(a){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(a),this._emit("addRange",{range:a})},this.$onRemoveRange=function(a){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var b=this.rangeList.ranges.pop();a.push(b),this.rangeCount=0}for(var c=a.length;c--;){var d=this.ranges.indexOf(a[c]);this.ranges.splice(d,1)}this._emit("removeRange",{ranges:a}),this.rangeCount==0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._emit("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),b=b||this.ranges[0],b&&!b.isEqual(this.getRange())&&this.fromOrientedRange(b)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new d,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeList.ranges.concat()},this.splitIntoLines=function(){if(this.rangeCount>1){var a=this.rangeList.ranges,b=a[a.length-1],c=e.fromPoints(a[0].start,b.end);this.toSingleRange(),this.setSelectionRange(c,b.cursor==b.start)}else{var c=this.getRange(),d=c.start.row,f=c.end.row;if(d==f)return;var g=[],h=this.getLineRange(d,!0);h.start.column=c.start.column,g.push(h);for(var i=d+1;i1){var a=this.rangeList.ranges,b=a[a.length-1],c=e.fromPoints(a[0].start,b.end);this.toSingleRange(),this.setSelectionRange(c,b.cursor==b.start)}else{var d=this.session.documentToScreenPosition(this.selectionLead),f=this.session.documentToScreenPosition(this.selectionAnchor),g=this.rectangularRangeBlock(d,f);g.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(a,b,c){var d=[],f=a.column0)p--;if(p>0){var q=0;while(d[q].isEmpty())q++}for(var r=p;r>=q;r--)d[r].isEmpty()&&d.splice(r,1)}return d}}.call(f.prototype);var m=a("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(a){a.cursor||(a.cursor=a.end);var b=this.getSelectionStyle();return a.marker=this.session.addMarker(a,"ace_selection",b),this.session.$selectionMarkers.push(a),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,a},this.removeSelectionMarker=function(a){if(!a.marker)return;this.session.removeMarker(a.marker);var b=this.session.$selectionMarkers.indexOf(a);b!=-1&&this.session.$selectionMarkers.splice(b,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(a){var b=this.session.$selectionMarkers;for(var c=a.length;c--;){var d=a[c];if(!d.marker)continue;this.session.removeMarker(d.marker);var e=b.indexOf(d);e!=-1&&b.splice(e,1)}this.session.selectionMarkerCount=b.length},this.$onAddRange=function(a){this.addSelectionMarker(a.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(a){this.removeSelectionMarkers(a.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(a){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("multiselect"),this.keyBinding.addKeyboardHandler(b.commands.keyboardHandler),this.commands.on("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(a){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("multiselect"),this.keyBinding.removeKeyboardHandler(b.commands.keyboardHandler),this.commands.removeEventListener("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelectExec=function(a){var b=a.command,c=a.editor;b.multiSelectAction?b.multiSelectAction=="forEach"?c.forEachSelection(b,a.args):b.multiSelectAction=="single"?(c.exitMultiSelectMode(),b.exec(c,a.args||{})):b.multiSelectAction(c,a.args||{}):(b.exec(c,a.args||{}),c.multiSelect.addRange(c.multiSelect.toOrientedRange()),c.multiSelect.mergeOverlappingRanges()),a.preventDefault()},this.forEachSelection=function(a,b){if(this.inVirtualSelectionMode)return;var c=this.session,d=this.selection,e=d.rangeList,g=d._eventRegistry;d._eventRegistry={};var h=new f(c);this.inVirtualSelectionMode=!0;for(var i=e.ranges.length;i--;)h.fromOrientedRange(e.ranges[i]),this.selection=c.selection=h,a.exec(this,b||{}),h.toOrientedRange(e.ranges[i]);h.detach(),this.selection=c.selection=d,this.inVirtualSelectionMode=!1,d._eventRegistry=g,d.mergeOverlappingRanges(),this.onCursorChange(),this.onSelectionChange()},this.exitMultiSelectMode=function(){if(this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getCopyText=function(){var a="";if(this.inMultiSelectMode){var b=this.multiSelect.rangeList.ranges;a=[];for(var c=0;cc.length){this.commands.exec("insertstring",this,a);return}for(var d=c.length;d--;){var e=c[d];e.isEmpty()||this.session.remove(e),this.session.insert(e.start,b[d])}},this.findAll=function(a,b,c){b=b||{},b.needle=a||b.needle,this.$search.set(b);var d=this.$search.findAll(this.session);if(!d.length)return 0;this.$blockScrolling+=1;var e=this.multiSelect;c||e.toSingleRange(d[0]);for(var f=d.length;f--;)e.addRange(d[f],!0);return this.$blockScrolling-=1,d.length},this.selectMoreLines=function(a,b){var c=this.selection.toOrientedRange(),d=c.cursor==c.end,f=this.session.documentToScreenPosition(c.cursor);this.selection.$desiredColumn&&(f.column=this.selection.$desiredColumn);var g=this.session.screenToDocumentPosition(f.row+a,f.column);if(!c.isEmpty())var h=this.session.documentToScreenPosition(d?c.end:c.start),i=this.session.screenToDocumentPosition(h.row+a,h.column);else var i=g;if(d){var j=e.fromPoints(g,i);j.cursor=j.start}else{var j=e.fromPoints(i,g);j.cursor=j.end}j.desiredColumn=f.column;if(!this.selection.inMultiSelectMode)this.selection.addRange(c);else if(b)var k=c.cursor;this.selection.addRange(j),k&&this.selection.substractPoint(k)},this.transposeSelections=function(a){var b=this.session,c=b.multiSelect,d=c.ranges;for(var e=d.length;e--;){var f=d[e];if(f.isEmpty()){var g=b.getWordRange(f.start.row,f.start.column);f.start.row=g.start.row,f.start.column=g.start.column,f.end.row=g.end.row,f.end.column=g.end.column}}c.mergeOverlappingRanges();var h=[];for(var e=d.length;e--;){var f=d[e];h.unshift(b.getTextRange(f))}a<0?h.unshift(h.pop()):h.push(h.shift());for(var e=d.length;e--;){var f=d[e],g=f.clone();b.replace(f,h[e]),f.start.row=g.start.row,f.start.column=g.start.column}},this.selectMore=function(a,b){var c=this.session,d=c.multiSelect,e=d.toOrientedRange();if(e.isEmpty()){var e=c.getWordRange(e.start.row,e.start.column);e.cursor=e.end,this.multiSelect.addRange(e)}var f=c.getTextRange(e),g=k(c,f,a);g&&(g.cursor=a==-1?g.start:g.end,this.multiSelect.addRange(g)),b&&this.multiSelect.substractPoint(e.cursor)}}).call(m.prototype),b.onSessionChange=function(a){var b=a.session;b.multiSelect||(b.$selectionMarkers=[],b.selection.$initRangeList(),b.multiSelect=b.selection),this.multiSelect=b.multiSelect;var c=a.oldSession;c&&(c.multiSelect&&c.multiSelect.editor==this&&(c.multiSelect.editor=null),b.multiSelect.removeEventListener("addRange",this.$onAddRange),b.multiSelect.removeEventListener("removeRange",this.$onRemoveRange),b.multiSelect.removeEventListener("multiSelect",this.$onMultiSelect),b.multiSelect.removeEventListener("singleSelect",this.$onSingleSelect)),b.multiSelect.on("addRange",this.$onAddRange),b.multiSelect.on("removeRange",this.$onRemoveRange),b.multiSelect.on("multiSelect",this.$onMultiSelect),b.multiSelect.on("singleSelect",this.$onSingleSelect),this.inMultiSelectMode!=b.selection.inMultiSelectMode&&(b.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},b.MultiSelect=o}),ace.define("ace/range_list",["require","exports","module"],function(a,b,c){"use strict";var d=function(){this.ranges=[]};(function(){this.comparePoints=function(a,b){return a.row-b.row||a.column-b.column},this.pointIndex=function(a,b){var c=this.ranges;for(var d=b||0;d0)continue;return f==0?d:(f=this.comparePoints(a,e.start),f>=0?d:-d-1)}return-d-1},this.add=function(a){var b=this.pointIndex(a.start);b<0&&(b=-b-1);var c=this.pointIndex(a.end,b);return c<0?c=-c-1:c++,this.ranges.splice(b,c-b,a)},this.addList=function(a){var b=[];for(var c=a.length;c--;)b.push.call(b,this.add(a[c]));return b},this.substractPoint=function(a){var b=this.pointIndex(a);if(b>=0)return this.ranges.splice(b,1)},this.merge=function(){var a=[],b=this.ranges,c=b[0],d;for(var e=1;e=0},this.containsPoint=function(a){return this.pointIndex(a)>=0},this.rangeAtPoint=function(a){var b=this.pointIndex(a);if(b>=0)return this.ranges[b]},this.clipRows=function(a,b){var c=this.ranges;if(c[0].start.row>b||c[c.length-1].start.rowe)break;l.start.row==e&&l.start.column>=c.column&&(l.start.column+=h,l.start.row+=g),l.end.row==e&&l.end.column>=c.column&&(l.end.column+=h,l.end.row+=g)}if(g!=0&&j=0?g=a.nameToUrl("ace/worker/worker_sourcemint"):g=this.$normalizePath(a.nameToUrl("ace/worker/worker",null,"_")),this.$worker=new Worker(g);var h={};for(var i=0;i=this.pos.column&&c.start.column<=this.pos.column+this.length+1){var f=c.start.column-this.pos.column;this.length+=e;if(!this.session.$fromUndo){if(b.action==="insertText")for(var g=this.others.length-1;g>=0;g--){var h=this.others[g],i={row:h.row,column:h.column+f};h.row===c.start.row&&c.start.column=0;g--){var h=this.others[g],i={row:h.row,column:h.column+f};h.row===c.start.row&&c.start.column=this.pos.column&&b.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",a)):(this.hideOtherMarkers(),this._emit("cursorLeave",a))},this.detach=function(){this.session.removeMarker(this.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.pos.detach();for(var a=0;a Editor + * - el (String | DOMElement): Either the id of an element, or the element itself + * + * This method embeds the Ace editor into the DOM, at the element provided by `el`. + * + **/ exports.edit = function(el) { if (typeof(el) == "string") { el = document.getElementById(el); @@ -289,7 +304,8 @@ exports.edit = function(el) { return editor; }; -});// vim:set ts=4 sts=4 sw=4 st: +}); +// vim:set ts=4 sts=4 sw=4 st: // -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project) // -- dantman Daniel Friesen Copyright(C) 2010 XXX No License Specified @@ -307,7 +323,8 @@ ace.define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/ require("./regexp"); require("./es5-shim"); -});/** +}); +/* * Based on code from: * * XRegExp 1.5.0 @@ -445,7 +462,7 @@ ace.define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require ace.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. * @@ -1475,7 +1492,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 * @@ -1540,7 +1558,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) { @@ -1549,7 +1567,7 @@ exports.addCssClass = function(el, name) { } }; -/** +/* * Remove a CSS class from the list of classes on the given node */ exports.removeCssClass = function(el, name) { @@ -1581,7 +1599,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 */ @@ -1732,7 +1750,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. * @@ -1766,7 +1784,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 @@ -1832,7 +1851,7 @@ exports.removeListener = function(elem, type, callback) { } }; -/** +/* * Prevents propagation and clobbers the default action of the passed event */ exports.stopEvent = function(e) { @@ -1855,23 +1874,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) { @@ -2128,7 +2131,7 @@ ace.define('ace/lib/keys', ['require', 'exports', 'module' , 'ace/lib/oop'], fun var oop = require("./oop"); -/** +/* * Helper functions and hashes for key handling. */ var Keys = (function() { @@ -2218,7 +2221,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 @@ -2322,13 +2326,13 @@ ace.define('ace/lib/useragent', ['require', 'exports', 'module' ], function(requ 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 = @@ -2337,16 +2341,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; @@ -2357,7 +2361,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. * @@ -2370,7 +2374,7 @@ exports.OS = { WINDOWS: "WINDOWS" }; -/** +/* * Return an exports.OS constant */ exports.getOS = function() { @@ -2444,12 +2448,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 @@ -2465,7 +2486,6 @@ var Editor = function(renderer, session) { wrap: true }); - this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands); this.setSession(session || new EditSession("")); }; @@ -2473,14 +2493,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; @@ -2580,39 +2616,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); @@ -2637,6 +2718,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 @@ -2648,26 +2734,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; @@ -2682,51 +2799,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; @@ -2737,11 +2873,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(); @@ -2762,34 +2903,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. @@ -2798,6 +2979,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()) @@ -2807,10 +2993,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(); @@ -2903,46 +3119,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; @@ -2951,23 +3224,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; @@ -2979,6 +3289,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; }; @@ -2991,6 +3306,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; @@ -2998,44 +3319,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) @@ -3046,13 +3424,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(); @@ -3071,6 +3469,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(); @@ -3079,6 +3482,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(); @@ -3087,6 +3495,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(); @@ -3095,6 +3508,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(); @@ -3109,6 +3527,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()); @@ -3120,6 +3543,11 @@ var Editor = function(renderer, session) { this.moveCursorToPosition(cursor); }; + /** + * Editor.transposeLetters() + * + * Transposes current line. + **/ this.transposeLetters = function() { if (!this.selection.isEmpty()) { return; @@ -3143,6 +3571,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()) { @@ -3155,6 +3588,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()) { @@ -3167,6 +3605,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(); @@ -3190,17 +3633,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; @@ -3215,18 +3673,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; @@ -3234,6 +3721,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); @@ -3241,6 +3736,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); @@ -3248,6 +3752,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; @@ -3271,6 +3782,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(); @@ -3280,141 +3799,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); @@ -3433,34 +4089,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; @@ -3475,6 +4167,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; @@ -3489,36 +4187,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); @@ -3539,6 +4278,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); @@ -3578,35 +4324,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())}); @@ -3615,35 +4384,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(); }; @@ -3756,7 +4536,7 @@ exports.arrayToMap = function(arr) { }; -/** +/* * splice out of 'array' anything that === 'value' */ exports.arrayRemove = function(array, value) { @@ -3854,7 +4634,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); @@ -3877,13 +4659,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 @@ -3904,7 +4691,7 @@ var TextInput = function(parentNode, host) { var onTextInput = function(e) { setTimeout(function () { if (!inCompostion) - sendText(e.data); + sendText(e.data); }, 0); }; @@ -3960,6 +4747,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) { @@ -4130,10 +4918,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); @@ -4150,7 +4938,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")); @@ -4172,7 +4960,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; @@ -4196,10 +4984,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; @@ -4228,6 +5054,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 @@ -4243,240 +5070,290 @@ exports.MouseHandler = MouseHandler; * * ***** END LICENSE BLOCK ***** */ -ace.define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/dom', 'ace/lib/browser_focus'], function(require, exports, module) { +ace.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; @@ -4533,7 +5410,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. @@ -4668,7 +5545,7 @@ EventEmitter._dispatchEvent = function(eventName, e) { } if (defaultHandler && !e.defaultPrevented) - defaultHandler(e); + return defaultHandler(e); }; EventEmitter.setDefaultHandler = function(eventName, callback) { @@ -4711,7 +5588,8 @@ EventEmitter.removeAllListeners = function(eventName) { exports.EventEmitter = EventEmitter; -});/* 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 * @@ -4752,19 +5630,31 @@ exports.EventEmitter = EventEmitter; ace.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 * @@ -4807,18 +5697,15 @@ ace.define('ace/mouse/mouse_event', ['require', 'exports', 'module' , 'ace/lib/e 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; @@ -4844,7 +5731,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 @@ -4852,14 +5739,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 @@ -4885,7 +5770,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 @@ -4894,7 +5779,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() { @@ -4978,7 +5863,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 @@ -5027,15 +5913,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) { @@ -5073,7 +5971,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; @@ -5083,20 +5981,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); @@ -5419,7 +6311,7 @@ exports.commands = [{ multiSelectAction: "forEach" }, { name: "togglecomment", - bindKey: bindKey("Ctrl-7", "Command-7"), + bindKey: bindKey("Ctrl-/", "Command-/"), exec: function(editor) { editor.toggleCommentLines(); }, multiSelectAction: "forEach" }, { @@ -5600,6 +6492,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 = []; @@ -5625,10 +6533,7 @@ var EditSession = function(text, mode) { } this.selection = new Selection(this); - if (mode) - this.setMode(mode); - else - this.setMode(new TextMode()); + this.setMode(mode); }; @@ -5636,6 +6541,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"); @@ -5650,10 +6562,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 = []; @@ -5668,11 +6593,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; @@ -5696,6 +6632,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); @@ -5708,23 +6651,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; @@ -5746,6 +6728,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); @@ -5758,6 +6746,11 @@ var EditSession = function(text, mode) { if (undoManager) { var self = this; + /** internal, hide + * EditSession.$syncInformUndoManager() + * + * + **/ this.$syncInformUndoManager = function() { self.$informUndoManager.cancel(); @@ -5797,10 +6790,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()); @@ -5810,17 +6813,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; @@ -5829,15 +6851,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; @@ -5845,18 +6885,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++; @@ -5906,6 +6991,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) @@ -5918,11 +7010,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, @@ -5931,6 +7030,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) { @@ -5962,6 +7084,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); @@ -5993,7 +7123,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); @@ -6004,15 +7140,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; @@ -6024,10 +7179,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); @@ -6038,7 +7203,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 { @@ -6046,16 +7211,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] @@ -6066,33 +7232,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(); @@ -6127,6 +7308,11 @@ var EditSession = function(text, mode) { this._emit("changeMode"); }; + /** internal, hide + * EditSession.stopWorker() + * + * + **/ this.$stopWorker = function() { if (this.$worker) this.$worker.terminate(); @@ -6134,6 +7320,11 @@ var EditSession = function(text, mode) { this.$worker = null; }; + /** internal, hide + * EditSession.$startWorker() + * + * + **/ this.$startWorker = function() { if (typeof Worker !== "undefined" && !require.noWorker) { try { @@ -6148,11 +7339,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) @@ -6162,11 +7364,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) @@ -6176,15 +7388,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; @@ -6229,33 +7456,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; @@ -6282,6 +7558,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; @@ -6304,10 +7587,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 = @@ -6362,19 +7656,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); @@ -6405,12 +7716,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); @@ -6435,6 +7764,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; @@ -6443,6 +7782,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; @@ -6451,6 +7799,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); @@ -6462,6 +7821,7 @@ var EditSession = function(text, mode) { return addedRows; }; + this.$clipRowToDocument = function(row) { return Math.max(0, Math.min(row, this.doc.getLength()-1)); }; @@ -6472,6 +7832,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); @@ -6504,7 +7865,7 @@ var EditSession = function(text, mode) { range.start.column ); } - + var len = this.doc.getLength() - 1; if (range.end.row > len) { range.end.row = len; @@ -6526,6 +7887,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; @@ -6546,6 +7913,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; }; @@ -6554,6 +7926,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; @@ -6564,8 +7943,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) { @@ -6581,6 +7964,11 @@ var EditSession = function(text, mode) { return false; }; + /** internal, hide + * EditSession.$constrainWrapLimit(wrapLimit) + * + * + **/ this.$constrainWrapLimit = function(wrapLimit) { var min = this.$wrapLimitRange.min; if (min) @@ -6594,10 +7982,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 { @@ -6606,6 +8007,11 @@ var EditSession = function(text, mode) { }; }; + /** internal, hide + * EditSession.$updateInternalDataOnChange() + * + * + **/ this.$updateInternalDataOnChange = function(e) { var useWrapMode = this.$useWrapMode; var len; @@ -6721,6 +8127,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(); @@ -6780,6 +8191,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 []; @@ -6896,11 +8312,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; @@ -6932,15 +8350,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]; @@ -6973,8 +8395,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; @@ -6984,27 +8410,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; @@ -7014,20 +8465,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 { @@ -7123,6 +8597,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") @@ -7226,14 +8711,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; @@ -7439,7 +8939,8 @@ function deHyphenate(str) { return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); }); } -});/** +}); +/* * based on code from: * * @license RequireJS text 0.25.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. @@ -7500,7 +9001,8 @@ exports.loadScript = function(path, callback) { s.onload = callback; }; -});/* ***** 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 @@ -7547,22 +9049,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"); @@ -7580,13 +9090,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; @@ -7595,12 +9115,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; @@ -7608,20 +9140,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; }; @@ -7640,15 +9190,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); @@ -7661,6 +9221,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; @@ -7668,12 +9233,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); @@ -7686,80 +9264,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); @@ -7769,22 +9428,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)) { @@ -7804,20 +9487,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 @@ -7825,9 +9513,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. @@ -7853,8 +9546,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( @@ -7863,19 +9561,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); @@ -7889,14 +9602,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); @@ -7905,7 +9618,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; @@ -7915,9 +9628,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; @@ -7930,19 +9648,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); @@ -7961,10 +9679,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) { @@ -7980,10 +9791,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); @@ -7993,13 +9818,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); @@ -8007,8 +9840,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; } @@ -8077,6 +9910,23 @@ exports.Selection = Selection; ace.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, @@ -8090,6 +9940,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 && @@ -8097,28 +9954,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, @@ -8148,27 +10028,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; @@ -8179,6 +10118,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; @@ -8189,6 +10136,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)) { @@ -8200,6 +10155,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)) { @@ -8211,6 +10174,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)) { @@ -8222,6 +10193,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) { @@ -8245,8 +10237,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; @@ -8256,8 +10268,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; @@ -8266,6 +10296,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; @@ -8276,6 +10321,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 = { @@ -8307,6 +10360,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); @@ -8320,33 +10381,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) @@ -8354,6 +10418,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); @@ -8368,7 +10438,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); }; @@ -8636,6 +10713,21 @@ exports.Mode = Mode; ace.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; @@ -8681,6 +10773,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]; @@ -8977,7 +11074,8 @@ var Behaviour = function() { }).call(Behaviour.prototype); exports.Behaviour = Behaviour; -});ace.define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) { +}); +ace.define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) { "use strict"; /* @@ -9083,7 +11181,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 @@ -9128,6 +11227,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 = []; @@ -9147,20 +11261,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) { @@ -9172,6 +11314,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) { @@ -9181,6 +11328,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": @@ -9196,6 +11354,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; @@ -9203,51 +11367,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) { @@ -9257,6 +11462,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; @@ -9280,6 +11494,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}; @@ -9298,6 +11525,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] || ""; @@ -9320,6 +11558,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; @@ -9344,6 +11595,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); @@ -9376,6 +11636,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; @@ -9396,12 +11667,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); @@ -9416,6 +11690,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); @@ -9433,6 +11714,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; @@ -9453,6 +11746,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]; @@ -9534,9 +11837,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; @@ -9553,14 +11869,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; @@ -9626,6 +11964,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) { @@ -9654,10 +12002,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 = {}; @@ -9726,6 +12090,23 @@ ace.define('ace/background_tokenizer', ['require', 'exports', 'module' , 'ace/li 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 = []; @@ -9767,6 +12148,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 = []; @@ -9774,6 +12163,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 = []; @@ -9781,6 +12178,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, @@ -9789,6 +12195,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()); @@ -9801,20 +12215,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':[]}]; @@ -9906,7 +12354,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 @@ -9930,7 +12378,7 @@ function Folding() { } }; - /** + /* * Returns all folds in the given range. Note, that this will return folds * */ @@ -9976,7 +12424,7 @@ function Folding() { return foundFolds; }; - /** + /* * Returns all folds in the document */ this.getAllFolds = function() { @@ -9999,7 +12447,7 @@ function Folding() { return folds; }; - /** + /* * Returns the string between folds at the given position. * E.g. * foob|arwolrd -> "bar" @@ -10118,7 +12566,7 @@ function Folding() { return foldLine; }; - /** + /* * Adds a new fold. * * @returns @@ -10318,7 +12766,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. **/ @@ -10658,7 +13106,7 @@ ace.define('ace/edit_session/fold_line', ['require', 'exports', 'module' , 'ace/ var Range = require("../range").Range; -/** +/* * If an array is passed in, the folds are expected to be sorted already. */ function FoldLine(foldData, folds) { @@ -10681,7 +13129,7 @@ function FoldLine(foldData, folds) { } (function() { - /** + /* * Note: This doesn't update wrapData! */ this.shiftRow = function(shift) { @@ -10794,7 +13242,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); @@ -10888,7 +13338,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 * @@ -10929,7 +13380,7 @@ exports.FoldLine = FoldLine; ace.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) { @@ -11003,7 +13454,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 * @@ -11044,6 +13496,22 @@ var Fold = exports.Fold = function(range, placeholder) { ace.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; @@ -11054,7 +13522,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; @@ -11071,7 +13545,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; @@ -11089,15 +13568,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; @@ -11163,8 +13660,34 @@ ace.define('ace/edit_session/bracket_match', ['require', 'exports', 'module' , ' 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; @@ -11347,6 +13870,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: "", @@ -11364,15 +13909,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; @@ -11392,6 +13957,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) @@ -11418,6 +13990,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); @@ -11432,6 +14016,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; @@ -11466,6 +14057,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; @@ -11651,6 +14249,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 = {}; @@ -11659,7 +14275,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 || {}); }); }; @@ -11679,8 +14295,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() { @@ -11822,6 +14448,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]; @@ -11844,18 +14482,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]); @@ -11871,10 +14497,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]]) @@ -11887,17 +14513,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 { @@ -11951,12 +14572,33 @@ exports.HashHandler = HashHandler; ace.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]; @@ -11964,6 +14606,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; @@ -11975,6 +14623,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; @@ -11986,15 +14640,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; }; @@ -12063,6 +14732,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; @@ -12071,6 +14756,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"); @@ -12088,8 +14776,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); @@ -12105,14 +14795,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; @@ -12123,12 +14814,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 = { @@ -12193,19 +14881,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; @@ -12228,26 +14929,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; @@ -12282,53 +14995,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; @@ -12337,6 +15116,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; @@ -12357,56 +15174,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); @@ -12417,10 +15276,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; @@ -12468,6 +15338,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; } @@ -12484,6 +15356,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; } @@ -12503,8 +15377,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); @@ -12581,7 +15458,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"; @@ -12627,55 +15504,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; @@ -12686,10 +15619,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); } @@ -12699,75 +15634,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 @@ -12777,6 +15765,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; @@ -12786,11 +15781,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; @@ -12799,32 +15808,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); @@ -12838,14 +15853,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"); @@ -12864,10 +15894,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(); @@ -12888,6 +15929,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; @@ -12942,6 +15989,11 @@ var VirtualRenderer = function(container, theme) { } }; + /** + * VirtualRenderer.getTheme() -> String + * + * [Returns the path of the current theme.]{: #VirtualRenderer.getTheme} + **/ this.getTheme = function() { return this.$themeValue; }; @@ -12950,14 +16002,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(); @@ -13267,9 +16336,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; @@ -13293,9 +16360,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; @@ -13342,9 +16407,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; @@ -13765,21 +16828,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"; @@ -13788,13 +16848,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) { @@ -14322,6 +17427,19 @@ ace.define('ace/renderloop', ['require', 'exports', 'module' , 'ace/lib/event'], 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; @@ -14331,6 +17449,12 @@ var RenderLoop = function(onRender, win) { (function() { + /** internal, hide + * RenderLoop.schedule(change) + * - change (Array): + * + * + **/ this.schedule = function(change) { //this.onRender(change); //return; @@ -14353,8 +17477,7 @@ var RenderLoop = function(onRender, win) { exports.RenderLoop = RenderLoop; }); -ace.define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono);\n" + - "\n" + +ace.define("text!ace/css/editor.css", [], "\n" + ".ace_editor {\n" + " position: absolute;\n" + " overflow: hidden;\n" + @@ -14392,6 +17515,12 @@ ace.define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/cs " 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" + @@ -14450,8 +17579,8 @@ ace.define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/cs ".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" + @@ -14486,6 +17615,7 @@ ace.define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/cs "\n" + ".ace_text-layer {\n" + " color: black;\n" + + " font: inherit !important;\n" + "}\n" + "\n" + ".ace_cjk {\n" + @@ -14534,10 +17664,6 @@ ace.define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/cs " 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" + @@ -14644,6 +17770,28 @@ ace.define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/cs " 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: @@ -14684,12 +17832,13 @@ ace.define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/cs * * ***** END LICENSE BLOCK ***** */ -ace.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) { +ace.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 @@ -14719,10 +17868,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) @@ -14766,11 +17917,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); @@ -14780,10 +17931,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(); @@ -14841,6 +17992,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]; @@ -14857,11 +18039,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 = []; @@ -14931,21 +18116,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) @@ -14959,11 +18145,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) @@ -14994,13 +18180,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; @@ -15013,7 +18199,7 @@ var Editor = require("./editor").Editor; this.renderer.updateCursor(); this.renderer.updateBackMarkers(); }; - + this.$onSingleSelect = function(e) { if (this.session.multiSelect.inVirtualMode) return; @@ -15045,12 +18231,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) @@ -15081,11 +18267,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) @@ -15109,14 +18295,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 || {}; @@ -15129,10 +18336,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); @@ -15142,12 +18349,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(); @@ -15187,12 +18394,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; @@ -15210,7 +18416,7 @@ var Editor = require("./editor").Editor; } } sel.mergeOverlappingRanges(); - + var words = []; for (var i = all.length; i--; ) { var range = all[i]; @@ -15231,13 +18437,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; @@ -15304,12 +18509,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); @@ -15321,7 +18523,7 @@ function MultiSelect(editor) { editor.on("mousedown", onMouseDown); editor.commands.addCommands(exports.commands.defaultCommands); - + addAltCursorListeners(editor); } @@ -15329,7 +18531,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"; @@ -15339,9 +18541,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 = ""; @@ -15352,7 +18554,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 @@ -15661,10 +18864,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() { @@ -15749,7 +18952,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 * @@ -15835,20 +19039,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); -});/* ***** 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 @@ -15900,7 +19106,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 = {}; @@ -16063,7 +19276,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. @@ -16214,7 +19427,7 @@ StateHandler.prototype = { } }, - /** + /* * This function is called by keyBinding. */ handleKeyboard: function(data, hashId, key, keyCode, e) { @@ -16240,7 +19453,7 @@ StateHandler.prototype = { } } -/** +/* * This is a useful matching function and therefore is defined here so that * users of KeyboardStateMapper can use it. * @@ -16312,6 +19525,26 @@ var Range = require('./range').Range; var EventEmitter = require("./lib/event_emitter").EventEmitter; var oop = require("./lib/oop"); +/** + * class PlaceHolder + * + * TODO + * + **/ + +/** + * new PlaceHolder(session, length, pos, others, mainClass, othersClass) + * - session (Document): The document to associate with the anchor + * - length (Number): The starting row position + * - pos (Number): The starting column position + * - others (String): + * - mainClass (String): + * - othersClass (String): + * + * TODO + * + **/ + var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) { var _self = this; this.length = length; @@ -16342,6 +19575,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) oop.implement(this, EventEmitter); + /** + * PlaceHolder.setup() + * + * TODO + * + **/ this.setup = function() { var _self = this; var doc = this.doc; @@ -16362,6 +19601,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) session.setUndoSelect(false); }; + /** + * PlaceHolder.showOtherMarkers() + * + * TODO + * + **/ this.showOtherMarkers = function() { if(this.othersActive) return; var session = this.session; @@ -16376,6 +19621,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) }); }; + /** + * PlaceHolder.hideOtherMarkers() + * + * Hides all over markers in the [[EditSession `EditSession`]] that are not the currently selected one. + * + **/ this.hideOtherMarkers = function() { if(!this.othersActive) return; this.othersActive = false; @@ -16384,6 +19635,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) } }; + /** + * PlaceHolder@onUpdate(e) + * + * Emitted when the place holder updates. + * + **/ this.onUpdate = function(event) { var delta = event.data; var range = delta.range; @@ -16446,6 +19703,13 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.$updating = false; }; + /** + * PlaceHolder@onCursorChange(e) + * + * Emitted when the cursor changes. + * + **/ + this.onCursorChange = function(event) { if (this.$updating) return; var pos = this.session.selection.getCursor(); @@ -16458,6 +19722,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) } }; + /** + * PlaceHolder.detach() + * + * TODO + * + **/ this.detach = function() { this.session.removeMarker(this.markerId); this.hideOtherMarkers(); @@ -16470,6 +19740,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.session.setUndoSelect(true); }; + /** + * PlaceHolder.cancel() + * + * TODO + * + **/ this.cancel = function() { if(this.$undoStackDepth === -1) throw Error("Canceling placeholders only supported with undo manager attached to session."); @@ -16587,8 +19863,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 {\ @@ -16675,6 +19951,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);\ diff --git a/build/src/ace-uncompressed.js b/build/src/ace-uncompressed.js index 72729cd2..0487834d 100644 --- a/build/src/ace-uncompressed.js +++ b/build/src/ace-uncompressed.js @@ -241,6 +241,14 @@ exportAce(ACE_NAMESPACE); * * ***** END LICENSE BLOCK ***** */ +/** + * class Ace + * + * The main class required to set up an Ace instance in the browser. + * + * + **/ + define('ace/ace', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/dom', 'ace/lib/event', 'ace/editor', 'ace/edit_session', 'ace/undomanager', 'ace/virtual_renderer', 'ace/multi_select', 'ace/worker/worker_client', 'ace/keyboard/hash_handler', 'ace/keyboard/state_handler', 'ace/placeholder', 'ace/config', 'ace/theme/textmate'], function(require, exports, module) { "use strict"; @@ -262,6 +270,13 @@ require("./keyboard/state_handler"); require("./placeholder"); require("./config").init(); + /** + * Ace.edit(el) -> Editor + * - el (String | DOMElement): Either the id of an element, or the element itself + * + * This method embeds the Ace editor into the DOM, at the element provided by `el`. + * + **/ exports.edit = function(el) { if (typeof(el) == "string") { el = document.getElementById(el); @@ -289,7 +304,8 @@ exports.edit = function(el) { return editor; }; -});// vim:set ts=4 sts=4 sw=4 st: +}); +// vim:set ts=4 sts=4 sw=4 st: // -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project) // -- dantman Daniel Friesen Copyright(C) 2010 XXX No License Specified @@ -307,7 +323,8 @@ define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/rege require("./regexp"); require("./es5-shim"); -});/** +}); +/* * Based on code from: * * XRegExp 1.5.0 @@ -445,7 +462,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. * @@ -1475,7 +1492,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 * @@ -1540,7 +1558,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) { @@ -1549,7 +1567,7 @@ exports.addCssClass = function(el, name) { } }; -/** +/* * Remove a CSS class from the list of classes on the given node */ exports.removeCssClass = function(el, name) { @@ -1581,7 +1599,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 */ @@ -1732,7 +1750,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. * @@ -1766,7 +1784,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 @@ -1832,7 +1851,7 @@ exports.removeListener = function(elem, type, callback) { } }; -/** +/* * Prevents propagation and clobbers the default action of the passed event */ exports.stopEvent = function(e) { @@ -1855,23 +1874,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) { @@ -2128,7 +2131,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() { @@ -2218,7 +2221,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 @@ -2322,13 +2326,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 = @@ -2337,16 +2341,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; @@ -2357,7 +2361,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. * @@ -2370,7 +2374,7 @@ exports.OS = { WINDOWS: "WINDOWS" }; -/** +/* * Return an exports.OS constant */ exports.getOS = function() { @@ -2444,12 +2448,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 @@ -2465,7 +2486,6 @@ var Editor = function(renderer, session) { wrap: true }); - this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands); this.setSession(session || new EditSession("")); }; @@ -2473,14 +2493,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; @@ -2580,39 +2616,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); @@ -2637,6 +2718,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 @@ -2648,26 +2734,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; @@ -2682,51 +2799,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; @@ -2737,11 +2873,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(); @@ -2762,34 +2903,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. @@ -2798,6 +2979,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()) @@ -2807,10 +2993,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(); @@ -2903,46 +3119,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; @@ -2951,23 +3224,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; @@ -2979,6 +3289,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; }; @@ -2991,6 +3306,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; @@ -2998,44 +3319,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) @@ -3046,13 +3424,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(); @@ -3071,6 +3469,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(); @@ -3079,6 +3482,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(); @@ -3087,6 +3495,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(); @@ -3095,6 +3508,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(); @@ -3109,6 +3527,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()); @@ -3120,6 +3543,11 @@ var Editor = function(renderer, session) { this.moveCursorToPosition(cursor); }; + /** + * Editor.transposeLetters() + * + * Transposes current line. + **/ this.transposeLetters = function() { if (!this.selection.isEmpty()) { return; @@ -3143,6 +3571,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()) { @@ -3155,6 +3588,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()) { @@ -3167,6 +3605,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(); @@ -3190,17 +3633,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; @@ -3215,18 +3673,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; @@ -3234,6 +3721,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); @@ -3241,6 +3736,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); @@ -3248,6 +3752,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; @@ -3271,6 +3782,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(); @@ -3280,141 +3799,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); @@ -3433,34 +4089,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; @@ -3475,6 +4167,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; @@ -3489,36 +4187,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); @@ -3539,6 +4278,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); @@ -3578,35 +4324,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())}); @@ -3615,35 +4384,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(); }; @@ -3756,7 +4536,7 @@ exports.arrayToMap = function(arr) { }; -/** +/* * splice out of 'array' anything that === 'value' */ exports.arrayRemove = function(array, value) { @@ -3854,7 +4634,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); @@ -3877,13 +4659,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 @@ -3904,7 +4691,7 @@ var TextInput = function(parentNode, host) { var onTextInput = function(e) { setTimeout(function () { if (!inCompostion) - sendText(e.data); + sendText(e.data); }, 0); }; @@ -3960,6 +4747,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) { @@ -4130,10 +4918,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); @@ -4150,7 +4938,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")); @@ -4172,7 +4960,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; @@ -4196,10 +4984,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; @@ -4228,6 +5054,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 @@ -4243,240 +5070,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; @@ -4533,7 +5410,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. @@ -4668,7 +5545,7 @@ EventEmitter._dispatchEvent = function(eventName, e) { } if (defaultHandler && !e.defaultPrevented) - defaultHandler(e); + return defaultHandler(e); }; EventEmitter.setDefaultHandler = function(eventName, callback) { @@ -4711,7 +5588,8 @@ EventEmitter.removeAllListeners = function(eventName) { exports.EventEmitter = EventEmitter; -});/* 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 * @@ -4752,19 +5630,31 @@ exports.EventEmitter = EventEmitter; 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 * @@ -4807,18 +5697,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; @@ -4844,7 +5731,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 @@ -4852,14 +5739,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 @@ -4885,7 +5770,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 @@ -4894,7 +5779,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() { @@ -4978,7 +5863,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 @@ -5027,15 +5913,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) { @@ -5073,7 +5971,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; @@ -5083,20 +5981,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); @@ -5419,7 +6311,7 @@ exports.commands = [{ multiSelectAction: "forEach" }, { name: "togglecomment", - bindKey: bindKey("Ctrl-7", "Command-7"), + bindKey: bindKey("Ctrl-/", "Command-/"), exec: function(editor) { editor.toggleCommentLines(); }, multiSelectAction: "forEach" }, { @@ -5600,6 +6492,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 = []; @@ -5625,10 +6533,7 @@ var EditSession = function(text, mode) { } this.selection = new Selection(this); - if (mode) - this.setMode(mode); - else - this.setMode(new TextMode()); + this.setMode(mode); }; @@ -5636,6 +6541,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"); @@ -5650,10 +6562,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 = []; @@ -5668,11 +6593,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; @@ -5696,6 +6632,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); @@ -5708,23 +6651,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; @@ -5746,6 +6728,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); @@ -5758,6 +6746,11 @@ var EditSession = function(text, mode) { if (undoManager) { var self = this; + /** internal, hide + * EditSession.$syncInformUndoManager() + * + * + **/ this.$syncInformUndoManager = function() { self.$informUndoManager.cancel(); @@ -5797,10 +6790,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()); @@ -5810,17 +6813,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; @@ -5829,15 +6851,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; @@ -5845,18 +6885,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++; @@ -5906,6 +6991,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) @@ -5918,11 +7010,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, @@ -5931,6 +7030,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) { @@ -5962,6 +7084,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); @@ -5993,7 +7123,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); @@ -6004,15 +7140,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; @@ -6024,10 +7179,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); @@ -6038,7 +7203,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 { @@ -6046,16 +7211,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] @@ -6066,33 +7232,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(); @@ -6127,6 +7308,11 @@ var EditSession = function(text, mode) { this._emit("changeMode"); }; + /** internal, hide + * EditSession.stopWorker() + * + * + **/ this.$stopWorker = function() { if (this.$worker) this.$worker.terminate(); @@ -6134,6 +7320,11 @@ var EditSession = function(text, mode) { this.$worker = null; }; + /** internal, hide + * EditSession.$startWorker() + * + * + **/ this.$startWorker = function() { if (typeof Worker !== "undefined" && !require.noWorker) { try { @@ -6148,11 +7339,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) @@ -6162,11 +7364,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) @@ -6176,15 +7388,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; @@ -6229,33 +7456,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; @@ -6282,6 +7558,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; @@ -6304,10 +7587,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 = @@ -6362,19 +7656,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); @@ -6405,12 +7716,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); @@ -6435,6 +7764,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; @@ -6443,6 +7782,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; @@ -6451,6 +7799,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); @@ -6462,6 +7821,7 @@ var EditSession = function(text, mode) { return addedRows; }; + this.$clipRowToDocument = function(row) { return Math.max(0, Math.min(row, this.doc.getLength()-1)); }; @@ -6472,6 +7832,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); @@ -6504,7 +7865,7 @@ var EditSession = function(text, mode) { range.start.column ); } - + var len = this.doc.getLength() - 1; if (range.end.row > len) { range.end.row = len; @@ -6526,6 +7887,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; @@ -6546,6 +7913,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; }; @@ -6554,6 +7926,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; @@ -6564,8 +7943,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) { @@ -6581,6 +7964,11 @@ var EditSession = function(text, mode) { return false; }; + /** internal, hide + * EditSession.$constrainWrapLimit(wrapLimit) + * + * + **/ this.$constrainWrapLimit = function(wrapLimit) { var min = this.$wrapLimitRange.min; if (min) @@ -6594,10 +7982,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 { @@ -6606,6 +8007,11 @@ var EditSession = function(text, mode) { }; }; + /** internal, hide + * EditSession.$updateInternalDataOnChange() + * + * + **/ this.$updateInternalDataOnChange = function(e) { var useWrapMode = this.$useWrapMode; var len; @@ -6721,6 +8127,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(); @@ -6780,6 +8191,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 []; @@ -6896,11 +8312,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; @@ -6932,15 +8350,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]; @@ -6973,8 +8395,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; @@ -6984,27 +8410,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; @@ -7014,20 +8465,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 { @@ -7123,6 +8597,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") @@ -7226,14 +8711,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; @@ -7439,7 +8939,8 @@ function deHyphenate(str) { return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); }); } -});/** +}); +/* * based on code from: * * @license RequireJS text 0.25.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. @@ -7500,7 +9001,8 @@ exports.loadScript = function(path, callback) { s.onload = callback; }; -});/* ***** 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 @@ -7547,22 +9049,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"); @@ -7580,13 +9090,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; @@ -7595,12 +9115,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; @@ -7608,20 +9140,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; }; @@ -7640,15 +9190,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); @@ -7661,6 +9221,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; @@ -7668,12 +9233,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); @@ -7686,80 +9264,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); @@ -7769,22 +9428,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)) { @@ -7804,20 +9487,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 @@ -7825,9 +9513,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. @@ -7853,8 +9546,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( @@ -7863,19 +9561,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); @@ -7889,14 +9602,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); @@ -7905,7 +9618,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; @@ -7915,9 +9628,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; @@ -7930,19 +9648,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); @@ -7961,10 +9679,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) { @@ -7980,10 +9791,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); @@ -7993,13 +9818,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); @@ -8007,8 +9840,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; } @@ -8077,6 +9910,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, @@ -8090,6 +9940,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 && @@ -8097,28 +9954,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, @@ -8148,27 +10028,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; @@ -8179,6 +10118,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; @@ -8189,6 +10136,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)) { @@ -8200,6 +10155,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)) { @@ -8211,6 +10174,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)) { @@ -8222,6 +10193,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) { @@ -8245,8 +10237,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; @@ -8256,8 +10268,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; @@ -8266,6 +10296,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; @@ -8276,6 +10321,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 = { @@ -8307,6 +10360,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); @@ -8320,33 +10381,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) @@ -8354,6 +10418,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); @@ -8368,7 +10438,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); }; @@ -8636,6 +10713,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; @@ -8681,6 +10773,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]; @@ -8977,7 +11074,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"; /* @@ -9083,7 +11181,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 @@ -9128,6 +11227,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 = []; @@ -9147,20 +11261,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) { @@ -9172,6 +11314,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) { @@ -9181,6 +11328,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": @@ -9196,6 +11354,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; @@ -9203,51 +11367,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) { @@ -9257,6 +11462,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; @@ -9280,6 +11494,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}; @@ -9298,6 +11525,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] || ""; @@ -9320,6 +11558,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; @@ -9344,6 +11595,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); @@ -9376,6 +11636,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; @@ -9396,12 +11667,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); @@ -9416,6 +11690,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); @@ -9433,6 +11714,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; @@ -9453,6 +11746,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]; @@ -9534,9 +11837,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; @@ -9553,14 +11869,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; @@ -9626,6 +11964,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) { @@ -9654,10 +12002,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 = {}; @@ -9726,6 +12090,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 = []; @@ -9767,6 +12148,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 = []; @@ -9774,6 +12163,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 = []; @@ -9781,6 +12178,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, @@ -9789,6 +12195,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()); @@ -9801,20 +12215,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':[]}]; @@ -9906,7 +12354,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 @@ -9930,7 +12378,7 @@ function Folding() { } }; - /** + /* * Returns all folds in the given range. Note, that this will return folds * */ @@ -9976,7 +12424,7 @@ function Folding() { return foundFolds; }; - /** + /* * Returns all folds in the document */ this.getAllFolds = function() { @@ -9999,7 +12447,7 @@ function Folding() { return folds; }; - /** + /* * Returns the string between folds at the given position. * E.g. * foob|arwolrd -> "bar" @@ -10118,7 +12566,7 @@ function Folding() { return foldLine; }; - /** + /* * Adds a new fold. * * @returns @@ -10318,7 +12766,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. **/ @@ -10658,7 +13106,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) { @@ -10681,7 +13129,7 @@ function FoldLine(foldData, folds) { } (function() { - /** + /* * Note: This doesn't update wrapData! */ this.shiftRow = function(shift) { @@ -10794,7 +13242,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); @@ -10888,7 +13338,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 * @@ -10929,7 +13380,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) { @@ -11003,7 +13454,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 * @@ -11044,6 +13496,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; @@ -11054,7 +13522,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; @@ -11071,7 +13545,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; @@ -11089,15 +13568,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; @@ -11163,8 +13660,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; @@ -11347,6 +13870,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: "", @@ -11364,15 +13909,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; @@ -11392,6 +13957,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) @@ -11418,6 +13990,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); @@ -11432,6 +14016,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; @@ -11466,6 +14057,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; @@ -11651,6 +14249,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 = {}; @@ -11659,7 +14275,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 || {}); }); }; @@ -11679,8 +14295,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() { @@ -11822,6 +14448,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]; @@ -11844,18 +14482,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]); @@ -11871,10 +14497,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]]) @@ -11887,17 +14513,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 { @@ -11951,12 +14572,33 @@ exports.HashHandler = HashHandler; 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]; @@ -11964,6 +14606,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; @@ -11975,6 +14623,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; @@ -11986,15 +14640,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; }; @@ -12063,6 +14732,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; @@ -12071,6 +14756,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"); @@ -12088,8 +14776,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); @@ -12105,14 +14795,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; @@ -12123,12 +14814,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 = { @@ -12193,19 +14881,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; @@ -12228,26 +14929,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; @@ -12282,53 +14995,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; @@ -12337,6 +15116,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; @@ -12357,56 +15174,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); @@ -12417,10 +15276,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; @@ -12468,6 +15338,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; } @@ -12484,6 +15356,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; } @@ -12503,8 +15377,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); @@ -12581,7 +15458,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"; @@ -12627,55 +15504,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; @@ -12686,10 +15619,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); } @@ -12699,75 +15634,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 @@ -12777,6 +15765,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; @@ -12786,11 +15781,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; @@ -12799,32 +15808,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); @@ -12838,14 +15853,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"); @@ -12864,10 +15894,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(); @@ -12888,6 +15929,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; @@ -12942,6 +15989,11 @@ var VirtualRenderer = function(container, theme) { } }; + /** + * VirtualRenderer.getTheme() -> String + * + * [Returns the path of the current theme.]{: #VirtualRenderer.getTheme} + **/ this.getTheme = function() { return this.$themeValue; }; @@ -12950,14 +16002,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(); @@ -13267,9 +16336,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; @@ -13293,9 +16360,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; @@ -13342,9 +16407,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; @@ -13765,21 +16828,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"; @@ -13788,13 +16848,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) { @@ -14322,6 +17427,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; @@ -14331,6 +17449,12 @@ var RenderLoop = function(onRender, win) { (function() { + /** internal, hide + * RenderLoop.schedule(change) + * - change (Array): + * + * + **/ this.schedule = function(change) { //this.onRender(change); //return; @@ -14353,8 +17477,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" + @@ -14392,6 +17515,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" + @@ -14450,8 +17579,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" + @@ -14486,6 +17615,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" + @@ -14534,10 +17664,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" + @@ -14644,6 +17770,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: @@ -14684,12 +17832,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 @@ -14719,10 +17868,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) @@ -14766,11 +17917,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); @@ -14780,10 +17931,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(); @@ -14841,6 +17992,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]; @@ -14857,11 +18039,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 = []; @@ -14931,21 +18116,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) @@ -14959,11 +18145,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) @@ -14994,13 +18180,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; @@ -15013,7 +18199,7 @@ var Editor = require("./editor").Editor; this.renderer.updateCursor(); this.renderer.updateBackMarkers(); }; - + this.$onSingleSelect = function(e) { if (this.session.multiSelect.inVirtualMode) return; @@ -15045,12 +18231,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) @@ -15081,11 +18267,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) @@ -15109,14 +18295,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 || {}; @@ -15129,10 +18336,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); @@ -15142,12 +18349,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(); @@ -15187,12 +18394,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; @@ -15210,7 +18416,7 @@ var Editor = require("./editor").Editor; } } sel.mergeOverlappingRanges(); - + var words = []; for (var i = all.length; i--; ) { var range = all[i]; @@ -15231,13 +18437,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; @@ -15304,12 +18509,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); @@ -15321,7 +18523,7 @@ function MultiSelect(editor) { editor.on("mousedown", onMouseDown); editor.commands.addCommands(exports.commands.defaultCommands); - + addAltCursorListeners(editor); } @@ -15329,7 +18531,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"; @@ -15339,9 +18541,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 = ""; @@ -15352,7 +18554,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 @@ -15661,10 +18864,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() { @@ -15749,7 +18952,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 * @@ -15835,20 +19039,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); -});/* ***** 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 @@ -15900,7 +19106,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 = {}; @@ -16063,7 +19276,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. @@ -16214,7 +19427,7 @@ StateHandler.prototype = { } }, - /** + /* * This function is called by keyBinding. */ handleKeyboard: function(data, hashId, key, keyCode, e) { @@ -16240,7 +19453,7 @@ StateHandler.prototype = { } } -/** +/* * This is a useful matching function and therefore is defined here so that * users of KeyboardStateMapper can use it. * @@ -16312,6 +19525,26 @@ var Range = require('./range').Range; var EventEmitter = require("./lib/event_emitter").EventEmitter; var oop = require("./lib/oop"); +/** + * class PlaceHolder + * + * TODO + * + **/ + +/** + * new PlaceHolder(session, length, pos, others, mainClass, othersClass) + * - session (Document): The document to associate with the anchor + * - length (Number): The starting row position + * - pos (Number): The starting column position + * - others (String): + * - mainClass (String): + * - othersClass (String): + * + * TODO + * + **/ + var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) { var _self = this; this.length = length; @@ -16342,6 +19575,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) oop.implement(this, EventEmitter); + /** + * PlaceHolder.setup() + * + * TODO + * + **/ this.setup = function() { var _self = this; var doc = this.doc; @@ -16362,6 +19601,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) session.setUndoSelect(false); }; + /** + * PlaceHolder.showOtherMarkers() + * + * TODO + * + **/ this.showOtherMarkers = function() { if(this.othersActive) return; var session = this.session; @@ -16376,6 +19621,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) }); }; + /** + * PlaceHolder.hideOtherMarkers() + * + * Hides all over markers in the [[EditSession `EditSession`]] that are not the currently selected one. + * + **/ this.hideOtherMarkers = function() { if(!this.othersActive) return; this.othersActive = false; @@ -16384,6 +19635,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) } }; + /** + * PlaceHolder@onUpdate(e) + * + * Emitted when the place holder updates. + * + **/ this.onUpdate = function(event) { var delta = event.data; var range = delta.range; @@ -16446,6 +19703,13 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.$updating = false; }; + /** + * PlaceHolder@onCursorChange(e) + * + * Emitted when the cursor changes. + * + **/ + this.onCursorChange = function(event) { if (this.$updating) return; var pos = this.session.selection.getCursor(); @@ -16458,6 +19722,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) } }; + /** + * PlaceHolder.detach() + * + * TODO + * + **/ this.detach = function() { this.session.removeMarker(this.markerId); this.hideOtherMarkers(); @@ -16470,6 +19740,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.session.setUndoSelect(true); }; + /** + * PlaceHolder.cancel() + * + * TODO + * + **/ this.cancel = function() { if(this.$undoStackDepth === -1) throw Error("Canceling placeholders only supported with undo manager attached to session."); @@ -16587,8 +19863,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 {\ @@ -16675,6 +19951,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);\ diff --git a/build/src/ace.js b/build/src/ace.js index 3d6bcff7..14e314b0 100644 --- a/build/src/ace.js +++ b/build/src/ace.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):e(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="",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})}),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)}}),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)}}),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()}}),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)}}),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}}),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}),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}),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}),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}),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}),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}),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}),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}),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)}),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}),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}),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}),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("
",e+1);if(i){var k=i[e];k==null&&(k=i[e]=this.session.getFoldWidget(e)),k&&c.push("")}var l=this.session.getRowLength(e)-1;while(l--)c.push("
¦");c.push("
"),e++}this.element=d.setInnerHtml(this.element,c.join("")),this.element.style.height=a.minHeight+"px";var m=this.element.offsetWidth;m!==this.gutterWidth&&(this.gutterWidth=m,this._emit("changeGutterWidth",m))},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(a){a?d.addCssClass(this.element,"ace_folding-enabled"):d.removeCssClass(this.element,"ace_folding-enabled"),this.$showFoldWidgets=a},this.getShowFoldWidgets=function(){return this.$showFoldWidgets}}).call(g.prototype),b.Gutter=g}),define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(a,b,c){"use strict";var d=a("../range").Range,e=a("../lib/dom"),f=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_marker-layer",a.appendChild(this.element)};(function(){this.$padding=0,this.setPadding=function(a){this.$padding=a},this.setSession=function(a){this.session=a},this.setMarkers=function(a){this.markers=a},this.update=function(a){var a=a||this.config;if(!a)return;this.config=a;var b=[];for(var c in this.markers){var d=this.markers[c],f=d.range.clipRows(a.firstRow,a.lastRow);if(f.isEmpty())continue;f=f.toScreenRange(this.session);if(d.renderer){var g=this.$getTop(f.start.row,a),h=Math.round(this.$padding+f.start.column*a.characterWidth);d.renderer(b,f,h,g,a)}else f.isMultiLine()?d.type=="text"?this.drawTextMarker(b,f,d.clazz,a):this.drawMultiLineMarker(b,f,d.clazz,a,d.type):this.drawSingleLineMarker(b,f,d.clazz+" start",a,null,d.type)}this.element=e.setInnerHtml(this.element,b.join(""))},this.$getTop=function(a,b){return(a-b.firstRowScreen)*b.lineHeight},this.drawTextMarker=function(a,b,c,e){var f=b.start.row,g=new d(f,b.start.column,f,this.session.getScreenLastRowColumn(f));this.drawSingleLineMarker(a,g,c+" start",e,1,"text"),f=b.end.row,g=new d(f,0,f,b.end.column),this.drawSingleLineMarker(a,g,c,e,0,"text");for(f=b.start.row+1;f"),j=this.$getTop(b.end.row,d),i=Math.round(b.end.column*d.characterWidth),a.push("
"),h=(b.end.row-b.start.row-1)*d.lineHeight;if(h<0)return;j=this.$getTop(b.start.row+1,d),a.push("
")},this.drawSingleLineMarker=function(a,b,c,d,e,f){var g=f==="background"?0:this.$padding,h=d.lineHeight;if(f==="background")var i=d.width;else i=Math.round((b.end.column+(e||0)-b.start.column)*d.characterWidth);var j=this.$getTop(b.start.row,d),k=Math.round(g+b.start.column*d.characterWidth);a.push("
")}}).call(f.prototype),b.Marker=f}),define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("../lib/oop"),e=a("../lib/dom"),f=a("../lib/lang"),g=a("../lib/useragent"),h=a("../lib/event_emitter").EventEmitter,i=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_text-layer",a.appendChild(this.element),this.$characterSize=this.$measureSizes()||{width:0,height:0},this.$pollSizeChanges()};(function(){d.implement(this,h),this.EOF_CHAR="¶",this.EOL_CHAR="¬",this.TAB_CHAR="→",this.SPACE_CHAR="·",this.$padding=0,this.setPadding=function(a){this.$padding=a,this.element.style.padding="0 "+a+"px"},this.getLineHeight=function(){return this.$characterSize.height||1},this.getCharacterWidth=function(){return this.$characterSize.width||1},this.checkForSizeChanges=function(){var a=this.$measureSizes();a&&(this.$characterSize.width!==a.width||this.$characterSize.height!==a.height)&&(this.$characterSize=a,this._emit("changeCharacterSize",{data:a}))},this.$pollSizeChanges=function(){var a=this;this.$pollSizeChangesTimer=setInterval(function(){a.checkForSizeChanges()},500)},this.$fontStyles={fontFamily:1,fontSize:1,fontWeight:1,fontStyle:1,lineHeight:1},this.$measureSizes=g.isIE||g.isOldGecko?function(){var a=1e3;if(!this.$measureNode){var b=this.$measureNode=e.createElement("div"),c=b.style;c.width=c.height="auto",c.left=c.top=-a*40+"px",c.visibility="hidden",c.position="fixed",c.overflow="visible",c.whiteSpace="nowrap",b.innerHTML=f.stringRepeat("Xy",a);if(this.element.ownerDocument.body)this.element.ownerDocument.body.appendChild(b);else{var d=this.element.parentNode;while(!e.hasCssClass(d,"ace_editor"))d=d.parentNode;d.appendChild(b)}}if(!this.element.offsetWidth)return null;var c=this.$measureNode.style,g=e.computedStyle(this.element);for(var h in this.$fontStyles)c[h]=g[h];var i={height:this.$measureNode.offsetHeight,width:this.$measureNode.offsetWidth/(a*2)};return i.width==0||i.height==0?null:i}:function(){if(!this.$measureNode){var a=this.$measureNode=e.createElement("div"),b=a.style;b.width=b.height="auto",b.left=b.top="-100px",b.visibility="hidden",b.position="fixed",b.overflow="visible",b.whiteSpace="nowrap",a.innerHTML="X";var c=this.element.parentNode;while(c&&!e.hasCssClass(c,"ace_editor"))c=c.parentNode;if(!c)return this.$measureNode=null;c.appendChild(a)}var d=this.$measureNode.getBoundingClientRect(),f={height:d.height,width:d.width};return f.width==0||f.height==0?null:f},this.setSession=function(a){this.session=a},this.showInvisibles=!1,this.setShowInvisibles=function(a){return this.showInvisibles==a?!1:(this.showInvisibles=a,!0)},this.$tabStrings=[],this.$computeTabString=function(){var a=this.session.getTabSize(),b=this.$tabStrings=[0];for(var c=1;c"+this.TAB_CHAR+(new Array(c)).join(" ")+"
"):b.push((new Array(c+1)).join(" "))},this.updateLines=function(a,b,c){this.$computeTabString(),(this.config.lastRow!=a.lastRow||this.config.firstRow!=a.firstRow)&&this.scrollLines(a),this.config=a;var d=Math.max(b,a.firstRow),f=Math.min(c,a.lastRow),g=this.element.childNodes,h=0;for(var i=a.firstRow;i0;d--)c.removeChild(c.firstChild);if(b.lastRow>a.lastRow)for(var d=this.session.getFoldedRowCount(a.lastRow+1,b.lastRow);d>0;d--)c.removeChild(c.lastChild);if(a.firstRowb.lastRow){var e=this.$renderLinesFragment(a,b.lastRow+1,a.lastRow);c.appendChild(e)}},this.$renderLinesFragment=function(a,b,c){var d=this.element.ownerDocument.createDocumentFragment(),f=b,g=this.session.getNextFoldLine(f),h=g?g.start.row:Infinity;for(;;){f>h&&(f=g.end.row+1,g=this.session.getNextFoldLine(f,g),h=g?g.start.row:Infinity);if(f>c)break;var i=e.createElement("div"),j=[],k=this.session.getTokens(f,f);k.length==1&&this.$renderLine(j,f,k[0].tokens,!1),i.innerHTML=j.join("");if(this.$useLineGroups())i.className="ace_line_group",d.appendChild(i);else{var l=i.childNodes;while(l.length)d.appendChild(l[0])}f++}return d},this.update=function(a){this.$computeTabString(),this.config=a;var b=[],c=a.firstRow,d=a.lastRow,f=c,g=this.session.getNextFoldLine(f),h=g?g.start.row:Infinity;for(;;){f>h&&(f=g.end.row+1,g=this.session.getNextFoldLine(f,g),h=g?g.start.row:Infinity);if(f>d)break;this.$useLineGroups()&&b.push("
");var i=this.session.getTokens(f,f);i.length==1&&this.$renderLine(b,f,i[0].tokens,!1),this.$useLineGroups()&&b.push("
"),f++}this.element=e.setInnerHtml(this.element,b.join(""))},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(a,b,c,d){var e=this,f=/\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,h=function(a,c,d,f,h){if(a.charCodeAt(0)==32)return(new Array(a.length+1)).join(" ");if(a==" "){var i=e.session.getScreenTabSize(b+f);return b+=i-1,e.$tabStrings[i]}if(a=="&")return g.isOldGecko?"&":"&";if(a=="<")return"<";if(a==" "){var j=e.showInvisibles?"ace_cjk ace_invisible":"ace_cjk",k=e.showInvisibles?e.SPACE_CHAR:"";return b+=1,""+k+""}if(a.match(/[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/)){if(e.showInvisibles){var k=(new Array(a.length+1)).join(e.SPACE_CHAR);return""+k+""}return" "}return b+=1,""+a+""},i=d.replace(f,h);if(!this.$textToken[c.type]){var j="ace_"+c.type.replace(/\./g," ace_"),k="";c.type=="fold"&&(k=" style='width:"+c.value.length*this.config.characterWidth+"px;' "),a.push("",i,"")}else a.push(i);return b+d.length},this.$renderLineCore=function(a,b,c,d,e){var f=0,g=0,h,i=0,j=this;!d||d.length==0?h=Number.MAX_VALUE:h=d[0],e||a.push("
");for(var k=0;k=h)i=j.$renderToken(a,i,l,m.substring(0,h-f)),m=m.substring(h-f),f=h,e||a.push("
","
"),g++,i=0,h=d[g]||Number.MAX_VALUE;m.length!=0&&(f+=m.length,i=j.$renderToken(a,i,l,m))}}this.showInvisibles&&(b!==this.session.getLength()-1?a.push(""+this.EOL_CHAR+""):a.push(""+this.EOF_CHAR+"")),e||a.push("
")},this.$renderLine=function(a,b,c,d){if(!this.session.isRowFolded(b)){var e=this.session.getRowSplitData(b);this.$renderLineCore(a,b,c,e,d)}else this.$renderFoldLine(a,b,c,d)},this.$renderFoldLine=function(a,b,c,d){function h(a,b,c){var d=0,e=0;while(e+a[d].value.lengthc-b&&(f=f.substring(0,c-b)),g.push({type:a[d].type,value:f}),e=b+f.length,d+=1}while(ec&&(f=f.substring(0,c-e)),g.push({type:a[d].type,value:f}),e+=f.length,d+=1}}var e=this.session,f=e.getFoldLine(b),g=[];f.walk(function(a,b,d,e,f){a?g.push({type:"fold",value:a}):(f&&(c=this.session.getTokens(b,b)[0].tokens),c.length!=0&&h(c,e,d))}.bind(this),f.end.row,this.session.getLine(f.end.row).length);var i=this.session.$useWrapMode?this.session.$wrapData[b]:null;this.$renderLineCore(a,b,g,i,d)},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(i.prototype),b.Text=i}),define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(a,b,c){"use strict";var d=a("../lib/dom"),e=function(a){this.element=d.createElement("div"),this.element.className="ace_layer ace_cursor-layer",a.appendChild(this.element),this.isVisible=!1,this.cursors=[],this.cursor=this.addCursor()};(function(){this.$padding=0,this.setPadding=function(a){this.$padding=a},this.setSession=function(a){this.session=a},this.addCursor=function(){var a=d.createElement("div"),b="ace_cursor";return this.isVisible||(b+=" ace_hidden"),this.overwrite&&(b+=" ace_overwrite"),a.className=b,this.element.appendChild(a),this.cursors.push(a),a},this.removeCursor=function(){if(this.cursors.length>1){var a=this.cursors.pop();return a.parentNode.removeChild(a),a}},this.hideCursor=function(){this.isVisible=!1;for(var a=this.cursors.length;a--;)d.addCssClass(this.cursors[a],"ace_hidden");clearInterval(this.blinkId)},this.showCursor=function(){this.isVisible=!0;for(var a=this.cursors.length;a--;)d.removeCssClass(this.cursors[a],"ace_hidden");this.element.style.visibility="",this.restartTimer()},this.restartTimer=function(){clearInterval(this.blinkId);if(!this.isVisible)return;var a=this.cursors.length==1?this.cursor:this.element;this.blinkId=setInterval(function(){a.style.visibility="hidden",setTimeout(function(){a.style.visibility=""},400)},1e3)},this.getPixelPosition=function(a,b){if(!this.config||!this.session)return{left:0,top:0};a||(a=this.session.selection.getCursor());var c=this.session.documentToScreenPosition(a),d=Math.round(this.$padding+c.column*this.config.characterWidth),e=(c.row-(b?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:d,top:e}},this.update=function(a){this.config=a;if(this.session.selectionMarkerCount>0){var b=this.session.$selectionMarkers,c=0,d,e=0;for(var c=b.length;c--;){d=b[c];var f=this.getPixelPosition(d.cursor,!0),g=(this.cursors[e++]||this.addCursor()).style;g.left=f.left+"px",g.top=f.top+"px",g.width=a.characterWidth+"px",g.height=a.lineHeight+"px"}if(e>1)while(this.cursors.length>e)this.removeCursor()}else{var f=this.getPixelPosition(null,!0),g=this.cursor.style;g.left=f.left+"px",g.top=f.top+"px",g.width=a.characterWidth+"px",g.height=a.lineHeight+"px";while(this.cursors.length>1)this.removeCursor()}var h=this.session.getOverwrite();h!=this.overwrite&&this.$setOverite(h),this.restartTimer()},this.$setOverite=function(a){this.overwrite=a;for(var b=this.cursors.length;b--;)a?d.addCssClass(this.cursors[b],"ace_overwrite"):d.removeCssClass(this.cursors[b],"ace_overwrite")},this.destroy=function(){clearInterval(this.blinkId)}}).call(e.prototype),b.Cursor=e}),define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("./lib/oop"),e=a("./lib/dom"),f=a("./lib/event"),g=a("./lib/event_emitter").EventEmitter,h=function(a){this.element=e.createElement("div"),this.element.className="ace_sb",this.inner=e.createElement("div"),this.element.appendChild(this.inner),a.appendChild(this.element),this.width=e.scrollbarWidth(a.ownerDocument),this.element.style.width=(this.width||15)+5+"px",f.addListener(this.element,"scroll",this.onScroll.bind(this))};(function(){d.implement(this,g),this.onScroll=function(){this._emit("scroll",{data:this.element.scrollTop})},this.getWidth=function(){return this.width},this.setHeight=function(a){this.element.style.height=a+"px"},this.setInnerHeight=function(a){this.inner.style.height=a+"px"},this.setScrollTop=function(a){this.element.scrollTop=a}}).call(h.prototype),b.ScrollBar=h}),define("ace/renderloop",["require","exports","module","ace/lib/event"],function(a,b,c){"use strict";var d=a("./lib/event"),e=function(a,b){this.onRender=a,this.pending=!1,this.changes=0,this.window=b||window};(function(){this.schedule=function(a){this.changes=this.changes|a;if(!this.pending){this.pending=!0;var b=this;d.nextTick(function(){b.pending=!1;var a;while(a=b.changes)b.changes=0,b.onRender(a)},this.window)}}}).call(e.prototype),b.RenderLoop=e}),define("text!ace/css/editor.css",[],"@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono);\n\n.ace_editor {\n position: absolute;\n overflow: hidden;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Droid Sans Mono', 'Consolas', monospace;\n font-size: 12px;\n}\n\n.ace_scroller {\n position: absolute;\n overflow-x: scroll;\n overflow-y: hidden;\n}\n\n.ace_content {\n position: absolute;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n cursor: text;\n}\n\n.ace_composition {\n position: absolute;\n background: #555;\n color: #DDD;\n z-index: 4;\n}\n\n.ace_gutter {\n position: absolute;\n overflow : hidden;\n height: 100%;\n width: auto;\n cursor: default;\n z-index: 1000;\n}\n\n.ace_gutter.horscroll {\n box-shadow: 0px 0px 20px rgba(0,0,0,0.4);\n}\n\n.ace_gutter-cell {\n padding-left: 19px;\n padding-right: 6px;\n}\n\n.ace_gutter-cell.ace_error {\n background-image: url(\"data:image/gif,GIF89a%10%00%10%00%D5%00%00%F5or%F5%87%88%F5nr%F4ns%EBmq%F5z%7F%DDJT%DEKS%DFOW%F1Yc%F2ah%CE(7%CE)8%D18E%DD%40M%F2KZ%EBU%60%F4%60m%DCir%C8%16(%C8%19*%CE%255%F1%3FR%F1%3FS%E6%AB%B5%CA%5DI%CEn%5E%F7%A2%9A%C9G%3E%E0a%5B%F7%89%85%F5yy%F6%82%80%ED%82%80%FF%BF%BF%E3%C4%C4%FF%FF%FF%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%25%00%2C%00%00%00%00%10%00%10%00%00%06p%C0%92pH%2C%1A%8F%C8%D2H%93%E1d4%23%E4%88%D3%09mB%1DN%B48%F5%90%40%60%92G%5B%94%20%3E%22%D2%87%24%FA%20%24%C5%06A%00%20%B1%07%02B%A38%89X.v%17%82%11%13q%10%0Fi%24%0F%8B%10%7BD%12%0Ei%09%92%09%0EpD%18%15%24%0A%9Ci%05%0C%18F%18%0B%07%04%01%04%06%A0H%18%12%0D%14%0D%12%A1I%B3%B4%B5IA%00%3B\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_warning {\n background-image: url(\"data:image/gif,GIF89a%10%00%10%00%D5%00%00%FF%DBr%FF%DE%81%FF%E2%8D%FF%E2%8F%FF%E4%96%FF%E3%97%FF%E5%9D%FF%E6%9E%FF%EE%C1%FF%C8Z%FF%CDk%FF%D0s%FF%D4%81%FF%D5%82%FF%D5%83%FF%DC%97%FF%DE%9D%FF%E7%B8%FF%CCl%7BQ%13%80U%15%82W%16%81U%16%89%5B%18%87%5B%18%8C%5E%1A%94d%1D%C5%83-%C9%87%2F%C6%84.%C6%85.%CD%8B2%C9%871%CB%8A3%CD%8B5%DC%98%3F%DF%9BB%E0%9CC%E1%A5U%CB%871%CF%8B5%D1%8D6%DB%97%40%DF%9AB%DD%99B%E3%B0p%E7%CC%AE%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%2F%00%2C%00%00%00%00%10%00%10%00%00%06a%C0%97pH%2C%1A%8FH%A1%ABTr%25%87%2B%04%82%F4%7C%B9X%91%08%CB%99%1C!%26%13%84*iJ9(%15G%CA%84%14%01%1A%97%0C%03%80%3A%9A%3E%81%84%3E%11%08%B1%8B%20%02%12%0F%18%1A%0F%0A%03'F%1C%04%0B%10%16%18%10%0B%05%1CF%1D-%06%07%9A%9A-%1EG%1B%A0%A1%A0U%A4%A5%A6BA%00%3B\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_info {\n background-image: url(\"data:image/gif;base64,R0lGODlhEAAQAMQAAAAAAEFBQVJSUl5eXmRkZGtra39/f4WFhYmJiZGRkaampry8vMPDw8zMzNXV1dzc3OTk5Orq6vDw8P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABQALAAAAAAQABAAAAUuICWOZGmeaBml5XGwFCQSBGyXRSAwtqQIiRuiwIM5BoYVbEFIyGCQoeJGrVptIQA7\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_editor .ace_sb {\n position: absolute;\n overflow-x: hidden;\n overflow-y: scroll;\n right: 0;\n}\n\n.ace_editor .ace_sb div {\n position: absolute;\n width: 1px;\n left: 0;\n}\n\n.ace_editor .ace_print_margin_layer {\n z-index: 0;\n position: absolute;\n overflow: hidden;\n margin: 0;\n left: 0;\n height: 100%;\n width: 100%;\n}\n\n.ace_editor .ace_print_margin {\n position: absolute;\n height: 100%;\n}\n\n.ace_editor textarea {\n position: fixed;\n z-index: 0;\n width: 10px;\n height: 30px;\n opacity: 0;\n background: transparent;\n appearance: none;\n -moz-appearance: none;\n border: none;\n resize: none;\n outline: none;\n overflow: hidden;\n}\n\n.ace_layer {\n z-index: 1;\n position: absolute;\n overflow: hidden;\n white-space: nowrap;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n /* setting pointer-events: auto; on node under the mouse, which changes\n during scroll, will break mouse wheel scrolling in Safari */\n pointer-events: none;\n}\n\n.ace_gutter .ace_layer {\n position: relative;\n min-width: 40px;\n text-align: right;\n pointer-events: auto;\n}\n\n.ace_text-layer {\n color: black;\n}\n\n.ace_cjk {\n display: inline-block;\n text-align: center;\n}\n\n.ace_cursor-layer {\n z-index: 4;\n}\n\n.ace_cursor {\n z-index: 4;\n position: absolute;\n}\n\n.ace_cursor.ace_hidden {\n opacity: 0.2;\n}\n\n.ace_editor.multiselect .ace_cursor {\n border-left-width: 1px;\n}\n\n.ace_line {\n white-space: nowrap;\n}\n\n.ace_marker-layer .ace_step {\n position: absolute;\n z-index: 3;\n}\n\n.ace_marker-layer .ace_selection {\n position: absolute;\n z-index: 5;\n}\n\n.ace_marker-layer .ace_bracket {\n position: absolute;\n z-index: 6;\n}\n\n.ace_marker-layer .ace_active_line {\n position: absolute;\n 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 box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n}\n\n.ace_line .ace_fold {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n \n display: inline-block;\n height: 11px;\n margin-top: -2px;\n vertical-align: middle;\n\n background-image: \n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%3AIDAT8%11c%FC%FF%FF%7F%18%03%1A%60%01%F2%3F%A0%891%80%04%FF%11-%F8%17%9BJ%E2%05%B1ZD%81v%26t%E7%80%F8%A3%82h%A12%1A%20%A3%01%02%0F%01%BA%25%06%00%19%C0%0D%AEF%D5%3ES%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat, repeat-x;\n background-position: center center, top left;\n color: transparent;\n\n border: 1px solid black;\n -moz-border-radius: 2px;\n -webkit-border-radius: 2px;\n border-radius: 2px;\n \n cursor: pointer;\n pointer-events: auto;\n}\n\n.ace_dark .ace_fold {\n}\n\n.ace_fold:hover{\n background-image: \n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%003IDAT8%11c%FC%FF%FF%7F%3E%03%1A%60%01%F2%3F%A3%891%80%04%FFQ%26%F8w%C0%B43%A1%DB%0C%E2%8F%0A%A2%85%CAh%80%8C%06%08%3C%04%E8%96%18%00%A3S%0D%CD%CF%D8%C1%9D%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat, repeat-x;\n background-position: center center, top left;\n}\n\n.ace_dragging .ace_content {\n cursor: move;\n}\n\n.ace_folding-enabled > .ace_gutter-cell {\n padding-right: 13px;\n}\n\n.ace_fold-widget {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n\n margin: 0 -12px 1px 1px;\n display: inline-block;\n height: 14px;\n width: 11px;\n vertical-align: text-bottom;\n \n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAe%8A%B1%0D%000%0C%C2%F2%2CK%96%BC%D0%8F9%81%88H%E9%D0%0E%96%C0%10%92%3E%02%80%5E%82%E4%A9*-%EEsw%C8%CC%11%EE%96w%D8%DC%E9*Eh%0C%151(%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat;\n background-position: center 5px;\n\n border-radius: 3px;\n}\n\n.ace_fold-widget.end {\n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAm%C7%C1%09%000%08C%D1%8C%ECE%C8E(%8E%EC%02)%1EZJ%F1%C1'%04%07I%E1%E5%EE%CAL%F5%A2%99%99%22%E2%D6%1FU%B5%FE0%D9x%A7%26Wz5%0E%D5%00%00%00%00IEND%AEB%60%82\");\n}\n\n.ace_fold-widget.closed {\n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%03%00%00%00%06%08%06%00%00%00%06%E5%24%0C%00%00%009IDATx%DA5%CA%C1%09%000%08%03%C0%AC*(%3E%04%C1%0D%BA%B1%23%A4Uh%E0%20%81%C0%CC%F8%82%81%AA%A2%AArGfr%88%08%11%11%1C%DD%7D%E0%EE%5B%F6%F6%CB%B8%05Q%2F%E9tai%D9%00%00%00%00IEND%AEB%60%82\");\n}\n\n.ace_fold-widget:hover {\n border: 1px solid rgba(0, 0, 0, 0.3);\n background-color: rgba(255, 255, 255, 0.2);\n -moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n -moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n -webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n -webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n background-position: center 4px;\n}\n\n.ace_fold-widget:active {\n border: 1px solid rgba(0, 0, 0, 0.4);\n background-color: rgba(0, 0, 0, 0.05);\n -moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n -moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n -webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n -webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n}\n\n.ace_fold-widget.invalid {\n background-color: #FFB4B4;\n border-color: #DE5555;\n}\n"),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(a,b,c){function j(a,b,c){return i.$options.wrap=!0,i.$options.needle=b,i.$options.backwards=c==-1,i.find(a)}function m(a,b){return a.row==b.row&&a.column==b.column}function n(a){a.$onAddRange=a.$onAddRange.bind(a),a.$onRemoveRange=a.$onRemoveRange.bind(a),a.$onMultiSelect=a.$onMultiSelect.bind(a),a.$onSingleSelect=a.$onSingleSelect.bind(a),b.onSessionChange.call(a,a),a.on("changeSession",b.onSessionChange.bind(a)),a.on("mousedown",g),a.commands.addCommands(b.commands.defaultCommands),o(a)}function o(a){function e(){c&&(d.style.cursor="",c=!1)}var b=a.textInput.getElement(),c=!1,d=a.renderer.content;b.addEventListener("keydown",function(a){a.keyCode==18&&!(a.ctrlKey||a.shiftKey||a.metaKey)?c||(d.style.cursor="crosshair",c=!0):c&&(d.style.cursor="")}),b.addEventListener("keyup",e),b.addEventListener("blur",e)}var d=a("./range_list").RangeList,e=a("./range").Range,f=a("./selection").Selection,g=a("./mouse/multi_select_handler").onMouseDown;b.commands=a("./commands/multi_select_commands");var h=a("./search").Search,i=new h,k=a("./edit_session").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(k.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(a,b){if(!a)return;if(!this.inMultiSelectMode&&this.rangeCount==0){var c=this.toOrientedRange();if(a.intersects(c))return b||this.fromOrientedRange(a);this.rangeList.add(c),this.$onAddRange(c)}a.cursor||(a.cursor=a.end);var d=this.rangeList.add(a);return this.$onAddRange(a),d.length&&this.$onRemoveRange(d),this.rangeCount>1&&!this.inMultiSelectMode&&(this._emit("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),b||this.fromOrientedRange(a)},this.toSingleRange=function(a){a=a||this.ranges[0];var b=this.rangeList.removeAll();b.length&&this.$onRemoveRange(b),a&&this.fromOrientedRange(a)},this.substractPoint=function(a){var b=this.rangeList.substractPoint(a);if(b)return this.$onRemoveRange(b),b[0]},this.mergeOverlappingRanges=function(){var a=this.rangeList.merge();a.length?this.$onRemoveRange(a):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(a){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(a),this._emit("addRange",{range:a})},this.$onRemoveRange=function(a){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var b=this.rangeList.ranges.pop();a.push(b),this.rangeCount=0}for(var c=a.length;c--;){var d=this.ranges.indexOf(a[c]);this.ranges.splice(d,1)}this._emit("removeRange",{ranges:a}),this.rangeCount==0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._emit("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),b=b||this.ranges[0],b&&!b.isEqual(this.getRange())&&this.fromOrientedRange(b)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new d,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeList.ranges.concat()},this.splitIntoLines=function(){if(this.rangeCount>1){var a=this.rangeList.ranges,b=a[a.length-1],c=e.fromPoints(a[0].start,b.end);this.toSingleRange(),this.setSelectionRange(c,b.cursor==b.start)}else{var d=this.session.documentToScreenPosition(this.selectionLead),f=this.session.documentToScreenPosition(this.selectionAnchor),g=this.rectangularRangeBlock(d,f);g.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(a,b,c){var d=[],f=a.column0)p--;if(p>0){var q=0;while(d[q].isEmpty())q++}for(var r=p;r>=q;r--)d[r].isEmpty()&&d.splice(r,1)}return d}}.call(f.prototype);var l=a("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(a){a.cursor||(a.cursor=a.end);var b=this.getSelectionStyle();return a.marker=this.session.addMarker(a,"ace_selection",b),this.session.$selectionMarkers.push(a),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,a},this.removeSelectionMarker=function(a){if(!a.marker)return;this.session.removeMarker(a.marker);var b=this.session.$selectionMarkers.indexOf(a);b!=-1&&this.session.$selectionMarkers.splice(b,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(a){var b=this.session.$selectionMarkers;for(var c=a.length;c--;){var d=a[c];if(!d.marker)continue;this.session.removeMarker(d.marker);var e=b.indexOf(d);e!=-1&&b.splice(e,1)}this.session.selectionMarkerCount=b.length},this.$onAddRange=function(a){this.addSelectionMarker(a.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(a){this.removeSelectionMarkers(a.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(a){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("multiselect"),this.keyBinding.addKeyboardHandler(b.commands.keyboardHandler),this.commands.on("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(a){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("multiselect"),this.keyBinding.removeKeyboardHandler(b.commands.keyboardHandler),this.commands.removeEventListener("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelectExec=function(a){var b=a.command,c=a.editor;b.multiSelectAction?b.multiSelectAction=="forEach"?c.forEachSelection(b,a.args):b.multiSelectAction=="single"?(c.exitMultiSelectMode(),b.exec(c,a.args||{})):b.multiSelectAction(c,a.args||{}):(b.exec(c,a.args||{}),c.multiSelect.addRange(c.multiSelect.toOrientedRange()),c.multiSelect.mergeOverlappingRanges()),a.preventDefault()},this.forEachSelection=function(a,b){if(this.inVirtualSelectionMode)return;var c=this.session,d=this.selection,e=d.rangeList,g=d._eventRegistry;d._eventRegistry={};var h=new f(c);this.inVirtualSelectionMode=!0;for(var i=e.ranges.length;i--;)h.fromOrientedRange(e.ranges[i]),this.selection=c.selection=h,a.exec(this,b||{}),h.toOrientedRange(e.ranges[i]);h.detach(),this.selection=c.selection=d,this.inVirtualSelectionMode=!1,d._eventRegistry=g,d.mergeOverlappingRanges(),this.onCursorChange(),this.onSelectionChange()},this.exitMultiSelectMode=function(){if(this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getCopyText=function(){var a="";if(this.inMultiSelectMode){var b=this.multiSelect.rangeList.ranges;a=[];for(var c=0;c0)continue;return f==0?d:(f=this.comparePoints(a,e.start),f>=0?d:-d-1)}return-d-1},this.add=function(a){var b=this.pointIndex(a.start);b<0&&(b=-b-1);var c=this.pointIndex(a.end,b);return c<0?c=-c-1:c++,this.ranges.splice(b,c-b,a)},this.addList=function(a){var b=[];for(var c=a.length;c--;)b.push.call(b,this.add(a[c]));return b},this.substractPoint=function(a){var b=this.pointIndex(a);if(b>=0)return this.ranges.splice(b,1)},this.merge=function(){var a=[],b=this.ranges,c=b[0],d;for(var e=1;e=0},this.containsPoint=function(a){return this.pointIndex(a)>=0},this.rangeAtPoint=function(a){var b=this.pointIndex(a);if(b>=0)return this.ranges[b]},this.clipRows=function(a,b){var c=this.ranges;if(c[0].start.row>b||c[c.length-1].start.rowe)break;l.start.row==e&&l.start.column>=c.column&&(l.start.column+=h,l.start.row+=g),l.end.row==e&&l.end.column>=c.column&&(l.end.column+=h,l.end.row+=g)}if(g!=0&&j=this.pos.column&&c.start.column<=this.pos.column+this.length+1){var f=c.start.column-this.pos.column;this.length+=e;if(!this.session.$fromUndo){if(b.action==="insertText")for(var g=this.others.length-1;g>=0;g--){var h=this.others[g],i={row:h.row,column:h.column+f};h.row===c.start.row&&c.start.column=0;g--){var h=this.others[g],i={row:h.row,column:h.column+f};h.row===c.start.row&&c.start.column=this.pos.column&&b.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",a)):(this.hideOtherMarkers(),this._emit("cursorLeave",a))},this.detach=function(){this.session.removeMarker(this.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.pos.detach();for(var a=0;a1&&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})}),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)}}),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)}}),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()}}),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)}}),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}}),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.commands=new o(f.isMac?"mac":"win",p),this.textInput=new g(a.getTextAreaContainer(),this),this.renderer.textarea=this.textInput.getElement(),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.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.$cursorChange=function(){this.renderer.updateCursor()},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.$cursorChange()},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.$cursorChange(),this.$blockScrolling||this.renderer.scrollCursorIntoView(),this.$highlightBrackets(),this.$updateHighlightActiveLine()},this.$updateHighlightActiveLine=function(){var a=this.getSession();a.$highlightLineMarker&&a.removeMarker(a.$highlightLineMarker),a.$highlightLineMarker=null;if(this.$highlightActiveLine){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.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.onCopy=function(){this.commands.exec("copy",this)},this.onCut=function(){this.commands.exec("cut",this)},this.onPaste=function(a){this._emit("paste",a),this.insert(a)},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){this.keyBinding.onTextInput(a)},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.$highlightGutterLine=!0,this.setHighlightGutterLine=function(a){if(this.$highlightGutterLine==a)return;this.renderer.setHighlightGutterLine(a)},this.getHighlightGutterLine=function(){return this.$highlightGutterLine},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.setFadeFoldWidgets=function(a){this.renderer.setFadeFoldWidgets(a)},this.getFadeFoldWidgets=function(){return this.renderer.getFadeFoldWidgets()},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.$moveByPage=function(a,b){var c=this.renderer,d=this.renderer.layerConfig,e=a*Math.floor(d.height/d.lineHeight);this.$blockScrolling++,b==1?this.selection.$moveSelection(function(){this.moveCursorBy(e,0)}):b==0&&(this.selection.moveCursorBy(e,0),this.selection.clearSelection()),this.$blockScrolling--;var f=c.scrollTop;c.scrollBy(0,e*d.lineHeight),b!=null&&c.scrollCursorIntoView(null,.5),c.animateScrolling(f)},this.selectPageDown=function(){this.$moveByPage(1,!0)},this.selectPageUp=function(){this.$moveByPage(-1,!0)},this.gotoPageDown=function(){this.$moveByPage(1,!1)},this.gotoPageUp=function(){this.$moveByPage(-1,!1)},this.scrollPageDown=function(){this.$moveByPage(1)},this.scrollPageUp=function(){this.$moveByPage(-1)},this.scrollToRow=function(a){this.renderer.scrollToRow(a)},this.scrollToLine=function(a,b,c,d){this.renderer.scrollToLine(a,b,c,d)},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,c){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(a-1)||this.scrollToLine(a-1,!0,c)},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(){var a=this.renderer.scrollTop;this.selection.moveCursorFileEnd(),this.clearSelection(),this.renderer.animateScrolling(a)},this.navigateFileStart=function(){var a=this.renderer.scrollTop;this.selection.moveCursorFileStart(),this.clearSelection(),this.renderer.animateScrolling(a)},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,c){this.clearSelection(),b=b||{},b.needle=a,this.$search.set(b),this.$find(!1,c)},this.findNext=function(a,b){a=a||{},this.$search.set(a),this.$find(!1,b)},this.findPrevious=function(a,b){a=a||{},this.$search.set(a),this.$find(!0,b)},this.$find=function(a,b){this.selection.isEmpty()||this.$search.set({needle:this.session.getTextRange(this.getSelectionRange())}),typeof a!="undefined"&&this.$search.set({backwards:a});var c=this.$search.find(this.session);if(c){this.$blockScrolling+=1,this.session.unfold(c),this.selection.setSelectionRange(c),this.$blockScrolling-=1;var d=this.renderer.scrollTop;this.renderer.scrollSelectionIntoView(c.start,c.end,.5),this.renderer.animateScrolling(d)}},this.undo=function(){this.$blockScrolling++,this.session.getUndoManager().undo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.redo=function(){this.$blockScrolling++,this.session.getUndoManager().redo(),this.$blockScrolling--,this.renderer.scrollCursorIntoView(null,.5)},this.destroy=function(){this.renderer.destroy()}}).call(q.prototype),b.Editor=q}),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;c1&&(d.charAt(0)==g?d=d.substr(1):d.charAt(d.length-1)==g&&(d=d.slice(0,-1))),d&&d!=g&&(j?b.onPaste(d):b.onTextInput(d));if(!v())return!1}}i=!1,j=!1,c.value=g,l()}function v(){return document.activeElement===c}var c=f.createElement("textarea");e.isTouchPad&&c.setAttribute("x-palm-disable-auto-cap",!0),c.setAttribute("wrap","off"),c.style.left="-10000px",c.style.position="fixed",a.insertBefore(c,a.firstChild);var g=String.fromCharCode(0);m();var h=!1,i=!1,j=!1,k="",n=function(a){setTimeout(function(){h||m(a.data)},0)},o=function(a){if(e.isOldIE&&c.value.charCodeAt(0)>128)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}),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(this),new f(this),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)},this.setState=function(a){this.state=a},this.captureMouse=function(a,b){b&&this.setState(b),this.x=a.x,this.y=a.y;var c=this.editor.renderer.$keepTextAreaAtCursor;this.editor.renderer.$keepTextAreaAtCursor=!1;var e=this,f=function(a){e.x=a.clientX,e.y=a.clientY},g=function(a){clearInterval(i),e[e.state+"End"]&&e[e.state+"End"](a),e.$clickSelection=null,e.editor.renderer.$keepTextAreaAtCursor=c,e.editor.renderer.$moveTextAreaToCursor()},h=function(){e[e.state]&&e[e.state]()};d.capture(this.editor.container,f,g);var i=setInterval(h,20);a.preventDefault()}}).call(h.prototype),b.MouseHandler=h}),define("ace/mouse/default_handlers",["require","exports","module","ace/lib/dom","ace/lib/browser_focus"],function(a,b,c){function g(a){a.$clickSelection=null,a.browserFocus=new e;var b=a.editor;b.setDefaultHandler("mousedown",this.onMouseDown.bind(a)),b.setDefaultHandler("dblclick",this.onDoubleClick.bind(a)),b.setDefaultHandler("tripleclick",this.onTripleClick.bind(a)),b.setDefaultHandler("quadclick",this.onQuadClick.bind(a)),b.setDefaultHandler("mousewheel",this.onScroll.bind(a));var c=["select","startSelect","drag","dragEnd","dragWait","dragWaitEnd","startDrag"];c.forEach(function(b){a[b]=this[b]},this),a.selectByLines=this.extendSelectionBy.bind(a,"getLineRange"),a.selectByWords=this.extendSelectionBy.bind(a,"getWordRange")}function h(a,b,c,d){return Math.sqrt(Math.pow(c-a,2)+Math.pow(d-b,2))}"use strict";var d=a("../lib/dom"),e=a("../lib/browser_focus").BrowserFocus,f=5;(function(){this.onMouseDown=function(a){this.mousedownEvent=a;var b=a.inSelection(),c=a.getDocumentPosition(),d=this.editor,e=this;this.ev=a;var f=d.getSelectionRange(),g=f.isEmpty(),h=a.getButton();if(h!==0){g&&(d.moveCursorToPosition(c),d.selection.clearSelection()),this.moveTextarea=function(){d.textInput.onContextMenu({x:e.x,y:e.y})},this.moveTextareaEnd=d.textInput.onContextMenuClose,d.textInput.onContextMenu({x:this.x,y:this.y},g),this.captureMouse(a,"moveTextarea");return}if(b&&!d.isFocused()){d.focus();return}if(!b||this.$clickSelection||a.getShiftKey())this.startSelect(c);else if(b){var i=a.domEvent;i.ctrlKey||i.altKey?this.startDrag():(this.mousedownEvent.time=(new Date).getTime(),this.setState("dragWait"))}this.captureMouse(a)},this.startSelect=function(a){a=a||this.editor.renderer.screenToTextCoordinates(this.x,this.y),this.mousedownEvent.getShiftKey()?this.editor.selection.selectToPosition(a):this.$clickSelection||(this.editor.moveCursorToPosition(a),this.editor.selection.clearSelection()),this.setState("select")},this.select=function(){var a,b=this.editor,c=b.renderer.screenToTextCoordinates(this.x,this.y);if(this.$clickSelection){var d=this.$clickSelection.comparePoint(c);d==-1?a=this.$clickSelection.end:d==1?a=this.$clickSelection.start:(c=this.$clickSelection.end,a=this.$clickSelection.start),b.selection.setSelectionAnchor(a.row,a.column)}b.selection.selectToPosition(c),b.renderer.scrollCursorIntoView()},this.extendSelectionBy=function(a){var b,c=this.editor,d=c.renderer.screenToTextCoordinates(this.x,this.y),e=c.selection[a](d.row,d.column);if(this.$clickSelection){var f=this.$clickSelection.comparePoint(e.start),g=this.$clickSelection.comparePoint(e.end);f==-1&&g<=0?(b=this.$clickSelection.end,d=e.start):g==1&&f>=0?(b=this.$clickSelection.start,d=e.end):f==-1&&g==1?(d=e.end,b=e.start):(d=this.$clickSelection.end,b=this.$clickSelection.start),c.selection.setSelectionAnchor(b.row,b.column)}c.selection.selectToPosition(d),c.renderer.scrollCursorIntoView()},this.startDrag=function(){var a=this.editor;this.setState("drag"),this.dragRange=a.getSelectionRange();var b=a.getSelectionStyle();this.dragSelectionMarker=a.session.addMarker(this.dragRange,"ace_selection",b),a.clearSelection(),d.addCssClass(a.container,"ace_dragging"),this.$dragKeybinding||(this.$dragKeybinding={handleKeyboard:function(a,b,c,d){if(c=="esc")return{command:this.command}},command:{exec:function(a){var b=a.$mouseHandler;b.dragCursor=null,b.dragEnd(),b.startSelect()}}}),a.keyBinding.addKeyboardHandler(this.$dragKeybinding)},this.dragWait=function(){var a=h(this.mousedownEvent.x,this.mousedownEvent.y,this.x,this.y),b=(new Date).getTime(),c=this.editor;a>f?this.startSelect():b-this.mousedownEvent.time>c.getDragDelay()&&this.startDrag()},this.dragWaitEnd=function(a){this.mousedownEvent.domEvent=a,this.startSelect()},this.drag=function(){var a=this.editor;this.dragCursor=a.renderer.screenToTextCoordinates(this.x,this.y),a.moveCursorToPosition(this.dragCursor),a.renderer.scrollCursorIntoView()},this.dragEnd=function(a){var b=this.editor,c=this.dragCursor,e=this.dragRange;d.removeCssClass(b.container,"ace_dragging"),b.session.removeMarker(this.dragSelectionMarker),b.keyBinding.removeKeyboardHandler(this.$dragKeybinding);if(!c)return;b.clearSelection();if(a&&(a.ctrlKey||a.altKey)){var f=b.session,g=e;g.end=f.insert(c,f.getTextRange(e)),g.start=c}else{if(e.contains(c.row,c.column))return;var g=b.moveText(e,c)}if(!g)return;b.selection.setSelectionRange(g)},this.onDoubleClick=function(a){var b=a.getDocumentPosition(),c=this.editor;this.setState("selectByWords"),c.moveCursorToPosition(b),c.selection.selectWord(),this.$clickSelection=c.getSelectionRange()},this.onTripleClick=function(a){var b=a.getDocumentPosition(),c=this.editor;this.setState("selectByLines"),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.setState("select")},this.onScroll=function(a){var b=this.editor,c=b.renderer.isScrollableBy(a.wheelX*a.speed,a.wheelY*a.speed);if(c)this.$passScrollEvent=!1;else{if(this.$passScrollEvent)return;if(!this.$scrollStopTimeout){var d=this;this.$scrollStopTimeout=setTimeout(function(){d.$passScrollEvent=!0,d.$scrollStopTimeout=null},200)}}return b.renderer.scrollBy(a.wheelX*a.speed,a.wheelY*a.speed),a.preventDefault()}}).call(g.prototype),b.DefaultHandlers=g}),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}),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,j,k=a;b=Math.min(b,c.length-1);while(k<=b){j=this.getFoldLine(k,j);if(!j)h=this.$getDisplayTokens(f.stringTrimRight(c[k])),e[k]=this.$computeWrapSplits(h,g,d),k++;else{h=[],j.walk(function(a,b,d,e){var f;if(a){f=this.$getDisplayTokens(a,h.length),f[0]=i;for(var g=1;g=o)h.pop();e[j.start.row]=this.$computeWrapSplits(h,g,d),k=j.end.row+1}}};var b=1,c=2,i=3,l=4,n=9,o=10,p=11,q=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]>=o){while(a[h]>=o)h++;g(h);continue}if(a[h]==i||a[h]==l){for(h;h!=e-1;h--)if(a[h]==i)break;if(h>e){g(h);continue}h=e+b;for(h;hj&&a[h]j&&a[h]==n)h--;if(h>j){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(n):h>=4352&&r(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&&r(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}),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.anchor,b=this.lead;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.lead;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.getWordRange=function(a,b){if(typeof b=="undefined"){var c=a||this.lead;a=c.row,b=c.column}return this.session.getWordRange(a,b)},this.selectWord=function(){this.setSelectionRange(this.getWordRange())},this.selectAWord=function(){var a=this.getCursor(),b=this.session.getAWordRange(a.row,a.column);this.setSelectionRange(b)},this.getLineRange=function(a,b){var c=typeof a=="number"?a:this.lead.row,d,e=this.session.getFoldLine(c);return e?(c=e.start.row,d=e.end.row):d=c,b?new g(c,0,d,this.session.getLine(d).length):new g(c,0,d+1,0)},this.selectLine=function(){this.setSelectionRange(this.getLineRange())},this.moveCursorUp=function(){this.moveCursorBy(-1,0)},this.moveCursorDown=function(){this.moveCursorBy(1,0)},this.moveCursorLeft=function(){var a=this.lead.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.lead.getPosition(),b;if(b=this.session.getFoldAt(a.row,a.column,1))this.moveCursorTo(b.end.row,b.end.column);else if(this.lead.column==this.doc.getLine(this.lead.row).length)this.lead.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.$shortWordEndIndex=function(a){var b,c=0,d,e=/\s/,f=this.session.tokenRe;f.lastIndex=0;if(b=this.session.tokenRe.exec(a))c=this.session.tokenRe.lastIndex;else{while((d=a[c])&&e.test(d))c++;if(c<=1){f.lastIndex=0;while((d=a[c])&&!f.test(d)){f.lastIndex=0,c++;if(e.test(d)){if(c>2){c--;break}while((d=a[c])&&e.test(d))c++;if(c>2)break}}}}return f.lastIndex=0,c},this.moveCursorShortWordRight=function(){var a=this.lead.row,b=this.lead.column,c=this.doc.getLine(a),d=c.substring(b),e=this.session.getFoldAt(a,b,1);if(e)return this.moveCursorTo(e.end.row,e.end.column);if(b==c.length)return this.moveCursorRight();var f=this.$shortWordEndIndex(d);this.moveCursorTo(a,b+f)},this.moveCursorShortWordLeft=function(){var a=this.lead.row,b=this.lead.column,c;if(c=this.session.getFoldAt(a,b,-1))return this.moveCursorTo(c.start.row,c.start.column);if(b==0)return this.moveCursorLeft();var d=this.session.getLine(a).substring(0,b),f=e.stringReverse(d),g=this.$shortWordEndIndex(f);return this.moveCursorTo(a,b-g)},this.moveCursorWordRight=function(){this.session.$selectLongWords?this.moveCursorLongWordRight():this.moveCursorShortWordRight()},this.moveCursorWordLeft=function(){this.session.$selectLongWords?this.moveCursorLongWordLeft():this.moveCursorShortWordLeft()},this.moveCursorBy=function(a,b){var c=this.session.documentToScreenPosition(this.lead.row,this.lead.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.lead.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.lead.detach(),this.anchor.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}),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}),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)}),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}),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}),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}),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,this.$keepTextAreaAtCursor=!g.isIE,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.setHighlightGutterLine(!0),this.$gutterLayer=new j(this.$gutter),this.$gutterLayer.on("changeGutterWidth",this.onResize.bind(this,!0)),this.setFadeFoldWidgets(!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=!1,this.$horizScrollAlwaysVisible=!1,this.$animatedScroll=!1,this.scrollBar=new n(a),this.scrollBar.addEventListener("scroll",function(a){c.$inScrollAnimation||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),c.scroller.className=a==0?"ace_scroller":"ace_scroller 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.scroller.className="ace_scroller",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.lastRowthis.layerConfig.height)return;b+=(this.showGutter?this.$gutterLayer.gutterWidth:0)-this.scrollLeft;var c=this.container.getBoundingClientRect();this.textarea.style.left=c.left+b+"px",this.textarea.style.top=c.top+a+"px"},this.getFirstVisibleRow=function(){return this.layerConfig.firstRow},this.getFirstFullyVisibleRow=function(){return this.layerConfig.firstRow+(this.layerConfig.offset===0?0:1)},this.getLastFullyVisibleRow=function(){var a=Math.floor((this.layerConfig.height+this.layerConfig.offset)/this.layerConfig.lineHeight);return this.layerConfig.firstRow-1+a},this.getLastVisibleRow=function(){return this.layerConfig.lastRow},this.$padding=null,this.setPadding=function(a){this.$padding=a,this.$textLayer.setPadding(a),this.$cursorLayer.setPadding(a),this.$markerFront.setPadding(a),this.$markerBack.setPadding(a),this.$loop.schedule(this.CHANGE_FULL),this.$updatePrintMargin()},this.getHScrollBarAlwaysVisible=function(){return this.$horizScrollAlwaysVisible},this.setHScrollBarAlwaysVisible=function(a){this.$horizScrollAlwaysVisible!=a&&(this.$horizScrollAlwaysVisible=a,(!this.$horizScrollAlwaysVisible||!this.$horizScroll)&&this.$loop.schedule(this.CHANGE_SCROLL))},this.$updateScrollBar=function(){this.scrollBar.setInnerHeight(this.layerConfig.maxHeight),this.scrollBar.setScrollTop(this.scrollTop)},this.$renderChanges=function(a){if(!a||!this.session||!this.container.offsetWidth)return;(a&this.CHANGE_FULL||a&this.CHANGE_SIZE||a&this.CHANGE_TEXT||a&this.CHANGE_LINES||a&this.CHANGE_SCROLL)&&this.$computeLayerConfig();if(a&this.CHANGE_H_SCROLL){this.scroller.scrollLeft=this.scrollLeft;var b=this.scroller.scrollLeft;this.scrollLeft=b,this.session.setScrollLeft(b)}if(a&this.CHANGE_FULL){this.$textLayer.checkForSizeChanges(),this.$updateScrollBar(),this.$textLayer.update(this.layerConfig),this.showGutter&&this.$gutterLayer.update(this.layerConfig),this.$markerBack.update(this.layerConfig),this.$markerFront.update(this.layerConfig),this.$cursorLayer.update(this.layerConfig),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight();return}if(a&this.CHANGE_SCROLL){this.$updateScrollBar(),a&this.CHANGE_TEXT||a&this.CHANGE_LINES?this.$textLayer.update(this.layerConfig):this.$textLayer.scrollLines(this.layerConfig),this.showGutter&&this.$gutterLayer.update(this.layerConfig),this.$markerBack.update(this.layerConfig),this.$markerFront.update(this.layerConfig),this.$cursorLayer.update(this.layerConfig),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight();return}a&this.CHANGE_TEXT?(this.$textLayer.update(this.layerConfig),this.showGutter&&this.$gutterLayer.update(this.layerConfig)):a&this.CHANGE_LINES?this.$updateLines()&&(this.$updateScrollBar(),this.showGutter&&this.$gutterLayer.update(this.layerConfig)):a&this.CHANGE_GUTTER&&this.showGutter&&this.$gutterLayer.update(this.layerConfig),a&this.CHANGE_CURSOR&&(this.$cursorLayer.update(this.layerConfig),this.$moveTextAreaToCursor(),this.$highlightGutterLine&&this.$updateGutterLineHighlight()),a&(this.CHANGE_MARKER|this.CHANGE_MARKER_FRONT)&&this.$markerFront.update(this.layerConfig),a&(this.CHANGE_MARKER|this.CHANGE_MARKER_BACK)&&this.$markerBack.update(this.layerConfig),a&this.CHANGE_SIZE&&this.$updateScrollBar()},this.$computeLayerConfig=function(){var a=this.session,b=this.scrollTop%this.lineHeight,c=this.$size.scrollerHeight+this.lineHeight,d=this.$getLongestLine(),e=this.$horizScrollAlwaysVisible||this.$size.scrollerWidth-d<0,f=this.$horizScroll!==e;this.$horizScroll=e,f&&(this.scroller.style.overflowX=e?"scroll":"hidden",e||this.session.setScrollLeft(0));var g=this.session.getScreenLength()*this.lineHeight;this.session.setScrollTop(Math.max(0,Math.min(this.scrollTop,g-this.$size.scrollerHeight)));var h=Math.ceil(c/this.lineHeight)-1,i=Math.max(0,Math.round((this.scrollTop-b)/this.lineHeight)),j=i+h,k,l,m={lineHeight:this.lineHeight};i=a.screenToDocumentRow(i,0);var n=a.getFoldLine(i);n&&(i=n.start.row),k=a.documentToScreenRow(i,0),l=a.getRowHeight(m,i),j=Math.min(a.screenToDocumentRow(j,0),a.getLength()-1),c=this.$size.scrollerHeight+a.getRowHeight(m,j)+l,b=this.scrollTop-k*this.lineHeight,this.layerConfig={width:d,padding:this.$padding,firstRow:i,firstRowScreen:k,lastRow:j,lineHeight:this.lineHeight,characterWidth:this.characterWidth,minHeight:c,maxHeight:g,offset:b,height:this.$size.scrollerHeight},this.$gutter.style.marginTop=-b+"px",this.content.style.marginTop=-b+"px",this.content.style.width=d+2*this.$padding+"px",this.content.style.height=c+"px",f&&this.onResize(!0)},this.$updateLines=function(){var a=this.$changedLines.firstRow,b=this.$changedLines.lastRow;this.$changedLines=null;var c=this.layerConfig;if(c.width!=this.$getLongestLine())return this.$textLayer.update(c);if(a>c.lastRow+1)return;if(be?(b&&(e-=b*this.$size.scrollerHeight),this.session.setScrollTop(e)):this.scrollTop+this.$size.scrollerHeightd?(d0)return!0;if(b>0&&this.session.getScrollTop()+this.$size.scrollerHeight0?1:-1}},this.screenToTextCoordinates=function(a,b){var c=this.scroller.getBoundingClientRect(),d=Math.round((a+this.scrollLeft-c.left-this.$padding)/this.characterWidth),e=Math.floor((b+this.scrollTop-c.top)/this.lineHeight);return this.session.screenToDocumentPosition(e,Math.max(d,0))},this.textToScreenCoordinates=function(a,b){var c=this.scroller.getBoundingClientRect(),d=this.session.documentToScreenPosition(a,b),e=this.$padding+Math.round(d.column*this.characterWidth),f=d.row*this.lineHeight;return{pageX:c.left+e-this.scrollLeft,pageY:c.top+f-this.scrollTop}},this.visualizeFocus=function(){e.addCssClass(this.container,"ace_focus")},this.visualizeBlur=function(){e.removeCssClass(this.container,"ace_focus")},this.showComposition=function(a){this.$composition||(this.$composition=e.createElement("div"),this.$composition.className="ace_composition",this.content.appendChild(this.$composition)),this.$composition.innerHTML=" ";var b=this.$cursorLayer.getPixelPosition(),c=this.$composition.style;c.top=b.top+"px",c.left=b.left+this.$padding+"px",c.height=this.lineHeight+"px",this.hideCursor()},this.setCompositionText=function(a){e.setInnerText(this.$composition,a)},this.hideComposition=function(){this.showCursor();if(!this.$composition)return;var a=this.$composition.style;a.top="-10000px",a.left="-10000px"},this._loadTheme=function(a,b){if(!h.get("packaged"))return b();var c=a.split("/").pop(),d=h.get("themePath")+"/theme-"+c+h.get("suffix");i.loadScript(d,b)},this.setTheme=function(b){function h(a){e.importCssString(a.cssText,a.cssClass,c.container.ownerDocument),c.$theme&&e.removeCssClass(c.container,c.$theme),c.$theme=a?a.cssClass:null,c.$theme&&e.addCssClass(c.container,c.$theme),a&&a.isDark?e.addCssClass(c.container,"ace_dark"):e.removeCssClass(c.container,"ace_dark"),c.$size&&(c.$size.width=0,c.onResize())}var c=this;this.$themeValue=b;if(!b||typeof b=="string"){var d=b||"ace/theme/textmate",f;try{f=a(d)}catch(g){}if(f)return h(f);c._loadTheme(d,function(){a([d],function(a){if(c.$themeValue!==b)return;h(a)})})}else h(b)},this.getTheme=function(){return this.$themeValue},this.setStyle=function(b){e.addCssClass(this.container,b)},this.unsetStyle=function(b){e.removeCssClass(this.container,b)},this.destroy=function(){this.$textLayer.destroy(),this.$cursorLayer.destroy()}}).call(r.prototype),b.VirtualRenderer=r}),define("ace/layer/gutter",["require","exports","module","ace/lib/dom","ace/lib/oop","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("../lib/dom"),e=a("../lib/oop"),f=a("../lib/event_emitter").EventEmitter,g=function(a){this.element=d.createElement("div"),this.element.className="ace_layer ace_gutter-layer",a.appendChild(this.element),this.setShowFoldWidgets(this.$showFoldWidgets),this.gutterWidth=0,this.$breakpoints=[],this.$annotations=[],this.$decorations=[]};(function(){e.implement(this,f),this.setSession=function(a){this.session=a},this.addGutterDecoration=function(a,b){this.$decorations[a]||(this.$decorations[a]=""),this.$decorations[a]+=" "+b},this.removeGutterDecoration=function(a,b){this.$decorations[a]=this.$decorations[a].replace(" "+b,"")},this.setBreakpoints=function(a){this.$breakpoints=a.concat()},this.setAnnotations=function(a){this.$annotations=[];for(var b in a)if(a.hasOwnProperty(b)){var c=a[b];if(!c)continue;var d=this.$annotations[b]={text:[]};for(var e=0;eh&&(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("
",e+1);if(i){var k=i[e];k==null&&(k=i[e]=this.session.getFoldWidget(e)),k&&c.push("")}var l=this.session.getRowLength(e)-1;while(l--)c.push("
¦");c.push("
"),e++}this.element=d.setInnerHtml(this.element,c.join("")),this.element.style.height=a.minHeight+"px";var m=this.element.offsetWidth;m!==this.gutterWidth&&(this.gutterWidth=m,this._emit("changeGutterWidth",m))},this.$showFoldWidgets=!0,this.setShowFoldWidgets=function(a){a?d.addCssClass(this.element,"ace_folding-enabled"):d.removeCssClass(this.element,"ace_folding-enabled"),this.$showFoldWidgets=a},this.getShowFoldWidgets=function(){return this.$showFoldWidgets}}).call(g.prototype),b.Gutter=g}),define("ace/layer/marker",["require","exports","module","ace/range","ace/lib/dom"],function(a,b,c){"use strict";var d=a("../range").Range,e=a("../lib/dom"),f=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_marker-layer",a.appendChild(this.element)};(function(){this.$padding=0,this.setPadding=function(a){this.$padding=a},this.setSession=function(a){this.session=a},this.setMarkers=function(a){this.markers=a},this.update=function(a){var a=a||this.config;if(!a)return;this.config=a;var b=[];for(var c in this.markers){var d=this.markers[c],f=d.range.clipRows(a.firstRow,a.lastRow);if(f.isEmpty())continue;f=f.toScreenRange(this.session);if(d.renderer){var g=this.$getTop(f.start.row,a),h=Math.round(this.$padding+f.start.column*a.characterWidth);d.renderer(b,f,h,g,a)}else f.isMultiLine()?d.type=="text"?this.drawTextMarker(b,f,d.clazz,a):this.drawMultiLineMarker(b,f,d.clazz,a,d.type):this.drawSingleLineMarker(b,f,d.clazz+" start",a,null,d.type)}this.element=e.setInnerHtml(this.element,b.join(""))},this.$getTop=function(a,b){return(a-b.firstRowScreen)*b.lineHeight},this.drawTextMarker=function(a,b,c,e){var f=b.start.row,g=new d(f,b.start.column,f,this.session.getScreenLastRowColumn(f));this.drawSingleLineMarker(a,g,c+" start",e,1,"text"),f=b.end.row,g=new d(f,0,f,b.end.column),this.drawSingleLineMarker(a,g,c,e,0,"text");for(f=b.start.row+1;f"),j=this.$getTop(b.end.row,d),i=Math.round(b.end.column*d.characterWidth),a.push("
"),h=(b.end.row-b.start.row-1)*d.lineHeight;if(h<0)return;j=this.$getTop(b.start.row+1,d),a.push("
")},this.drawSingleLineMarker=function(a,b,c,d,e,f){var g=f==="background"?0:this.$padding,h=d.lineHeight;if(f==="background")var i=d.width;else i=Math.round((b.end.column+(e||0)-b.start.column)*d.characterWidth);var j=this.$getTop(b.start.row,d),k=Math.round(g+b.start.column*d.characterWidth);a.push("
")}}).call(f.prototype),b.Marker=f}),define("ace/layer/text",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/lang","ace/lib/useragent","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("../lib/oop"),e=a("../lib/dom"),f=a("../lib/lang"),g=a("../lib/useragent"),h=a("../lib/event_emitter").EventEmitter,i=function(a){this.element=e.createElement("div"),this.element.className="ace_layer ace_text-layer",a.appendChild(this.element),this.$characterSize=this.$measureSizes()||{width:0,height:0},this.$pollSizeChanges()};(function(){d.implement(this,h),this.EOF_CHAR="¶",this.EOL_CHAR="¬",this.TAB_CHAR="→",this.SPACE_CHAR="·",this.$padding=0,this.setPadding=function(a){this.$padding=a,this.element.style.padding="0 "+a+"px"},this.getLineHeight=function(){return this.$characterSize.height||1},this.getCharacterWidth=function(){return this.$characterSize.width||1},this.checkForSizeChanges=function(){var a=this.$measureSizes();a&&(this.$characterSize.width!==a.width||this.$characterSize.height!==a.height)&&(this.$characterSize=a,this._emit("changeCharacterSize",{data:a}))},this.$pollSizeChanges=function(){var a=this;this.$pollSizeChangesTimer=setInterval(function(){a.checkForSizeChanges()},500)},this.$fontStyles={fontFamily:1,fontSize:1,fontWeight:1,fontStyle:1,lineHeight:1},this.$measureSizes=g.isIE||g.isOldGecko?function(){var a=1e3;if(!this.$measureNode){var b=this.$measureNode=e.createElement("div"),c=b.style;c.width=c.height="auto",c.left=c.top=-a*40+"px",c.visibility="hidden",c.position="fixed",c.overflow="visible",c.whiteSpace="nowrap",b.innerHTML=f.stringRepeat("Xy",a);if(this.element.ownerDocument.body)this.element.ownerDocument.body.appendChild(b);else{var d=this.element.parentNode;while(!e.hasCssClass(d,"ace_editor"))d=d.parentNode;d.appendChild(b)}}if(!this.element.offsetWidth)return null;var c=this.$measureNode.style,g=e.computedStyle(this.element);for(var h in this.$fontStyles)c[h]=g[h];var i={height:this.$measureNode.offsetHeight,width:this.$measureNode.offsetWidth/(a*2)};return i.width==0||i.height==0?null:i}:function(){if(!this.$measureNode){var a=this.$measureNode=e.createElement("div"),b=a.style;b.width=b.height="auto",b.left=b.top="-100px",b.visibility="hidden",b.position="fixed",b.overflow="visible",b.whiteSpace="nowrap",a.innerHTML="X";var c=this.element.parentNode;while(c&&!e.hasCssClass(c,"ace_editor"))c=c.parentNode;if(!c)return this.$measureNode=null;c.appendChild(a)}var d=this.$measureNode.getBoundingClientRect(),f={height:d.height,width:d.width};return f.width==0||f.height==0?null:f},this.setSession=function(a){this.session=a},this.showInvisibles=!1,this.setShowInvisibles=function(a){return this.showInvisibles==a?!1:(this.showInvisibles=a,!0)},this.$tabStrings=[],this.$computeTabString=function(){var a=this.session.getTabSize(),b=this.$tabStrings=[0];for(var c=1;c"+this.TAB_CHAR+(new Array(c)).join(" ")+"
"):b.push((new Array(c+1)).join(" "))},this.updateLines=function(a,b,c){this.$computeTabString(),(this.config.lastRow!=a.lastRow||this.config.firstRow!=a.firstRow)&&this.scrollLines(a),this.config=a;var d=Math.max(b,a.firstRow),f=Math.min(c,a.lastRow),g=this.element.childNodes,h=0;for(var i=a.firstRow;i0;d--)c.removeChild(c.firstChild);if(b.lastRow>a.lastRow)for(var d=this.session.getFoldedRowCount(a.lastRow+1,b.lastRow);d>0;d--)c.removeChild(c.lastChild);if(a.firstRowb.lastRow){var e=this.$renderLinesFragment(a,b.lastRow+1,a.lastRow);c.appendChild(e)}},this.$renderLinesFragment=function(a,b,c){var d=this.element.ownerDocument.createDocumentFragment(),f=b,g=this.session.getNextFoldLine(f),h=g?g.start.row:Infinity;for(;;){f>h&&(f=g.end.row+1,g=this.session.getNextFoldLine(f,g),h=g?g.start.row:Infinity);if(f>c)break;var i=e.createElement("div"),j=[],k=this.session.getTokens(f,f);k.length==1&&this.$renderLine(j,f,k[0].tokens,!1),i.innerHTML=j.join("");if(this.$useLineGroups())i.className="ace_line_group",d.appendChild(i);else{var l=i.childNodes;while(l.length)d.appendChild(l[0])}f++}return d},this.update=function(a){this.$computeTabString(),this.config=a;var b=[],c=a.firstRow,d=a.lastRow,f=c,g=this.session.getNextFoldLine(f),h=g?g.start.row:Infinity;for(;;){f>h&&(f=g.end.row+1,g=this.session.getNextFoldLine(f,g),h=g?g.start.row:Infinity);if(f>d)break;this.$useLineGroups()&&b.push("
");var i=this.session.getTokens(f,f);i.length==1&&this.$renderLine(b,f,i[0].tokens,!1),this.$useLineGroups()&&b.push("
"),f++}this.element=e.setInnerHtml(this.element,b.join(""))},this.$textToken={text:!0,rparen:!0,lparen:!0},this.$renderToken=function(a,b,c,d){var e=this,f=/\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,g=function(a,c,d,f,g){if(c)return(new Array(a.length+1)).join(" ");if(a=="&")return"&";if(a=="<")return"<";if(a==" "){var h=e.session.getScreenTabSize(b+f);return b+=h-1,e.$tabStrings[h]}if(a==" "){var i=e.showInvisibles?"ace_cjk ace_invisible":"ace_cjk",j=e.showInvisibles?e.SPACE_CHAR:"";return b+=1,""+j+""}return d?""+e.SPACE_CHAR+"":(b+=1,""+a+"")},h=d.replace(f,g);if(!this.$textToken[c.type]){var i="ace_"+c.type.replace(/\./g," ace_"),j="";c.type=="fold"&&(j=" style='width:"+c.value.length*this.config.characterWidth+"px;' "),a.push("",h,"")}else a.push(h);return b+d.length},this.$renderLineCore=function(a,b,c,d,e){var f=0,g=0,h,i=0,j=this;!d||d.length==0?h=Number.MAX_VALUE:h=d[0],e||a.push("
");for(var k=0;k=h)i=j.$renderToken(a,i,l,m.substring(0,h-f)),m=m.substring(h-f),f=h,e||a.push("
","
"),g++,i=0,h=d[g]||Number.MAX_VALUE;m.length!=0&&(f+=m.length,i=j.$renderToken(a,i,l,m))}}this.showInvisibles&&(b!==this.session.getLength()-1?a.push(""+this.EOL_CHAR+""):a.push(""+this.EOF_CHAR+"")),e||a.push("
")},this.$renderLine=function(a,b,c,d){if(!this.session.isRowFolded(b)){var e=this.session.getRowSplitData(b);this.$renderLineCore(a,b,c,e,d)}else this.$renderFoldLine(a,b,c,d)},this.$renderFoldLine=function(a,b,c,d){function h(a,b,c){var d=0,e=0;while(e+a[d].value.lengthc-b&&(f=f.substring(0,c-b)),g.push({type:a[d].type,value:f}),e=b+f.length,d+=1}while(ec&&(f=f.substring(0,c-e)),g.push({type:a[d].type,value:f}),e+=f.length,d+=1}}var e=this.session,f=e.getFoldLine(b),g=[];f.walk(function(a,b,d,e,f){a?g.push({type:"fold",value:a}):(f&&(c=this.session.getTokens(b,b)[0].tokens),c.length!=0&&h(c,e,d))}.bind(this),f.end.row,this.session.getLine(f.end.row).length);var i=this.session.$useWrapMode?this.session.$wrapData[b]:null;this.$renderLineCore(a,b,g,i,d)},this.$useLineGroups=function(){return this.session.getUseWrapMode()},this.destroy=function(){clearInterval(this.$pollSizeChangesTimer),this.$measureNode&&this.$measureNode.parentNode.removeChild(this.$measureNode),delete this.$measureNode}}).call(i.prototype),b.Text=i}),define("ace/layer/cursor",["require","exports","module","ace/lib/dom"],function(a,b,c){"use strict";var d=a("../lib/dom"),e=function(a){this.element=d.createElement("div"),this.element.className="ace_layer ace_cursor-layer",a.appendChild(this.element),this.isVisible=!1,this.cursors=[],this.cursor=this.addCursor()};(function(){this.$padding=0,this.setPadding=function(a){this.$padding=a},this.setSession=function(a){this.session=a},this.addCursor=function(){var a=d.createElement("div"),b="ace_cursor";return this.isVisible||(b+=" ace_hidden"),this.overwrite&&(b+=" ace_overwrite"),a.className=b,this.element.appendChild(a),this.cursors.push(a),a},this.removeCursor=function(){if(this.cursors.length>1){var a=this.cursors.pop();return a.parentNode.removeChild(a),a}},this.hideCursor=function(){this.isVisible=!1;for(var a=this.cursors.length;a--;)d.addCssClass(this.cursors[a],"ace_hidden");clearInterval(this.blinkId)},this.showCursor=function(){this.isVisible=!0;for(var a=this.cursors.length;a--;)d.removeCssClass(this.cursors[a],"ace_hidden");this.element.style.visibility="",this.restartTimer()},this.restartTimer=function(){clearInterval(this.blinkId);if(!this.isVisible)return;var a=this.cursors.length==1?this.cursor:this.element;this.blinkId=setInterval(function(){a.style.visibility="hidden",setTimeout(function(){a.style.visibility=""},400)},1e3)},this.getPixelPosition=function(a,b){if(!this.config||!this.session)return{left:0,top:0};a||(a=this.session.selection.getCursor());var c=this.session.documentToScreenPosition(a),d=Math.round(this.$padding+c.column*this.config.characterWidth),e=(c.row-(b?this.config.firstRowScreen:0))*this.config.lineHeight;return{left:d,top:e}},this.update=function(a){this.config=a;if(this.session.selectionMarkerCount>0){var b=this.session.$selectionMarkers,c=0,d,e=0;for(var c=b.length;c--;){d=b[c];var f=this.getPixelPosition(d.cursor,!0),g=(this.cursors[e++]||this.addCursor()).style;g.left=f.left+"px",g.top=f.top+"px",g.width=a.characterWidth+"px",g.height=a.lineHeight+"px"}if(e>1)while(this.cursors.length>e)this.removeCursor()}else{var f=this.getPixelPosition(null,!0),g=this.cursor.style;g.left=f.left+"px",g.top=f.top+"px",g.width=a.characterWidth+"px",g.height=a.lineHeight+"px";while(this.cursors.length>1)this.removeCursor()}var h=this.session.getOverwrite();h!=this.overwrite&&this.$setOverite(h),this.$pixelPos=f,this.restartTimer()},this.$setOverite=function(a){this.overwrite=a;for(var b=this.cursors.length;b--;)a?d.addCssClass(this.cursors[b],"ace_overwrite"):d.removeCssClass(this.cursors[b],"ace_overwrite")},this.destroy=function(){clearInterval(this.blinkId)}}).call(e.prototype),b.Cursor=e}),define("ace/scrollbar",["require","exports","module","ace/lib/oop","ace/lib/dom","ace/lib/event","ace/lib/event_emitter"],function(a,b,c){"use strict";var d=a("./lib/oop"),e=a("./lib/dom"),f=a("./lib/event"),g=a("./lib/event_emitter").EventEmitter,h=function(a){this.element=e.createElement("div"),this.element.className="ace_sb",this.inner=e.createElement("div"),this.element.appendChild(this.inner),a.appendChild(this.element),this.width=e.scrollbarWidth(a.ownerDocument),this.element.style.width=(this.width||15)+5+"px",f.addListener(this.element,"scroll",this.onScroll.bind(this))};(function(){d.implement(this,g),this.onScroll=function(){this._emit("scroll",{data:this.element.scrollTop})},this.getWidth=function(){return this.width},this.setHeight=function(a){this.element.style.height=a+"px"},this.setInnerHeight=function(a){this.inner.style.height=a+"px"},this.setScrollTop=function(a){this.element.scrollTop=a}}).call(h.prototype),b.ScrollBar=h}),define("ace/renderloop",["require","exports","module","ace/lib/event"],function(a,b,c){"use strict";var d=a("./lib/event"),e=function(a,b){this.onRender=a,this.pending=!1,this.changes=0,this.window=b||window};(function(){this.schedule=function(a){this.changes=this.changes|a;if(!this.pending){this.pending=!0;var b=this;d.nextTick(function(){b.pending=!1;var a;while(a=b.changes)b.changes=0,b.onRender(a)},this.window)}}}).call(e.prototype),b.RenderLoop=e}),define("text!ace/css/editor.css",[],"\n.ace_editor {\n position: absolute;\n overflow: hidden;\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Droid Sans Mono', 'Consolas', monospace;\n font-size: 12px;\n}\n\n.ace_scroller {\n position: absolute;\n overflow-x: scroll;\n overflow-y: hidden;\n}\n\n.ace_content {\n position: absolute;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n cursor: text;\n}\n\n.ace_composition {\n position: absolute;\n background: #555;\n color: #DDD;\n z-index: 4;\n}\n\n.ace_gutter {\n position: absolute;\n overflow : hidden;\n height: 100%;\n width: auto;\n cursor: default;\n 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\n.ace_gutter-cell {\n padding-left: 19px;\n padding-right: 6px;\n}\n\n.ace_gutter-cell.ace_error {\n background-image: url(\"data:image/gif,GIF89a%10%00%10%00%D5%00%00%F5or%F5%87%88%F5nr%F4ns%EBmq%F5z%7F%DDJT%DEKS%DFOW%F1Yc%F2ah%CE(7%CE)8%D18E%DD%40M%F2KZ%EBU%60%F4%60m%DCir%C8%16(%C8%19*%CE%255%F1%3FR%F1%3FS%E6%AB%B5%CA%5DI%CEn%5E%F7%A2%9A%C9G%3E%E0a%5B%F7%89%85%F5yy%F6%82%80%ED%82%80%FF%BF%BF%E3%C4%C4%FF%FF%FF%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%25%00%2C%00%00%00%00%10%00%10%00%00%06p%C0%92pH%2C%1A%8F%C8%D2H%93%E1d4%23%E4%88%D3%09mB%1DN%B48%F5%90%40%60%92G%5B%94%20%3E%22%D2%87%24%FA%20%24%C5%06A%00%20%B1%07%02B%A38%89X.v%17%82%11%13q%10%0Fi%24%0F%8B%10%7BD%12%0Ei%09%92%09%0EpD%18%15%24%0A%9Ci%05%0C%18F%18%0B%07%04%01%04%06%A0H%18%12%0D%14%0D%12%A1I%B3%B4%B5IA%00%3B\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_warning {\n background-image: url(\"data:image/gif,GIF89a%10%00%10%00%D5%00%00%FF%DBr%FF%DE%81%FF%E2%8D%FF%E2%8F%FF%E4%96%FF%E3%97%FF%E5%9D%FF%E6%9E%FF%EE%C1%FF%C8Z%FF%CDk%FF%D0s%FF%D4%81%FF%D5%82%FF%D5%83%FF%DC%97%FF%DE%9D%FF%E7%B8%FF%CCl%7BQ%13%80U%15%82W%16%81U%16%89%5B%18%87%5B%18%8C%5E%1A%94d%1D%C5%83-%C9%87%2F%C6%84.%C6%85.%CD%8B2%C9%871%CB%8A3%CD%8B5%DC%98%3F%DF%9BB%E0%9CC%E1%A5U%CB%871%CF%8B5%D1%8D6%DB%97%40%DF%9AB%DD%99B%E3%B0p%E7%CC%AE%FF%FF%FF%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00!%F9%04%01%00%00%2F%00%2C%00%00%00%00%10%00%10%00%00%06a%C0%97pH%2C%1A%8FH%A1%ABTr%25%87%2B%04%82%F4%7C%B9X%91%08%CB%99%1C!%26%13%84*iJ9(%15G%CA%84%14%01%1A%97%0C%03%80%3A%9A%3E%81%84%3E%11%08%B1%8B%20%02%12%0F%18%1A%0F%0A%03'F%1C%04%0B%10%16%18%10%0B%05%1CF%1D-%06%07%9A%9A-%1EG%1B%A0%A1%A0U%A4%A5%A6BA%00%3B\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_gutter-cell.ace_info {\n background-image: url(\"data:image/gif;base64,R0lGODlhEAAQAMQAAAAAAEFBQVJSUl5eXmRkZGtra39/f4WFhYmJiZGRkaampry8vMPDw8zMzNXV1dzc3OTk5Orq6vDw8P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABQALAAAAAAQABAAAAUuICWOZGmeaBml5XGwFCQSBGyXRSAwtqQIiRuiwIM5BoYVbEFIyGCQoeJGrVptIQA7\");\n background-repeat: no-repeat;\n background-position: 2px center;\n}\n\n.ace_editor .ace_sb {\n position: absolute;\n overflow-x: hidden;\n overflow-y: scroll;\n right: 0;\n}\n\n.ace_editor .ace_sb div {\n position: absolute;\n width: 1px;\n left: 0;\n}\n\n.ace_editor .ace_print_margin_layer {\n z-index: 0;\n position: absolute;\n overflow: hidden;\n margin: 0;\n left: 0;\n height: 100%;\n width: 100%;\n}\n\n.ace_editor .ace_print_margin {\n position: absolute;\n height: 100%;\n}\n\n.ace_editor textarea {\n position: fixed;\n z-index: 0;\n width: 0.5em;\n height: 1em;\n opacity: 0;\n background: transparent;\n appearance: none;\n -moz-appearance: none;\n border: none;\n resize: none;\n outline: none;\n overflow: hidden;\n}\n\n.ace_layer {\n z-index: 1;\n position: absolute;\n overflow: hidden;\n white-space: nowrap;\n height: 100%;\n width: 100%;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n /* setting pointer-events: auto; on node under the mouse, which changes\n during scroll, will break mouse wheel scrolling in Safari */\n pointer-events: none;\n}\n\n.ace_gutter .ace_layer {\n position: relative;\n min-width: 40px;\n text-align: right;\n pointer-events: auto;\n}\n\n.ace_text-layer {\n color: black;\n font: inherit !important;\n}\n\n.ace_cjk {\n display: inline-block;\n text-align: center;\n}\n\n.ace_cursor-layer {\n z-index: 4;\n}\n\n.ace_cursor {\n z-index: 4;\n position: absolute;\n}\n\n.ace_cursor.ace_hidden {\n opacity: 0.2;\n}\n\n.ace_editor.multiselect .ace_cursor {\n border-left-width: 1px;\n}\n\n.ace_line {\n white-space: nowrap;\n}\n\n.ace_marker-layer .ace_step {\n position: absolute;\n z-index: 3;\n}\n\n.ace_marker-layer .ace_selection {\n position: absolute;\n z-index: 5;\n}\n\n.ace_marker-layer .ace_bracket {\n position: absolute;\n z-index: 6;\n}\n\n.ace_marker-layer .ace_active_line {\n position: absolute;\n z-index: 2;\n}\n\n.ace_marker-layer .ace_selected_word {\n position: absolute;\n z-index: 4;\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n}\n\n.ace_line .ace_fold {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n \n display: inline-block;\n height: 11px;\n margin-top: -2px;\n vertical-align: middle;\n\n background-image: \n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%3AIDAT8%11c%FC%FF%FF%7F%18%03%1A%60%01%F2%3F%A0%891%80%04%FF%11-%F8%17%9BJ%E2%05%B1ZD%81v%26t%E7%80%F8%A3%82h%A12%1A%20%A3%01%02%0F%01%BA%25%06%00%19%C0%0D%AEF%D5%3ES%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat, repeat-x;\n background-position: center center, top left;\n color: transparent;\n\n border: 1px solid black;\n -moz-border-radius: 2px;\n -webkit-border-radius: 2px;\n border-radius: 2px;\n \n cursor: pointer;\n pointer-events: auto;\n}\n\n.ace_dark .ace_fold {\n}\n\n.ace_fold:hover{\n background-image: \n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%11%00%00%00%09%08%06%00%00%00%D4%E8%C7%0C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%00%B5IDAT(%15%A5%91%3D%0E%02!%10%85ac%E1%05%D6%CE%D6%C6%CE%D2%E8%ED%CD%DE%C0%C6%D6N.%E0V%F8%3D%9Ca%891XH%C2%BE%D9y%3F%90!%E6%9C%C3%BFk%E5%011%C6-%F5%C8N%04%DF%BD%FF%89%DFt%83DN%60%3E%F3%AB%A0%DE%1A%5Dg%BE%10Q%97%1B%40%9C%A8o%10%8F%5E%828%B4%1B%60%87%F6%02%26%85%1Ch%1E%C1%2B%5Bk%FF%86%EE%B7j%09%9A%DA%9B%ACe%A3%F9%EC%DA!9%B4%D5%A6%81%86%86%98%CC%3C%5B%40%FA%81%B3%E9%CB%23%94%C16Azo%05%D4%E1%C1%95a%3B%8A'%A0%E8%CC%17%22%85%1D%BA%00%A2%FA%DC%0A%94%D1%D1%8D%8B%3A%84%17B%C7%60%1A%25Z%FC%8D%00%00%00%00IEND%AEB%60%82\"),\n url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%007%08%06%00%00%00%C4%DD%80C%00%00%03%1EiCCPICC%20Profile%00%00x%01%85T%DFk%D3P%14%FE%DAe%9D%B0%E1%8B%3Ag%11%09%3Eh%91ndStC%9C%B6kW%BA%CDZ%EA6%B7!H%9B%A6m%5C%9A%C6%24%ED~%B0%07%D9%8Bo%3A%C5w%F1%07%3E%F9%07%0C%D9%83o%7B%92%0D%C6%14a%F8%AC%88%22L%F6%22%B3%9E%9B4M'S%03%B9%F7%BB%DF%F9%EE9'%E7%E4%5E%A0%F9qZ%D3%14%2F%0F%14USO%C5%C2%FC%C4%E4%14%DF%F2%01%5E%1CC%2B%FChM%8B%86%16J%26G%40%0F%D3%B2y%EF%B3%F3%0E%1E%C6lt%EEo%DF%AB%FEc%D5%9A%95%0C%11%F0%1C%20%BE%945%C4%22%E1Y%A0i%5C%D4t%13%E0%D6%89%EF%9D15%C2%CDLsX%A7%04%09%1Fg8oc%81%E1%8C%8D%23%96f45%40%9A%09%C2%07%C5B%3AK%B8%408%98i%E0%F3%0D%D8%CE%81%14%E4'%26%A9%92.%8B%3C%ABER%2F%E5dE%B2%0C%F6%F0%1Fs%83%F2_%B0%A8%94%E9%9B%AD%E7%10%8Dm%9A%19N%D1%7C%8A%DE%1F9%7Dp%8C%E6%00%D5%C1%3F_%18%BDA%B8%9DpX6%E3%A35~B%CD%24%AE%11%26%BD%E7%EEti%98%EDe%9A%97Y)%12%25%1C%24%BCbT%AE3li%E6%0B%03%89%9A%E6%D3%ED%F4P%92%B0%9F4%BF43Y%F3%E3%EDP%95%04%EB1%C5%F5%F6KF%F4%BA%BD%D7%DB%91%93%07%E35%3E%A7)%D6%7F%40%FE%BD%F7%F5r%8A%E5y%92%F0%EB%B4%1E%8D%D5%F4%5B%92%3AV%DB%DB%E4%CD%A6%23%C3%C4wQ%3F%03HB%82%8E%1Cd(%E0%91B%0Ca%9Ac%C4%AA%F8L%16%19%22J%A4%D2itTy%B28%D6%3B(%93%96%ED%1CGx%C9_%0E%B8%5E%16%F5%5B%B2%B8%F6%E0%FB%9E%DD%25%D7%8E%BC%15%85%C5%B7%A3%D8Q%ED%B5%81%E9%BA%B2%13%9A%1B%7Fua%A5%A3n%E17%B9%E5%9B%1Bm%AB%0B%08Q%FE%8A%E5%B1H%5Ee%CAO%82Q%D7u6%E6%90S%97%FCu%0B%CF2%94%EE%25v%12X%0C%BA%AC%F0%5E%F8*l%0AO%85%17%C2%97%BF%D4%C8%CE%DE%AD%11%CB%80q%2C%3E%AB%9ES%CD%C6%EC%25%D2L%D2%EBd%B8%BF%8A%F5B%C6%18%F9%901CZ%9D%BE%24M%9C%8A9%F2%DAP%0B'%06w%82%EB%E6%E2%5C%2F%D7%07%9E%BB%CC%5D%E1%FA%B9%08%AD.r%23%8E%C2%17%F5E%7C!%F0%BE3%BE%3E_%B7o%88a%A7%DB%BE%D3d%EB%A31Z%EB%BB%D3%91%BA%A2%B1z%94%8F%DB'%F6%3D%8E%AA%13%19%B2%B1%BE%B1~V%08%2B%B4%A2cjJ%B3tO%00%03%25mN%97%F3%05%93%EF%11%84%0B%7C%88%AE-%89%8F%ABbW%90O%2B%0Ao%99%0C%5E%97%0CI%AFH%D9.%B0%3B%8F%ED%03%B6S%D6%5D%E6i_s9%F3*p%E9%1B%FD%C3%EB.7U%06%5E%19%C0%D1s.%17%A03u%E4%09%B0%7C%5E%2C%EB%15%DB%1F%3C%9E%B7%80%91%3B%DBc%AD%3Dma%BA%8B%3EV%AB%DBt.%5B%1E%01%BB%0F%AB%D5%9F%CF%AA%D5%DD%E7%E4%7F%0Bx%A3%FC%06%A9%23%0A%D6%C2%A1_2%00%00%00%09pHYs%00%00%0B%13%00%00%0B%13%01%00%9A%9C%18%00%00%003IDAT8%11c%FC%FF%FF%7F%3E%03%1A%60%01%F2%3F%A3%891%80%04%FFQ%26%F8w%C0%B43%A1%DB%0C%E2%8F%0A%A2%85%CAh%80%8C%06%08%3C%04%E8%96%18%00%A3S%0D%CD%CF%D8%C1%9D%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat, repeat-x;\n background-position: center center, top left;\n}\n\n.ace_dragging .ace_content {\n cursor: move;\n}\n\n.ace_folding-enabled > .ace_gutter-cell {\n padding-right: 13px;\n}\n\n.ace_fold-widget {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n -webkit-box-sizing: border-box;\n\n margin: 0 -12px 1px 1px;\n display: inline-block;\n height: 14px;\n width: 11px;\n vertical-align: text-bottom;\n \n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAe%8A%B1%0D%000%0C%C2%F2%2CK%96%BC%D0%8F9%81%88H%E9%D0%0E%96%C0%10%92%3E%02%80%5E%82%E4%A9*-%EEsw%C8%CC%11%EE%96w%D8%DC%E9*Eh%0C%151(%00%00%00%00IEND%AEB%60%82\");\n background-repeat: no-repeat;\n background-position: center 5px;\n\n border-radius: 3px;\n}\n\n.ace_fold-widget.end {\n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%05%00%00%00%05%08%06%00%00%00%8Do%26%E5%00%00%004IDATx%DAm%C7%C1%09%000%08C%D1%8C%ECE%C8E(%8E%EC%02)%1EZJ%F1%C1'%04%07I%E1%E5%EE%CAL%F5%A2%99%99%22%E2%D6%1FU%B5%FE0%D9x%A7%26Wz5%0E%D5%00%00%00%00IEND%AEB%60%82\");\n}\n\n.ace_fold-widget.closed {\n background-image: url(\"data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%03%00%00%00%06%08%06%00%00%00%06%E5%24%0C%00%00%009IDATx%DA5%CA%C1%09%000%08%03%C0%AC*(%3E%04%C1%0D%BA%B1%23%A4Uh%E0%20%81%C0%CC%F8%82%81%AA%A2%AArGfr%88%08%11%11%1C%DD%7D%E0%EE%5B%F6%F6%CB%B8%05Q%2F%E9tai%D9%00%00%00%00IEND%AEB%60%82\");\n}\n\n.ace_fold-widget:hover {\n border: 1px solid rgba(0, 0, 0, 0.3);\n background-color: rgba(255, 255, 255, 0.2);\n -moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n -moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n -webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n -webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n box-shadow:inset 0 1px 1px rgba(255, 255, 255, 0.7);\n box-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);\n background-position: center 4px;\n}\n\n.ace_fold-widget:active {\n border: 1px solid rgba(0, 0, 0, 0.4);\n background-color: rgba(0, 0, 0, 0.05);\n -moz-box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n -moz-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n -webkit-box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n -webkit-box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n box-shadow:inset 0 1px 1px rgba(255, 255, 255);\n box-shadow: 0 1px 1px rgba(255, 255, 255, 0.8);\n}\n\n.ace_fold-widget.invalid {\n 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"),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(a,b,c){function k(a,b,c){return j.$options.wrap=!0,j.$options.needle=b,j.$options.backwards=c==-1,j.find(a)}function n(a,b){return a.row==b.row&&a.column==b.column}function o(a){a.$onAddRange=a.$onAddRange.bind(a),a.$onRemoveRange=a.$onRemoveRange.bind(a),a.$onMultiSelect=a.$onMultiSelect.bind(a),a.$onSingleSelect=a.$onSingleSelect.bind(a),b.onSessionChange.call(a,a),a.on("changeSession",b.onSessionChange.bind(a)),a.on("mousedown",g),a.commands.addCommands(b.commands.defaultCommands),p(a)}function p(a){function e(){c&&(d.style.cursor="",c=!1)}var b=a.textInput.getElement(),c=!1,d=a.renderer.content;h.addListener(b,"keydown",function(a){a.keyCode==18&&!(a.ctrlKey||a.shiftKey||a.metaKey)?c||(d.style.cursor="crosshair",c=!0):c&&(d.style.cursor="")}),h.addListener(b,"keyup",e),h.addListener(b,"blur",e)}var d=a("./range_list").RangeList,e=a("./range").Range,f=a("./selection").Selection,g=a("./mouse/multi_select_handler").onMouseDown,h=a("./lib/event");b.commands=a("./commands/multi_select_commands");var i=a("./search").Search,j=new i,l=a("./edit_session").EditSession;(function(){this.getSelectionMarkers=function(){return this.$selectionMarkers}}).call(l.prototype),function(){this.ranges=null,this.rangeList=null,this.addRange=function(a,b){if(!a)return;if(!this.inMultiSelectMode&&this.rangeCount==0){var c=this.toOrientedRange();if(a.intersects(c))return b||this.fromOrientedRange(a);this.rangeList.add(c),this.$onAddRange(c)}a.cursor||(a.cursor=a.end);var d=this.rangeList.add(a);return this.$onAddRange(a),d.length&&this.$onRemoveRange(d),this.rangeCount>1&&!this.inMultiSelectMode&&(this._emit("multiSelect"),this.inMultiSelectMode=!0,this.session.$undoSelect=!1,this.rangeList.attach(this.session)),b||this.fromOrientedRange(a)},this.toSingleRange=function(a){a=a||this.ranges[0];var b=this.rangeList.removeAll();b.length&&this.$onRemoveRange(b),a&&this.fromOrientedRange(a)},this.substractPoint=function(a){var b=this.rangeList.substractPoint(a);if(b)return this.$onRemoveRange(b),b[0]},this.mergeOverlappingRanges=function(){var a=this.rangeList.merge();a.length?this.$onRemoveRange(a):this.ranges[0]&&this.fromOrientedRange(this.ranges[0])},this.$onAddRange=function(a){this.rangeCount=this.rangeList.ranges.length,this.ranges.unshift(a),this._emit("addRange",{range:a})},this.$onRemoveRange=function(a){this.rangeCount=this.rangeList.ranges.length;if(this.rangeCount==1&&this.inMultiSelectMode){var b=this.rangeList.ranges.pop();a.push(b),this.rangeCount=0}for(var c=a.length;c--;){var d=this.ranges.indexOf(a[c]);this.ranges.splice(d,1)}this._emit("removeRange",{ranges:a}),this.rangeCount==0&&this.inMultiSelectMode&&(this.inMultiSelectMode=!1,this._emit("singleSelect"),this.session.$undoSelect=!0,this.rangeList.detach(this.session)),b=b||this.ranges[0],b&&!b.isEqual(this.getRange())&&this.fromOrientedRange(b)},this.$initRangeList=function(){if(this.rangeList)return;this.rangeList=new d,this.ranges=[],this.rangeCount=0},this.getAllRanges=function(){return this.rangeList.ranges.concat()},this.splitIntoLines=function(){if(this.rangeCount>1){var a=this.rangeList.ranges,b=a[a.length-1],c=e.fromPoints(a[0].start,b.end);this.toSingleRange(),this.setSelectionRange(c,b.cursor==b.start)}else{var c=this.getRange(),d=c.start.row,f=c.end.row;if(d==f)return;var g=[],h=this.getLineRange(d,!0);h.start.column=c.start.column,g.push(h);for(var i=d+1;i1){var a=this.rangeList.ranges,b=a[a.length-1],c=e.fromPoints(a[0].start,b.end);this.toSingleRange(),this.setSelectionRange(c,b.cursor==b.start)}else{var d=this.session.documentToScreenPosition(this.selectionLead),f=this.session.documentToScreenPosition(this.selectionAnchor),g=this.rectangularRangeBlock(d,f);g.forEach(this.addRange,this)}},this.rectangularRangeBlock=function(a,b,c){var d=[],f=a.column0)p--;if(p>0){var q=0;while(d[q].isEmpty())q++}for(var r=p;r>=q;r--)d[r].isEmpty()&&d.splice(r,1)}return d}}.call(f.prototype);var m=a("./editor").Editor;(function(){this.updateSelectionMarkers=function(){this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.addSelectionMarker=function(a){a.cursor||(a.cursor=a.end);var b=this.getSelectionStyle();return a.marker=this.session.addMarker(a,"ace_selection",b),this.session.$selectionMarkers.push(a),this.session.selectionMarkerCount=this.session.$selectionMarkers.length,a},this.removeSelectionMarker=function(a){if(!a.marker)return;this.session.removeMarker(a.marker);var b=this.session.$selectionMarkers.indexOf(a);b!=-1&&this.session.$selectionMarkers.splice(b,1),this.session.selectionMarkerCount=this.session.$selectionMarkers.length},this.removeSelectionMarkers=function(a){var b=this.session.$selectionMarkers;for(var c=a.length;c--;){var d=a[c];if(!d.marker)continue;this.session.removeMarker(d.marker);var e=b.indexOf(d);e!=-1&&b.splice(e,1)}this.session.selectionMarkerCount=b.length},this.$onAddRange=function(a){this.addSelectionMarker(a.range),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onRemoveRange=function(a){this.removeSelectionMarkers(a.ranges),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelect=function(a){if(this.inMultiSelectMode)return;this.inMultiSelectMode=!0,this.setStyle("multiselect"),this.keyBinding.addKeyboardHandler(b.commands.keyboardHandler),this.commands.on("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onSingleSelect=function(a){if(this.session.multiSelect.inVirtualMode)return;this.inMultiSelectMode=!1,this.unsetStyle("multiselect"),this.keyBinding.removeKeyboardHandler(b.commands.keyboardHandler),this.commands.removeEventListener("exec",this.$onMultiSelectExec),this.renderer.updateCursor(),this.renderer.updateBackMarkers()},this.$onMultiSelectExec=function(a){var b=a.command,c=a.editor;b.multiSelectAction?b.multiSelectAction=="forEach"?c.forEachSelection(b,a.args):b.multiSelectAction=="single"?(c.exitMultiSelectMode(),b.exec(c,a.args||{})):b.multiSelectAction(c,a.args||{}):(b.exec(c,a.args||{}),c.multiSelect.addRange(c.multiSelect.toOrientedRange()),c.multiSelect.mergeOverlappingRanges()),a.preventDefault()},this.forEachSelection=function(a,b){if(this.inVirtualSelectionMode)return;var c=this.session,d=this.selection,e=d.rangeList,g=d._eventRegistry;d._eventRegistry={};var h=new f(c);this.inVirtualSelectionMode=!0;for(var i=e.ranges.length;i--;)h.fromOrientedRange(e.ranges[i]),this.selection=c.selection=h,a.exec(this,b||{}),h.toOrientedRange(e.ranges[i]);h.detach(),this.selection=c.selection=d,this.inVirtualSelectionMode=!1,d._eventRegistry=g,d.mergeOverlappingRanges(),this.onCursorChange(),this.onSelectionChange()},this.exitMultiSelectMode=function(){if(this.inVirtualSelectionMode)return;this.multiSelect.toSingleRange()},this.getCopyText=function(){var a="";if(this.inMultiSelectMode){var b=this.multiSelect.rangeList.ranges;a=[];for(var c=0;cc.length){this.commands.exec("insertstring",this,a);return}for(var d=c.length;d--;){var e=c[d];e.isEmpty()||this.session.remove(e),this.session.insert(e.start,b[d])}},this.findAll=function(a,b,c){b=b||{},b.needle=a||b.needle,this.$search.set(b);var d=this.$search.findAll(this.session);if(!d.length)return 0;this.$blockScrolling+=1;var e=this.multiSelect;c||e.toSingleRange(d[0]);for(var f=d.length;f--;)e.addRange(d[f],!0);return this.$blockScrolling-=1,d.length},this.selectMoreLines=function(a,b){var c=this.selection.toOrientedRange(),d=c.cursor==c.end,f=this.session.documentToScreenPosition(c.cursor);this.selection.$desiredColumn&&(f.column=this.selection.$desiredColumn);var g=this.session.screenToDocumentPosition(f.row+a,f.column);if(!c.isEmpty())var h=this.session.documentToScreenPosition(d?c.end:c.start),i=this.session.screenToDocumentPosition(h.row+a,h.column);else var i=g;if(d){var j=e.fromPoints(g,i);j.cursor=j.start}else{var j=e.fromPoints(i,g);j.cursor=j.end}j.desiredColumn=f.column;if(!this.selection.inMultiSelectMode)this.selection.addRange(c);else if(b)var k=c.cursor;this.selection.addRange(j),k&&this.selection.substractPoint(k)},this.transposeSelections=function(a){var b=this.session,c=b.multiSelect,d=c.ranges;for(var e=d.length;e--;){var f=d[e];if(f.isEmpty()){var g=b.getWordRange(f.start.row,f.start.column);f.start.row=g.start.row,f.start.column=g.start.column,f.end.row=g.end.row,f.end.column=g.end.column}}c.mergeOverlappingRanges();var h=[];for(var e=d.length;e--;){var f=d[e];h.unshift(b.getTextRange(f))}a<0?h.unshift(h.pop()):h.push(h.shift());for(var e=d.length;e--;){var f=d[e],g=f.clone();b.replace(f,h[e]),f.start.row=g.start.row,f.start.column=g.start.column}},this.selectMore=function(a,b){var c=this.session,d=c.multiSelect,e=d.toOrientedRange();if(e.isEmpty()){var e=c.getWordRange(e.start.row,e.start.column);e.cursor=e.end,this.multiSelect.addRange(e)}var f=c.getTextRange(e),g=k(c,f,a);g&&(g.cursor=a==-1?g.start:g.end,this.multiSelect.addRange(g)),b&&this.multiSelect.substractPoint(e.cursor)}}).call(m.prototype),b.onSessionChange=function(a){var b=a.session;b.multiSelect||(b.$selectionMarkers=[],b.selection.$initRangeList(),b.multiSelect=b.selection),this.multiSelect=b.multiSelect;var c=a.oldSession;c&&(c.multiSelect&&c.multiSelect.editor==this&&(c.multiSelect.editor=null),b.multiSelect.removeEventListener("addRange",this.$onAddRange),b.multiSelect.removeEventListener("removeRange",this.$onRemoveRange),b.multiSelect.removeEventListener("multiSelect",this.$onMultiSelect),b.multiSelect.removeEventListener("singleSelect",this.$onSingleSelect)),b.multiSelect.on("addRange",this.$onAddRange),b.multiSelect.on("removeRange",this.$onRemoveRange),b.multiSelect.on("multiSelect",this.$onMultiSelect),b.multiSelect.on("singleSelect",this.$onSingleSelect),this.inMultiSelectMode!=b.selection.inMultiSelectMode&&(b.selection.inMultiSelectMode?this.$onMultiSelect():this.$onSingleSelect())},b.MultiSelect=o}),define("ace/range_list",["require","exports","module"],function(a,b,c){"use strict";var d=function(){this.ranges=[]};(function(){this.comparePoints=function(a,b){return a.row-b.row||a.column-b.column},this.pointIndex=function(a,b){var c=this.ranges;for(var d=b||0;d0)continue;return f==0?d:(f=this.comparePoints(a,e.start),f>=0?d:-d-1)}return-d-1},this.add=function(a){var b=this.pointIndex(a.start);b<0&&(b=-b-1);var c=this.pointIndex(a.end,b);return c<0?c=-c-1:c++,this.ranges.splice(b,c-b,a)},this.addList=function(a){var b=[];for(var c=a.length;c--;)b.push.call(b,this.add(a[c]));return b},this.substractPoint=function(a){var b=this.pointIndex(a);if(b>=0)return this.ranges.splice(b,1)},this.merge=function(){var a=[],b=this.ranges,c=b[0],d;for(var e=1;e=0},this.containsPoint=function(a){return this.pointIndex(a)>=0},this.rangeAtPoint=function(a){var b=this.pointIndex(a);if(b>=0)return this.ranges[b]},this.clipRows=function(a,b){var c=this.ranges;if(c[0].start.row>b||c[c.length-1].start.rowe)break;l.start.row==e&&l.start.column>=c.column&&(l.start.column+=h,l.start.row+=g),l.end.row==e&&l.end.column>=c.column&&(l.end.column+=h,l.end.row+=g)}if(g!=0&&j=0?g=a.nameToUrl("ace/worker/worker_sourcemint"):g=this.$normalizePath(a.nameToUrl("ace/worker/worker",null,"_")),this.$worker=new Worker(g);var h={};for(var i=0;i=this.pos.column&&c.start.column<=this.pos.column+this.length+1){var f=c.start.column-this.pos.column;this.length+=e;if(!this.session.$fromUndo){if(b.action==="insertText")for(var g=this.others.length-1;g>=0;g--){var h=this.others[g],i={row:h.row,column:h.column+f};h.row===c.start.row&&c.start.column=0;g--){var h=this.others[g],i={row:h.row,column:h.column+f};h.row===c.start.row&&c.start.column=this.pos.column&&b.column<=this.pos.column+this.length?(this.showOtherMarkers(),this._emit("cursorEnter",a)):(this.hideOtherMarkers(),this._emit("cursorLeave",a))},this.detach=function(){this.session.removeMarker(this.markerId),this.hideOtherMarkers(),this.doc.removeEventListener("change",this.$onUpdate),this.session.selection.removeEventListener("changeCursor",this.$onCursorChange),this.pos.detach();for(var a=0;a)\s*$/);return e&&(d+=c),d},this.checkOutdent=function(a,b,c){return/^\s+$/.test(b)?/^\s*[\}\)]/.test(c):!1},this.autoOutdent=function(a,b,c){var d=b.getLine(c),e=d.match(/^(\s*[\}\)])/);if(!e)return 0;var f=e[1].length,g=b.findMatchingBracket({row:c,column:f});if(!g||g.row==c)return 0;var h=this.$getIndent(b.getLine(g.row));b.replace(new j(c,0,c,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""},this.toggleCommentLines=function(a,b,c,d){var e,f,g=!0,h=/^\s*\(:(.*):\)/;for(e=c;e<=d;e++)if(!h.test(b.getLine(e))){g=!1;break}var i=new j(0,0,0,0);for(e=c;e<=d;e++)f=b.getLine(e),i.start.row=e,i.end.row=e,i.end.column=f.length,b.replace(i,g?f.match(h)[1]:"(:"+f+":)")},this.deltas=[],this.createWorker=function(a){var b=new d(["ace"],"worker-xquery.js","ace/mode/xquery_worker","XQueryWorker"),c=this;return a.getDocument().on("change",function(a){c.deltas.push(a.data)}),b.attachToDocument(a.getDocument()),b.on("start",function(a){console.log("start"),c.deltas=[]}),b.on("error",function(b){a.setAnnotations([b.data])}),b.on("ok",function(b){a.clearAnnotations()}),b.on("highlight",function(b){var d=0,e=a.getLength()-1,f=b.data;for(var g in c.deltas){var h=c.deltas[g];if(h.action==="insertLines"){var i=h.range.end.row-h.range.start.row;for(var g=0;g"},{token:"comment",regex:"<\\!--",next:"comment"},{token:"comment",regex:"\\(:",next:"comment"},{token:"text",regex:"<\\/?",next:"tag"},{token:"constant",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"variable",regex:"\\$[a-zA-Z_][a-zA-Z0-9_\\-:]*\\b"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"text",regex:"\\s+"},{token:"support.function",regex:"\\w[\\w+_\\-:]+(?=\\()"},{token:function(b){return a[b]?"keyword":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\*|=|<|>|\\-|\\+|and|or|eq|ne|lt|gt"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"}],tag:[{token:"text",regex:">",next:"start"},{token:"meta.tag",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"}],cdata:[{token:"text",regex:"\\]\\]>",next:"start"},{token:"text",regex:"\\s+"},{token:"text",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment",regex:".*?-->",next:"start"},{token:"comment",regex:".*:\\)",next:"start"},{token:"comment",regex:".+"}]}};d.inherits(g,f),b.XQueryHighlightRules=g}),ace.define("ace/mode/behaviour/xquery",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle"],function(a,b,c){"use strict";var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=a("./cstyle").CstyleBehaviour,g=function(a){this.inherit(f,["braces","parens","string_dquotes"]),this.parent=a,this.add("brackets","insertion",function(a,b,c,d,e){if(e=="\n"){var f=c.getCursorPosition(),g=d.doc.getLine(f.row),h=g.substring(f.column,f.column+2);if(h=="0&&h.charAt(g.column-1)=="<"){h=h.substring(0,g.column)+"/"+h.substring(g.column);var i=e.doc.getAllLines();i[g.row]=h,a.exec("closeTag",i.join(e.doc.getNewLineCharacter()),g.row)}}return!1})};d.inherits(g,e),b.XQueryBehaviour=g}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour"],function(a,b,c){"use strict";var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=function(){this.add("braces","insertion",function(a,b,c,d,e){if(e=="{"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"{"+g+"}",selection:!1}:{text:"{}",selection:[1,1]}}if(e=="}"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var k=d.$findOpeningBracket("}",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var l=d.findMatchingBracket({row:h.row,column:h.column+1});if(!l)return null;var m=this.getNextLineIndent(a,i.substring(0,i.length-1),d.getTabString()),n=this.$getIndent(d.doc.getLine(l.row));return{text:"\n"+m+"\n"+n,selection:[1,m.length,1,m.length]}}}}),this.add("braces","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="{"){var g=d.doc.getLine(e.start.row),h=g.substring(e.end.column,e.end.column+1);if(h=="}")return e.end.column++,e}}),this.add("parens","insertion",function(a,b,c,d,e){if(e=="("){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"("+g+")",selection:!1}:{text:"()",selection:[1,1]}}if(e==")"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==")"){var k=d.$findOpeningBracket(")",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="("){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h==")")return e.end.column++,e}}),this.add("string_dquotes","insertion",function(a,b,c,d,e){if(e=='"'||e=="'"){var f=e,g=c.getSelectionRange(),h=d.doc.getTextRange(g);if(h!=="")return{text:f+h+f,selection:!1};var i=c.getCursorPosition(),j=d.doc.getLine(i.row),k=j.substring(i.column-1,i.column);if(k=="\\")return null;var l=d.getTokens(g.start.row,g.start.row)[0].tokens,m=0,n,o=-1;for(var p=0;pg.start.column)break;m+=l[p].value.length}if(!n||o<0&&n.type!=="comment"&&(n.type!=="string"||g.start.column!==n.value.length+m-1&&n.value.lastIndexOf(f)===n.value.length-1))return{text:f+f,selection:[1,1]};if(n&&n.type==="string"){var q=j.substring(i.column,i.column+1);if(q==f)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&(f=='"'||f=="'")){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}})};d.inherits(f,e),b.CstyleBehaviour=f}) \ No newline at end of file +ace.define("ace/mode/xquery",["require","exports","module","ace/worker/worker_client","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/xquery_highlight_rules","ace/mode/behaviour/xquery","ace/range"],function(a,b,c){"use strict";var d=a("../worker/worker_client").WorkerClient,e=a("../lib/oop"),f=a("./text").Mode,g=a("../tokenizer").Tokenizer,h=a("./xquery_highlight_rules").XQueryHighlightRules,i=a("./behaviour/xquery").XQueryBehaviour,j=a("../range").Range,k=function(a){this.$tokenizer=new g((new h).getRules()),this.$behaviour=new i(a)};e.inherits(k,f),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=b.match(/\s*(?:then|else|return|[{\(]|<\w+>)\s*$/);return e&&(d+=c),d},this.checkOutdent=function(a,b,c){return/^\s+$/.test(b)?/^\s*[\}\)]/.test(c):!1},this.autoOutdent=function(a,b,c){var d=b.getLine(c),e=d.match(/^(\s*[\}\)])/);if(!e)return 0;var f=e[1].length,g=b.findMatchingBracket({row:c,column:f});if(!g||g.row==c)return 0;var h=this.$getIndent(b.getLine(g.row));b.replace(new j(c,0,c,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""},this.toggleCommentLines=function(a,b,c,d){var e,f,g=!0,h=/^\s*\(:(.*):\)/;for(e=c;e<=d;e++)if(!h.test(b.getLine(e))){g=!1;break}var i=new j(0,0,0,0);for(e=c;e<=d;e++)f=b.getLine(e),i.start.row=e,i.end.row=e,i.end.column=f.length,b.replace(i,g?f.match(h)[1]:"(:"+f+":)")},this.deltas=[],this.createWorker=function(a){var b=new d(["ace"],"worker-xquery.js","ace/mode/xquery_worker","XQueryWorker"),c=this;return a.getDocument().on("change",function(a){c.deltas.push(a.data)}),b.attachToDocument(a.getDocument()),b.on("start",function(a){console.log("start"),c.deltas=[]}),b.on("error",function(b){a.setAnnotations([b.data])}),b.on("ok",function(b){a.clearAnnotations()}),b.on("highlight",function(b){var d=0,e=a.getLength()-1,f=b.data;for(var g in c.deltas){var h=c.deltas[g];if(h.action==="insertLines"){var i=h.range.end.row-h.range.start.row;for(var g=0;g"},{token:"comment",regex:"<\\!--",next:"comment"},{token:"comment",regex:"\\(:",next:"comment"},{token:"text",regex:"<\\/?",next:"tag"},{token:"constant",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"variable",regex:"\\$[a-zA-Z_][a-zA-Z0-9_\\-:]*\\b"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"text",regex:"\\s+"},{token:"support.function",regex:"\\w[\\w+_\\-:]+(?=\\()"},{token:function(b){return a[b]?"keyword":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\*|=|<|>|\\-|\\+|and|or|eq|ne|lt|gt"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"}],tag:[{token:"text",regex:">",next:"start"},{token:"meta.tag",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"}],cdata:[{token:"text",regex:"\\]\\]>",next:"start"},{token:"text",regex:"\\s+"},{token:"text",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment",regex:".*?-->",next:"start"},{token:"comment",regex:".*:\\)",next:"start"},{token:"comment",regex:".+"}]}};d.inherits(g,f),b.XQueryHighlightRules=g}),ace.define("ace/mode/behaviour/xquery",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle"],function(a,b,c){"use strict";var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=a("./cstyle").CstyleBehaviour,g=function(a){this.inherit(f,["braces","parens","string_dquotes"]),this.parent=a,this.add("brackets","insertion",function(a,b,c,d,e){if(e=="\n"){var f=c.getCursorPosition(),g=d.doc.getLine(f.row),h=g.substring(f.column,f.column+2);if(h=="0&&h.charAt(g.column-1)=="<"){h=h.substring(0,g.column)+"/"+h.substring(g.column);var i=e.doc.getAllLines();i[g.row]=h,a.exec("closeTag",i.join(e.doc.getNewLineCharacter()),g.row)}}return!1})};d.inherits(g,e),b.XQueryBehaviour=g}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour"],function(a,b,c){"use strict";var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=function(){this.add("braces","insertion",function(a,b,c,d,e){if(e=="{"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"{"+g+"}",selection:!1}:{text:"{}",selection:[1,1]}}if(e=="}"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var k=d.$findOpeningBracket("}",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var l=d.findMatchingBracket({row:h.row,column:h.column+1});if(!l)return null;var m=this.getNextLineIndent(a,i.substring(0,i.length-1),d.getTabString()),n=this.$getIndent(d.doc.getLine(l.row));return{text:"\n"+m+"\n"+n,selection:[1,m.length,1,m.length]}}}}),this.add("braces","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="{"){var g=d.doc.getLine(e.start.row),h=g.substring(e.end.column,e.end.column+1);if(h=="}")return e.end.column++,e}}),this.add("parens","insertion",function(a,b,c,d,e){if(e=="("){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"("+g+")",selection:!1}:{text:"()",selection:[1,1]}}if(e==")"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==")"){var k=d.$findOpeningBracket(")",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="("){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h==")")return e.end.column++,e}}),this.add("string_dquotes","insertion",function(a,b,c,d,e){if(e=='"'||e=="'"){var f=e,g=c.getSelectionRange(),h=d.doc.getTextRange(g);if(h!=="")return{text:f+h+f,selection:!1};var i=c.getCursorPosition(),j=d.doc.getLine(i.row),k=j.substring(i.column-1,i.column);if(k=="\\")return null;var l=d.getTokens(g.start.row,g.start.row)[0].tokens,m=0,n,o=-1;for(var p=0;pg.start.column)break;m+=l[p].value.length}if(!n||o<0&&n.type!=="comment"&&(n.type!=="string"||g.start.column!==n.value.length+m-1&&n.value.lastIndexOf(f)===n.value.length-1))return{text:f+f,selection:[1,1]};if(n&&n.type==="string"){var q=j.substring(i.column,i.column+1);if(q==f)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&(f=='"'||f=="'")){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}})};d.inherits(f,e),b.CstyleBehaviour=f}) \ No newline at end of file diff --git a/build/src/mode-xquery-uncompressed-noconflict.js b/build/src/mode-xquery-uncompressed-noconflict.js index 77354b1d..6fa08e85 100644 --- a/build/src/mode-xquery-uncompressed-noconflict.js +++ b/build/src/mode-xquery-uncompressed-noconflict.js @@ -222,8 +222,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("|") ); @@ -629,4 +629,4 @@ var CstyleBehaviour = function () { oop.inherits(CstyleBehaviour, Behaviour); exports.CstyleBehaviour = CstyleBehaviour; -}); \ No newline at end of file +}); diff --git a/build/src/mode-xquery-uncompressed.js b/build/src/mode-xquery-uncompressed.js index 4dc25111..6a70306a 100644 --- a/build/src/mode-xquery-uncompressed.js +++ b/build/src/mode-xquery-uncompressed.js @@ -222,8 +222,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("|") ); @@ -629,4 +629,4 @@ var CstyleBehaviour = function () { oop.inherits(CstyleBehaviour, Behaviour); exports.CstyleBehaviour = CstyleBehaviour; -}); \ No newline at end of file +}); diff --git a/build/src/mode-xquery.js b/build/src/mode-xquery.js index 12e9bcbd..bcc2445b 100644 --- a/build/src/mode-xquery.js +++ b/build/src/mode-xquery.js @@ -1 +1 @@ -define("ace/mode/xquery",["require","exports","module","ace/worker/worker_client","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/xquery_highlight_rules","ace/mode/behaviour/xquery","ace/range"],function(a,b,c){"use strict";var d=a("../worker/worker_client").WorkerClient,e=a("../lib/oop"),f=a("./text").Mode,g=a("../tokenizer").Tokenizer,h=a("./xquery_highlight_rules").XQueryHighlightRules,i=a("./behaviour/xquery").XQueryBehaviour,j=a("../range").Range,k=function(a){this.$tokenizer=new g((new h).getRules()),this.$behaviour=new i(a)};e.inherits(k,f),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=b.match(/\s*(?:then|else|return|[{\(]|<\w+>)\s*$/);return e&&(d+=c),d},this.checkOutdent=function(a,b,c){return/^\s+$/.test(b)?/^\s*[\}\)]/.test(c):!1},this.autoOutdent=function(a,b,c){var d=b.getLine(c),e=d.match(/^(\s*[\}\)])/);if(!e)return 0;var f=e[1].length,g=b.findMatchingBracket({row:c,column:f});if(!g||g.row==c)return 0;var h=this.$getIndent(b.getLine(g.row));b.replace(new j(c,0,c,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""},this.toggleCommentLines=function(a,b,c,d){var e,f,g=!0,h=/^\s*\(:(.*):\)/;for(e=c;e<=d;e++)if(!h.test(b.getLine(e))){g=!1;break}var i=new j(0,0,0,0);for(e=c;e<=d;e++)f=b.getLine(e),i.start.row=e,i.end.row=e,i.end.column=f.length,b.replace(i,g?f.match(h)[1]:"(:"+f+":)")},this.deltas=[],this.createWorker=function(a){var b=new d(["ace"],"worker-xquery.js","ace/mode/xquery_worker","XQueryWorker"),c=this;return a.getDocument().on("change",function(a){c.deltas.push(a.data)}),b.attachToDocument(a.getDocument()),b.on("start",function(a){console.log("start"),c.deltas=[]}),b.on("error",function(b){a.setAnnotations([b.data])}),b.on("ok",function(b){a.clearAnnotations()}),b.on("highlight",function(b){var d=0,e=a.getLength()-1,f=b.data;for(var g in c.deltas){var h=c.deltas[g];if(h.action==="insertLines"){var i=h.range.end.row-h.range.start.row;for(var g=0;g"},{token:"comment",regex:"<\\!--",next:"comment"},{token:"comment",regex:"\\(:",next:"comment"},{token:"text",regex:"<\\/?",next:"tag"},{token:"constant",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"variable",regex:"\\$[a-zA-Z_][a-zA-Z0-9_\\-:]*\\b"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"text",regex:"\\s+"},{token:"support.function",regex:"\\w[\\w+_\\-:]+(?=\\()"},{token:function(b){return a[b]?"keyword":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\*|=|<|>|\\-|\\+|and|or|eq|ne|lt|gt"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"}],tag:[{token:"text",regex:">",next:"start"},{token:"meta.tag",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"}],cdata:[{token:"text",regex:"\\]\\]>",next:"start"},{token:"text",regex:"\\s+"},{token:"text",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment",regex:".*?-->",next:"start"},{token:"comment",regex:".*:\\)",next:"start"},{token:"comment",regex:".+"}]}};d.inherits(g,f),b.XQueryHighlightRules=g}),define("ace/mode/behaviour/xquery",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle"],function(a,b,c){"use strict";var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=a("./cstyle").CstyleBehaviour,g=function(a){this.inherit(f,["braces","parens","string_dquotes"]),this.parent=a,this.add("brackets","insertion",function(a,b,c,d,e){if(e=="\n"){var f=c.getCursorPosition(),g=d.doc.getLine(f.row),h=g.substring(f.column,f.column+2);if(h=="0&&h.charAt(g.column-1)=="<"){h=h.substring(0,g.column)+"/"+h.substring(g.column);var i=e.doc.getAllLines();i[g.row]=h,a.exec("closeTag",i.join(e.doc.getNewLineCharacter()),g.row)}}return!1})};d.inherits(g,e),b.XQueryBehaviour=g}),define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour"],function(a,b,c){"use strict";var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=function(){this.add("braces","insertion",function(a,b,c,d,e){if(e=="{"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"{"+g+"}",selection:!1}:{text:"{}",selection:[1,1]}}if(e=="}"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var k=d.$findOpeningBracket("}",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var l=d.findMatchingBracket({row:h.row,column:h.column+1});if(!l)return null;var m=this.getNextLineIndent(a,i.substring(0,i.length-1),d.getTabString()),n=this.$getIndent(d.doc.getLine(l.row));return{text:"\n"+m+"\n"+n,selection:[1,m.length,1,m.length]}}}}),this.add("braces","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="{"){var g=d.doc.getLine(e.start.row),h=g.substring(e.end.column,e.end.column+1);if(h=="}")return e.end.column++,e}}),this.add("parens","insertion",function(a,b,c,d,e){if(e=="("){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"("+g+")",selection:!1}:{text:"()",selection:[1,1]}}if(e==")"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==")"){var k=d.$findOpeningBracket(")",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="("){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h==")")return e.end.column++,e}}),this.add("string_dquotes","insertion",function(a,b,c,d,e){if(e=='"'||e=="'"){var f=e,g=c.getSelectionRange(),h=d.doc.getTextRange(g);if(h!=="")return{text:f+h+f,selection:!1};var i=c.getCursorPosition(),j=d.doc.getLine(i.row),k=j.substring(i.column-1,i.column);if(k=="\\")return null;var l=d.getTokens(g.start.row,g.start.row)[0].tokens,m=0,n,o=-1;for(var p=0;pg.start.column)break;m+=l[p].value.length}if(!n||o<0&&n.type!=="comment"&&(n.type!=="string"||g.start.column!==n.value.length+m-1&&n.value.lastIndexOf(f)===n.value.length-1))return{text:f+f,selection:[1,1]};if(n&&n.type==="string"){var q=j.substring(i.column,i.column+1);if(q==f)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&(f=='"'||f=="'")){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}})};d.inherits(f,e),b.CstyleBehaviour=f}) \ No newline at end of file +define("ace/mode/xquery",["require","exports","module","ace/worker/worker_client","ace/lib/oop","ace/mode/text","ace/tokenizer","ace/mode/xquery_highlight_rules","ace/mode/behaviour/xquery","ace/range"],function(a,b,c){"use strict";var d=a("../worker/worker_client").WorkerClient,e=a("../lib/oop"),f=a("./text").Mode,g=a("../tokenizer").Tokenizer,h=a("./xquery_highlight_rules").XQueryHighlightRules,i=a("./behaviour/xquery").XQueryBehaviour,j=a("../range").Range,k=function(a){this.$tokenizer=new g((new h).getRules()),this.$behaviour=new i(a)};e.inherits(k,f),function(){this.getNextLineIndent=function(a,b,c){var d=this.$getIndent(b),e=b.match(/\s*(?:then|else|return|[{\(]|<\w+>)\s*$/);return e&&(d+=c),d},this.checkOutdent=function(a,b,c){return/^\s+$/.test(b)?/^\s*[\}\)]/.test(c):!1},this.autoOutdent=function(a,b,c){var d=b.getLine(c),e=d.match(/^(\s*[\}\)])/);if(!e)return 0;var f=e[1].length,g=b.findMatchingBracket({row:c,column:f});if(!g||g.row==c)return 0;var h=this.$getIndent(b.getLine(g.row));b.replace(new j(c,0,c,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""},this.toggleCommentLines=function(a,b,c,d){var e,f,g=!0,h=/^\s*\(:(.*):\)/;for(e=c;e<=d;e++)if(!h.test(b.getLine(e))){g=!1;break}var i=new j(0,0,0,0);for(e=c;e<=d;e++)f=b.getLine(e),i.start.row=e,i.end.row=e,i.end.column=f.length,b.replace(i,g?f.match(h)[1]:"(:"+f+":)")},this.deltas=[],this.createWorker=function(a){var b=new d(["ace"],"worker-xquery.js","ace/mode/xquery_worker","XQueryWorker"),c=this;return a.getDocument().on("change",function(a){c.deltas.push(a.data)}),b.attachToDocument(a.getDocument()),b.on("start",function(a){console.log("start"),c.deltas=[]}),b.on("error",function(b){a.setAnnotations([b.data])}),b.on("ok",function(b){a.clearAnnotations()}),b.on("highlight",function(b){var d=0,e=a.getLength()-1,f=b.data;for(var g in c.deltas){var h=c.deltas[g];if(h.action==="insertLines"){var i=h.range.end.row-h.range.start.row;for(var g=0;g"},{token:"comment",regex:"<\\!--",next:"comment"},{token:"comment",regex:"\\(:",next:"comment"},{token:"text",regex:"<\\/?",next:"tag"},{token:"constant",regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"},{token:"variable",regex:"\\$[a-zA-Z_][a-zA-Z0-9_\\-:]*\\b"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"},{token:"text",regex:"\\s+"},{token:"support.function",regex:"\\w[\\w+_\\-:]+(?=\\()"},{token:function(b){return a[b]?"keyword":"identifier"},regex:"[a-zA-Z_$][a-zA-Z0-9_$]*\\b"},{token:"keyword.operator",regex:"\\*|=|<|>|\\-|\\+|and|or|eq|ne|lt|gt"},{token:"lparen",regex:"[[({]"},{token:"rparen",regex:"[\\])}]"}],tag:[{token:"text",regex:">",next:"start"},{token:"meta.tag",regex:"[-_a-zA-Z0-9:]+"},{token:"text",regex:"\\s+"},{token:"string",regex:'".*?"'},{token:"string",regex:"'.*?'"}],cdata:[{token:"text",regex:"\\]\\]>",next:"start"},{token:"text",regex:"\\s+"},{token:"text",regex:"(?:[^\\]]|\\](?!\\]>))+"}],comment:[{token:"comment",regex:".*?-->",next:"start"},{token:"comment",regex:".*:\\)",next:"start"},{token:"comment",regex:".+"}]}};d.inherits(g,f),b.XQueryHighlightRules=g}),define("ace/mode/behaviour/xquery",["require","exports","module","ace/lib/oop","ace/mode/behaviour","ace/mode/behaviour/cstyle"],function(a,b,c){"use strict";var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=a("./cstyle").CstyleBehaviour,g=function(a){this.inherit(f,["braces","parens","string_dquotes"]),this.parent=a,this.add("brackets","insertion",function(a,b,c,d,e){if(e=="\n"){var f=c.getCursorPosition(),g=d.doc.getLine(f.row),h=g.substring(f.column,f.column+2);if(h=="0&&h.charAt(g.column-1)=="<"){h=h.substring(0,g.column)+"/"+h.substring(g.column);var i=e.doc.getAllLines();i[g.row]=h,a.exec("closeTag",i.join(e.doc.getNewLineCharacter()),g.row)}}return!1})};d.inherits(g,e),b.XQueryBehaviour=g}),define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour"],function(a,b,c){"use strict";var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=function(){this.add("braces","insertion",function(a,b,c,d,e){if(e=="{"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"{"+g+"}",selection:!1}:{text:"{}",selection:[1,1]}}if(e=="}"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var k=d.$findOpeningBracket("}",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var l=d.findMatchingBracket({row:h.row,column:h.column+1});if(!l)return null;var m=this.getNextLineIndent(a,i.substring(0,i.length-1),d.getTabString()),n=this.$getIndent(d.doc.getLine(l.row));return{text:"\n"+m+"\n"+n,selection:[1,m.length,1,m.length]}}}}),this.add("braces","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="{"){var g=d.doc.getLine(e.start.row),h=g.substring(e.end.column,e.end.column+1);if(h=="}")return e.end.column++,e}}),this.add("parens","insertion",function(a,b,c,d,e){if(e=="("){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"("+g+")",selection:!1}:{text:"()",selection:[1,1]}}if(e==")"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==")"){var k=d.$findOpeningBracket(")",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="("){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h==")")return e.end.column++,e}}),this.add("string_dquotes","insertion",function(a,b,c,d,e){if(e=='"'||e=="'"){var f=e,g=c.getSelectionRange(),h=d.doc.getTextRange(g);if(h!=="")return{text:f+h+f,selection:!1};var i=c.getCursorPosition(),j=d.doc.getLine(i.row),k=j.substring(i.column-1,i.column);if(k=="\\")return null;var l=d.getTokens(g.start.row,g.start.row)[0].tokens,m=0,n,o=-1;for(var p=0;pg.start.column)break;m+=l[p].value.length}if(!n||o<0&&n.type!=="comment"&&(n.type!=="string"||g.start.column!==n.value.length+m-1&&n.value.lastIndexOf(f)===n.value.length-1))return{text:f+f,selection:[1,1]};if(n&&n.type==="string"){var q=j.substring(i.column,i.column+1);if(q==f)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&(f=='"'||f=="'")){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}})};d.inherits(f,e),b.CstyleBehaviour=f}) \ No newline at end of file diff --git a/build/src/theme-monokai-noconflict.js b/build/src/theme-monokai-noconflict.js index d45c7e8c..588ae0c4 100644 --- a/build/src/theme-monokai-noconflict.js +++ b/build/src/theme-monokai-noconflict.js @@ -1 +1 @@ -ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-monokai",b.cssText=".ace-monokai .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-monokai .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-monokai .ace_gutter { background: #e8e8e8; color: #333;}.ace-monokai .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-monokai .ace_scroller { background-color: #272822;}.ace-monokai .ace_text-layer { cursor: text; color: #F8F8F2;}.ace-monokai .ace_cursor { border-left: 2px solid #F8F8F0;}.ace-monokai .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #F8F8F0;}.ace-monokai .ace_marker-layer .ace_selection { background: #49483E;}.ace-monokai.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #272822; border-radius: 2px;}.ace-monokai .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-monokai .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #49483E;}.ace-monokai .ace_marker-layer .ace_active_line { background: #49483E;}.ace-monokai .ace_marker-layer .ace_selected_word { border: 1px solid #49483E;}.ace-monokai .ace_invisible { color: #49483E;}.ace-monokai .ace_keyword, .ace-monokai .ace_meta { color:#F92672;}.ace-monokai .ace_constant.ace_language { color:#AE81FF;}.ace-monokai .ace_constant.ace_numeric { color:#AE81FF;}.ace-monokai .ace_constant.ace_other { color:#AE81FF;}.ace-monokai .ace_invalid { color:#F8F8F0;background-color:#F92672;}.ace-monokai .ace_invalid.ace_deprecated { color:#F8F8F0;background-color:#AE81FF;}.ace-monokai .ace_support.ace_constant { color:#66D9EF;}.ace-monokai .ace_fold { background-color: #A6E22E; border-color: #F8F8F2;}.ace-monokai .ace_support.ace_function { color:#66D9EF;}.ace-monokai .ace_storage { color:#F92672;}.ace-monokai .ace_storage.ace_type, .ace-monokai .ace_support.ace_type{ font-style:italic;color:#66D9EF;}.ace-monokai .ace_variable { color:#A6E22E;}.ace-monokai .ace_variable.ace_parameter { font-style:italic;color:#FD971F;}.ace-monokai .ace_string { color:#E6DB74;}.ace-monokai .ace_comment { color:#75715E;}.ace-monokai .ace_entity.ace_other.ace_attribute-name { color:#A6E22E;}.ace-monokai .ace_entity.ace_name.ace_function { color:#A6E22E;}.ace-monokai .ace_markup.ace_underline { text-decoration:underline;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file +ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-monokai",b.cssText=".ace-monokai .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-monokai .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-monokai .ace_gutter { background: #292a24; color: #f1f1f1;}.ace-monokai .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-monokai .ace_scroller { background-color: #272822;}.ace-monokai .ace_text-layer { cursor: text; color: #F8F8F2;}.ace-monokai .ace_cursor { border-left: 2px solid #F8F8F0;}.ace-monokai .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #F8F8F0;}.ace-monokai .ace_marker-layer .ace_selection { background: #49483E;}.ace-monokai.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #272822; border-radius: 2px;}.ace-monokai .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-monokai .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #49483E;}.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;}.ace-monokai .ace_invisible { color: #49483E;}.ace-monokai .ace_keyword, .ace-monokai .ace_meta { color:#F92672;}.ace-monokai .ace_constant.ace_language { color:#AE81FF;}.ace-monokai .ace_constant.ace_numeric { color:#AE81FF;}.ace-monokai .ace_constant.ace_other { color:#AE81FF;}.ace-monokai .ace_invalid { color:#F8F8F0;background-color:#F92672;}.ace-monokai .ace_invalid.ace_deprecated { color:#F8F8F0;background-color:#AE81FF;}.ace-monokai .ace_support.ace_constant { color:#66D9EF;}.ace-monokai .ace_fold { background-color: #A6E22E; border-color: #F8F8F2;}.ace-monokai .ace_support.ace_function { color:#66D9EF;}.ace-monokai .ace_storage { color:#F92672;}.ace-monokai .ace_storage.ace_type, .ace-monokai .ace_support.ace_type{ font-style:italic;color:#66D9EF;}.ace-monokai .ace_variable { color:#A6E22E;}.ace-monokai .ace_variable.ace_parameter { font-style:italic;color:#FD971F;}.ace-monokai .ace_string { color:#E6DB74;}.ace-monokai .ace_comment { color:#75715E;}.ace-monokai .ace_entity.ace_other.ace_attribute-name { color:#A6E22E;}.ace-monokai .ace_entity.ace_name.ace_function { color:#A6E22E;}.ace-monokai .ace_markup.ace_underline { text-decoration:underline;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file diff --git a/build/src/theme-monokai-uncompressed-noconflict.js b/build/src/theme-monokai-uncompressed-noconflict.js index c97dc06f..d0c9d9db 100644 --- a/build/src/theme-monokai-uncompressed-noconflict.js +++ b/build/src/theme-monokai-uncompressed-noconflict.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/src/theme-monokai-uncompressed.js b/build/src/theme-monokai-uncompressed.js index 414b07f7..4f639944 100644 --- a/build/src/theme-monokai-uncompressed.js +++ b/build/src/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/src/theme-monokai.js b/build/src/theme-monokai.js index 7ffd84f9..f6b455bc 100644 --- a/build/src/theme-monokai.js +++ b/build/src/theme-monokai.js @@ -1 +1 @@ -define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-monokai",b.cssText=".ace-monokai .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-monokai .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-monokai .ace_gutter { background: #e8e8e8; color: #333;}.ace-monokai .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-monokai .ace_scroller { background-color: #272822;}.ace-monokai .ace_text-layer { cursor: text; color: #F8F8F2;}.ace-monokai .ace_cursor { border-left: 2px solid #F8F8F0;}.ace-monokai .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #F8F8F0;}.ace-monokai .ace_marker-layer .ace_selection { background: #49483E;}.ace-monokai.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #272822; border-radius: 2px;}.ace-monokai .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-monokai .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #49483E;}.ace-monokai .ace_marker-layer .ace_active_line { background: #49483E;}.ace-monokai .ace_marker-layer .ace_selected_word { border: 1px solid #49483E;}.ace-monokai .ace_invisible { color: #49483E;}.ace-monokai .ace_keyword, .ace-monokai .ace_meta { color:#F92672;}.ace-monokai .ace_constant.ace_language { color:#AE81FF;}.ace-monokai .ace_constant.ace_numeric { color:#AE81FF;}.ace-monokai .ace_constant.ace_other { color:#AE81FF;}.ace-monokai .ace_invalid { color:#F8F8F0;background-color:#F92672;}.ace-monokai .ace_invalid.ace_deprecated { color:#F8F8F0;background-color:#AE81FF;}.ace-monokai .ace_support.ace_constant { color:#66D9EF;}.ace-monokai .ace_fold { background-color: #A6E22E; border-color: #F8F8F2;}.ace-monokai .ace_support.ace_function { color:#66D9EF;}.ace-monokai .ace_storage { color:#F92672;}.ace-monokai .ace_storage.ace_type, .ace-monokai .ace_support.ace_type{ font-style:italic;color:#66D9EF;}.ace-monokai .ace_variable { color:#A6E22E;}.ace-monokai .ace_variable.ace_parameter { font-style:italic;color:#FD971F;}.ace-monokai .ace_string { color:#E6DB74;}.ace-monokai .ace_comment { color:#75715E;}.ace-monokai .ace_entity.ace_other.ace_attribute-name { color:#A6E22E;}.ace-monokai .ace_entity.ace_name.ace_function { color:#A6E22E;}.ace-monokai .ace_markup.ace_underline { text-decoration:underline;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file +define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-monokai",b.cssText=".ace-monokai .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-monokai .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-monokai .ace_gutter { background: #292a24; color: #f1f1f1;}.ace-monokai .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-monokai .ace_scroller { background-color: #272822;}.ace-monokai .ace_text-layer { cursor: text; color: #F8F8F2;}.ace-monokai .ace_cursor { border-left: 2px solid #F8F8F0;}.ace-monokai .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #F8F8F0;}.ace-monokai .ace_marker-layer .ace_selection { background: #49483E;}.ace-monokai.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #272822; border-radius: 2px;}.ace-monokai .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-monokai .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #49483E;}.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;}.ace-monokai .ace_invisible { color: #49483E;}.ace-monokai .ace_keyword, .ace-monokai .ace_meta { color:#F92672;}.ace-monokai .ace_constant.ace_language { color:#AE81FF;}.ace-monokai .ace_constant.ace_numeric { color:#AE81FF;}.ace-monokai .ace_constant.ace_other { color:#AE81FF;}.ace-monokai .ace_invalid { color:#F8F8F0;background-color:#F92672;}.ace-monokai .ace_invalid.ace_deprecated { color:#F8F8F0;background-color:#AE81FF;}.ace-monokai .ace_support.ace_constant { color:#66D9EF;}.ace-monokai .ace_fold { background-color: #A6E22E; border-color: #F8F8F2;}.ace-monokai .ace_support.ace_function { color:#66D9EF;}.ace-monokai .ace_storage { color:#F92672;}.ace-monokai .ace_storage.ace_type, .ace-monokai .ace_support.ace_type{ font-style:italic;color:#66D9EF;}.ace-monokai .ace_variable { color:#A6E22E;}.ace-monokai .ace_variable.ace_parameter { font-style:italic;color:#FD971F;}.ace-monokai .ace_string { color:#E6DB74;}.ace-monokai .ace_comment { color:#75715E;}.ace-monokai .ace_entity.ace_other.ace_attribute-name { color:#A6E22E;}.ace-monokai .ace_entity.ace_name.ace_function { color:#A6E22E;}.ace-monokai .ace_markup.ace_underline { text-decoration:underline;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file diff --git a/build/src/theme-solarized_dark-noconflict.js b/build/src/theme-solarized_dark-noconflict.js index 149c7039..96b23b16 100644 --- a/build/src/theme-solarized_dark-noconflict.js +++ b/build/src/theme-solarized_dark-noconflict.js @@ -1 +1 @@ -ace.define("ace/theme/solarized_dark",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-solarized-dark",b.cssText=".ace-solarized-dark .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-solarized-dark .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-solarized-dark .ace_gutter { background: #e8e8e8; color: #333;}.ace-solarized-dark .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-solarized-dark .ace_scroller { background-color: #002B36;}.ace-solarized-dark .ace_text-layer { cursor: text; color: #93A1A1;}.ace-solarized-dark .ace_cursor { border-left: 2px solid #D30102;}.ace-solarized-dark .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #D30102;}.ace-solarized-dark .ace_marker-layer .ace_selection { background: #073642;}.ace-solarized-dark.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #002B36; border-radius: 2px;}.ace-solarized-dark .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-solarized-dark .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(147, 161, 161, 0.50);}.ace-solarized-dark .ace_marker-layer .ace_active_line { background: #073642;}.ace-solarized-dark .ace_marker-layer .ace_selected_word { border: 1px solid #073642;}.ace-solarized-dark .ace_invisible { color: rgba(147, 161, 161, 0.50);}.ace-solarized-dark .ace_keyword, .ace-solarized-dark .ace_meta { color:#859900;}.ace-solarized-dark .ace_constant.ace_language { color:#B58900;}.ace-solarized-dark .ace_constant.ace_numeric { color:#D33682;}.ace-solarized-dark .ace_constant.ace_other { color:#CB4B16;}.ace-solarized-dark .ace_fold { background-color: #268BD2; border-color: #93A1A1;}.ace-solarized-dark .ace_support.ace_function { color:#268BD2;}.ace-solarized-dark .ace_storage { color:#93A1A1;}.ace-solarized-dark .ace_variable { color:#268BD2;}.ace-solarized-dark .ace_string { color:#2AA198;}.ace-solarized-dark .ace_string.ace_regexp { color:#D30102;}.ace-solarized-dark .ace_comment { font-style:italic;color:#657B83;}.ace-solarized-dark .ace_variable.ace_language { color:#268BD2;}.ace-solarized-dark .ace_entity.ace_other.ace_attribute-name { color:#93A1A1;}.ace-solarized-dark .ace_entity.ace_name.ace_function { color:#268BD2;}.ace-solarized-dark .ace_markup.ace_underline { text-decoration:underline;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file +ace.define("ace/theme/solarized_dark",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-solarized-dark",b.cssText=".ace-solarized-dark .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-solarized-dark .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-solarized-dark .ace_gutter { background: #09222b; color: #d0edf7;}.ace-solarized-dark .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-solarized-dark .ace_scroller { background-color: #002B36;}.ace-solarized-dark .ace_text-layer { cursor: text; color: #93A1A1;}.ace-solarized-dark .ace_cursor { border-left: 2px solid #D30102;}.ace-solarized-dark .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #D30102;}.ace-solarized-dark .ace_marker-layer .ace_selection { background: #073642;}.ace-solarized-dark.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #002B36; border-radius: 2px;}.ace-solarized-dark .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-solarized-dark .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(147, 161, 161, 0.50);}.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;}.ace-solarized-dark .ace_invisible { color: rgba(147, 161, 161, 0.50);}.ace-solarized-dark .ace_keyword, .ace-solarized-dark .ace_meta { color:#859900;}.ace-solarized-dark .ace_constant.ace_language { color:#B58900;}.ace-solarized-dark .ace_constant.ace_numeric { color:#D33682;}.ace-solarized-dark .ace_constant.ace_other { color:#CB4B16;}.ace-solarized-dark .ace_fold { background-color: #268BD2; border-color: #93A1A1;}.ace-solarized-dark .ace_support.ace_function { color:#268BD2;}.ace-solarized-dark .ace_storage { color:#93A1A1;}.ace-solarized-dark .ace_variable { color:#268BD2;}.ace-solarized-dark .ace_string { color:#2AA198;}.ace-solarized-dark .ace_string.ace_regexp { color:#D30102;}.ace-solarized-dark .ace_comment { font-style:italic;color:#657B83;}.ace-solarized-dark .ace_variable.ace_language { color:#268BD2;}.ace-solarized-dark .ace_entity.ace_other.ace_attribute-name { color:#93A1A1;}.ace-solarized-dark .ace_entity.ace_name.ace_function { color:#268BD2;}.ace-solarized-dark .ace_markup.ace_underline { text-decoration:underline;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file diff --git a/build/src/theme-solarized_dark-uncompressed-noconflict.js b/build/src/theme-solarized_dark-uncompressed-noconflict.js index 06e8a1d8..9b6eb694 100644 --- a/build/src/theme-solarized_dark-uncompressed-noconflict.js +++ b/build/src/theme-solarized_dark-uncompressed-noconflict.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/src/theme-solarized_dark-uncompressed.js b/build/src/theme-solarized_dark-uncompressed.js index 65ccdf28..f96e08e7 100644 --- a/build/src/theme-solarized_dark-uncompressed.js +++ b/build/src/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/src/theme-solarized_dark.js b/build/src/theme-solarized_dark.js index 2ea52c5d..5d266f6b 100644 --- a/build/src/theme-solarized_dark.js +++ b/build/src/theme-solarized_dark.js @@ -1 +1 @@ -define("ace/theme/solarized_dark",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-solarized-dark",b.cssText=".ace-solarized-dark .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-solarized-dark .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-solarized-dark .ace_gutter { background: #e8e8e8; color: #333;}.ace-solarized-dark .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-solarized-dark .ace_scroller { background-color: #002B36;}.ace-solarized-dark .ace_text-layer { cursor: text; color: #93A1A1;}.ace-solarized-dark .ace_cursor { border-left: 2px solid #D30102;}.ace-solarized-dark .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #D30102;}.ace-solarized-dark .ace_marker-layer .ace_selection { background: #073642;}.ace-solarized-dark.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #002B36; border-radius: 2px;}.ace-solarized-dark .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-solarized-dark .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(147, 161, 161, 0.50);}.ace-solarized-dark .ace_marker-layer .ace_active_line { background: #073642;}.ace-solarized-dark .ace_marker-layer .ace_selected_word { border: 1px solid #073642;}.ace-solarized-dark .ace_invisible { color: rgba(147, 161, 161, 0.50);}.ace-solarized-dark .ace_keyword, .ace-solarized-dark .ace_meta { color:#859900;}.ace-solarized-dark .ace_constant.ace_language { color:#B58900;}.ace-solarized-dark .ace_constant.ace_numeric { color:#D33682;}.ace-solarized-dark .ace_constant.ace_other { color:#CB4B16;}.ace-solarized-dark .ace_fold { background-color: #268BD2; border-color: #93A1A1;}.ace-solarized-dark .ace_support.ace_function { color:#268BD2;}.ace-solarized-dark .ace_storage { color:#93A1A1;}.ace-solarized-dark .ace_variable { color:#268BD2;}.ace-solarized-dark .ace_string { color:#2AA198;}.ace-solarized-dark .ace_string.ace_regexp { color:#D30102;}.ace-solarized-dark .ace_comment { font-style:italic;color:#657B83;}.ace-solarized-dark .ace_variable.ace_language { color:#268BD2;}.ace-solarized-dark .ace_entity.ace_other.ace_attribute-name { color:#93A1A1;}.ace-solarized-dark .ace_entity.ace_name.ace_function { color:#268BD2;}.ace-solarized-dark .ace_markup.ace_underline { text-decoration:underline;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file +define("ace/theme/solarized_dark",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-solarized-dark",b.cssText=".ace-solarized-dark .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-solarized-dark .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-solarized-dark .ace_gutter { background: #09222b; color: #d0edf7;}.ace-solarized-dark .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-solarized-dark .ace_scroller { background-color: #002B36;}.ace-solarized-dark .ace_text-layer { cursor: text; color: #93A1A1;}.ace-solarized-dark .ace_cursor { border-left: 2px solid #D30102;}.ace-solarized-dark .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #D30102;}.ace-solarized-dark .ace_marker-layer .ace_selection { background: #073642;}.ace-solarized-dark.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #002B36; border-radius: 2px;}.ace-solarized-dark .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-solarized-dark .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(147, 161, 161, 0.50);}.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;}.ace-solarized-dark .ace_invisible { color: rgba(147, 161, 161, 0.50);}.ace-solarized-dark .ace_keyword, .ace-solarized-dark .ace_meta { color:#859900;}.ace-solarized-dark .ace_constant.ace_language { color:#B58900;}.ace-solarized-dark .ace_constant.ace_numeric { color:#D33682;}.ace-solarized-dark .ace_constant.ace_other { color:#CB4B16;}.ace-solarized-dark .ace_fold { background-color: #268BD2; border-color: #93A1A1;}.ace-solarized-dark .ace_support.ace_function { color:#268BD2;}.ace-solarized-dark .ace_storage { color:#93A1A1;}.ace-solarized-dark .ace_variable { color:#268BD2;}.ace-solarized-dark .ace_string { color:#2AA198;}.ace-solarized-dark .ace_string.ace_regexp { color:#D30102;}.ace-solarized-dark .ace_comment { font-style:italic;color:#657B83;}.ace-solarized-dark .ace_variable.ace_language { color:#268BD2;}.ace-solarized-dark .ace_entity.ace_other.ace_attribute-name { color:#93A1A1;}.ace-solarized-dark .ace_entity.ace_name.ace_function { color:#268BD2;}.ace-solarized-dark .ace_markup.ace_underline { text-decoration:underline;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file diff --git a/build/src/theme-tomorrow_night_blue-noconflict.js b/build/src/theme-tomorrow_night_blue-noconflict.js index 540e8397..35fa6971 100644 --- a/build/src/theme-tomorrow_night_blue-noconflict.js +++ b/build/src/theme-tomorrow_night_blue-noconflict.js @@ -1 +1 @@ -ace.define("ace/theme/tomorrow_night_blue",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-tomorrow-night-blue",b.cssText=".ace-tomorrow-night-blue .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-tomorrow-night-blue .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-tomorrow-night-blue .ace_gutter { background: #e8e8e8; color: #333;}.ace-tomorrow-night-blue .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-tomorrow-night-blue .ace_scroller { background-color: #002451;}.ace-tomorrow-night-blue .ace_text-layer { cursor: text; color: #FFFFFF;}.ace-tomorrow-night-blue .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-tomorrow-night-blue .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;}.ace-tomorrow-night-blue .ace_marker-layer .ace_selection { background: #003F8E;}.ace-tomorrow-night-blue.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #002451; border-radius: 2px;}.ace-tomorrow-night-blue .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-tomorrow-night-blue .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #404F7D;}.ace-tomorrow-night-blue .ace_marker-layer .ace_active_line { background: #00346E;}.ace-tomorrow-night-blue .ace_marker-layer .ace_selected_word { border: 1px solid #003F8E;}.ace-tomorrow-night-blue .ace_invisible { color: #404F7D;}.ace-tomorrow-night-blue .ace_keyword, .ace-tomorrow-night-blue .ace_meta { color:#EBBBFF;}.ace-tomorrow-night-blue .ace_keyword.ace_operator { color:#99FFFF;}.ace-tomorrow-night-blue .ace_constant.ace_language { color:#FFC58F;}.ace-tomorrow-night-blue .ace_constant.ace_numeric { color:#FFC58F;}.ace-tomorrow-night-blue .ace_constant.ace_other { color:#FFFFFF;}.ace-tomorrow-night-blue .ace_invalid { color:#FFFFFF;background-color:#F99DA5;}.ace-tomorrow-night-blue .ace_invalid.ace_deprecated { color:#FFFFFF;background-color:#EBBBFF;}.ace-tomorrow-night-blue .ace_support.ace_constant { color:#FFC58F;}.ace-tomorrow-night-blue .ace_fold { background-color: #BBDAFF; border-color: #FFFFFF;}.ace-tomorrow-night-blue .ace_support.ace_function { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_storage { color:#EBBBFF;}.ace-tomorrow-night-blue .ace_storage.ace_type, .ace-tomorrow-night-blue .ace_support.ace_type{ color:#EBBBFF;}.ace-tomorrow-night-blue .ace_variable { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_variable.ace_parameter { color:#FFC58F;}.ace-tomorrow-night-blue .ace_string { color:#D1F1A9;}.ace-tomorrow-night-blue .ace_string.ace_regexp { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_comment { color:#7285B7;}.ace-tomorrow-night-blue .ace_variable { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_meta.ace_tag { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_entity.ace_other.ace_attribute-name { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_entity.ace_name.ace_function { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_markup.ace_underline { text-decoration:underline;}.ace-tomorrow-night-blue .ace_markup.ace_heading { color:#D1F1A9;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file +ace.define("ace/theme/tomorrow_night_blue",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-tomorrow-night-blue",b.cssText=".ace-tomorrow-night-blue .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-tomorrow-night-blue .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-tomorrow-night-blue .ace_gutter { background: #022346; color: #7388b5;}.ace-tomorrow-night-blue .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-tomorrow-night-blue .ace_scroller { background-color: #002451;}.ace-tomorrow-night-blue .ace_text-layer { cursor: text; color: #FFFFFF;}.ace-tomorrow-night-blue .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-tomorrow-night-blue .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;}.ace-tomorrow-night-blue .ace_marker-layer .ace_selection { background: #003F8E;}.ace-tomorrow-night-blue.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #002451; border-radius: 2px;}.ace-tomorrow-night-blue .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-tomorrow-night-blue .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #404F7D;}.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;}.ace-tomorrow-night-blue .ace_invisible { color: #404F7D;}.ace-tomorrow-night-blue .ace_keyword, .ace-tomorrow-night-blue .ace_meta { color:#EBBBFF;}.ace-tomorrow-night-blue .ace_keyword.ace_operator { color:#99FFFF;}.ace-tomorrow-night-blue .ace_constant.ace_language { color:#FFC58F;}.ace-tomorrow-night-blue .ace_constant.ace_numeric { color:#FFC58F;}.ace-tomorrow-night-blue .ace_constant.ace_other { color:#FFFFFF;}.ace-tomorrow-night-blue .ace_invalid { color:#FFFFFF;background-color:#F99DA5;}.ace-tomorrow-night-blue .ace_invalid.ace_deprecated { color:#FFFFFF;background-color:#EBBBFF;}.ace-tomorrow-night-blue .ace_support.ace_constant { color:#FFC58F;}.ace-tomorrow-night-blue .ace_fold { background-color: #BBDAFF; border-color: #FFFFFF;}.ace-tomorrow-night-blue .ace_support.ace_function { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_storage { color:#EBBBFF;}.ace-tomorrow-night-blue .ace_storage.ace_type, .ace-tomorrow-night-blue .ace_support.ace_type{ color:#EBBBFF;}.ace-tomorrow-night-blue .ace_variable { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_variable.ace_parameter { color:#FFC58F;}.ace-tomorrow-night-blue .ace_string { color:#D1F1A9;}.ace-tomorrow-night-blue .ace_string.ace_regexp { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_comment { color:#7285B7;}.ace-tomorrow-night-blue .ace_variable { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_meta.ace_tag { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_entity.ace_other.ace_attribute-name { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_entity.ace_name.ace_function { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_markup.ace_underline { text-decoration:underline;}.ace-tomorrow-night-blue .ace_markup.ace_heading { color:#D1F1A9;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file diff --git a/build/src/theme-tomorrow_night_blue-uncompressed-noconflict.js b/build/src/theme-tomorrow_night_blue-uncompressed-noconflict.js index 784bb54d..a5d95ca6 100644 --- a/build/src/theme-tomorrow_night_blue-uncompressed-noconflict.js +++ b/build/src/theme-tomorrow_night_blue-uncompressed-noconflict.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/src/theme-tomorrow_night_blue-uncompressed.js b/build/src/theme-tomorrow_night_blue-uncompressed.js index ff831a06..7c014296 100644 --- a/build/src/theme-tomorrow_night_blue-uncompressed.js +++ b/build/src/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/src/theme-tomorrow_night_blue.js b/build/src/theme-tomorrow_night_blue.js index 69f20bb2..252a4fdd 100644 --- a/build/src/theme-tomorrow_night_blue.js +++ b/build/src/theme-tomorrow_night_blue.js @@ -1 +1 @@ -define("ace/theme/tomorrow_night_blue",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-tomorrow-night-blue",b.cssText=".ace-tomorrow-night-blue .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-tomorrow-night-blue .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-tomorrow-night-blue .ace_gutter { background: #e8e8e8; color: #333;}.ace-tomorrow-night-blue .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-tomorrow-night-blue .ace_scroller { background-color: #002451;}.ace-tomorrow-night-blue .ace_text-layer { cursor: text; color: #FFFFFF;}.ace-tomorrow-night-blue .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-tomorrow-night-blue .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;}.ace-tomorrow-night-blue .ace_marker-layer .ace_selection { background: #003F8E;}.ace-tomorrow-night-blue.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #002451; border-radius: 2px;}.ace-tomorrow-night-blue .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-tomorrow-night-blue .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #404F7D;}.ace-tomorrow-night-blue .ace_marker-layer .ace_active_line { background: #00346E;}.ace-tomorrow-night-blue .ace_marker-layer .ace_selected_word { border: 1px solid #003F8E;}.ace-tomorrow-night-blue .ace_invisible { color: #404F7D;}.ace-tomorrow-night-blue .ace_keyword, .ace-tomorrow-night-blue .ace_meta { color:#EBBBFF;}.ace-tomorrow-night-blue .ace_keyword.ace_operator { color:#99FFFF;}.ace-tomorrow-night-blue .ace_constant.ace_language { color:#FFC58F;}.ace-tomorrow-night-blue .ace_constant.ace_numeric { color:#FFC58F;}.ace-tomorrow-night-blue .ace_constant.ace_other { color:#FFFFFF;}.ace-tomorrow-night-blue .ace_invalid { color:#FFFFFF;background-color:#F99DA5;}.ace-tomorrow-night-blue .ace_invalid.ace_deprecated { color:#FFFFFF;background-color:#EBBBFF;}.ace-tomorrow-night-blue .ace_support.ace_constant { color:#FFC58F;}.ace-tomorrow-night-blue .ace_fold { background-color: #BBDAFF; border-color: #FFFFFF;}.ace-tomorrow-night-blue .ace_support.ace_function { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_storage { color:#EBBBFF;}.ace-tomorrow-night-blue .ace_storage.ace_type, .ace-tomorrow-night-blue .ace_support.ace_type{ color:#EBBBFF;}.ace-tomorrow-night-blue .ace_variable { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_variable.ace_parameter { color:#FFC58F;}.ace-tomorrow-night-blue .ace_string { color:#D1F1A9;}.ace-tomorrow-night-blue .ace_string.ace_regexp { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_comment { color:#7285B7;}.ace-tomorrow-night-blue .ace_variable { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_meta.ace_tag { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_entity.ace_other.ace_attribute-name { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_entity.ace_name.ace_function { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_markup.ace_underline { text-decoration:underline;}.ace-tomorrow-night-blue .ace_markup.ace_heading { color:#D1F1A9;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file +define("ace/theme/tomorrow_night_blue",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-tomorrow-night-blue",b.cssText=".ace-tomorrow-night-blue .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-tomorrow-night-blue .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-tomorrow-night-blue .ace_gutter { background: #022346; color: #7388b5;}.ace-tomorrow-night-blue .ace_print_margin { width: 1px; background: #e8e8e8;}.ace-tomorrow-night-blue .ace_scroller { background-color: #002451;}.ace-tomorrow-night-blue .ace_text-layer { cursor: text; color: #FFFFFF;}.ace-tomorrow-night-blue .ace_cursor { border-left: 2px solid #FFFFFF;}.ace-tomorrow-night-blue .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #FFFFFF;}.ace-tomorrow-night-blue .ace_marker-layer .ace_selection { background: #003F8E;}.ace-tomorrow-night-blue.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #002451; border-radius: 2px;}.ace-tomorrow-night-blue .ace_marker-layer .ace_step { background: rgb(198, 219, 174);}.ace-tomorrow-night-blue .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid #404F7D;}.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;}.ace-tomorrow-night-blue .ace_invisible { color: #404F7D;}.ace-tomorrow-night-blue .ace_keyword, .ace-tomorrow-night-blue .ace_meta { color:#EBBBFF;}.ace-tomorrow-night-blue .ace_keyword.ace_operator { color:#99FFFF;}.ace-tomorrow-night-blue .ace_constant.ace_language { color:#FFC58F;}.ace-tomorrow-night-blue .ace_constant.ace_numeric { color:#FFC58F;}.ace-tomorrow-night-blue .ace_constant.ace_other { color:#FFFFFF;}.ace-tomorrow-night-blue .ace_invalid { color:#FFFFFF;background-color:#F99DA5;}.ace-tomorrow-night-blue .ace_invalid.ace_deprecated { color:#FFFFFF;background-color:#EBBBFF;}.ace-tomorrow-night-blue .ace_support.ace_constant { color:#FFC58F;}.ace-tomorrow-night-blue .ace_fold { background-color: #BBDAFF; border-color: #FFFFFF;}.ace-tomorrow-night-blue .ace_support.ace_function { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_storage { color:#EBBBFF;}.ace-tomorrow-night-blue .ace_storage.ace_type, .ace-tomorrow-night-blue .ace_support.ace_type{ color:#EBBBFF;}.ace-tomorrow-night-blue .ace_variable { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_variable.ace_parameter { color:#FFC58F;}.ace-tomorrow-night-blue .ace_string { color:#D1F1A9;}.ace-tomorrow-night-blue .ace_string.ace_regexp { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_comment { color:#7285B7;}.ace-tomorrow-night-blue .ace_variable { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_meta.ace_tag { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_entity.ace_other.ace_attribute-name { color:#FF9DA4;}.ace-tomorrow-night-blue .ace_entity.ace_name.ace_function { color:#BBDAFF;}.ace-tomorrow-night-blue .ace_markup.ace_underline { text-decoration:underline;}.ace-tomorrow-night-blue .ace_markup.ace_heading { color:#D1F1A9;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) \ No newline at end of file diff --git a/build/src/worker-coffee.js b/build/src/worker-coffee.js index f6bdddce..aa9daade 100644 --- a/build/src/worker-coffee.js +++ b/build/src/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/src/worker-css.js b/build/src/worker-css.js index ed475ec5..a86bbcb0 100644 --- a/build/src/worker-css.js +++ b/build/src/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/src/worker-javascript.js b/build/src/worker-javascript.js index 236565a2..bd77cc7f 100644 --- a/build/src/worker-javascript.js +++ b/build/src/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/src/worker-json.js b/build/src/worker-json.js index b00a47b9..cffed24f 100644 --- a/build/src/worker-json.js +++ b/build/src/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/src/worker-xquery.js b/build/src/worker-xquery.js index f056d536..60f818cc 100644 --- a/build/src/worker-xquery.js +++ b/build/src/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/textarea/images/logo_half.png b/build/textarea/images/logo_half.png new file mode 100644 index 00000000..f99b0c4b Binary files /dev/null and b/build/textarea/images/logo_half.png differ diff --git a/build/textarea/src/ace-bookmarklet.js b/build/textarea/src/ace-bookmarklet.js index 09de1d77..8b27207e 100644 --- a/build/textarea/src/ace-bookmarklet.js +++ b/build/textarea/src/ace-bookmarklet.js @@ -252,7 +252,7 @@ var ace = require("../ace"); require("ace/theme/textmate"); -/** +/* * Returns the CSS property of element. * 1) If the CSS property is on the style object of the element, use it, OR * 2) Compute the CSS property @@ -776,7 +776,7 @@ exports.removeListener = function(elem, type, callback) { } }; -/** +/* * Prevents propagation and clobbers the default action of the passed event */ exports.stopEvent = function(e) { @@ -799,23 +799,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) { @@ -1072,7 +1056,7 @@ __ace_shadowed__.define('ace/lib/keys', ['require', 'exports', 'module' , 'ace/l var oop = require("./oop"); -/** +/* * Helper functions and hashes for key handling. */ var Keys = (function() { @@ -1162,7 +1146,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 @@ -1266,13 +1251,13 @@ __ace_shadowed__.define('ace/lib/useragent', ['require', 'exports', 'module' ], 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 = @@ -1281,16 +1266,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; @@ -1301,7 +1286,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. * @@ -1314,7 +1299,7 @@ exports.OS = { WINDOWS: "WINDOWS" }; -/** +/* * Return an exports.OS constant */ exports.getOS = function() { @@ -1393,7 +1378,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) { @@ -1402,7 +1387,7 @@ exports.addCssClass = function(el, name) { } }; -/** +/* * Remove a CSS class from the list of classes on the given node */ exports.removeCssClass = function(el, name) { @@ -1434,7 +1419,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 */ @@ -1585,7 +1570,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. * @@ -1619,7 +1604,8 @@ exports.getParentWindow = function(document) { return document.defaultView || document.parentWindow; }; -});/** +}); +/* * based on code from: * * @license RequireJS text 0.25.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved. @@ -1680,7 +1666,8 @@ exports.loadScript = function(path, callback) { s.onload = callback; }; -});/* ***** 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 @@ -1717,6 +1704,14 @@ exports.loadScript = function(path, callback) { * * ***** END LICENSE BLOCK ***** */ +/** + * class Ace + * + * The main class required to set up an Ace instance in the browser. + * + * + **/ + __ace_shadowed__.define('ace/ace', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/dom', 'ace/lib/event', 'ace/editor', 'ace/edit_session', 'ace/undomanager', 'ace/virtual_renderer', 'ace/multi_select', 'ace/worker/worker_client', 'ace/keyboard/hash_handler', 'ace/keyboard/state_handler', 'ace/placeholder', 'ace/config', 'ace/theme/textmate'], function(require, exports, module) { "use strict"; @@ -1738,6 +1733,13 @@ require("./keyboard/state_handler"); require("./placeholder"); require("./config").init(); + /** + * Ace.edit(el) -> Editor + * - el (String | DOMElement): Either the id of an element, or the element itself + * + * This method embeds the Ace editor into the DOM, at the element provided by `el`. + * + **/ exports.edit = function(el) { if (typeof(el) == "string") { el = document.getElementById(el); @@ -1765,7 +1767,8 @@ exports.edit = function(el) { return editor; }; -});// vim:set ts=4 sts=4 sw=4 st: +}); +// vim:set ts=4 sts=4 sw=4 st: // -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License // -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project) // -- dantman Daniel Friesen Copyright(C) 2010 XXX No License Specified @@ -1783,7 +1786,8 @@ __ace_shadowed__.define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module require("./regexp"); require("./es5-shim"); -});/** +}); +/* * Based on code from: * * XRegExp 1.5.0 @@ -1921,7 +1925,7 @@ __ace_shadowed__.define('ace/lib/regexp', ['require', 'exports', 'module' ], fun __ace_shadowed__.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. * @@ -2951,7 +2955,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 * @@ -3011,12 +3016,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 @@ -3032,7 +3054,6 @@ var Editor = function(renderer, session) { wrap: true }); - this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands); this.setSession(session || new EditSession("")); }; @@ -3040,14 +3061,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; @@ -3147,39 +3184,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); @@ -3204,6 +3286,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 @@ -3215,26 +3302,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; @@ -3249,51 +3367,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; @@ -3304,11 +3441,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(); @@ -3329,34 +3471,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. @@ -3365,6 +3547,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()) @@ -3374,10 +3561,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(); @@ -3470,46 +3687,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; @@ -3518,23 +3792,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; @@ -3546,6 +3857,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; }; @@ -3558,6 +3874,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; @@ -3565,44 +3887,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) @@ -3613,13 +3992,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(); @@ -3638,6 +4037,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(); @@ -3646,6 +4050,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(); @@ -3654,6 +4063,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(); @@ -3662,6 +4076,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(); @@ -3676,6 +4095,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()); @@ -3687,6 +4111,11 @@ var Editor = function(renderer, session) { this.moveCursorToPosition(cursor); }; + /** + * Editor.transposeLetters() + * + * Transposes current line. + **/ this.transposeLetters = function() { if (!this.selection.isEmpty()) { return; @@ -3710,6 +4139,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()) { @@ -3722,6 +4156,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()) { @@ -3734,6 +4173,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(); @@ -3757,17 +4201,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; @@ -3782,18 +4241,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; @@ -3801,6 +4289,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); @@ -3808,6 +4304,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); @@ -3815,6 +4320,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; @@ -3838,6 +4350,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(); @@ -3847,141 +4367,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); @@ -4000,34 +4657,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; @@ -4042,6 +4735,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; @@ -4056,36 +4755,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); @@ -4106,6 +4846,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); @@ -4145,35 +4892,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())}); @@ -4182,35 +4952,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(); }; @@ -4323,7 +5104,7 @@ exports.arrayToMap = function(arr) { }; -/** +/* * splice out of 'array' anything that === 'value' */ exports.arrayRemove = function(array, value) { @@ -4421,7 +5202,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); @@ -4444,13 +5227,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 @@ -4471,7 +5259,7 @@ var TextInput = function(parentNode, host) { var onTextInput = function(e) { setTimeout(function () { if (!inCompostion) - sendText(e.data); + sendText(e.data); }, 0); }; @@ -4527,6 +5315,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) { @@ -4697,10 +5486,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); @@ -4717,7 +5506,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")); @@ -4739,7 +5528,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; @@ -4763,10 +5552,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; @@ -4795,6 +5622,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 @@ -4810,240 +5638,290 @@ exports.MouseHandler = MouseHandler; * * ***** END LICENSE BLOCK ***** */ -__ace_shadowed__.define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/dom', 'ace/lib/browser_focus'], function(require, exports, module) { +__ace_shadowed__.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; @@ -5100,7 +5978,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. @@ -5235,7 +6113,7 @@ EventEmitter._dispatchEvent = function(eventName, e) { } if (defaultHandler && !e.defaultPrevented) - defaultHandler(e); + return defaultHandler(e); }; EventEmitter.setDefaultHandler = function(eventName, callback) { @@ -5278,7 +6156,8 @@ EventEmitter.removeAllListeners = function(eventName) { exports.EventEmitter = EventEmitter; -});/* 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 * @@ -5319,19 +6198,31 @@ exports.EventEmitter = EventEmitter; __ace_shadowed__.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 * @@ -5374,18 +6265,15 @@ __ace_shadowed__.define('ace/mouse/mouse_event', ['require', 'exports', 'module' 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; @@ -5411,7 +6299,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 @@ -5419,14 +6307,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 @@ -5452,7 +6338,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 @@ -5461,7 +6347,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() { @@ -5545,7 +6431,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 @@ -5594,15 +6481,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) { @@ -5640,7 +6539,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; @@ -5650,20 +6549,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); @@ -5986,7 +6879,7 @@ exports.commands = [{ multiSelectAction: "forEach" }, { name: "togglecomment", - bindKey: bindKey("Ctrl-7", "Command-7"), + bindKey: bindKey("Ctrl-/", "Command-/"), exec: function(editor) { editor.toggleCommentLines(); }, multiSelectAction: "forEach" }, { @@ -6167,6 +7060,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 = []; @@ -6192,10 +7101,7 @@ var EditSession = function(text, mode) { } this.selection = new Selection(this); - if (mode) - this.setMode(mode); - else - this.setMode(new TextMode()); + this.setMode(mode); }; @@ -6203,6 +7109,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"); @@ -6217,10 +7130,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 = []; @@ -6235,11 +7161,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; @@ -6263,6 +7200,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); @@ -6275,23 +7219,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; @@ -6313,6 +7296,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); @@ -6325,6 +7314,11 @@ var EditSession = function(text, mode) { if (undoManager) { var self = this; + /** internal, hide + * EditSession.$syncInformUndoManager() + * + * + **/ this.$syncInformUndoManager = function() { self.$informUndoManager.cancel(); @@ -6364,10 +7358,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()); @@ -6377,17 +7381,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; @@ -6396,15 +7419,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; @@ -6412,18 +7453,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++; @@ -6473,6 +7559,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) @@ -6485,11 +7578,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, @@ -6498,6 +7598,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) { @@ -6529,6 +7652,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); @@ -6560,7 +7691,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); @@ -6571,15 +7708,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; @@ -6591,10 +7747,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); @@ -6605,7 +7771,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 { @@ -6613,16 +7779,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] @@ -6633,33 +7800,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(); @@ -6694,6 +7876,11 @@ var EditSession = function(text, mode) { this._emit("changeMode"); }; + /** internal, hide + * EditSession.stopWorker() + * + * + **/ this.$stopWorker = function() { if (this.$worker) this.$worker.terminate(); @@ -6701,6 +7888,11 @@ var EditSession = function(text, mode) { this.$worker = null; }; + /** internal, hide + * EditSession.$startWorker() + * + * + **/ this.$startWorker = function() { if (typeof Worker !== "undefined" && !require.noWorker) { try { @@ -6715,11 +7907,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) @@ -6729,11 +7932,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) @@ -6743,15 +7956,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; @@ -6796,33 +8024,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; @@ -6849,6 +8126,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; @@ -6871,10 +8155,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 = @@ -6929,19 +8224,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); @@ -6972,12 +8284,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); @@ -7002,6 +8332,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; @@ -7010,6 +8350,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; @@ -7018,6 +8367,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); @@ -7029,6 +8389,7 @@ var EditSession = function(text, mode) { return addedRows; }; + this.$clipRowToDocument = function(row) { return Math.max(0, Math.min(row, this.doc.getLength()-1)); }; @@ -7039,6 +8400,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); @@ -7071,7 +8433,7 @@ var EditSession = function(text, mode) { range.start.column ); } - + var len = this.doc.getLength() - 1; if (range.end.row > len) { range.end.row = len; @@ -7093,6 +8455,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; @@ -7113,6 +8481,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; }; @@ -7121,6 +8494,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; @@ -7131,8 +8511,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) { @@ -7148,6 +8532,11 @@ var EditSession = function(text, mode) { return false; }; + /** internal, hide + * EditSession.$constrainWrapLimit(wrapLimit) + * + * + **/ this.$constrainWrapLimit = function(wrapLimit) { var min = this.$wrapLimitRange.min; if (min) @@ -7161,10 +8550,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 { @@ -7173,6 +8575,11 @@ var EditSession = function(text, mode) { }; }; + /** internal, hide + * EditSession.$updateInternalDataOnChange() + * + * + **/ this.$updateInternalDataOnChange = function(e) { var useWrapMode = this.$useWrapMode; var len; @@ -7288,6 +8695,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(); @@ -7347,6 +8759,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 []; @@ -7463,11 +8880,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; @@ -7499,15 +8918,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]; @@ -7540,8 +8963,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; @@ -7551,27 +8978,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; @@ -7581,20 +9033,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 { @@ -7690,6 +9165,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") @@ -7793,14 +9279,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; @@ -8006,7 +9507,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 @@ -8053,22 +9555,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"); @@ -8086,13 +9596,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; @@ -8101,12 +9621,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; @@ -8114,20 +9646,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; }; @@ -8146,15 +9696,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); @@ -8167,6 +9727,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; @@ -8174,12 +9739,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); @@ -8192,80 +9770,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); @@ -8275,22 +9934,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)) { @@ -8310,20 +9993,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 @@ -8331,9 +10019,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. @@ -8359,8 +10052,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( @@ -8369,19 +10067,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); @@ -8395,14 +10108,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); @@ -8411,7 +10124,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; @@ -8421,9 +10134,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; @@ -8436,19 +10154,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); @@ -8467,10 +10185,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) { @@ -8486,10 +10297,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); @@ -8499,13 +10324,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); @@ -8513,8 +10346,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; } @@ -8583,6 +10416,23 @@ exports.Selection = Selection; __ace_shadowed__.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, @@ -8596,6 +10446,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 && @@ -8603,28 +10460,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, @@ -8654,27 +10534,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; @@ -8685,6 +10624,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; @@ -8695,6 +10642,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)) { @@ -8706,6 +10661,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)) { @@ -8717,6 +10680,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)) { @@ -8728,6 +10699,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) { @@ -8751,8 +10743,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; @@ -8762,8 +10774,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; @@ -8772,6 +10802,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; @@ -8782,6 +10827,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 = { @@ -8813,6 +10866,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); @@ -8826,33 +10887,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) @@ -8860,6 +10924,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); @@ -8874,7 +10944,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); }; @@ -9142,6 +11219,21 @@ exports.Mode = Mode; __ace_shadowed__.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; @@ -9187,6 +11279,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]; @@ -9483,7 +11580,8 @@ var Behaviour = function() { }).call(Behaviour.prototype); exports.Behaviour = Behaviour; -});__ace_shadowed__.define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) { +}); +__ace_shadowed__.define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) { "use strict"; /* @@ -9589,7 +11687,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 @@ -9634,6 +11733,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 = []; @@ -9653,20 +11767,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) { @@ -9678,6 +11820,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) { @@ -9687,6 +11834,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": @@ -9702,6 +11860,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; @@ -9709,51 +11873,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) { @@ -9763,6 +11968,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; @@ -9786,6 +12000,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}; @@ -9804,6 +12031,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] || ""; @@ -9826,6 +12064,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; @@ -9850,6 +12101,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); @@ -9882,6 +12142,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; @@ -9902,12 +12173,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); @@ -9922,6 +12196,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); @@ -9939,6 +12220,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; @@ -9959,6 +12252,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]; @@ -10040,9 +12343,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; @@ -10059,14 +12375,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; @@ -10132,6 +12470,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) { @@ -10160,10 +12508,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 = {}; @@ -10232,6 +12596,23 @@ __ace_shadowed__.define('ace/background_tokenizer', ['require', 'exports', 'modu 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 = []; @@ -10273,6 +12654,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 = []; @@ -10280,6 +12669,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 = []; @@ -10287,6 +12684,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, @@ -10295,6 +12701,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()); @@ -10307,20 +12721,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':[]}]; @@ -10412,7 +12860,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 @@ -10436,7 +12884,7 @@ function Folding() { } }; - /** + /* * Returns all folds in the given range. Note, that this will return folds * */ @@ -10482,7 +12930,7 @@ function Folding() { return foundFolds; }; - /** + /* * Returns all folds in the document */ this.getAllFolds = function() { @@ -10505,7 +12953,7 @@ function Folding() { return folds; }; - /** + /* * Returns the string between folds at the given position. * E.g. * foob|arwolrd -> "bar" @@ -10624,7 +13072,7 @@ function Folding() { return foldLine; }; - /** + /* * Adds a new fold. * * @returns @@ -10824,7 +13272,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. **/ @@ -11164,7 +13612,7 @@ __ace_shadowed__.define('ace/edit_session/fold_line', ['require', 'exports', 'mo var Range = require("../range").Range; -/** +/* * If an array is passed in, the folds are expected to be sorted already. */ function FoldLine(foldData, folds) { @@ -11187,7 +13635,7 @@ function FoldLine(foldData, folds) { } (function() { - /** + /* * Note: This doesn't update wrapData! */ this.shiftRow = function(shift) { @@ -11300,7 +13748,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); @@ -11394,7 +13844,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 * @@ -11435,7 +13886,7 @@ exports.FoldLine = FoldLine; __ace_shadowed__.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) { @@ -11509,7 +13960,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 * @@ -11550,6 +14002,22 @@ var Fold = exports.Fold = function(range, placeholder) { __ace_shadowed__.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; @@ -11560,7 +14028,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; @@ -11577,7 +14051,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; @@ -11595,15 +14074,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; @@ -11669,8 +14166,34 @@ __ace_shadowed__.define('ace/edit_session/bracket_match', ['require', 'exports', 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; @@ -11853,6 +14376,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: "", @@ -11870,15 +14415,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; @@ -11898,6 +14463,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) @@ -11924,6 +14496,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); @@ -11938,6 +14522,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; @@ -11972,6 +14563,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; @@ -12157,6 +14755,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 = {}; @@ -12165,7 +14781,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 || {}); }); }; @@ -12185,8 +14801,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() { @@ -12328,6 +14954,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]; @@ -12350,18 +14988,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]); @@ -12377,10 +15003,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]]) @@ -12393,17 +15019,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 { @@ -12457,12 +15078,33 @@ exports.HashHandler = HashHandler; __ace_shadowed__.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]; @@ -12470,6 +15112,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; @@ -12481,6 +15129,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; @@ -12492,15 +15146,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; }; @@ -12569,6 +15238,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; @@ -12577,6 +15262,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"); @@ -12594,8 +15282,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); @@ -12611,14 +15301,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; @@ -12629,12 +15320,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 = { @@ -12699,19 +15387,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; @@ -12734,26 +15435,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; @@ -12788,53 +15501,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; @@ -12843,6 +15622,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; @@ -12863,56 +15680,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); @@ -12923,10 +15782,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; @@ -12974,6 +15844,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; } @@ -12990,6 +15862,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; } @@ -13009,8 +15883,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); @@ -13087,7 +15964,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"; @@ -13133,55 +16010,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; @@ -13192,10 +16125,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); } @@ -13205,75 +16140,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 @@ -13283,6 +16271,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; @@ -13292,11 +16287,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; @@ -13305,32 +16314,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); @@ -13344,14 +16359,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"); @@ -13370,10 +16400,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(); @@ -13394,6 +16435,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; @@ -13448,6 +16495,11 @@ var VirtualRenderer = function(container, theme) { } }; + /** + * VirtualRenderer.getTheme() -> String + * + * [Returns the path of the current theme.]{: #VirtualRenderer.getTheme} + **/ this.getTheme = function() { return this.$themeValue; }; @@ -13456,14 +16508,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(); @@ -13773,9 +16842,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; @@ -13799,9 +16866,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; @@ -13848,9 +16913,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; @@ -14271,21 +17334,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"; @@ -14294,13 +17354,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) { @@ -14828,6 +17933,19 @@ __ace_shadowed__.define('ace/renderloop', ['require', 'exports', 'module' , 'ace 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; @@ -14837,6 +17955,12 @@ var RenderLoop = function(onRender, win) { (function() { + /** internal, hide + * RenderLoop.schedule(change) + * - change (Array): + * + * + **/ this.schedule = function(change) { //this.onRender(change); //return; @@ -14859,8 +17983,7 @@ var RenderLoop = function(onRender, win) { exports.RenderLoop = RenderLoop; }); -__ace_shadowed__.define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono);\n" + - "\n" + +__ace_shadowed__.define("text!ace/css/editor.css", [], "\n" + ".ace_editor {\n" + " position: absolute;\n" + " overflow: hidden;\n" + @@ -14898,6 +18021,12 @@ __ace_shadowed__.define("text!ace/css/editor.css", [], "@import url(//fonts.goog " 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" + @@ -14956,8 +18085,8 @@ __ace_shadowed__.define("text!ace/css/editor.css", [], "@import url(//fonts.goog ".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" + @@ -14992,6 +18121,7 @@ __ace_shadowed__.define("text!ace/css/editor.css", [], "@import url(//fonts.goog "\n" + ".ace_text-layer {\n" + " color: black;\n" + + " font: inherit !important;\n" + "}\n" + "\n" + ".ace_cjk {\n" + @@ -15040,10 +18170,6 @@ __ace_shadowed__.define("text!ace/css/editor.css", [], "@import url(//fonts.goog " 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" + @@ -15150,6 +18276,28 @@ __ace_shadowed__.define("text!ace/css/editor.css", [], "@import url(//fonts.goog " 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: @@ -15190,12 +18338,13 @@ __ace_shadowed__.define("text!ace/css/editor.css", [], "@import url(//fonts.goog * * ***** END LICENSE BLOCK ***** */ -__ace_shadowed__.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) { +__ace_shadowed__.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 @@ -15225,10 +18374,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) @@ -15272,11 +18423,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); @@ -15286,10 +18437,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(); @@ -15347,6 +18498,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]; @@ -15363,11 +18545,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 = []; @@ -15437,21 +18622,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) @@ -15465,11 +18651,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) @@ -15500,13 +18686,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; @@ -15519,7 +18705,7 @@ var Editor = require("./editor").Editor; this.renderer.updateCursor(); this.renderer.updateBackMarkers(); }; - + this.$onSingleSelect = function(e) { if (this.session.multiSelect.inVirtualMode) return; @@ -15551,12 +18737,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) @@ -15587,11 +18773,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) @@ -15615,14 +18801,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 || {}; @@ -15635,10 +18842,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); @@ -15648,12 +18855,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(); @@ -15693,12 +18900,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; @@ -15716,7 +18922,7 @@ var Editor = require("./editor").Editor; } } sel.mergeOverlappingRanges(); - + var words = []; for (var i = all.length; i--; ) { var range = all[i]; @@ -15737,13 +18943,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; @@ -15810,12 +19015,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); @@ -15827,7 +19029,7 @@ function MultiSelect(editor) { editor.on("mousedown", onMouseDown); editor.commands.addCommands(exports.commands.defaultCommands); - + addAltCursorListeners(editor); } @@ -15835,7 +19037,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"; @@ -15845,9 +19047,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 = ""; @@ -15858,7 +19060,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 @@ -16167,10 +19370,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() { @@ -16255,7 +19458,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 * @@ -16341,20 +19545,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); -});/* ***** 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 @@ -16569,7 +19775,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. @@ -16720,7 +19926,7 @@ StateHandler.prototype = { } }, - /** + /* * This function is called by keyBinding. */ handleKeyboard: function(data, hashId, key, keyCode, e) { @@ -16746,7 +19952,7 @@ StateHandler.prototype = { } } -/** +/* * This is a useful matching function and therefore is defined here so that * users of KeyboardStateMapper can use it. * @@ -16818,6 +20024,26 @@ var Range = require('./range').Range; var EventEmitter = require("./lib/event_emitter").EventEmitter; var oop = require("./lib/oop"); +/** + * class PlaceHolder + * + * TODO + * + **/ + +/** + * new PlaceHolder(session, length, pos, others, mainClass, othersClass) + * - session (Document): The document to associate with the anchor + * - length (Number): The starting row position + * - pos (Number): The starting column position + * - others (String): + * - mainClass (String): + * - othersClass (String): + * + * TODO + * + **/ + var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) { var _self = this; this.length = length; @@ -16848,6 +20074,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) oop.implement(this, EventEmitter); + /** + * PlaceHolder.setup() + * + * TODO + * + **/ this.setup = function() { var _self = this; var doc = this.doc; @@ -16868,6 +20100,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) session.setUndoSelect(false); }; + /** + * PlaceHolder.showOtherMarkers() + * + * TODO + * + **/ this.showOtherMarkers = function() { if(this.othersActive) return; var session = this.session; @@ -16882,6 +20120,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) }); }; + /** + * PlaceHolder.hideOtherMarkers() + * + * Hides all over markers in the [[EditSession `EditSession`]] that are not the currently selected one. + * + **/ this.hideOtherMarkers = function() { if(!this.othersActive) return; this.othersActive = false; @@ -16890,6 +20134,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) } }; + /** + * PlaceHolder@onUpdate(e) + * + * Emitted when the place holder updates. + * + **/ this.onUpdate = function(event) { var delta = event.data; var range = delta.range; @@ -16952,6 +20202,13 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.$updating = false; }; + /** + * PlaceHolder@onCursorChange(e) + * + * Emitted when the cursor changes. + * + **/ + this.onCursorChange = function(event) { if (this.$updating) return; var pos = this.session.selection.getCursor(); @@ -16964,6 +20221,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) } }; + /** + * PlaceHolder.detach() + * + * TODO + * + **/ this.detach = function() { this.session.removeMarker(this.markerId); this.hideOtherMarkers(); @@ -16976,6 +20239,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.session.setUndoSelect(true); }; + /** + * PlaceHolder.cancel() + * + * TODO + * + **/ this.cancel = function() { if(this.$undoStackDepth === -1) throw Error("Canceling placeholders only supported with undo manager attached to session."); @@ -17093,8 +20362,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 {\ @@ -17181,6 +20450,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);\ diff --git a/build/textarea/src/mode-c_cpp.js b/build/textarea/src/mode-c_cpp.js index 09454170..44145d6e 100644 --- a/build/textarea/src/mode-c_cpp.js +++ b/build/textarea/src/mode-c_cpp.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/textarea/src/mode-coffee.js b/build/textarea/src/mode-coffee.js index 66133902..68b9704d 100644 --- a/build/textarea/src/mode-coffee.js +++ b/build/textarea/src/mode-coffee.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 diff --git a/build/textarea/src/mode-coldfusion.js b/build/textarea/src/mode-coldfusion.js index fa21479f..56d59ab3 100644 --- a/build/textarea/src/mode-coldfusion.js +++ b/build/textarea/src/mode-coldfusion.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 @@ -1965,7 +1968,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/textarea/src/mode-csharp.js b/build/textarea/src/mode-csharp.js index e43d1742..c7796443 100644 --- a/build/textarea/src/mode-csharp.js +++ b/build/textarea/src/mode-csharp.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/textarea/src/mode-css.js b/build/textarea/src/mode-css.js index 5f102f4f..9398d0f0 100644 --- a/build/textarea/src/mode-css.js +++ b/build/textarea/src/mode-css.js @@ -525,7 +525,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/textarea/src/mode-groovy.js b/build/textarea/src/mode-groovy.js index 7db69e93..36f92e6f 100644 --- a/build/textarea/src/mode-groovy.js +++ b/build/textarea/src/mode-groovy.js @@ -1039,7 +1039,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 @@ -1133,7 +1134,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/textarea/src/mode-haxe.js b/build/textarea/src/mode-haxe.js index 958cb7a4..f3cb5e11 100644 --- a/build/textarea/src/mode-haxe.js +++ b/build/textarea/src/mode-haxe.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/textarea/src/mode-html.js b/build/textarea/src/mode-html.js index 11cc9595..d058d3dd 100644 --- a/build/textarea/src/mode-html.js +++ b/build/textarea/src/mode-html.js @@ -1098,7 +1098,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 @@ -1192,7 +1193,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 @@ -2034,7 +2036,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 @@ -2119,7 +2122,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 @@ -2206,7 +2210,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 @@ -2309,7 +2314,7 @@ oop.inherits(FoldMode, BaseFoldMode); }; }; - /** + /* * reads a full tag and places the iterator after the tag */ this._readTagForward = function(iterator) { @@ -2467,4 +2472,4 @@ oop.inherits(FoldMode, BaseFoldMode); }).call(FoldMode.prototype); -}); \ No newline at end of file +}); diff --git a/build/textarea/src/mode-java.js b/build/textarea/src/mode-java.js index b1548318..014f2153 100644 --- a/build/textarea/src/mode-java.js +++ b/build/textarea/src/mode-java.js @@ -1040,7 +1040,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 @@ -1134,7 +1135,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/textarea/src/mode-javascript.js b/build/textarea/src/mode-javascript.js index f952ef41..29e6083c 100644 --- a/build/textarea/src/mode-javascript.js +++ b/build/textarea/src/mode-javascript.js @@ -1015,7 +1015,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 @@ -1109,7 +1110,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/textarea/src/mode-json.js b/build/textarea/src/mode-json.js index be945e38..05fbcfa9 100644 --- a/build/textarea/src/mode-json.js +++ b/build/textarea/src/mode-json.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 diff --git a/build/textarea/src/mode-less.js b/build/textarea/src/mode-less.js index ba4c7d42..15f7af2d 100644 --- a/build/textarea/src/mode-less.js +++ b/build/textarea/src/mode-less.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/textarea/src/mode-lua.js b/build/textarea/src/mode-lua.js index 7544bfb4..b6aab7a8 100644 --- a/build/textarea/src/mode-lua.js +++ b/build/textarea/src/mode-lua.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/textarea/src/mode-markdown.js b/build/textarea/src/mode-markdown.js index e07dfc76..f8d570c6 100644 --- a/build/textarea/src/mode-markdown.js +++ b/build/textarea/src/mode-markdown.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 @@ -1095,7 +1096,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 @@ -1189,7 +1191,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 @@ -1713,7 +1716,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 @@ -1816,7 +1820,7 @@ oop.inherits(FoldMode, BaseFoldMode); }; }; - /** + /* * reads a full tag and places the iterator after the tag */ this._readTagForward = function(iterator) { @@ -1974,7 +1978,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 @@ -2634,7 +2639,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 @@ -2721,7 +2727,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 @@ -2915,4 +2922,4 @@ var MarkdownHighlightRules = function() { oop.inherits(MarkdownHighlightRules, TextHighlightRules); exports.MarkdownHighlightRules = MarkdownHighlightRules; -}); \ No newline at end of file +}); diff --git a/build/textarea/src/mode-perl.js b/build/textarea/src/mode-perl.js index 079d8e20..24a60d81 100644 --- a/build/textarea/src/mode-perl.js +++ b/build/textarea/src/mode-perl.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/textarea/src/mode-php.js b/build/textarea/src/mode-php.js index 2afbfc54..84155259 100644 --- a/build/textarea/src/mode-php.js +++ b/build/textarea/src/mode-php.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/textarea/src/mode-powershell.js b/build/textarea/src/mode-powershell.js index 24861489..9ddf6f92 100644 --- a/build/textarea/src/mode-powershell.js +++ b/build/textarea/src/mode-powershell.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/textarea/src/mode-python.js b/build/textarea/src/mode-python.js index 03c4f919..bbc111f3 100644 --- a/build/textarea/src/mode-python.js +++ b/build/textarea/src/mode-python.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/textarea/src/mode-scad.js b/build/textarea/src/mode-scad.js index f9663ffa..adc07d35 100644 --- a/build/textarea/src/mode-scad.js +++ b/build/textarea/src/mode-scad.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/textarea/src/mode-scala.js b/build/textarea/src/mode-scala.js index 8b050523..1631e377 100644 --- a/build/textarea/src/mode-scala.js +++ b/build/textarea/src/mode-scala.js @@ -1040,7 +1040,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 @@ -1134,7 +1135,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/textarea/src/mode-scss.js b/build/textarea/src/mode-scss.js index 07ae5959..60bf8ef3 100644 --- a/build/textarea/src/mode-scss.js +++ b/build/textarea/src/mode-scss.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/textarea/src/mode-svg.js b/build/textarea/src/mode-svg.js index 1f3ce577..8ab120f1 100644 --- a/build/textarea/src/mode-svg.js +++ b/build/textarea/src/mode-svg.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 @@ -1972,7 +1975,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 @@ -2130,4 +2134,4 @@ oop.inherits(FoldMode, BaseFoldMode); }).call(FoldMode.prototype); -}); \ No newline at end of file +}); diff --git a/build/textarea/src/mode-xml.js b/build/textarea/src/mode-xml.js index b7f8f7c1..e5bf388a 100644 --- a/build/textarea/src/mode-xml.js +++ b/build/textarea/src/mode-xml.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/textarea/src/mode-xquery.js b/build/textarea/src/mode-xquery.js index bffb204a..6d3bb851 100644 --- a/build/textarea/src/mode-xquery.js +++ b/build/textarea/src/mode-xquery.js @@ -629,4 +629,4 @@ var CstyleBehaviour = function () { oop.inherits(CstyleBehaviour, Behaviour); exports.CstyleBehaviour = CstyleBehaviour; -}); \ No newline at end of file +}); diff --git a/build/textarea/src/theme-monokai.js b/build/textarea/src/theme-monokai.js index 00e8b261..a2f49455 100644 --- a/build/textarea/src/theme-monokai.js +++ b/build/textarea/src/theme-monokai.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/textarea/src/theme-solarized_dark.js b/build/textarea/src/theme-solarized_dark.js index 9029c310..efb9955c 100644 --- a/build/textarea/src/theme-solarized_dark.js +++ b/build/textarea/src/theme-solarized_dark.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/textarea/src/theme-tomorrow_night_blue.js b/build/textarea/src/theme-tomorrow_night_blue.js index 7decc08c..756cbf19 100644 --- a/build/textarea/src/theme-tomorrow_night_blue.js +++ b/build/textarea/src/theme-tomorrow_night_blue.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/textarea/style.css b/build/textarea/style.css index b452add7..43f46d0e 100644 --- a/build/textarea/style.css +++ b/build/textarea/style.css @@ -1,3 +1,5 @@ +@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono); + body { margin:0; padding:0; diff --git a/build_support/style.css b/build_support/style.css index b452add7..43f46d0e 100644 --- a/build_support/style.css +++ b/build_support/style.css @@ -1,3 +1,5 @@ +@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono); + body { margin:0; padding:0; diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 9d272bd6..bcd240ff 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -301,7 +301,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"); @@ -395,10 +396,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) { @@ -480,6 +499,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) { diff --git a/demo/kitchen-sink/package.json b/demo/kitchen-sink/package.json new file mode 100644 index 00000000..2345fccd --- /dev/null +++ b/demo/kitchen-sink/package.json @@ -0,0 +1,16 @@ +{ + "main": "./demo.js", + "mappings": { + "ace": "../.." + }, + "config": { + "github.com/sourcemint/bundler-js/0/-meta/config/0": { + "adapter": "github.com/sourcemint/sdk-requirejs/0", + "resources": [ + "./icons/*", + "./logo.png", + "./styles.css" + ] + } + } +} \ No newline at end of file diff --git a/demo/kitchen-sink/styles.css b/demo/kitchen-sink/styles.css index 74c53b90..e71e7e53 100644 --- a/demo/kitchen-sink/styles.css +++ b/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/doc/README.md b/doc/README.md new file mode 100644 index 00000000..38dbd144 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,27 @@ +# Introduction + +The API doc build takes a look a source Javascript files in the _lib_ directory, and turns it into HTML output in the _api_ directory. It uses [Panino](https://github.com/gjtorikian/panino-docs) to perform the conversion. + +For any questions, please see that repo. + +# Building + +In the root directory, just run: + + make doc + +In this directory, just run: + + node build.js + +# Build File + +Here's a breakdown of what the arguments in _build.js_ are doing: + +`--path=srcPath`: The location of the Ace source +`-o=../api/`: The location of the output +`-a=./additionalObjs.json`: A list of URLs to use for "missing objects" that the documentation requires +`-i=index.md`: The location of the Ace index/landing page +`-t=Ace API`: The title of the documentation +`--skin=./resources/ace/`: The location of all the templates and design +`-s`: Choose to split each class into its own file \ No newline at end of file diff --git a/doc/additionalObjs.json b/doc/additionalObjs.json new file mode 100644 index 00000000..45903778 --- /dev/null +++ b/doc/additionalObjs.json @@ -0,0 +1,26 @@ +{ + "Array" : "http://www.nodemanual.org/latest/js_doc/Array.html", + "Boolean" : "http://www.nodemanual.org/latest/js_doc/Boolean.html", + "Date" : "http://www.nodemanual.org/latest/js_doc/Date.html", + "Error" : "http://www.nodemanual.org/latest/js_doc/Error.html", + "EvalError" : "http://www.nodemanual.org/latest/js_doc/EvalError.html", + "RangeError" : "http://www.nodemanual.org/latest/js_doc/RangeError.html", + "ReferenceError" : "http://www.nodemanual.org/latest/js_doc/ReferenceError.html", + "SyntaxError" : "http://www.nodemanual.org/latest/js_doc/SyntaxError.html", + "TypeError" : "http://www.nodemanual.org/latest/js_doc/TypeError.html", + "URIError" : "http://www.nodemanual.org/latest/js_doc/URIError.html", + "Function" : "http://www.nodemanual.org/latest/js_doc/Function.html", + "Infinity" : "http://www.nodemanual.org/latest/js_doc/Infinity.html", + "JSON" : "http://www.nodemanual.org/latest/js_doc/JSON.html", + "Math" : "http://www.nodemanual.org/latest/js_doc/Math.html", + "NaN" : "http://www.nodemanual.org/latest/js_doc/NaN.html", + "Number" : "http://www.nodemanual.org/latest/js_doc/Number.html", + "Object" : "http://www.nodemanual.org/latest/js_doc/Object.html", + "RegExp" : "http://www.nodemanual.org/latest/js_doc/RegExp.html", + "String" : "http://www.nodemanual.org/latest/js_doc/String.html", + "DOMElement": "https://developer.mozilla.org/en/DOM/element", + "Event": "https://github.com/ajaxorg/ace/blob/master/lib/ace/lib/event.js", + "TextMode": "https://github.com/ajaxorg/ace/blob/master/lib/ace/mode/text.js", + "KeyBinding": "https://github.com/ajaxorg/ace/blob/master/lib/ace/keyboard/keybinding.js", + "Cursor": "https://github.com/ajaxorg/ace/blob/master/lib/ace/layer/cursor.js" +} \ No newline at end of file diff --git a/doc/build.js b/doc/build.js new file mode 100644 index 00000000..81455917 --- /dev/null +++ b/doc/build.js @@ -0,0 +1,10 @@ +var panino = require("panino"); + +var srcPath = process.cwd() + "/../lib/ace"; + +panino.main(["--path=" + srcPath, "-o", "../api/", "-a", "./additionalObjs.json", "-i", "index.md", "-t", "Ace API", "--skin", "./resources/ace/", "-s"], function(err) { + if (err) { + console.error(err); + process.exit(-1); + } +}); \ No newline at end of file diff --git a/doc/index.md b/doc/index.md new file mode 100644 index 00000000..41733852 --- /dev/null +++ b/doc/index.md @@ -0,0 +1,5 @@ +# Ace API Reference + +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](http://ace.ajax.org). \ No newline at end of file diff --git a/doc/resources/ace/skeleton/csses/ace_api.css b/doc/resources/ace/skeleton/csses/ace_api.css new file mode 100644 index 00000000..0db6ecca --- /dev/null +++ b/doc/resources/ace/skeleton/csses/ace_api.css @@ -0,0 +1,1027 @@ +/* + Generic "affects everything" stuff +*/ +body { + min-width: 1010px; + color: #2D2D2D; + background: #EDF5FA url(../images/main_bg.png) 0 0 repeat; +} + +ul { + font-size: 13px; +} + +li { + color: black; +} + +a, a:hover { + color : #00438a; +} + +code { + font-size: 12px; + line-height: 16px; + font-family: 'Ubuntu Mono',Monaco,Consolas,monospace !important; + background-color: #F9F9F9; + border-radius: 3px 3px 3px 3px; + box-shadow: 0 0 2px #888888; + display: inline-block; + padding: 0 4px; + margin: 2px 1px; + color: inherit; +} + +pre { + margin-top: 10px; + border-radius: none; + box-shadow: none; + background : white; + /*background : #f5f5f5; + border: 0;*/ + + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; + + padding: 5px; +} + +.method pre, .event pre, .property pre { + background : white; +} + +pre code { + background-color: transparent; + border-radius: none; + box-shadow: none; +} + +a code { + color: #00438a; +} + +h2 { + font-size: 26px; +} +p { + font-size: 13px; + line-height : 20px; + margin-bottom : 13px; +} +li p:last-child { + margin-bottom : 5px; +} + +blockquote p{ + font-size: 14px; + font-weight: 500; + line-height: 23px; + font-style: italic; +} + +.alert-message{ + margin-bottom : 13px; +} +/* + Header and shoulders +*/ + +.navbar .nav > li { + float:none; + display:inline-block; + *display:inline; /* ie7 fix */ + zoom:1; /* hasLayout ie7 trigger */ +} + +.navbar { + text-align:center; +} + +.small_win #topSection { + width: 100%; +} +.small_win #topSection .dropdown { + margin-right: 40%; +} +.brand { + background: transparent url(../images/ace_logo_menu.png) no-repeat 13px 5px; + width: 105px; + outline: none; + height: 40px; + padding: 0 10px !important; + border: none; +} +.brand.dropdown-toggle:after { + content: none; + display: block; + height: 40px; + border: none; +} + +.ace_logo { + position: absolute; + top: 45px; + z-index: 20000; + left: 210px; +} + +.masthead { + background: #101010 url(../images/dashed_back.png) repeat 0 0; +} +.masthead .container { + /*width: 680px;*/ + padding-left: 285px; + margin: 0 auto; + color: white; +} +.jumbotron { + min-width: 1000px; + padding-top: 40px; + position: relative; +} + +.jumbotron .inner { +/* background: transparent url(../images/header-back.png) top center;*/ + padding: 45px 0; +/* -webkit-box-shadow: inset 0 10px 30px rgba(0,0,0,.3); + -moz-box-shadow: inset 0 10px 30px rgba(0,0,0,.3);*/ +} + +.headerTitle { + position: relative; + top: 100px; + left: 250px; +} + +/* + Menu venue +*/ + +ul.menu { + margin-left: 16px; +} + +.menu li { + list-style-image: url(../images/menu_disc.png); + margin-bottom: 3px; + font-weight : 700; +} + +.menu li .menu-item a.menuLink, .menu li .menu-item span.menuLink { + color: #262626; +} +.menuTwo { + margin-bottom: 5px; + margin-top: 2px; +} +.menuTwo li .menu-item a.menuLink { + color: #262626; +} + +/* need specificity to "beat" the above colors */ +.menu li .menu-item a.currentItem, .menuTwo li .menu-item { + color: #0072bc; +} + +/* + Members and the tabs that represent them +*/ + +.members { +/* width: 800px; */ + /*width: 700px;*/ +/* margin: 0 10px;*/ + + height: 42px; + left: 0; +/* position: fixed;*/ + top: 0; +/* transition-duration: 300ms, 300ms; + transition-property: box-shadow, height; + transition-timing-function: ease-out, ease-out; + -moz-transition-duration: 300ms, 300ms; + -moz-transition-property: -moz-box-shadow, height; + -moz-transition-timing-function: ease-out, ease-out; + -o-transition-duration: 300ms, 300ms; + -o-transition-property: -o-box-shadow, height; + -o-transition-timing-function: ease-out, ease-out; + -webkit-transition-duration: 300ms, 300ms; + -webkit-transition-property: -webkit-box-shadow, height; + -webkit-transition-timing-function: ease-out, ease-out;*/ +/* width: 100%;*/ + /*transition-duration: 300ms; + transition-property: box-shadow; + transition-timing-function: ease-out; + -moz-transition-duration: 300ms, 300ms; + -moz-transition-property: -moz-box-shadow, height; + -moz-transition-timing-function: ease-out, ease-out; + -o-transition-duration: 300ms; + -o-transition-property: -o-box-shadow; + -o-transition-timing-function: ease-out;*/ + -webkit-transition-duration: 400ms, 0ms; + -webkit-transition-property: -webkit-box-shadow, background; + -webkit-transition-timing-function: ease-out, ease-out; + z-index: 100; + padding-bottom : 5px; + overflow: visible !important; + +/* background: #FFF; + width: 100%; + padding-bottom: 13px; + top: 40px; + position: fixed;*/ +} +.srolled .members { + width: 100%; +/* -webkit-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); + -moz-box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); + box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.35); */ + padding-bottom: 15px; +/* height: 31px;*/ + top: 40px; + position: fixed; +} +.shadow.members{ + background: #edf8fd; + box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); + -moz-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); + -o-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); + -webkit-box-shadow: 0 0.1em 1em rgba(0,0,0, 0.3); +} + +.membersContent { + +/* border-bottom: 0.1em solid #FFF;*/ + height: 3em; + padding-top: 4px; +/* line-height: 4;*/ +/* margin-top: -0.1em;*/ + position: relative; +/* transition-property: border-color, line-height; + transition-duration: 125ms, 250ms; + transition-timing-function: ease-out, ease-out; + -moz-transition-property: border-color, line-height; + -moz-transition-duration: 125ms, 250ms; + -moz-transition-timing-function: ease-out, ease-out; + -o-transition-property: border-color, line-height; + -o-transition-duration: 125ms, 250ms; + -o-transition-timing-function: ease-out, ease-out; + -webkit-transition-property: border-color, line-height; + -webkit-transition-duration: 125ms, 250ms; + -webkit-transition-timing-function: ease-out, ease-out;*/ + + /*transition-duration: 125ms; + transition-property: top; + transition-timing-function: ease-out; + + top : 11px;*/ + z-index: 103; + /*width: 700px;*/ +} +.srolledHeader .membersContent { + line-height: 3; +} +.srolled .membersContent { + /*top : 0;*/ + width : 695px; + padding-left : 305px; + margin : 0 auto 0 auto; +} +.membersBackground { +/* background-color: white; + position: fixed; + z-index: 2; + top: 40px; + left: 0px; + right: 0px; + width: 100%; + height: 55px; + opacity: 0; + display: none; + box-shadow: rgba(0, 0, 0, 0.398438) 1px 4px 6px;*/ + + background-color: transparent; + height: 47px; + /*width: 700px;*/ + position: absolute; +} +.srolled .membersBackground { + position: relative; +} +.srolledHeader .membersBackground { +/* display: block;*/ +} +.memberHeader { + float: left; + padding-right: 10px; + margin-bottom: 5px; + position: absolute; + padding-top: 4px; + +} + +.tabs a.menu:after, .tabs .dropdown-toggle:after { + margin-top: 22px; +} + +.dropdown .caret { + margin-top: 14px; + color: #6D8CA0; +} + +li.dropdown { + color: #2D2D2D; + font-weight: bold; +} + + +.backToMDN, .editInC9 { + font-size: 11px; + color: #657383; + margin : 0 0 0 5px; +} + +.backToMDN a, .editInC9 a { + color: #657383; + font-weight: normal; + position : relative; + top : -2px; +} + +.tabs { + padding-top: 10px; + /*border-bottom: 1px solid #848484;*/ + min-height : 27px; + padding-bottom : 5px; +} +.tabsSansBorder { + border: 0; +} +.tabs, .pills { + margin-bottom: 0; +} +.srolledHeader .members .tabs { + background-color: white; +} + +li.dropdown { + color: #2D2D2D; + font-weight: bold; +} + +.members .tabs .dropdown a, +.members .tabs a.menu:after, +.members .tabs .dropdown-toggle:after { + margin-right: 0; + margin-left: 6px; +} + +.members .tabs ul li { + font-weight: bold; +} + +.memberLink a { + margin-left: 0 !important; +} +.menu-dropdown, .dropdown-menu { + min-width : 105px; + max-height: 350px; + overflow: auto; + border-color : rgba(0, 0, 0, 0.1); +} +.topbar div > ul .menu-dropdown li a:hover, +.nav .menu-dropdown li a:hover, +.topbar div > ul .dropdown-menu li a:hover, +.nav .dropdown-menu li a:hover { + background-color: #ffffff; + color: #000000; +} +.dropdown-menu { + border-top: none; +} + +.tabs a.menu:after, .tabs .dropdown-toggle:after { + margin-top: 13px; + line-height: 28px; +} +.open .menu, .dropdown.open .menu, .open .dropdown-toggle, .dropdown.open .dropdown-toggle { + background: transparent; + color: black; +/* font-weight: bold;*/ +} +#topSection .open .menu, #topSection .dropdown.open .menu, #topSection .open .dropdown-toggle, +#topSection .dropdown.open .dropdown-toggle { + color: #bfbfbf; +} + +.tabs > li { + font-weight: bold; +} + +.tabs > li > a { + border: none; + outline: none; + line-height: 28px; + font-size: 11px; + padding: 0 5px; +} +.tabs > li > a:hover { + color: #000000; + text-decoration: none; + background-color: transparent; + border: none; +} +.tabs > li, .pills > li { + float: right; +} +.topbar .dropdown-menu a, .dropdown-menu a { + font-size: 11px; +/* padding: 2px 12px;*/ + line-height: 14px; +} +.tabs .active > a, .tabs .active > a:hover { + color: #000000; + border: none; + cursor: default; +} +.tabs .menu-dropdown, .tabs .dropdown-menu { + border-radius: 0 0 6px 6px; + top: 32px; + right: 0px; + width: 150px; +} +.srolled .tabs .menu-dropdown, .srolled .tabs .dropdown-menu { + top: 32px; +} +.dropdown-toggle { + color: #6D8CA0; +} + +ul.tabs .double ul, ul.tabs .triple ul, ul.tabs .quad ul{ + width:760px; + margin-bottom:20px; + overflow:hidden; + border-top:1px solid #ccc; +} +/*ul.tabs .double li, ul.tabs .triple li, ul.tabs .quad li{ + line-height:1.5em; + border-bottom:1px solid #ccc; + float:left; + display:inline; +}*/ + +/* + Center content (the "real stuff") +*/ + +.content .row { + width: 1000px; + margin-left: auto; + margin-right: auto; +} + +.content .centerpiece { + background: url(../images/sidebar_border.png) repeat-y 180px 0; + padding-bottom: 9em; +} + +header.filler { + position: relative; + height: 50px; + width: 100%; +} + +.container { + width: 100%; +} + +/* +.container-fluid .row-fluid { + width: 1000px; + margin-left: auto; + margin-right: auto; +}*/ + +.divider { + height: 3px; + background-color: #BEDAEA; + margin-bottom: 3px; +} + +.sidebarContainer { + width: 280px; + margin-left: 0px; +} + +#sidebar { + margin-top: 9px; + /*background: url(../images/sidebar-border.png) repeat-y right 0;*/ + margin-left: 12px; +/* width: 280px;*/ +/* overflow: auto;*/ + padding-right : 10px; +} + +#sidebar h3 a, +#sidebar h3 a:hover { + color: #404040; +} + +.mainContent .hero-unit { + background: rgba(255, 255, 255, 0.5); +} + +#documentation { + padding-bottom: 10px; +} + +#documentation article.article { +/* border-bottom: 1px solid #e9e9e9;*/ + border-top: 1px solid #e9e9e9; + padding: 16px 10px 2px; +} +div#documentation article:last-child { + border-bottom: 1px solid #e9e9e9; + padding-bottom: 40px; +} +#documentation article.article.methodToggleOpen { + background: rgba(255, 255, 255, 0.5); + padding: 20px; + font-size: 13px; + line-height: 24px; + margin: 0 0 10px 0; +} + +#documentation article:first-child { + border:none; +} + +.site_logo { + display: block; + margin-left: auto; + margin-right: auto; +} +/* + Edit in Cloud9, sucka +*/ + +.snippet pre { + margin-bottom: 0; +} + +.snippet .toolbar { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + + text-align: right; + padding: 3px 10px; + margin-top : -1px; +} + +.snippet .filename, .snippet .toolbar { + font-family: Ubuntu, sans-serif; + font-size: 12px; + color: #EEE; +} + +.snippet .filename { + padding: 0 5px 2px 5px; + font-size: 10px; + background: rgba(230,230,230,0.5); + padding: 0 5px 2px 5px; + border-radius: 0 6px 0 6px; + margin : 1px; + position : absolute; + right : 0; + top : 0; +} + +.snippet .filename span{ + color : #666; +} + +.snippet .toolbar { + background-color: rgba(30,30,30,0.5); +} + +div.snippet { + margin-bottom: 18px; + position : relative; +} + +div.snippet a, div.toolbar a { + color: #FFF; +} + +/* + All about signatures +*/ + +.signatures { +/* width: 800px;*/ + margin-left: 20px; + margin-bottom: 5px; +} +.sideToggler { + padding-left: 20px; +} +ul.signatures ul { + list-style: none; + display: inline; +} + +li.signature { + list-style: none; +} + +.signature ul { + padding: 0; + margin: 0; +} + +.signature li { + display: inline; +} + +.signature ul.argument-types::before { + content: '→'; + margin: 0 5px; +} + +.signature li.argument-type::after { + content: '|'; + padding: 0 5px 0 5px; +} + +.signature li.argument-type:last-child:after { + content: ''; + padding: 0 5px 0 5px; +} + +.member-name { + color: #4397cd; + font-weight: bold; + text-decoration: none; + cursor: pointer; + padding-right: 3px; +} + +.signature-call { + cursor: pointer; +} +.signature-call a { + color: #8e487e; +} + +.sigClassName { + display: none; +} + +.eventObjName { + font-style: italic; +} +.eventListenerStart, .eventFunctionOpen, .eventFunctionClose { + color: #999999; +} +.eventMember { + padding-right: 0px; +} + +.metaInfo { + float: right; + z-index: 1; + position: relative; +} + +.chainable { + background-color: #0072bc; + color: #ffffff; +} + +.deprecated { + background-color: #f7941d; + color: #ffffff; +} + +.alias { + background-color: #6c951e; + color: #ffffff; +} + +.related-to { + background-color: #89289a; + color: #ffffff; + font-size: 10px; + padding: 2px 5px 3px; + text-transform: capitalize; +} + +.alias a, .related-to a { + color: #ffffff; + /* text-decoration: underline; */ +} +.alias a:hover, .related-to a:hover { + text-decoration: none; +} +.alias:hover, .related-to:hover { + opacity: 0.8; + cursor: pointer; +} +.memberContent .title { + +} +.memberContent .description { + position:relative; + /*top: -13px;*/ + display: none; +} +.snip-container .actions .toggle-plaintext label { + margin-top: 1px; + padding-top: 0; + text-align: left; +} +.snip-container .actions .toggle-plaintext input { + margin-top: 4px !important; +} +.snip-container label { + color: #ffffff; +} +.description h4 { + font-size: 18px; + margin: 20px 0 10px; + line-height : 18px; +} + +.table-striped tbody tr:nth-child(odd) td, .table-striped tbody tr:nth-child(odd) th { + background-color: #F9F9F9; +} +.table-striped tbody tr:nth-child(even) td, .table-striped tbody tr:nth-child(even) th { + background-color: #fbfbfb; +} +.table-striped tbody tr:hover td, .table-striped tbody tr:hover th { +} + +.argument-list { + margin-bottom : 13px; +} +.argName { + font-style: italic; +} + + +/* + Everyday I'm togglin' +*/ +.mainContent { + padding-top: 10px; + float: right + margin-left: 0px; + width: 695px; + padding-left: 5px; +} + +#documentation h3 { + font-size: 24px; + margin-top: 5px; +} +#documentation h3.methodToggle { + margin: 0; +} +#documentation h3.sectionHeader { + margin: 10px 0 17px 0; + line-height : 24px; +} + +div.method { + position: relative; +} + +.methodToggle a { + color: #fff; + border-bottom: 0px; + text-decoration: none; +} + +h3.methodToggle { + height : 13px; + width : 8px; + background-position : 0px 0px; + position: absolute; + top: -20px; + background-image : url(../images/member-sprites.png); + background-color : transparent; + background-repeat : no-repeat; + overflow: hidden; + left: 0px; +} + +h3.methodToggleHover { + /* background-position : 0px -28px; */ +} + +h3.methodToggle.inactive { + top: 4px; +} + +h3.methodToggle.active { + top: 6px; + height : 13px; + width : 8px; + background-position : 0px -59px; +} + +.hidden { + display: none; + visibility: hidden; +} + +.hiddenSpan { + display: none; +} + +.ellipsis_description, .short_description { +/* width: 800px;*/ +} +.methodToggleOpen .ellipsis_description { + display: none; +} +.sideToggler .short_description, +.sideToggler .description{ + display: none; +} +.methodToggleOpen .short_description, +.methodToggleOpen .description { + display: block; +} +.description td p { + margin: 0; +} +/* + Footer? I hardly know her +*/ + +#footer { + left:0px; + bottom:0px; + padding-top: 0; + width:100%; + background: #101010 url(../images/dashed_back.png) repeat 0 0; + font-size: 12px; + color: white; + border-top: none; + margin-top: 0; +} +#footer .container { + width: 710px; + padding-left: 300px; + margin-left: auto; + margin-right: auto; + min-height: 60px; +} +#footer .footer-text { + display: block; + float: right; + margin-right: 10px; + margin-top: 24px; +} +#footer .sponsors { + display: inline-block; + margin-top: 18px; +} + +#footer .sponsors .sponsor { + padding-right: 22px; +} + +#footer a, #footer a:hover { + color: #8DD0FF; +} +#footer .c9-logo { + width: 141px; + height: 20px; + background: url(../images/c9-log-footer.png) no-repeat 0 0; + display: inline-block; + padding-right: 10px; +} +#footer .joyent-logo { + width: 70px; + height: 19px; + background: url(../images/joyent-logo-footer.png) no-repeat 0 0; + display: inline-block; + padding-right: 10px; +} +#footer .mozilla-logo { + width: 78px; + height: 24px; + background: url(../images/mozilla-logo-footer.png) no-repeat 0 0; + display: inline-block; + padding-right: 10px; +} +#footer .debuggable-logo { + width: 119px; + height: 25px; + background: url(../images/debuggable-logo-footer.png) no-repeat 0 0; + display: inline-block; + padding-right: 0 !important; + margin-bottom : -3px; +} +#footer .span11 { + margin-left: 0; +} + +.logoText, .logoImg { + /*position: absolute;*/ + margin-bottom: 5px; +} + +.logoImg { + top: 40px; +} +.topbar div > ul .menu-dropdown li a:hover, +.nav .menu-dropdown li a:hover, +.topbar div > ul .dropdown-menu li a:hover, +.nav .dropdown-menu li a:hover { + background-color: #191919; + background-repeat: repeat-x; + background-image: -khtml-gradient(linear, left top, left bottom, from(#292929), to(#191919)); + background-image: -moz-linear-gradient(top, #292929, #191919); + background-image: -ms-linear-gradient(top, #292929, #191919); + background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #292929), color-stop(100%, #191919)); + background-image: -webkit-linear-gradient(top, #292929, #191919); + background-image: -o-linear-gradient(top, #292929, #191919); + background-image: linear-gradient(top, #292929, #191919); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#292929', endColorstr='#191919', GradientType=0); + color: #ffffff; +} + +.alert-message.block-message { + background: #fefaca; + border-color : #fefaca; + padding : 8px 14px 8px 14px; +} + +body .dsq-reply{ + margin-top : 10px; +} + +#disqus_thread{ + border-top : 1px solid #ddd; + margin-top : 30px; +} + +#disqus_thread h3, body #dsq-content h3 { + font-size : 12px; + margin : 0 0 20px 0; + line-height : 12px; +} +body #dsq-reply h3{ + font-size : 18px; + line-height : 18px; + margin : 15px 0 20px 0; +} + +#disqus_thread select{ + font-size : 11px; + height : 20px; + color : #444; +} + +#dsq-global-toolbar, #dsq-pagination, .dsq-trackback-url{ + display : none; +} + +/* Sticky footer stuff */ + +html +{ +height: 100%; +} + +body +{ +height: 100%; +} + +#nonFooter +{ +position: relative; +min-height: 100%; +} + +* html #nonFooter +{ +height: 100%; +} + +#wrapper +{ + +} + +#footer +{ +position: relative; +margin-top: -3.5em; +} \ No newline at end of file diff --git a/doc/resources/ace/skeleton/csses/bootstrap.min.css b/doc/resources/ace/skeleton/csses/bootstrap.min.css new file mode 100644 index 00000000..c9514677 --- /dev/null +++ b/doc/resources/ace/skeleton/csses/bootstrap.min.css @@ -0,0 +1,689 @@ +article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block;} +audio,canvas,video{display:inline-block;*display:inline;*zoom:1;} +audio:not([controls]){display:none;} +html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;} +a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +a:hover,a:active{outline:0;} +sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline;} +sup{top:-0.5em;} +sub{bottom:-0.25em;} +img{height:auto;border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;} +button,input,select,textarea{margin:0;font-size:100%;vertical-align:middle;} +button,input{*overflow:visible;line-height:normal;} +button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0;} +button,input[type="button"],input[type="reset"],input[type="submit"]{cursor:pointer;-webkit-appearance:button;} +input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;} +input[type="search"]::-webkit-search-decoration,input[type="search"]::-webkit-search-cancel-button{-webkit-appearance:none;} +textarea{overflow:auto;vertical-align:top;} +.clearfix{*zoom:1;}.clearfix:before,.clearfix:after{display:table;content:"";} +.clearfix:after{clear:both;} +.hide-text{overflow:hidden;text-indent:100%;white-space:nowrap;} +.input-block-level{display:block;width:100%;min-height:28px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;} +body{margin:0;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333333;background-color:#ffffff;} +a{color:#0088cc;text-decoration:none;} +a:hover{color:#005580;text-decoration:underline;} +.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";} +.row:after{clear:both;} +[class*="span"]{float:left;margin-left:20px;} +.container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.span12{width:940px;} +.span11{width:860px;} +.span10{width:780px;} +.span9{width:700px;} +.span8{width:620px;} +.span7{width:540px;} +.span6{width:460px;} +.span5{width:380px;} +.span4{width:300px;} +.span3{width:220px;} +.span2{width:140px;} +.span1{width:60px;} +.offset12{margin-left:980px;} +.offset11{margin-left:900px;} +.offset10{margin-left:820px;} +.offset9{margin-left:740px;} +.offset8{margin-left:660px;} +.offset7{margin-left:580px;} +.offset6{margin-left:500px;} +.offset5{margin-left:420px;} +.offset4{margin-left:340px;} +.offset3{margin-left:260px;} +.offset2{margin-left:180px;} +.offset1{margin-left:100px;} +.row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";} +.row-fluid:after{clear:both;} +.row-fluid>[class*="span"]{float:left;margin-left:2.127659574%;} +.row-fluid>[class*="span"]:first-child{margin-left:0;} +.row-fluid > .span12{width:99.99999998999999%;} +.row-fluid > .span11{width:91.489361693%;} +.row-fluid > .span10{width:82.97872339599999%;} +.row-fluid > .span9{width:74.468085099%;} +.row-fluid > .span8{width:65.95744680199999%;} +.row-fluid > .span7{width:57.446808505%;} +.row-fluid > .span6{width:48.93617020799999%;} +.row-fluid > .span5{width:40.425531911%;} +.row-fluid > .span4{width:31.914893614%;} +.row-fluid > .span3{width:23.404255317%;} +.row-fluid > .span2{width:14.89361702%;} +.row-fluid > .span1{width:6.382978723%;} +.container{margin-left:auto;margin-right:auto;*zoom:1;}.container:before,.container:after{display:table;content:"";} +.container:after{clear:both;} +.container-fluid{padding-left:20px;padding-right:20px;*zoom:1;}.container-fluid:before,.container-fluid:after{display:table;content:"";} +.container-fluid:after{clear:both;} +p{margin:0 0 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;}p small{font-size:11px;color:#999999;} +.lead{margin-bottom:18px;font-size:20px;font-weight:200;line-height:27px;} +h1,h2,h3,h4,h5,h6{margin:0;font-family:inherit;font-weight:bold;color:inherit;text-rendering:optimizelegibility;}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:normal;color:#999999;} +h1{font-size:30px;line-height:36px;}h1 small{font-size:18px;} +h2{font-size:24px;line-height:36px;}h2 small{font-size:18px;} +h3{line-height:27px;font-size:18px;}h3 small{font-size:14px;} +h4,h5,h6{line-height:18px;} +h4{font-size:14px;}h4 small{font-size:12px;} +h5{font-size:12px;} +h6{font-size:11px;color:#999999;text-transform:uppercase;} +.page-header{padding-bottom:17px;margin:18px 0;border-bottom:1px solid #eeeeee;} +.page-header h1{line-height:1;} +ul,ol{padding:0;margin:0 0 9px 25px;} +ul ul,ul ol,ol ol,ol ul{margin-bottom:0;} +ul{list-style:disc;} +ol{list-style:decimal;} +li{line-height:18px;} +ul.unstyled,ol.unstyled{margin-left:0;list-style:none;} +dl{margin-bottom:18px;} +dt,dd{line-height:18px;} +dt{font-weight:bold;line-height:17px;} +dd{margin-left:9px;} +.dl-horizontal dt{float:left;clear:left;width:120px;text-align:right;} +.dl-horizontal dd{margin-left:130px;} +hr{margin:18px 0;border:0;border-top:1px solid #eeeeee;border-bottom:1px solid #ffffff;} +strong{font-weight:bold;} +em{font-style:italic;} +.muted{color:#999999;} +abbr[title]{border-bottom:1px dotted #ddd;cursor:help;} +abbr.initialism{font-size:90%;text-transform:uppercase;} +blockquote{padding:0 0 0 15px;margin:0 0 18px;border-left:5px solid #eeeeee;}blockquote p{margin-bottom:0;font-size:16px;font-weight:300;line-height:22.5px;} +blockquote small{display:block;line-height:18px;color:#999999;}blockquote small:before{content:'\2014 \00A0';} +blockquote.pull-right{float:right;padding-left:0;padding-right:15px;border-left:0;border-right:5px solid #eeeeee;}blockquote.pull-right p,blockquote.pull-right small{text-align:right;} +q:before,q:after,blockquote:before,blockquote:after{content:"";} +address{display:block;margin-bottom:18px;line-height:18px;font-style:normal;} +small{font-size:100%;} +cite{font-style:normal;} +code,pre{padding:0 3px 2px;font-family:Menlo,Monaco,"Courier New",monospace;font-size:12px;color:#333333;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +code{padding:2px 4px;color:#d14;background-color:#f7f7f9;border:1px solid #e1e1e8;} +pre{display:block;padding:8.5px;margin:0 0 9px;font-size:12.025px;line-height:18px;background-color:#f5f5f5;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.15);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;white-space:pre;white-space:pre-wrap;word-break:break-all;word-wrap:break-word;}pre.prettyprint{margin-bottom:18px;} +pre code{padding:0;color:inherit;background-color:transparent;border:0;} +.pre-scrollable{max-height:340px;overflow-y:scroll;} +form{margin:0 0 18px;} +fieldset{padding:0;margin:0;border:0;} +legend{display:block;width:100%;padding:0;margin-bottom:27px;font-size:19.5px;line-height:36px;color:#333333;border:0;border-bottom:1px solid #eee;}legend small{font-size:13.5px;color:#999999;} +label,input,button,select,textarea{font-size:13px;font-weight:normal;line-height:18px;} +input,button,select,textarea{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;} +label{display:block;margin-bottom:5px;color:#333333;} +input,textarea,select,.uneditable-input{display:inline-block;width:210px;height:18px;padding:4px;margin-bottom:9px;font-size:13px;line-height:18px;color:#555555;border:1px solid #cccccc;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.uneditable-textarea{width:auto;height:auto;} +label input,label textarea,label select{display:block;} +input[type="image"],input[type="checkbox"],input[type="radio"]{width:auto;height:auto;padding:0;margin:3px 0;*margin-top:0;line-height:normal;cursor:pointer;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;border:0 \9;} +input[type="image"]{border:0;} +input[type="file"]{width:auto;padding:initial;line-height:initial;border:initial;background-color:#ffffff;background-color:initial;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +input[type="button"],input[type="reset"],input[type="submit"]{width:auto;height:auto;} +select,input[type="file"]{height:28px;*margin-top:4px;line-height:28px;} +input[type="file"]{line-height:18px \9;} +select{width:220px;background-color:#ffffff;} +select[multiple],select[size]{height:auto;} +input[type="image"]{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +textarea{height:auto;} +input[type="hidden"]{display:none;} +.radio,.checkbox{padding-left:18px;} +.radio input[type="radio"],.checkbox input[type="checkbox"]{float:left;margin-left:-18px;} +.controls>.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;} +.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;} +.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;} +input,textarea{-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border linear 0.2s,box-shadow linear 0.2s;-moz-transition:border linear 0.2s,box-shadow linear 0.2s;-ms-transition:border linear 0.2s,box-shadow linear 0.2s;-o-transition:border linear 0.2s,box-shadow linear 0.2s;transition:border linear 0.2s,box-shadow linear 0.2s;} +input:focus,textarea:focus{border-color:rgba(82, 168, 236, 0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);outline:0;outline:thin dotted \9;} +input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus,select:focus{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.input-mini{width:60px;} +.input-small{width:90px;} +.input-medium{width:150px;} +.input-large{width:210px;} +.input-xlarge{width:270px;} +.input-xxlarge{width:530px;} +input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{float:none;margin-left:0;} +input,textarea,.uneditable-input{margin-left:0;} +input.span12, textarea.span12, .uneditable-input.span12{width:930px;} +input.span11, textarea.span11, .uneditable-input.span11{width:850px;} +input.span10, textarea.span10, .uneditable-input.span10{width:770px;} +input.span9, textarea.span9, .uneditable-input.span9{width:690px;} +input.span8, textarea.span8, .uneditable-input.span8{width:610px;} +input.span7, textarea.span7, .uneditable-input.span7{width:530px;} +input.span6, textarea.span6, .uneditable-input.span6{width:450px;} +input.span5, textarea.span5, .uneditable-input.span5{width:370px;} +input.span4, textarea.span4, .uneditable-input.span4{width:290px;} +input.span3, textarea.span3, .uneditable-input.span3{width:210px;} +input.span2, textarea.span2, .uneditable-input.span2{width:130px;} +input.span1, textarea.span1, .uneditable-input.span1{width:50px;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{background-color:#eeeeee;border-color:#ddd;cursor:not-allowed;} +.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;} +.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;border-color:#c09853;}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:0 0 6px #dbc59e;-moz-box-shadow:0 0 6px #dbc59e;box-shadow:0 0 6px #dbc59e;} +.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} +.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} +.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;border-color:#b94a48;}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:0 0 6px #d59392;-moz-box-shadow:0 0 6px #d59392;box-shadow:0 0 6px #d59392;} +.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} +.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} +.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;border-color:#468847;}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:0 0 6px #7aba7b;-moz-box-shadow:0 0 6px #7aba7b;box-shadow:0 0 6px #7aba7b;} +.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} +input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} +.form-actions{padding:17px 20px 18px;margin-top:18px;margin-bottom:18px;background-color:#eeeeee;border-top:1px solid #ddd;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";} +.form-actions:after{clear:both;} +.uneditable-input{display:block;background-color:#ffffff;border-color:#eee;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.025);cursor:not-allowed;} +:-moz-placeholder{color:#999999;} +::-webkit-input-placeholder{color:#999999;} +.help-block,.help-inline{color:#555555;} +.help-block{display:block;margin-bottom:9px;} +.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;} +.input-prepend,.input-append{margin-bottom:5px;}.input-prepend input,.input-append input,.input-prepend select,.input-append select,.input-prepend .uneditable-input,.input-append .uneditable-input{*margin-left:0;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;}.input-prepend input:focus,.input-append input:focus,.input-prepend select:focus,.input-append select:focus,.input-prepend .uneditable-input:focus,.input-append .uneditable-input:focus{position:relative;z-index:2;} +.input-prepend .uneditable-input,.input-append .uneditable-input{border-left-color:#ccc;} +.input-prepend .add-on,.input-append .add-on{display:inline-block;width:auto;min-width:16px;height:18px;padding:4px 5px;font-weight:normal;line-height:18px;text-align:center;text-shadow:0 1px 0 #ffffff;vertical-align:middle;background-color:#eeeeee;border:1px solid #ccc;} +.input-prepend .add-on,.input-append .add-on,.input-prepend .btn,.input-append .btn{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-prepend .active,.input-append .active{background-color:#a9dba9;border-color:#46a546;} +.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;} +.input-append input,.input-append select .uneditable-input{-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-append .uneditable-input{border-left-color:#eee;border-right-color:#ccc;} +.input-append .add-on,.input-append .btn{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.search-query{padding-left:14px;padding-right:14px;margin-bottom:0;-webkit-border-radius:14px;-moz-border-radius:14px;border-radius:14px;} +.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;margin-bottom:0;} +.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;} +.form-search label,.form-inline label{display:inline-block;} +.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;} +.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;} +.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-left:0;margin-right:3px;} +.control-group{margin-bottom:9px;} +legend+.control-group{margin-top:18px;-webkit-margin-top-collapse:separate;} +.form-horizontal .control-group{margin-bottom:18px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";} +.form-horizontal .control-group:after{clear:both;} +.form-horizontal .control-label{float:left;width:140px;padding-top:5px;text-align:right;} +.form-horizontal .controls{margin-left:160px;*display:inline-block;*margin-left:0;*padding-left:20px;} +.form-horizontal .help-block{margin-top:9px;margin-bottom:0;} +.form-horizontal .form-actions{padding-left:160px;} +table{max-width:100%;border-collapse:collapse;border-spacing:0;background-color:transparent;} +.table{width:100%;margin-bottom:18px;}.table th,.table td{padding:8px;line-height:18px;text-align:left;vertical-align:top;border-top:1px solid #dddddd;} +.table th{font-weight:bold;} +.table thead th{vertical-align:bottom;} +.table colgroup+thead tr:first-child th,.table colgroup+thead tr:first-child td,.table thead:first-child tr:first-child th,.table thead:first-child tr:first-child td{border-top:0;} +.table tbody+tbody{border-top:2px solid #dddddd;} +.table-condensed th,.table-condensed td{padding:4px 5px;} +.table-bordered{border:1px solid #dddddd;border-left:0;border-collapse:separate;*border-collapse:collapsed;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.table-bordered th,.table-bordered td{border-left:1px solid #dddddd;} +.table-bordered thead:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child th,.table-bordered tbody:first-child tr:first-child td{border-top:0;} +.table-bordered thead:first-child tr:first-child th:first-child,.table-bordered tbody:first-child tr:first-child td:first-child{-webkit-border-radius:4px 0 0 0;-moz-border-radius:4px 0 0 0;border-radius:4px 0 0 0;} +.table-bordered thead:first-child tr:first-child th:last-child,.table-bordered tbody:first-child tr:first-child td:last-child{-webkit-border-radius:0 4px 0 0;-moz-border-radius:0 4px 0 0;border-radius:0 4px 0 0;} +.table-bordered thead:last-child tr:last-child th:first-child,.table-bordered tbody:last-child tr:last-child td:first-child{-webkit-border-radius:0 0 0 4px;-moz-border-radius:0 0 0 4px;border-radius:0 0 0 4px;} +.table-bordered thead:last-child tr:last-child th:last-child,.table-bordered tbody:last-child tr:last-child td:last-child{-webkit-border-radius:0 0 4px 0;-moz-border-radius:0 0 4px 0;border-radius:0 0 4px 0;} +.table-striped tbody tr:nth-child(odd) td,.table-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9;} +.table tbody tr:hover td,.table tbody tr:hover th{background-color:#f5f5f5;} +table .span1{float:none;width:44px;margin-left:0;} +table .span2{float:none;width:124px;margin-left:0;} +table .span3{float:none;width:204px;margin-left:0;} +table .span4{float:none;width:284px;margin-left:0;} +table .span5{float:none;width:364px;margin-left:0;} +table .span6{float:none;width:444px;margin-left:0;} +table .span7{float:none;width:524px;margin-left:0;} +table .span8{float:none;width:604px;margin-left:0;} +table .span9{float:none;width:684px;margin-left:0;} +table .span10{float:none;width:764px;margin-left:0;} +table .span11{float:none;width:844px;margin-left:0;} +table .span12{float:none;width:924px;margin-left:0;} +table .span13{float:none;width:1004px;margin-left:0;} +table .span14{float:none;width:1084px;margin-left:0;} +table .span15{float:none;width:1164px;margin-left:0;} +table .span16{float:none;width:1244px;margin-left:0;} +table .span17{float:none;width:1324px;margin-left:0;} +table .span18{float:none;width:1404px;margin-left:0;} +table .span19{float:none;width:1484px;margin-left:0;} +table .span20{float:none;width:1564px;margin-left:0;} +table .span21{float:none;width:1644px;margin-left:0;} +table .span22{float:none;width:1724px;margin-left:0;} +table .span23{float:none;width:1804px;margin-left:0;} +table .span24{float:none;width:1884px;margin-left:0;} +[class^="icon-"],[class*=" icon-"]{display:inline-block;width:14px;height:14px;line-height:14px;vertical-align:text-top;background-image:url("../img/glyphicons-halflings.png");background-position:14px 14px;background-repeat:no-repeat;*margin-right:.3em;}[class^="icon-"]:last-child,[class*=" icon-"]:last-child{*margin-left:0;} +.icon-white{background-image:url("../img/glyphicons-halflings-white.png");} +.icon-glass{background-position:0 0;} +.icon-music{background-position:-24px 0;} +.icon-search{background-position:-48px 0;} +.icon-envelope{background-position:-72px 0;} +.icon-heart{background-position:-96px 0;} +.icon-star{background-position:-120px 0;} +.icon-star-empty{background-position:-144px 0;} +.icon-user{background-position:-168px 0;} +.icon-film{background-position:-192px 0;} +.icon-th-large{background-position:-216px 0;} +.icon-th{background-position:-240px 0;} +.icon-th-list{background-position:-264px 0;} +.icon-ok{background-position:-288px 0;} +.icon-remove{background-position:-312px 0;} +.icon-zoom-in{background-position:-336px 0;} +.icon-zoom-out{background-position:-360px 0;} +.icon-off{background-position:-384px 0;} +.icon-signal{background-position:-408px 0;} +.icon-cog{background-position:-432px 0;} +.icon-trash{background-position:-456px 0;} +.icon-home{background-position:0 -24px;} +.icon-file{background-position:-24px -24px;} +.icon-time{background-position:-48px -24px;} +.icon-road{background-position:-72px -24px;} +.icon-download-alt{background-position:-96px -24px;} +.icon-download{background-position:-120px -24px;} +.icon-upload{background-position:-144px -24px;} +.icon-inbox{background-position:-168px -24px;} +.icon-play-circle{background-position:-192px -24px;} +.icon-repeat{background-position:-216px -24px;} +.icon-refresh{background-position:-240px -24px;} +.icon-list-alt{background-position:-264px -24px;} +.icon-lock{background-position:-287px -24px;} +.icon-flag{background-position:-312px -24px;} +.icon-headphones{background-position:-336px -24px;} +.icon-volume-off{background-position:-360px -24px;} +.icon-volume-down{background-position:-384px -24px;} +.icon-volume-up{background-position:-408px -24px;} +.icon-qrcode{background-position:-432px -24px;} +.icon-barcode{background-position:-456px -24px;} +.icon-tag{background-position:0 -48px;} +.icon-tags{background-position:-25px -48px;} +.icon-book{background-position:-48px -48px;} +.icon-bookmark{background-position:-72px -48px;} +.icon-print{background-position:-96px -48px;} +.icon-camera{background-position:-120px -48px;} +.icon-font{background-position:-144px -48px;} +.icon-bold{background-position:-167px -48px;} +.icon-italic{background-position:-192px -48px;} +.icon-text-height{background-position:-216px -48px;} +.icon-text-width{background-position:-240px -48px;} +.icon-align-left{background-position:-264px -48px;} +.icon-align-center{background-position:-288px -48px;} +.icon-align-right{background-position:-312px -48px;} +.icon-align-justify{background-position:-336px -48px;} +.icon-list{background-position:-360px -48px;} +.icon-indent-left{background-position:-384px -48px;} +.icon-indent-right{background-position:-408px -48px;} +.icon-facetime-video{background-position:-432px -48px;} +.icon-picture{background-position:-456px -48px;} +.icon-pencil{background-position:0 -72px;} +.icon-map-marker{background-position:-24px -72px;} +.icon-adjust{background-position:-48px -72px;} +.icon-tint{background-position:-72px -72px;} +.icon-edit{background-position:-96px -72px;} +.icon-share{background-position:-120px -72px;} +.icon-check{background-position:-144px -72px;} +.icon-move{background-position:-168px -72px;} +.icon-step-backward{background-position:-192px -72px;} +.icon-fast-backward{background-position:-216px -72px;} +.icon-backward{background-position:-240px -72px;} +.icon-play{background-position:-264px -72px;} +.icon-pause{background-position:-288px -72px;} +.icon-stop{background-position:-312px -72px;} +.icon-forward{background-position:-336px -72px;} +.icon-fast-forward{background-position:-360px -72px;} +.icon-step-forward{background-position:-384px -72px;} +.icon-eject{background-position:-408px -72px;} +.icon-chevron-left{background-position:-432px -72px;} +.icon-chevron-right{background-position:-456px -72px;} +.icon-plus-sign{background-position:0 -96px;} +.icon-minus-sign{background-position:-24px -96px;} +.icon-remove-sign{background-position:-48px -96px;} +.icon-ok-sign{background-position:-72px -96px;} +.icon-question-sign{background-position:-96px -96px;} +.icon-info-sign{background-position:-120px -96px;} +.icon-screenshot{background-position:-144px -96px;} +.icon-remove-circle{background-position:-168px -96px;} +.icon-ok-circle{background-position:-192px -96px;} +.icon-ban-circle{background-position:-216px -96px;} +.icon-arrow-left{background-position:-240px -96px;} +.icon-arrow-right{background-position:-264px -96px;} +.icon-arrow-up{background-position:-289px -96px;} +.icon-arrow-down{background-position:-312px -96px;} +.icon-share-alt{background-position:-336px -96px;} +.icon-resize-full{background-position:-360px -96px;} +.icon-resize-small{background-position:-384px -96px;} +.icon-plus{background-position:-408px -96px;} +.icon-minus{background-position:-433px -96px;} +.icon-asterisk{background-position:-456px -96px;} +.icon-exclamation-sign{background-position:0 -120px;} +.icon-gift{background-position:-24px -120px;} +.icon-leaf{background-position:-48px -120px;} +.icon-fire{background-position:-72px -120px;} +.icon-eye-open{background-position:-96px -120px;} +.icon-eye-close{background-position:-120px -120px;} +.icon-warning-sign{background-position:-144px -120px;} +.icon-plane{background-position:-168px -120px;} +.icon-calendar{background-position:-192px -120px;} +.icon-random{background-position:-216px -120px;} +.icon-comment{background-position:-240px -120px;} +.icon-magnet{background-position:-264px -120px;} +.icon-chevron-up{background-position:-288px -120px;} +.icon-chevron-down{background-position:-313px -119px;} +.icon-retweet{background-position:-336px -120px;} +.icon-shopping-cart{background-position:-360px -120px;} +.icon-folder-close{background-position:-384px -120px;} +.icon-folder-open{background-position:-408px -120px;} +.icon-resize-vertical{background-position:-432px -119px;} +.icon-resize-horizontal{background-position:-456px -118px;} +.dropdown{position:relative;} +.dropdown-toggle{*margin-bottom:-3px;} +.dropdown-toggle:active,.open .dropdown-toggle{outline:0;} +.caret{display:inline-block;width:0;height:0;vertical-align:top;border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid #000000;opacity:0.3;filter:alpha(opacity=30);content:"";} +.dropdown .caret{margin-top:8px;margin-left:2px;} +.dropdown:hover .caret,.open.dropdown .caret{opacity:1;filter:alpha(opacity=100);} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;float:left;display:none;min-width:160px;padding:4px 0;margin:0;list-style:none;background-color:#ffffff;border-color:#ccc;border-color:rgba(0, 0, 0, 0.2);border-style:solid;border-width:1px;-webkit-border-radius:0 0 5px 5px;-moz-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;*border-right-width:2px;*border-bottom-width:2px;}.dropdown-menu.pull-right{right:0;left:auto;} +.dropdown-menu .divider{height:1px;margin:8px 1px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;*width:100%;*margin:-5px 0 5px;} +.dropdown-menu a{display:block;padding:3px 15px;clear:both;font-weight:normal;line-height:18px;color:#333333;white-space:nowrap;} +.dropdown-menu li>a:hover,.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#ffffff;text-decoration:none;background-color:#0088cc;} +.dropdown.open{*z-index:1000;}.dropdown.open .dropdown-toggle{color:#ffffff;background:#ccc;background:rgba(0, 0, 0, 0.3);} +.dropdown.open .dropdown-menu{display:block;} +.pull-right .dropdown-menu{left:auto;right:0;} +.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"\2191";} +.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;} +.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} +.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.fade{-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-ms-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;opacity:0;}.fade.in{opacity:1;} +.collapse{-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-ms-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;position:relative;overflow:hidden;height:0;}.collapse.in{height:auto;} +.close{float:right;font-size:20px;font-weight:bold;line-height:18px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;opacity:0.4;filter:alpha(opacity=40);cursor:pointer;} +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 10px 4px;margin-bottom:0;font-size:13px;line-height:18px;color:#333333;text-align:center;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);vertical-align:middle;background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-ms-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(top, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);border:1px solid #cccccc;border-bottom-color:#b3b3b3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);cursor:pointer;*margin-left:.3em;}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{background-color:#e6e6e6;} +.btn:active,.btn.active{background-color:#cccccc \9;} +.btn:first-child{*margin-left:0;} +.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-ms-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} +.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.btn.active,.btn:active{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);background-color:#e6e6e6;background-color:#d9d9d9 \9;outline:0;} +.btn.disabled,.btn[disabled]{cursor:default;background-image:none;background-color:#e6e6e6;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-large{padding:9px 14px;font-size:15px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.btn-large [class^="icon-"]{margin-top:1px;} +.btn-small{padding:5px 9px;font-size:11px;line-height:16px;} +.btn-small [class^="icon-"]{margin-top:-1px;} +.btn-mini{padding:2px 6px;font-size:11px;line-height:14px;} +.btn-primary,.btn-primary:hover,.btn-warning,.btn-warning:hover,.btn-danger,.btn-danger:hover,.btn-success,.btn-success:hover,.btn-info,.btn-info:hover,.btn-inverse,.btn-inverse:hover{text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);color:#ffffff;} +.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);} +.btn-primary{background-color:#0074cc;background-image:-moz-linear-gradient(top, #0088cc, #0055cc);background-image:-ms-linear-gradient(top, #0088cc, #0055cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0055cc));background-image:-webkit-linear-gradient(top, #0088cc, #0055cc);background-image:-o-linear-gradient(top, #0088cc, #0055cc);background-image:linear-gradient(top, #0088cc, #0055cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0055cc', GradientType=0);border-color:#0055cc #0055cc #003580;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{background-color:#0055cc;} +.btn-primary:active,.btn-primary.active{background-color:#004099 \9;} +.btn-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{background-color:#f89406;} +.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} +.btn-danger{background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-ms-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(top, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#bd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{background-color:#bd362f;} +.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} +.btn-success{background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-ms-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(top, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{background-color:#51a351;} +.btn-success:active,.btn-success.active{background-color:#408140 \9;} +.btn-info{background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-ms-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(top, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{background-color:#2f96b4;} +.btn-info:active,.btn-info.active{background-color:#24748c \9;} +.btn-inverse{background-color:#414141;background-image:-moz-linear-gradient(top, #555555, #222222);background-image:-ms-linear-gradient(top, #555555, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#555555), to(#222222));background-image:-webkit-linear-gradient(top, #555555, #222222);background-image:-o-linear-gradient(top, #555555, #222222);background-image:linear-gradient(top, #555555, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#555555', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{background-color:#222222;} +.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;} +button.btn,input[type="submit"].btn{*padding-top:2px;*padding-bottom:2px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;} +button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;} +button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;} +button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;} +.btn-group{position:relative;*zoom:1;*margin-left:.3em;}.btn-group:before,.btn-group:after{display:table;content:"";} +.btn-group:after{clear:both;} +.btn-group:first-child{*margin-left:0;} +.btn-group+.btn-group{margin-left:5px;} +.btn-toolbar{margin-top:9px;margin-bottom:9px;}.btn-toolbar .btn-group{display:inline-block;*display:inline;*zoom:1;} +.btn-group .btn{position:relative;float:left;margin-left:-1px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group .btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.btn-group .btn:last-child,.btn-group .dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.btn-group .btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.btn-group .btn.large:last-child,.btn-group .large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.btn-group .btn:hover,.btn-group .btn:focus,.btn-group .btn:active,.btn-group .btn.active{z-index:2;} +.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;} +.btn-group .dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 1px 0 0 rgba(255, 255, 255, 0.125),inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05);*padding-top:3px;*padding-bottom:3px;} +.btn-group .btn-mini.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:1px;*padding-bottom:1px;} +.btn-group .btn-small.dropdown-toggle{*padding-top:4px;*padding-bottom:4px;} +.btn-group .btn-large.dropdown-toggle{padding-left:12px;padding-right:12px;} +.btn-group.open{*z-index:1000;}.btn-group.open .dropdown-menu{display:block;margin-top:1px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 6px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);} +.btn .caret{margin-top:7px;margin-left:0;} +.btn:hover .caret,.open.btn-group .caret{opacity:1;filter:alpha(opacity=100);} +.btn-mini .caret{margin-top:5px;} +.btn-small .caret{margin-top:6px;} +.btn-large .caret{margin-top:6px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:0.75;filter:alpha(opacity=75);} +.alert{padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;} +.alert-heading{color:inherit;} +.alert .close{position:relative;top:-2px;right:-21px;line-height:18px;} +.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;} +.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;} +.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;} +.alert-block{padding-top:14px;padding-bottom:14px;} +.alert-block>p,.alert-block>ul{margin-bottom:0;} +.alert-block p+p{margin-top:5px;} +.nav{margin-left:0;margin-bottom:18px;list-style:none;} +.nav>li>a{display:block;} +.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} +.nav .nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:18px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;} +.nav li+.nav-header{margin-top:9px;} +.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;} +.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} +.nav-list>li>a{padding:3px 15px;} +.nav-list>.active>a,.nav-list>.active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;} +.nav-list [class^="icon-"]{margin-right:2px;} +.nav-list .divider{height:1px;margin:8px 1px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;*width:100%;*margin:-5px 0 5px;} +.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";} +.nav-tabs:after,.nav-pills:after{clear:both;} +.nav-tabs>li,.nav-pills>li{float:left;} +.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} +.nav-tabs{border-bottom:1px solid #ddd;} +.nav-tabs>li{margin-bottom:-1px;} +.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:18px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#0088cc;} +.nav-stacked>li{float:none;} +.nav-stacked>li>a{margin-right:0;} +.nav-tabs.nav-stacked{border-bottom:0;} +.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} +.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} +.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;} +.nav-pills.nav-stacked>li>a{margin-bottom:3px;} +.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;} +.nav-tabs .dropdown-menu,.nav-pills .dropdown-menu{margin-top:1px;border-width:1px;} +.nav-pills .dropdown-menu{-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.nav-tabs .dropdown-toggle .caret,.nav-pills .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;} +.nav-tabs .dropdown-toggle:hover .caret,.nav-pills .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;} +.nav-tabs .active .dropdown-toggle .caret,.nav-pills .active .dropdown-toggle .caret{border-top-color:#333333;border-bottom-color:#333333;} +.nav>.dropdown.active>a:hover{color:#000000;cursor:pointer;} +.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;} +.nav .open .caret,.nav .open.active .caret,.nav .open a:hover .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);} +.tabs-stacked .open>a:hover{border-color:#999999;} +.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";} +.tabbable:after{clear:both;} +.tab-content{display:table;width:100%;} +.tabs-below .nav-tabs,.tabs-right .nav-tabs,.tabs-left .nav-tabs{border-bottom:0;} +.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;} +.tab-content>.active,.pill-content>.active{display:block;} +.tabs-below .nav-tabs{border-top:1px solid #ddd;} +.tabs-below .nav-tabs>li{margin-top:-1px;margin-bottom:0;} +.tabs-below .nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below .nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;} +.tabs-below .nav-tabs .active>a,.tabs-below .nav-tabs .active>a:hover{border-color:transparent #ddd #ddd #ddd;} +.tabs-left .nav-tabs>li,.tabs-right .nav-tabs>li{float:none;} +.tabs-left .nav-tabs>li>a,.tabs-right .nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;} +.tabs-left .nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;} +.tabs-left .nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.tabs-left .nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;} +.tabs-left .nav-tabs .active>a,.tabs-left .nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;} +.tabs-right .nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;} +.tabs-right .nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.tabs-right .nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;} +.tabs-right .nav-tabs .active>a,.tabs-right .nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} +.navbar{*position:relative;*z-index:2;overflow:visible;margin-bottom:18px;} +.navbar-inner{padding-left:20px;padding-right:20px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);box-shadow:0 1px 3px rgba(0, 0, 0, 0.25),inset 0 -1px 0 rgba(0, 0, 0, 0.1);} +.navbar .container{width:auto;} +.btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;background-color:#2c2c2c;background-image:-moz-linear-gradient(top, #333333, #222222);background-image:-ms-linear-gradient(top, #333333, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#333333), to(#222222));background-image:-webkit-linear-gradient(top, #333333, #222222);background-image:-o-linear-gradient(top, #333333, #222222);background-image:linear-gradient(top, #333333, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#333333', endColorstr='#222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);filter:progid:dximagetransform.microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.075);}.btn-navbar:hover,.btn-navbar:active,.btn-navbar.active,.btn-navbar.disabled,.btn-navbar[disabled]{background-color:#222222;} +.btn-navbar:active,.btn-navbar.active{background-color:#080808 \9;} +.btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);} +.btn-navbar .icon-bar+.icon-bar{margin-top:3px;} +.nav-collapse.collapse{height:auto;} +.navbar{color:#999999;}.navbar .brand:hover{text-decoration:none;} +.navbar .brand{float:left;display:block;padding:8px 20px 12px;margin-left:-20px;font-size:20px;font-weight:200;line-height:1;color:#ffffff;} +.navbar .navbar-text{margin-bottom:0;line-height:40px;} +.navbar .btn,.navbar .btn-group{margin-top:5px;} +.navbar .btn-group .btn{margin-top:0;} +.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";} +.navbar-form:after{clear:both;} +.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;} +.navbar-form input,.navbar-form select{display:inline-block;margin-bottom:0;} +.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;} +.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;} +.navbar-search{position:relative;float:left;margin-top:6px;margin-bottom:0;}.navbar-search .search-query{padding:4px 9px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;color:#ffffff;background-color:#626262;border:1px solid #151515;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1),0 1px 0px rgba(255, 255, 255, 0.15);-webkit-transition:none;-moz-transition:none;-ms-transition:none;-o-transition:none;transition:none;}.navbar-search .search-query:-moz-placeholder{color:#cccccc;} +.navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;} +.navbar-search .search-query:focus,.navbar-search .search-query.focused{padding:5px 10px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;} +.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;} +.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.navbar-fixed-top{top:0;} +.navbar-fixed-bottom{bottom:0;} +.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} +.navbar .nav.pull-right{float:right;} +.navbar .nav>li{display:block;float:left;} +.navbar .nav>li>a{float:none;padding:10px 10px 11px;line-height:19px;color:#999999;text-decoration:none;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);} +.navbar .nav>li>a:hover{background-color:transparent;color:#ffffff;text-decoration:none;} +.navbar .nav .active>a,.navbar .nav .active>a:hover{color:#ffffff;text-decoration:none;background-color:#222222;} +.navbar .divider-vertical{height:40px;width:1px;margin:0 9px;overflow:hidden;background-color:#222222;border-right:1px solid #333333;} +.navbar .nav.pull-right{margin-left:10px;margin-right:0;} +.navbar .dropdown-menu{margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.navbar .dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;} +.navbar .dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;} +.navbar-fixed-bottom .dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;} +.navbar-fixed-bottom .dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;} +.navbar .nav .dropdown-toggle .caret,.navbar .nav .open.dropdown .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.navbar .nav .active .caret{opacity:1;filter:alpha(opacity=100);} +.navbar .nav .open>.dropdown-toggle,.navbar .nav .active>.dropdown-toggle,.navbar .nav .open.active>.dropdown-toggle{background-color:transparent;} +.navbar .nav .active>.dropdown-toggle:hover{color:#ffffff;} +.navbar .nav.pull-right .dropdown-menu,.navbar .nav .dropdown-menu.pull-right{left:auto;right:0;}.navbar .nav.pull-right .dropdown-menu:before,.navbar .nav .dropdown-menu.pull-right:before{left:auto;right:12px;} +.navbar .nav.pull-right .dropdown-menu:after,.navbar .nav .dropdown-menu.pull-right:after{left:auto;right:13px;} +.breadcrumb{padding:7px 14px;margin:0 0 18px;list-style:none;background-color:#fbfbfb;background-image:-moz-linear-gradient(top, #ffffff, #f5f5f5);background-image:-ms-linear-gradient(top, #ffffff, #f5f5f5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f5f5f5));background-image:-webkit-linear-gradient(top, #ffffff, #f5f5f5);background-image:-o-linear-gradient(top, #ffffff, #f5f5f5);background-image:linear-gradient(top, #ffffff, #f5f5f5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f5f5f5', GradientType=0);border:1px solid #ddd;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#999999;} +.breadcrumb .active a{color:#333333;} +.pagination{height:36px;margin:18px 0;} +.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} +.pagination li{display:inline;} +.pagination a{float:left;padding:0 14px;line-height:34px;text-decoration:none;border:1px solid #ddd;border-left-width:0;} +.pagination a:hover,.pagination .active a{background-color:#f5f5f5;} +.pagination .active a{color:#999999;cursor:default;} +.pagination .disabled span,.pagination .disabled a,.pagination .disabled a:hover{color:#999999;background-color:transparent;cursor:default;} +.pagination li:first-child a{border-left-width:1px;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px;} +.pagination li:last-child a{-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0;} +.pagination-centered{text-align:center;} +.pagination-right{text-align:right;} +.pager{margin-left:0;margin-bottom:18px;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";} +.pager:after{clear:both;} +.pager li{display:inline;} +.pager a{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.pager a:hover{text-decoration:none;background-color:#f5f5f5;} +.pager .next a{float:right;} +.pager .previous a{float:left;} +.pager .disabled a,.pager .disabled a:hover{color:#999999;background-color:#fff;cursor:default;} +.modal-open .dropdown-menu{z-index:2050;} +.modal-open .dropdown.open{*z-index:2050;} +.modal-open .popover{z-index:2060;} +.modal-open .tooltip{z-index:2070;} +.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;} +.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);} +.modal{position:fixed;top:50%;left:50%;z-index:1050;overflow:auto;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-ms-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} +.modal.fade.in{top:50%;} +.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;} +.modal-body{overflow-y:auto;max-height:400px;padding:15px;} +.modal-form{margin-bottom:0;} +.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";} +.modal-footer:after{clear:both;} +.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;} +.modal-footer .btn-group .btn+.btn{margin-left:-1px;} +.tooltip{position:absolute;z-index:1020;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);} +.tooltip.top{margin-top:-2px;} +.tooltip.right{margin-left:2px;} +.tooltip.bottom{margin-top:2px;} +.tooltip.left{margin-left:-2px;} +.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} +.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} +.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} +.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.tooltip-arrow{position:absolute;width:0;height:0;} +.popover{position:absolute;top:0;left:0;z-index:1010;display:none;padding:5px;}.popover.top{margin-top:-5px;} +.popover.right{margin-left:5px;} +.popover.bottom{margin-top:5px;} +.popover.left{margin-left:-5px;} +.popover.top .arrow{bottom:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid #000000;} +.popover.right .arrow{top:50%;left:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-right:5px solid #000000;} +.popover.bottom .arrow{top:0;left:50%;margin-left:-5px;border-left:5px solid transparent;border-right:5px solid transparent;border-bottom:5px solid #000000;} +.popover.left .arrow{top:50%;right:0;margin-top:-5px;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid #000000;} +.popover .arrow{position:absolute;width:0;height:0;} +.popover-inner{padding:3px;width:280px;overflow:hidden;background:#000000;background:rgba(0, 0, 0, 0.8);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);} +.popover-title{padding:9px 15px;line-height:1;background-color:#f5f5f5;border-bottom:1px solid #eee;-webkit-border-radius:3px 3px 0 0;-moz-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;} +.popover-content{padding:14px;background-color:#ffffff;-webkit-border-radius:0 0 3px 3px;-moz-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} +.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";} +.thumbnails:after{clear:both;} +.thumbnails>li{float:left;margin:0 0 18px 20px;} +.thumbnail{display:block;padding:4px;line-height:1;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:0 1px 1px rgba(0, 0, 0, 0.075);} +a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} +.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;} +.thumbnail .caption{padding:9px;} +.label{padding:1px 4px 2px;font-size:10.998px;font-weight:bold;line-height:13px;color:#ffffff;vertical-align:middle;white-space:nowrap;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#999999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.label:hover{color:#ffffff;text-decoration:none;} +.label-important{background-color:#b94a48;} +.label-important:hover{background-color:#953b39;} +.label-warning{background-color:#f89406;} +.label-warning:hover{background-color:#c67605;} +.label-success{background-color:#468847;} +.label-success:hover{background-color:#356635;} +.label-info{background-color:#3a87ad;} +.label-info:hover{background-color:#2d6987;} +.label-inverse{background-color:#333333;} +.label-inverse:hover{background-color:#1a1a1a;} +.badge{padding:1px 9px 2px;font-size:12.025px;font-weight:bold;white-space:nowrap;color:#ffffff;background-color:#999999;-webkit-border-radius:9px;-moz-border-radius:9px;border-radius:9px;} +.badge:hover{color:#ffffff;text-decoration:none;cursor:pointer;} +.badge-error{background-color:#b94a48;} +.badge-error:hover{background-color:#953b39;} +.badge-warning{background-color:#f89406;} +.badge-warning:hover{background-color:#c67605;} +.badge-success{background-color:#468847;} +.badge-success:hover{background-color:#356635;} +.badge-info{background-color:#3a87ad;} +.badge-info:hover{background-color:#2d6987;} +.badge-inverse{background-color:#333333;} +.badge-inverse:hover{background-color:#1a1a1a;} +@-webkit-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}.progress{overflow:hidden;height:18px;margin-bottom:18px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-ms-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(top, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f5f5f5', endColorstr='#f9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.progress .bar{width:0%;height:18px;color:#ffffff;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-ms-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(top, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#149bdf', endColorstr='#0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-ms-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} +.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;} +.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;} +.progress-danger .bar{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-ms-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(top, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ee5f5b', endColorstr='#c43c35', GradientType=0);} +.progress-danger.progress-striped .bar{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-success .bar{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-ms-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(top, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#62c462', endColorstr='#57a957', GradientType=0);} +.progress-success.progress-striped .bar{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-info .bar{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-ms-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(top, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#5bc0de', endColorstr='#339bb9', GradientType=0);} +.progress-info.progress-striped .bar{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-warning .bar{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-ms-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(top, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89406', GradientType=0);} +.progress-warning.progress-striped .bar{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-ms-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(-45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.accordion{margin-bottom:18px;} +.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion-heading{border-bottom:0;} +.accordion-heading .accordion-toggle{display:block;padding:8px 15px;} +.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;} +.carousel{position:relative;margin-bottom:18px;line-height:1;} +.carousel-inner{overflow:hidden;width:100%;position:relative;} +.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-ms-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;} +.carousel .item>img{display:block;line-height:1;} +.carousel .active,.carousel .next,.carousel .prev{display:block;} +.carousel .active{left:0;} +.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;} +.carousel .next{left:100%;} +.carousel .prev{left:-100%;} +.carousel .next.left,.carousel .prev.right{left:0;} +.carousel .active.left{left:-100%;} +.carousel .active.right{left:100%;} +.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;} +.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);} +.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:10px 15px 5px;background:#333333;background:rgba(0, 0, 0, 0.75);} +.carousel-caption h4,.carousel-caption p{color:#ffffff;} +.hero-unit{padding:60px;margin-bottom:30px;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;} +.hero-unit p{font-size:18px;font-weight:200;line-height:27px;color:inherit;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.invisible{visibility:hidden;} diff --git a/doc/resources/ace/skeleton/csses/prettify.css b/doc/resources/ace/skeleton/csses/prettify.css new file mode 100644 index 00000000..2cd13649 --- /dev/null +++ b/doc/resources/ace/skeleton/csses/prettify.css @@ -0,0 +1,52 @@ +/* Pretty printing styles. Used with prettify.js. */ + +/* SPAN elements with the classes below are added by prettyprint. */ +.pln { color: #000 } /* plain text */ + +@media screen { + .str { color: #2e6a40 } /* string content */ + .kwd { color: #214afc } /* a keyword */ + .com { color: #4c886b } /* a comment */ + .typ { color: #1130ad } /* a type name */ + .lit { color: #1130ad } /* a literal value */ + /* punctuation, lisp open bracket, lisp close bracket */ + .pun, .opn, .clo { color: #2d0603 } + .tag { color: #008 } /* a markup tag name */ + .atn { color: #606 } /* a markup attribute name */ + .atv { color: #080 } /* a markup attribute value */ + .dec, .var { color: #606 } /* a declaration; a variable name */ + .fun { color: #1130ad } /* a function name */ +} + +/* Use higher contrast and text-weight for printable form. */ +@media print, projection { + .str { color: #060 } + .kwd { color: #006; font-weight: bold } + .com { color: #600; font-style: italic } + .typ { color: #404; font-weight: bold } + .lit { color: #044 } + .pun, .opn, .clo { color: #440 } + .tag { color: #006; font-weight: bold } + .atn { color: #404 } + .atv { color: #060 } +} + +/* Put a border around prettyprinted code snippets. */ +/*pre.prettyprint { padding: 2px; }*/ + +/* Specify class=linenums on a pre to get line numbering */ +ol.linenums { margin-top: 0; margin-bottom: 0 } /* IE indents via margin-left */` +li.L0, +li.L1, +li.L2, +li.L3, +li.L5, +li.L6, +li.L7, +li.L8 { list-style-type: none } +/* Alternate shading for lines */ +li.L1, +li.L3, +li.L5, +li.L7, +li.L9 { background: #eee } diff --git a/doc/resources/ace/skeleton/images/Ace_ERD.svg b/doc/resources/ace/skeleton/images/Ace_ERD.svg new file mode 100644 index 00000000..ba386287 --- /dev/null +++ b/doc/resources/ace/skeleton/images/Ace_ERD.svg @@ -0,0 +1,4 @@ + + + + diff --git a/doc/resources/ace/skeleton/images/ace_logo.png b/doc/resources/ace/skeleton/images/ace_logo.png new file mode 100644 index 00000000..4dab4f66 Binary files /dev/null and b/doc/resources/ace/skeleton/images/ace_logo.png differ diff --git a/doc/resources/ace/skeleton/images/ace_logo_menu.png b/doc/resources/ace/skeleton/images/ace_logo_menu.png new file mode 100644 index 00000000..b011fadd Binary files /dev/null and b/doc/resources/ace/skeleton/images/ace_logo_menu.png differ diff --git a/doc/resources/ace/skeleton/images/c9-log-footer.png b/doc/resources/ace/skeleton/images/c9-log-footer.png new file mode 100644 index 00000000..f3bcb4d7 Binary files /dev/null and b/doc/resources/ace/skeleton/images/c9-log-footer.png differ diff --git a/doc/resources/ace/skeleton/images/c9-sponsor.png b/doc/resources/ace/skeleton/images/c9-sponsor.png new file mode 100644 index 00000000..599d3b49 Binary files /dev/null and b/doc/resources/ace/skeleton/images/c9-sponsor.png differ diff --git a/doc/resources/ace/skeleton/images/cloud9-logo.png b/doc/resources/ace/skeleton/images/cloud9-logo.png new file mode 100644 index 00000000..912524a9 Binary files /dev/null and b/doc/resources/ace/skeleton/images/cloud9-logo.png differ diff --git a/doc/resources/ace/skeleton/images/content-top.png b/doc/resources/ace/skeleton/images/content-top.png new file mode 100644 index 00000000..ec4ccad0 Binary files /dev/null and b/doc/resources/ace/skeleton/images/content-top.png differ diff --git a/doc/resources/ace/skeleton/images/content_bg.png b/doc/resources/ace/skeleton/images/content_bg.png new file mode 100644 index 00000000..928f81e4 Binary files /dev/null and b/doc/resources/ace/skeleton/images/content_bg.png differ diff --git a/doc/resources/ace/skeleton/images/content_top_bg.png b/doc/resources/ace/skeleton/images/content_top_bg.png new file mode 100644 index 00000000..42039338 Binary files /dev/null and b/doc/resources/ace/skeleton/images/content_top_bg.png differ diff --git a/doc/resources/ace/skeleton/images/dashed_back.png b/doc/resources/ace/skeleton/images/dashed_back.png new file mode 100644 index 00000000..c6ee9313 Binary files /dev/null and b/doc/resources/ace/skeleton/images/dashed_back.png differ diff --git a/doc/resources/ace/skeleton/images/favicon.ico b/doc/resources/ace/skeleton/images/favicon.ico new file mode 100644 index 00000000..e97c70f6 Binary files /dev/null and b/doc/resources/ace/skeleton/images/favicon.ico differ diff --git a/doc/resources/ace/skeleton/images/footer-bg.png b/doc/resources/ace/skeleton/images/footer-bg.png new file mode 100644 index 00000000..0d572c28 Binary files /dev/null and b/doc/resources/ace/skeleton/images/footer-bg.png differ diff --git a/doc/resources/ace/skeleton/images/main_bg.png b/doc/resources/ace/skeleton/images/main_bg.png new file mode 100644 index 00000000..f26aefc2 Binary files /dev/null and b/doc/resources/ace/skeleton/images/main_bg.png differ diff --git a/doc/resources/ace/skeleton/images/member-sprites.png b/doc/resources/ace/skeleton/images/member-sprites.png new file mode 100644 index 00000000..96b0520f Binary files /dev/null and b/doc/resources/ace/skeleton/images/member-sprites.png differ diff --git a/doc/resources/ace/skeleton/images/menu_disc.png b/doc/resources/ace/skeleton/images/menu_disc.png new file mode 100644 index 00000000..1d3925b3 Binary files /dev/null and b/doc/resources/ace/skeleton/images/menu_disc.png differ diff --git a/doc/resources/ace/skeleton/images/method_bg.png b/doc/resources/ace/skeleton/images/method_bg.png new file mode 100644 index 00000000..b0189557 Binary files /dev/null and b/doc/resources/ace/skeleton/images/method_bg.png differ diff --git a/doc/resources/ace/skeleton/images/scrolled-heading-shadow.png b/doc/resources/ace/skeleton/images/scrolled-heading-shadow.png new file mode 100644 index 00000000..aed814ee Binary files /dev/null and b/doc/resources/ace/skeleton/images/scrolled-heading-shadow.png differ diff --git a/doc/resources/ace/skeleton/images/sidebar-top-bg.png b/doc/resources/ace/skeleton/images/sidebar-top-bg.png new file mode 100644 index 00000000..c0a800e1 Binary files /dev/null and b/doc/resources/ace/skeleton/images/sidebar-top-bg.png differ diff --git a/doc/resources/ace/skeleton/images/sidebar_border.png b/doc/resources/ace/skeleton/images/sidebar_border.png new file mode 100644 index 00000000..ea6cd700 Binary files /dev/null and b/doc/resources/ace/skeleton/images/sidebar_border.png differ diff --git a/doc/resources/ace/skeleton/images/swirl_divider.png b/doc/resources/ace/skeleton/images/swirl_divider.png new file mode 100644 index 00000000..f3e9f6c6 Binary files /dev/null and b/doc/resources/ace/skeleton/images/swirl_divider.png differ diff --git a/doc/resources/ace/skeleton/javascripts/bootstrap-dropdown.js b/doc/resources/ace/skeleton/javascripts/bootstrap-dropdown.js new file mode 100644 index 00000000..54b61c5e --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/bootstrap-dropdown.js @@ -0,0 +1,92 @@ +/* ============================================================ + * bootstrap-dropdown.js v2.0.2 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function( $ ){ + + "use strict" + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle="dropdown"]' + , Dropdown = function ( element ) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function ( e ) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + , isActive + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + $parent.length || ($parent = $this.parent()) + + isActive = $parent.hasClass('open') + + clearMenus() + !isActive && $parent.toggleClass('open') + + return false + } + + } + + function clearMenus() { + $(toggle).parent().removeClass('open') + } + + + /* DROPDOWN PLUGIN DEFINITION + * ========================== */ + + $.fn.dropdown = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('dropdown') + if (!data) $this.data('dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.dropdown.Constructor = Dropdown + + + /* APPLY TO STANDARD DROPDOWN ELEMENTS + * =================================== */ + + $(function () { + $('html').on('click.dropdown.data-api', clearMenus) + $('body').on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) + }) + +}( window.jQuery ); \ No newline at end of file diff --git a/doc/resources/ace/skeleton/javascripts/clicker.js b/doc/resources/ace/skeleton/javascripts/clicker.js new file mode 100644 index 00000000..5fe3dca2 --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/clicker.js @@ -0,0 +1,35 @@ +$(function() { + // when hovering over arrow, add highlight (only if inactive) + $("h3.methodToggle").hover(function () { + if (!$("h3.methodToggle").hasClass('active')) + $(this).addClass("methodToggleHover"); + }, + function () { + $(this).removeClass("methodToggleHover"); + } + ); + + // after expanding the hidden description, hide the ellipsis + $('.signature-call, .signature-returns', '.signature').click(function() { + var $article = $(this).closest('.article'), + $arrow = $('h3.methodClicker', $article); + + if (!$article.hasClass('methodToggleOpen') || this.force) { + $article.addClass('methodToggleOpen'); + $arrow.removeClass('inactive').addClass('active'); + + var data = location.hash = $arrow[0].id.replace(/^js_/, ""); + scrollTo(null, data); + } + else { + $article.removeClass('methodToggleOpen'); + $arrow.removeClass('active').addClass('inactive'); + } + + }); + + $('.related-to', '.metaInfo').click(function(){ + location.hash = $(this).find('a').attr('href').split('#')[1]; + }); +}); + diff --git a/doc/resources/ace/skeleton/javascripts/disqus-ext.js b/doc/resources/ace/skeleton/javascripts/disqus-ext.js new file mode 100644 index 00000000..6f966cc6 --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/disqus-ext.js @@ -0,0 +1,12 @@ +var disqus_shortname = 'aceapi'; + +var paths = window.location.pathname.split("/"); +var fileName = paths[paths.length - 2] + "/" + paths[paths.length - 1]; + +var disqus_identifier = fileName; + + (function() { + var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true; + dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js'; + (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq); + })(); \ No newline at end of file diff --git a/doc/resources/ace/skeleton/javascripts/ga.js b/doc/resources/ace/skeleton/javascripts/ga.js new file mode 100644 index 00000000..f0035835 --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/ga.js @@ -0,0 +1,9 @@ + var _gaq = _gaq || []; + _gaq.push(['_setAccount', 'UA-18736001-1']); + _gaq.push(['_trackPageview']); + + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; + ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); + })(); \ No newline at end of file diff --git a/doc/resources/ace/skeleton/javascripts/jquery-scrollspy.js b/doc/resources/ace/skeleton/javascripts/jquery-scrollspy.js new file mode 100644 index 00000000..71b4a363 --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/jquery-scrollspy.js @@ -0,0 +1,98 @@ +/*! + * jQuery Scrollspy Plugin + * Author: @sxalexander + * Licensed under the MIT license + */ + + +;(function ( $, window, document, undefined ) { + + $.fn.extend({ + scrollspy: function ( options ) { + + var defaults = { + min: 0, + max: 0, + mode: 'vertical', + buffer: 0, + container: window, + onEnter: options.onEnter ? options.onEnter : [], + onLeave: options.onLeave ? options.onLeave : [], + onTick: options.onTick ? options.onTick : [] + } + + var options = $.extend( {}, defaults, options ); + + return this.each(function (i) { + + var element = this; + var o = options; + var $container = $(o.container); + var mode = o.mode; + var buffer = o.buffer; + var enters = leaves = 0; + var inside = false; + + /* add listener to container */ + $container.bind('scroll', function(e){ + var position = {top: $(this).scrollTop(), left: $(this).scrollLeft()}; + var xy = (mode == 'vertical') ? position.top + buffer : position.left + buffer; + var max = o.max; + var min = o.min; + + /* fix max */ + if($.isFunction(o.max)){ + max = o.max(); + } + + /* fix max */ + if($.isFunction(o.min)){ + min = o.min(); + } + + if(max == 0){ + max = (mode == 'vertical') ? $container.height() : $container.outerWidth() + $(element).outerWidth(); + } + + /* if we have reached the minimum bound but are below the max ... */ + if(xy >= o.min && xy <= max){ + /* trigger enter event */ + if(!inside){ + inside = true; + enters++; + + /* fire enter event */ + $(element).trigger('scrollEnter', {position: position}) + if($.isFunction(o.onEnter)){ + o.onEnter(element, position); + } + + } + + /* triger tick event */ + $(element).trigger('scrollTick', {position: position, inside: inside, enters: enters, leaves: leaves}) + if($.isFunction(o.onTick)){ + o.onTick(element, position, inside, enters, leaves); + } + }else{ + + if(inside){ + inside = false; + leaves++; + /* trigger leave event */ + $(element).trigger('scrollLeave', {position: position, leaves:leaves}) + + if($.isFunction(o.onLeave)){ + o.onLeave(element, position); + } + } + } + }); + + }); + } + + }) + + +})( jQuery, window ); diff --git a/doc/resources/ace/skeleton/javascripts/jquery.collapse.js b/doc/resources/ace/skeleton/javascripts/jquery.collapse.js new file mode 100644 index 00000000..427ee5fa --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/jquery.collapse.js @@ -0,0 +1,151 @@ +/*! + * Collapse plugin for jQuery + * http://github.com/danielstocks/jQuery-Collapse/ + * + * @author Daniel Stocks (http://webcloud.se) + * @version 0.9.1 + * @updated 17-AUG-2010 + * + * Copyright 2010, Daniel Stocks + * Released under the MIT, BSD, and GPL Licenses. + */ + +(function($) { + + // Use a cookie counter to allow multiple instances of the plugin + var cookieCounter = 0; + + $.fn.extend({ + collapse: function(options) { + + var defaults = { + head : "h3", + group : "div, ul", + cookieName : "collapse", + // Default function for showing content + show: function() { + this.show(); + }, + // Default function for hiding content + hide: function() { + this.hide(); + } + }; + var op = $.extend(defaults, options); + + // Default CSS classes + var active = "active", + inactive = "inactive"; + + return this.each(function() { + + // Increment coookie counter to ensure cookie name integrity + cookieCounter++; + var obj = $(this), + // Find all headers and wrap them in for accessibility. + sections = obj.find(op.head).wrapInner(''), + l = sections.length, + cookie = op.cookieName + "_" + cookieCounter; + // Locate all panels directly following a header + var panel = obj.find(op.head).map(function() { + var head = $(this) + if(!head.hasClass(active)) { + return head.next(op.group).hide()[0]; + } + return head.next(op.group)[0]; + }); + + // Bind event for showing content + obj.bind("show", function(e, bypass) { + var obj = $(e.target); + // ARIA attribute + obj.attr('aria-hidden', false) + .prev() + .removeClass(inactive) + .addClass(active); + // Bypass method for instant display + if(bypass) { + obj.show(); + } else { + op.show.call(obj); + } + }); + + // Bind event for hiding content + obj.bind("hide", function(e, bypass) { + var obj = $(e.target); + obj.attr('aria-hidden', true) + .prev() + .removeClass(active) + .addClass(inactive); + if(bypass) { + obj.hide(); + } else { + op.hide.call(obj); + } + }); + + // Look for existing cookies + if(cookieSupport) { + for (var c=0;c<=l;c++) { + var val = $.cookie(cookie + c); + // Show content if associating cookie is found + if ( val == c + "open" ) { + panel.eq(c).trigger('show', [true]); + // Hide content + } else if ( val == c + "closed") { + panel.eq(c).trigger('hide', [true]); + } + } + } + + // Delegate click event to show/hide content. + obj.bind("click", function(e) { + var t = $(e.target); + // Check if header was clicked + if(!t.is(op.head)) { + // What about link inside header. + if ( t.parent().is(op.head) ) { + t = t.parent(); + } else { + return; + } + e.preventDefault(); + } + // Figure out what position the clicked header has. + var num = sections.index(t), + cookieName = cookie + num, + cookieVal = num, + content = t.next(op.group); + // If content is already active, hide it. + if(t.hasClass(active)) { + content.trigger('hide'); + cookieVal += 'closed'; + if(cookieSupport) { + $.cookie(cookieName, cookieVal, { path: '/', expires: 10 }); + } + return; + } + // Otherwise show it. + content.trigger('show'); + cookieVal += 'open'; + if(cookieSupport) { + $.cookie(cookieName, cookieVal, { path: '/', expires: 10 }); + } + }); + }); + } + }); + + // Make sure can we eat cookies without getting into trouble. + var cookieSupport = (function() { + try { + $.cookie('x', 'x', { path: '/', expires: 10 }); + $.cookie('x', null); + } + catch(e) { + return false; + } + return true; + })(); +})(jQuery); \ No newline at end of file diff --git a/doc/resources/ace/skeleton/javascripts/jquery.cookie.js b/doc/resources/ace/skeleton/javascripts/jquery.cookie.js new file mode 100644 index 00000000..6df1faca --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/jquery.cookie.js @@ -0,0 +1,96 @@ +/** + * Cookie plugin + * + * Copyright (c) 2006 Klaus Hartl (stilbuero.de) + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + */ + +/** + * Create a cookie with the given name and value and other optional parameters. + * + * @example $.cookie('the_cookie', 'the_value'); + * @desc Set the value of a cookie. + * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true }); + * @desc Create a cookie with all available options. + * @example $.cookie('the_cookie', 'the_value'); + * @desc Create a session cookie. + * @example $.cookie('the_cookie', null); + * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain + * used when the cookie was set. + * + * @param String name The name of the cookie. + * @param String value The value of the cookie. + * @param Object options An object literal containing key/value pairs to provide optional cookie attributes. + * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object. + * If a negative value is specified (e.g. a date in the past), the cookie will be deleted. + * If set to null or omitted, the cookie will be a session cookie and will not be retained + * when the the browser exits. + * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie). + * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie). + * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will + * require a secure protocol (like HTTPS). + * @type undefined + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ + +/** + * Get the value of a cookie with the given name. + * + * @example $.cookie('the_cookie'); + * @desc Get the value of a cookie. + * + * @param String name The name of the cookie. + * @return The value of the cookie. + * @type String + * + * @name $.cookie + * @cat Plugins/Cookie + * @author Klaus Hartl/klaus.hartl@stilbuero.de + */ +jQuery.cookie = function(name, value, options) { + if (typeof value != 'undefined') { // name and value given, set cookie + options = options || {}; + if (value === null) { + value = ''; + options.expires = -1; + } + var expires = ''; + if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) { + var date; + if (typeof options.expires == 'number') { + date = new Date(); + date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000)); + } else { + date = options.expires; + } + expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE + } + // CAUTION: Needed to parenthesize options.path and options.domain + // in the following expressions, otherwise they evaluate to undefined + // in the packed version for some reason... + var path = options.path ? '; path=' + (options.path) : ''; + var domain = options.domain ? '; domain=' + (options.domain) : ''; + var secure = options.secure ? '; secure' : ''; + document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''); + } else { // only name given, get cookie + var cookieValue = null; + if (document.cookie && document.cookie != '') { + var cookies = document.cookie.split(';'); + for (var i = 0; i < cookies.length; i++) { + var cookie = jQuery.trim(cookies[i]); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) == (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } +}; \ No newline at end of file diff --git a/doc/resources/ace/skeleton/javascripts/jquery.js b/doc/resources/ace/skeleton/javascripts/jquery.js new file mode 100644 index 00000000..3ca5e0f5 --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/jquery.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7 jquery.com | jquery.org/license */ +(function(a,b){function cA(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cx(a){if(!cm[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cn||(cn=c.createElement("iframe"),cn.frameBorder=cn.width=cn.height=0),b.appendChild(cn);if(!co||!cn.createElement)co=(cn.contentWindow||cn.contentDocument).document,co.write((c.compatMode==="CSS1Compat"?"":"")+""),co.close();d=co.createElement(a),co.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cn)}cm[a]=e}return cm[a]}function cw(a,b){var c={};f.each(cs.concat.apply([],cs.slice(0,b)),function(){c[this]=a});return c}function cv(){ct=b}function cu(){setTimeout(cv,0);return ct=f.now()}function cl(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ck(){try{return new a.XMLHttpRequest}catch(b){}}function ce(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bB(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function br(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bi,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bq(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bp(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bp)}function bp(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bo(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bn(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bm(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(){return!0}function M(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z]|[0-9])/ig,x=/^-ms-/,y=function(a,b){return(b+"").toUpperCase()},z=d.userAgent,A,B,C,D=Object.prototype.toString,E=Object.prototype.hasOwnProperty,F=Array.prototype.push,G=Array.prototype.slice,H=String.prototype.trim,I=Array.prototype.indexOf,J={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7",length:0,size:function(){return this.length},toArray:function(){return G.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?F.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),B.add(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(G.apply(this,arguments),"slice",G.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:F,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;B.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!B){B=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",C,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",C),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&K()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return a!=null&&m.test(a)&&!isNaN(a)},type:function(a){return a==null?String(a):J[D.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!E.call(a,"constructor")&&!E.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||E.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(x,"ms-").replace(w,y)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
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="
"+""+"
";m=c.getElementsByTagName("body")[0];!m||(a=c.createElement("div"),a.style.cssText=l+"width:0;height:0;position:static;top:0;margin-top:"+i+"px",m.insertBefore(a,m.firstChild),o=c.createElement("div"),o.style.cssText=j+l,o.innerHTML=p,a.appendChild(o),b=o.firstChild,d=b.firstChild,g=b.nextSibling.firstChild.firstChild,h={doesNotAddBorder:d.offsetTop!==5,doesAddBorderForTableAndCells:g.offsetTop===5},d.style.position="fixed",d.style.top="20px",h.fixedPosition=d.offsetTop===20||d.offsetTop===15,d.style.position=d.style.top="",b.style.overflow="hidden",b.style.position="relative",h.subtractsBorderForOverflowNotVisible=d.offsetTop===-5,h.doesNotIncludeMarginInBodyOffset=m.offsetTop!==i,m.removeChild(a),o=a=null,f.extend(k,h))}),o.innerHTML="",n.removeChild(o),o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[f.expando]:a[f.expando]&&f.expando,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[f.expando]=n=++f.uuid:n=f.expando),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[f.expando]:f.expando;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)?b=b:b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" "));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];if(!arguments.length){if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}return b}e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!a||j===3||j===8||j===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g},removeAttr:function(a,b){var c,d,e,g,h=0;if(a.nodeType===1){d=(b||"").split(p),g=d.length;for(;h=0}})});var z=/\.(.*)$/,A=/^(?:textarea|input|select)$/i,B=/\./g,C=/ /g,D=/[^\w\s.|`]/g,E=/^([^\.]*)?(?:\.(.+))?$/,F=/\bhover(\.\S+)?/,G=/^key/,H=/^(?:mouse|contextmenu)|click/,I=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,J=function(a){var b=I.exec(a);b&& +(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},K=function(a,b){return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||a.id===b[2])&&(!b[3]||b[3].test(a.className))},L=function(a){return f.event.special.hover?a:a.replace(F,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=L(c).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"",(g||!e)&&c.preventDefault();if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,n=null;for(m=e.parentNode;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l=0:t===b&&(t=o[s]=r.quick?K(m,r.quick):f(m).is(s)),t&&q.push(r);q.length&&j.push({elem:m,matches:q})}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),G.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),H.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y="abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",Z=/ jQuery\d+="(?:\d+|null)"/g,$=/^\s+/,_=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,ba=/<([\w:]+)/,bb=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bk=X(c);bj.optgroup=bj.option,bj.tbody=bj.tfoot=bj.colgroup=bj.caption=bj.thead,bj.th=bj.td,f.support.htmlSerialize||(bj._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after" +,arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Z,""):null;if(typeof a=="string"&&!bd.test(a)&&(f.support.leadingWhitespace||!$.test(a))&&!bj[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(_,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bn(a,d),e=bo(a),g=bo(d);for(h=0;e[h];++h)g[h]&&bn(e[h],g[h])}if(b){bm(a,d);if(c){e=bo(a),g=bo(d);for(h=0;e[h];++h)bm(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bc.test(k))k=b.createTextNode(k);else{k=k.replace(_,"<$1>");var l=(ba.exec(k)||["",""])[1].toLowerCase(),m=bj[l]||bj._default,n=m[0],o=b.createElement("div");b===c?bk.appendChild(o):X(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=bb.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&$.test(k)&&o.insertBefore(b.createTextNode($.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bt.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bs,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bs.test(g)?g.replace(bs,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bB(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bC=function(a,c){var d,e,g;c=c.replace(bu,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bD=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bv.test(f)&&bw.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bB=bC||bD,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bF=/%20/g,bG=/\[\]$/,bH=/\r?\n/g,bI=/#.*$/,bJ=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bK=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bL=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bM=/^(?:GET|HEAD)$/,bN=/^\/\//,bO=/\?/,bP=/)<[^<]*)*<\/script>/gi,bQ=/^(?:select|textarea)/i,bR=/\s+/,bS=/([?&])_=[^&]*/,bT=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bU=f.fn.load,bV={},bW={},bX,bY,bZ=["*/"]+["*"];try{bX=e.href}catch(b$){bX=c.createElement("a"),bX.href="",bX=bX.href}bY=bT.exec(bX.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bU)return bU.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bP,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bQ.test(this.nodeName)||bK.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bH,"\r\n")}}):{name:b.name,value:c.replace(bH,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?cb(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),cb(a,b);return a},ajaxSettings:{url:bX,isLocal:bL.test(bY[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bZ},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:b_(bV),ajaxTransport:b_(bW),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cd(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=ce(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bJ.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bI,"").replace(bN,bY[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bR),d.crossDomain==null&&(r=bT.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bY[1]&&r[2]==bY[2]&&(r[3]||(r[1]==="http:"?80:443))==(bY[3]||(bY[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),ca(bV,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bM.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bO.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bS,"$1_="+x);d.url=y+(y===d.url?(bO.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bZ+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=ca(bW,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){s<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)cc(g,a[g],c,e);return d.join("&").replace(bF,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cf=f.now(),cg=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cf++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cg.test(b.url)||e&&cg.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cg,l),b.url===j&&(e&&(k=k.replace(cg,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ch=a.ActiveXObject?function(){for(var a in cj)cj[a](0,1)}:!1,ci=0,cj;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ck()||cl()}:ck,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ch&&delete cj[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++ci,ch&&(cj||(cj={},f(a).unload(ch)),cj[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cm={},cn,co,cp=/^(?:toggle|show|hide)$/,cq=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cr,cs=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],ct;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cw("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cz.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cz.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cA(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cA(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file diff --git a/doc/resources/ace/skeleton/javascripts/plugins.js b/doc/resources/ace/skeleton/javascripts/plugins.js new file mode 100644 index 00000000..efda459c --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/plugins.js @@ -0,0 +1,13 @@ +window.log=function(){log.history=log.history||[];log.history.push(arguments);if(this.console){arguments.callee=arguments.callee.caller;var a=[].slice.call(arguments);(typeof console.log==="object"?log.apply.call(console.log,console,a):console.log.apply(console,a))}}; +(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try +{console.log();return window.console;}catch(err){return window.console={};}})()); + +/* + * jQuery throttle / debounce - v1.1 - 3/7/2010 + * http://benalman.com/projects/jquery-throttle-debounce-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this); diff --git a/doc/resources/ace/skeleton/javascripts/prettify-extension.js b/doc/resources/ace/skeleton/javascripts/prettify-extension.js new file mode 100644 index 00000000..ca8458dc --- /dev/null +++ b/doc/resources/ace/skeleton/javascripts/prettify-extension.js @@ -0,0 +1,24 @@ +// Stolen from StackOverflow. Find all
 
+// elements on the page and add the "prettyprint" style. If at least one 
+// prettyprint element was found, call the Google Prettify prettyPrint() API.
+//http://sstatic.net/so/js/master.js?v=6523
+function styleCode() 
+{
+    if (typeof disableStyleCode != "undefined") 
+    {
+        return;
+    }
+
+    var a = false;
+
+    $("pre code").parent().each(function() 
+    {
+        if (!$(this).hasClass("prettyprint")) 
+        {
+            $(this).addClass("prettyprint");
+            a = true
+        }
+    });
+    
+    if (a) { prettyPrint() } 
+}
\ No newline at end of file
diff --git a/doc/resources/ace/skeleton/javascripts/prettify.js b/doc/resources/ace/skeleton/javascripts/prettify.js
new file mode 100644
index 00000000..eef5ad7e
--- /dev/null
+++ b/doc/resources/ace/skeleton/javascripts/prettify.js
@@ -0,0 +1,28 @@
+var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
+(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
+[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
+l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
+q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
+q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
+"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
+a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
+for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
+"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
+H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
+J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
+I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
+["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
+/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
+["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
+hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b=
+!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p= 0) $('li#node_js_ref').addClass("active");
+    else if (pathName.indexOf("nodejs_dev_guide") >= 0) $('li#nodejs_dev_guide').addClass("active");
+    else if (pathName.indexOf("js_doc") >= 0) $('li#js_doc').addClass("active");
+
+    function loadCallback(evt) {
+        var form = document.getElementById("searchbox");
+        var input = form.query;
+        form.onsubmit = function (evt) {
+            var query = input.value;
+            if (query) {
+                input.value = "";
+                input.blur();
+                var currentVersion = $('#currentVersion').text();
+                var url = "https://www.google.com/search?q=" + encodeURIComponent("site:ace.ajax.org/api" + " " + query);
+                window.open(url);
+            }
+            return false;
+        };
+    }
+
+    var fileNameRE = new RegExp("^" + fileName, "i");
+
+    $('a.menuLink').each(function (index) {
+        if ($(this).attr("href").match(fileNameRE)) {
+            $(this).addClass("currentItem");
+            return false;
+        }
+    });
+
+    // init search
+    $('#search')
+    // prevent from form submit
+    .on('submit', function () {
+        return false;
+    }).find('input');
+
+    // init prettyprint
+    $('pre > code').addClass('prettyprint');
+    prettyPrint();
+    
+});
+
+$(document).ready(function () {
+    var d = 'a.menu, .dropdown-toggle'
+
+    function clearMenus() {
+        $(d).parent('li').each(function () {
+            $(this).removeClass('open')
+        });
+    }
+
+    var s, sx;
+
+    // scrolling offset calculation via www.quirksmode.org
+    if (window.pageYOffset || window.pageXOffset) {
+        s = window.pageYOffset;
+        sx = window.pageXOffset;
+    }
+    else if (document.documentElement && (document.documentElement.scrollTop || document.documentElement.scrollLeft)) {
+        s = document.documentElement.scrollTop;
+        sx = document.documentElement.scrollLeft;
+    }
+    else if (document.body) {
+        s = document.body.scrollTop;
+        sx = document.body.scrollLeft;
+    }
+
+    if (document.documentElement.offsetWidth < 1010) {
+        if (sx <= 0) sx = 0;
+        else if (sx + document.documentElement.offsetWidth > 1010) sx = 1010 - document.documentElement.offsetWidth;
+    }
+    else sx = 0;
+
+    $('.members').each(function (i) {
+        var position = $(this).position();
+        var $classContent = $(this).closest('.classContent');
+        
+        $(this).scrollspy({
+            min: $classContent.position().top - 35,
+            max: $classContent.position().top + $classContent.height(),
+            onEnter: function (element, position) {
+                var $pagination = $(element);
+                var $paginationContent = $('.membersContent pos' + i);
+                var $tabs = $('.tabs pos' + i);
+
+                $paginationContent.css('left', -1 * sx);
+                $paginationContent.css('top', 0);
+
+                $pagination.addClass('shadow').stop().css({
+                    height: 31,
+                    'top': 33
+                }).closest('.classContent').addClass('srolled');
+
+                $tabs.addClass('tabsSansBorder');
+            },
+            onLeave: function (element, position) {
+                var $pagination = $(element);
+                var $paginationContent = $('.membersContent pos' + i);
+                var $tabs = $('.tabs pos' + i);
+
+                $paginationContent.stop().css({
+                    top: 11
+                }); 
+                $pagination.css({
+                    'position': 'absolute',
+                    'top': 193
+                });
+                $pagination.stop().removeClass('shadow').css({
+                    height: 42
+                });
+
+                $paginationContent.css('left', 0);
+               // setTimeout(function () {
+                    $paginationContent.css({
+                        'top': ''
+                    });
+                    $pagination.css({
+                        'position': '',
+                        'top': ''
+                    });
+                    $paginationContent.css('left', 0);
+                    $pagination.closest('.classContent').removeClass('srolled')
+                    $tabs.removeClass('tabsSansBorder');
+               // }, 300);
+            }
+        });
+    });
+    
+    $('span.methodClicker, article.article, h3.methodClicker').each(function () {
+        var a = $(this);
+        var constructorPos = a.attr("id").indexOf("new ");
+
+        var objName = a.attr("id");
+        if (constructorPos >= 0) {
+            objName = objName.substring(constructorPos + 4);
+            objName += ".new";
+        }
+
+        a.attr("id", objName);
+    });
+
+    $('.brand').parent('.dropdown').hover(
+
+    function () {
+        $(this).addClass('open');
+    }, function () {
+        clearMenus();
+    });
+
+    $('.versions').hover(
+
+    function () {
+        $(this).addClass('open');
+    }, function () {
+        clearMenus();
+    });
+
+    function showMethodContent() {
+        if (!location.hash) return;
+
+        var $clickerEl = $('span#' + location.hash.replace(/^#/, '').replace(/\./g, '\\.'));
+        if ($clickerEl.length > 0 && $clickerEl.hasClass('methodClicker')) {
+            var p = $clickerEl.parent();
+            p[0].force = true;
+            p.trigger('click');
+            p[0].force = false;
+        }
+    }
+
+    if (location.hash) {
+        showMethodContent();
+        var data = location.hash;
+        scrollTo(null, data.substr(1));
+    }
+
+    window.onhashchange = function () {
+        showMethodContent();
+    }
+});
+
+function scrollTo(el, data) {
+    if (!data) {
+        data = el.getAttribute("data-id");
+        location.hash = data;
+    }
+    var el = $("span#" + data.replace(/\./g, "\\."))[0];
+    if (!el) return;
+
+    var article = $(el).closest('.article')[0];
+
+    var top = article.offsetTop - 100;
+
+    if (document.body.scrollTop > top || document.body.scrollTop != top && document.body.scrollTop + (window.innerHeight || document.documentElement.offsetHeight) < top + article.offsetHeight) {
+        $('body').animate({
+            scrollTop: top
+        }, {
+            duration: 200,
+            easing: "swing"
+        });
+    }
+}
\ No newline at end of file
diff --git a/doc/resources/ace/templates/ace_menu.jade b/doc/resources/ace/templates/ace_menu.jade
new file mode 100755
index 00000000..d325887c
--- /dev/null
+++ b/doc/resources/ace/templates/ace_menu.jade
@@ -0,0 +1,61 @@
+div#well
+
+   h3 Ace Reference
+
+   div.swirl_divider 
+
+   ul.menu
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="ace.html") Ace
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="anchor.html") Anchor
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="background_tokenizer.html") BackgroundTokenizer     
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="document.html") Document    
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="edit_session.html") EditSession                                                    
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="editor.html") Editor
+
+      //- probably not needing doc a(class="menuLink namespace", href="multi_select.html") MultiSelect
+
+      //- not actually doc'ed yet a(class="menuLink namespace", href="placeholder.html") PlaceHolder
+
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="range.html") Range
+
+      //- not actually doc'ed yet a(class="menuLink namespace", href="renderloop.html") RenderLoop
+
+                                     
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="scrollbar.html") Scrollbar
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="search.html") Search                     
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="selection.html") Selection   
+
+      //- not actually doc'ed yet  a(class="menuLink namespace", href="split.html") Split
+
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="token_iterator.html") TokenIterator
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="tokenizer.html") Tokenizer
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="undomanager.html") UndoManager
+      li
+         div.menu-item
+            a(class="menuLink namespace", href="virtual_renderer.html") VirtualRenderer
\ No newline at end of file
diff --git a/doc/resources/ace/templates/layout.jade b/doc/resources/ace/templates/layout.jade
new file mode 100644
index 00000000..43e99a48
--- /dev/null
+++ b/doc/resources/ace/templates/layout.jade
@@ -0,0 +1,40 @@
+include ../../common_layout
+include lib
+
+!!! 5
+
+
+
+  
+
+html(xmlns="http://www.w3.org/1999/xhtml")
+	head
+		mixin head
+	
+	body
+	
+		#nonFooter
+			#wrapper
+				mixin navBar
+			
+				header.filler
+			
+				
+				.container
+						.content
+							.row.centerpiece
+								.span3.offset6.sidebarContainer
+									#sidebar
+										include ace_menu.jade
+								.span9.mainContent
+									#documentation
+										-if (isIndex)
+											mixin markdown(indexContent)
+										-else
+											mixin api()
+			
+									div(id="disqus_thread")
+	
+		mixin footer
+	
+		mixin endingScripts
\ No newline at end of file
diff --git a/doc/resources/ace/templates/lib.jade b/doc/resources/ace/templates/lib.jade
new file mode 100644
index 00000000..ca9b277f
--- /dev/null
+++ b/doc/resources/ace/templates/lib.jade
@@ -0,0 +1,264 @@
+- var methodSection = constructorSection = propertySection = eventSection = false;
+		
+-function renameMemberTitle(title, count)
+	if title.indexOf("ethods") >= 0
+		span Functions (#{count})
+	else if title.indexOf("ropert") >= 0
+		span Properties (#{count})	 
+	else
+		span #{title} (#{count})
+
+mixin article(obj, parents)
+	if typeof obj === 'string'
+		obj = list[obj]
+
+	title = obj.id + (obj.type ? ' (' + obj.type + ')' : '')
+	article.article(id=obj.path, data-title=title)
+
+		if obj.type === 'section' || obj.type === 'namespace' || obj.type === 'class' || obj.type === 'mixin'
+
+			if obj.description
+				.section.description
+					.memberContent
+						mixin markdown(obj.description)
+
+			collection = obj.children.filter(function(x){return x.type === 'namespace'});
+			if collection.length
+				.section.namespaces
+					// 
+						h3 Namespaces
+						.memberContent
+							mixin short_description_list(collection)
+
+			collection = obj.children.filter(function(x){return x.type === 'mixin'});
+			if collection.length
+				.section.mixins
+					// 
+						h3 Mixins
+						.memberContent
+							mixin short_description_list(collection)
+
+			if obj.type === 'class'
+
+				if obj.superclass
+					.section.superclass
+						// h3 
+							Superclass
+							.memberContent
+								mixin link(obj.superclass)
+
+				if obj.subclasses.length
+					.section.subclasses
+						// h3 
+							Subclasses
+							.memberContent
+								mixin links(obj.subclasses)
+
+			if obj.included_mixins
+				.section.mixins
+					// h3 
+						Includes
+						.memberContent
+							mixin links(obj.included_mixins)
+
+			collection = obj.children.filter(function(x){return x.type === 'utility'})
+			if collection.length
+				.section.utilities
+					// h3 
+						Utilities
+						.memberContent
+							mixin links(collection)
+		
+		else
+
+			.section.method
+				.memberContent
+					if obj.signatures
+						div.title
+							ul.signatures
+								-var loops = 0;
+								for sig in obj.signatures
+									li.signature
+										ul
+											li.signature-call!= signature(obj, sig, ["methodClicker"])
+												if sig.returns
+													li.signature-returns
+														ul.argument-types
+															for ret in sig.returns
+																li.argument-type!= returnLink(obj, ret, [])
+										-if (loops == 0)
+											-loops = 1 // ensure that we only print ONE meta info UL per signature (some methods have multiple signatures)
+											ul.metaInfo
+													if obj.readonly
+														li
+															span.label.read-only Read-Only
+													if obj.chainable
+														li
+															span.label.chainable Chainable
+													if obj.internal
+														li
+															span.label.internal Internal
+													if obj.deprecated
+														li
+															span.label.deprecated
+																| Deprecated
+																if obj.deprecated.from
+																	|   (since #{obj.deprecated.from})
+																	if obj.deprecated.off
+																		|  and will be removed on #{obj.deprecated.off}
+													if obj.alias_of
+														li
+															span.label.alias.single
+																| Aliased as: 
+																!= link(obj.alias_of)
+													else if obj.aliases.length
+														li
+															span.label.alias.multiple
+																| Aliased as:
+																ul.alias
+																	for alias in obj.aliases
+																		li
+																			mixin link(alias)
+
+													if obj.related_to
+														li
+															span.label.related-to
+																| Related to 
+																mixin link(obj.related_to)	
+																	
+					div.sideToggler
+
+						if obj.ellipsis_description
+							div(id='ellipsis_#{obj.id}', class='ellipsis_description')
+								mixin markdown(obj.ellipsis_description)
+							div(id='short_#{obj.id}', class='short_description hiddenSpan')
+								mixin markdown(obj.short_description)
+
+						h3(id='#{obj.id}', class='methodToggle methodClicker inactive')
+							   
+						div.description
+
+							-description = obj.description.substring(obj.short_description.length) // cut the short_desc out
+							descArray = description.split("\n#### ")
+
+							if descArray[0].length && descArray[0] !== '' && descArray[0] !== '\n'
+								mixin markdown(descArray[0])
+
+							if obj.bound && ~obj.bound.indexOf('#')
+								p.note.methodized
+									| This method can be called either as an 
+									!= link(obj.bound, ['link-short'], 'instance method')
+									|	or as a generic method. If calling as generic, pass the instance in as the first argument.
+							else if obj.bound && !~obj.bound.indexOf('#')
+								p.note.functionalized
+									| This method can be called either as an instance method or as a 
+									!= link(obj.bound, ['link-short'], 'generic method')
+									|. If calling as generic, pass the instance in as the first argument.
+
+							if obj.arguments
+								h4 Arguments
+								!= argumentTable(obj.arguments, ["argument-list", "table", "table-striped", "table-bordered"])
+								
+							
+							if obj.retDesc
+								h4 Returns
+								!= returnTable(obj.retDesc, ["return-list", "table", "table-striped", "table-bordered"])   
+
+	//- children
+	for child in obj.children.filter(function(x){return x.type === 'section'})
+		mixin article(child, parents.concat(obj))
+	for child in obj.children.filter(function(x){return x.type === 'utility'})
+		mixin article(child, parents.concat(obj))
+
+	for child in obj.children.filter(function(x){return x.type === 'constructor'})
+		- if (!constructorSection)
+			- constructorSection = true
+			h3.sectionHeader Constructors
+		mixin article(child, parents.concat(obj))
+
+	for child in obj.children.filter(function(x){return x.type === 'namespace' || x.type === 'class' || x.type === 'mixin'})
+		mixin article(child, parents.concat(obj))
+
+	for child in obj.children.filter(function(x){return x.type === 'event'})
+		- if (!eventSection)
+			- eventSection = true
+			h3.sectionHeader Events
+		mixin article(child, parents.concat(obj), 'event')
+
+	for child in obj.children.filter(function(x){return x.type === 'class method'})
+		- if (!methodSection)
+			- methodSection = true
+			h3.sectionHeader Methods
+		mixin article(child, parents.concat(obj))
+
+	for child in obj.children.filter(function(x){return x.type === 'class property'})
+		- if (!propertySection)
+			- propertySection = true
+			h3.sectionHeader Properties
+		mixin article(child, parents.concat(obj))
+
+	for child in obj.children.filter(function(x){return x.type === 'instance method'})
+		mixin article(child, parents.concat(obj))
+	for child in obj.children.filter(function(x){return x.type === 'instance property'})
+		mixin article(child, parents.concat(obj))
+	for child in obj.children.filter(function(x){return x.type === 'constant'})
+		mixin article(child, parents.concat(obj))
+
+
+
+mixin api()
+	-pos = 0
+	for obj in tree.children
+		.classContent
+			.membersBackground
+			div(class=' members pos#{pos}')
+				div(class=' membersContent pos#{pos}')
+						h1.memberHeader
+							-var heading = obj.path
+							span.name #{heading}
+								span.editInC9
+									mixin formatGHHref(obj.fullPath, 'nodejs_ref_guide')
+						
+						-if (true || obj.filename.indexOf("index") < 0)
+							ul(class='nav tabs pos#{pos}', data-tabs='tabs')
+								for selector, title in {'Events': ['event', 'events'], 'Constructors': ['constructor', 'constructors'], 'Class methods': ['class method', 'class_methods'], 'Class properties': ['class property', 'class_properties'], 'Instance methods': ['instance method', 'instance_methods'], 'Instance properties': ['instance property', 'instance_properties'], 'Constants': ['constant', 'constants']}
+									members = obj.children.filter(function(x){return x.type === selector[0]})
+										li(class="dropdown", data-dropdown="dropdown")
+											if members.length
+												a(href="\#", class="dropdown-toggle", data-toggle="dropdown")
+													!= renameMemberTitle(title, members.length)
+													b.caret
+												ul.dropdown-menu
+													for m in members
+														li(data-id='#{m.id}', class='memberLink')
+															mixin link(m, [], true)
+			-pos++
+			mixin article(obj, [])
+
+
+mixin short_description_list(collection)
+	ul.method-details-list
+		for obj in collection
+			if typeof obj === 'string'
+				obj = list[obj]
+			li.method-description
+				h4
+					mixin link(obj)
+				if obj.short_description
+					mixin markdown(obj.short_description)
+
+mixin link(obj, classes, short)
+	l = link(obj, classes, short)
+	!= l
+
+mixin links(collection)
+	ul.method-list
+		for obj in collection
+			li
+				mixin link(obj)
+
+mixin formatGHHref(url, type)
+	url = url.substring(url.indexOf("ace/lib"))
+
+	-url = url.replace(/\/{2,}/g, "/").replace(/\//g,"%2F")
+	[edit]
\ No newline at end of file
diff --git a/doc/resources/common_layout.jade b/doc/resources/common_layout.jade
new file mode 100644
index 00000000..31a96eab
--- /dev/null
+++ b/doc/resources/common_layout.jade
@@ -0,0 +1,86 @@
+-var dirPrefix = "./";
+-var landingPage = 'false'
+-var versions = []
+
+mixin doctype
+	!!! 5
+
+	
+	
+	
+	  
+
+mixin head
+	meta(charset="utf-8")
+	//- N.B. http://blog.yjl.im/2011/01/bad-value-x-ua-compatible-for-attribute.html
+	meta(http-equiv="X-UA-Compatible", content="IE=edge,chrome=1")
+
+	-if (isIndex)
+		title #{title}
+	-else
+		title #{title} - #{fileName}
+
+	meta(name="generator", content="c9-doc-build")
+	meta(name="description", content="Ace API documentation for the online code editor.")
+	meta(name="author", content="Garen J. Torikian")
+
+	meta(name="viewport", content="width=device-width,initial-scale=1")
+
+	link(rel="stylesheet", href="#{dirPrefix}resources/csses/bootstrap.min.css")
+	link(rel="stylesheet", href="#{dirPrefix}resources/csses/prettify.css")
+	link(rel="stylesheet", href="#{dirPrefix}resources/csses/ace_api.css")
+
+	link(href="#{dirPrefix}resources/images/favicon.ico", rel="icon", type="image/x-icon")
+
+	script(src="#{dirPrefix}resources/javascripts/jquery.js")
+	script(src="#{dirPrefix}resources/javascripts/clicker.js")
+	script(src="#{dirPrefix}resources/javascripts/jquery.collapse.js")
+	script(src="#{dirPrefix}resources/javascripts/jquery.cookie.js")
+	script(src="#{dirPrefix}resources/javascripts/bootstrap-dropdown.js")
+	script(src="#{dirPrefix}resources/javascripts/jquery-scrollspy.js")
+	script(script src="#{dirPrefix}resources/javascripts/prettify-extension.js")
+
+mixin navBar
+	div.navbar.navbar-fixed-top
+		div.navbar-inner
+			div.container
+				span.brand
+
+				ul.nav.topLinks
+					li#ace_site
+						a(href='../index.html') Ace
+					li#ace_api.active
+						a(href='index.html') Ace API Reference
+				form(id='searchbox', action='', class='navbar-search pull-right')	
+					input(class='search-query span3', name='query', type='text', placeholder="Search the API", title="Search across all the documentation")
+
+mixin footer
+	footer#footer
+				.container
+					.footer-text.pull-right 
+						p
+							About Cloud9 | Ace & Cloud9 IDE are © Ajax.org 2012
+
+mixin endingScripts
+	// scripts concatenated and minified via ant build script
+	
+	
+	
+	
+	
+	
+	//-
+	// end scripts
+
+	//if lt IE 7
+		script(src="//ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js")
+		script
+			window.attachEvent('onload',function(){CFInstall.check({mode:'overlay'})})
+
+
+mixin identifyBuild(tree, type)
+		landingPage = 'true'
+		-dirPrefix = './'
+
+mixin markdown(text, inline)
+	!= markdown(text, inline)
\ No newline at end of file
diff --git a/doc/site/images/logo_half.png b/doc/site/images/logo_half.png
new file mode 100644
index 00000000..f99b0c4b
Binary files /dev/null and b/doc/site/images/logo_half.png differ
diff --git a/doc/site/style.css b/doc/site/style.css
index b452add7..c0a47fa5 100644
--- a/doc/site/style.css
+++ b/doc/site/style.css
@@ -51,12 +51,12 @@ PRE{
     padding : 10px;
 }
 
-#header {
-    height : 227px;
-    position:relative;
-    overflow:hidden;
-    background: url(images/background.png) repeat-x 0 0;
-    border-bottom:1px solid #c9e8fa;   
+	#header {
+	height: 93px;
+	position: relative;
+	background: url(images/background.png) repeat-x 0 0;
+	border-bottom: 1px solid #C9E8FA;
+	margin-top: 40px;
 }
 
 #header .content .signature {
@@ -72,31 +72,30 @@ PRE{
 .content {
     width:970px;
     position:relative;
-    overflow:hidden;
     margin:0 auto;
 }
 
 #header .content {
-    height:184px;
-    margin-top:22px;
+	height: 100%;
+	z-index: 90000;
 }
 
 #header .content .logo {
-    width  : 282px;
-    height : 184px;
-    background:url(images/logo.png) no-repeat 0 0;
-    position:absolute;
-    top:0;
-    left:0;
+	width: 141px;
+	height: 92px;
+	background: url(images/logo_half.png) no-repeat 0 0;
+	position: absolute;
+	top: -14px;
+	left: 0;
 }
 
 #header .content .title {
-    width  : 605px;
-    height : 58px;
-    background:url(images/ace.png) no-repeat 0 0;
-    position:absolute;
-    top:98px;
-    left:329px;
+	width: 605px;
+	height: 58px;
+	background: url(images/ace.png) no-repeat 0 0;
+	position: absolute;
+	top: 22px;
+	left: 329px;
 }
 
 #wrapper {
diff --git a/index.html b/index.html
index 6268c4e1..d69b2af8 100644
--- a/index.html
+++ b/index.html
@@ -8,19 +8,33 @@
          
          
          
+	    
+	    
+	    
      
      
+    	Fork me on GitHub
+        
+        
         
         
-
- + diff --git a/kitchen-sink.html b/kitchen-sink.html index bf37f827..5fc01e17 100644 --- a/kitchen-sink.html +++ b/kitchen-sink.html @@ -200,6 +200,14 @@ +
+ + +
+ + + +
diff --git a/lib/ace/ace.js b/lib/ace/ace.js index 91eb2c7f..b573e393 100644 --- a/lib/ace/ace.js +++ b/lib/ace/ace.js @@ -35,6 +35,14 @@ * * ***** END LICENSE BLOCK ***** */ +/** + * class Ace + * + * The main class required to set up an Ace instance in the browser. + * + * + **/ + define(function(require, exports, module) { "use strict"; @@ -56,6 +64,13 @@ require("./keyboard/state_handler"); require("./placeholder"); require("./config").init(); + /** + * Ace.edit(el) -> Editor + * - el (String | DOMElement): Either the id of an element, or the element itself + * + * This method embeds the Ace editor into the DOM, at the element provided by `el`. + * + **/ exports.edit = function(el) { if (typeof(el) == "string") { el = document.getElementById(el); @@ -83,4 +98,4 @@ exports.edit = function(el) { return editor; }; -}); \ No newline at end of file +}); diff --git a/lib/ace/anchor.js b/lib/ace/anchor.js index 8b13e3be..7aab9d55 100644 --- a/lib/ace/anchor.js +++ b/lib/ace/anchor.js @@ -42,9 +42,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; @@ -61,14 +74,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; @@ -134,6 +169,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) { @@ -162,10 +207,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 = {}; diff --git a/lib/ace/anchor_test.js b/lib/ace/anchor_test.js index 112a46fe..62511c70 100644 --- a/lib/ace/anchor_test.js +++ b/lib/ace/anchor_test.js @@ -181,4 +181,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/background_tokenizer.js b/lib/ace/background_tokenizer.js index 0cfe7941..742a0f1e 100644 --- a/lib/ace/background_tokenizer.js +++ b/lib/ace/background_tokenizer.js @@ -41,6 +41,23 @@ define(function(require, exports, module) { 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 = []; @@ -82,6 +99,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 = []; @@ -89,6 +114,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 = []; @@ -96,6 +129,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, @@ -104,6 +146,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()); @@ -116,20 +166,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':[]}]; diff --git a/lib/ace/commands/command_manager.js b/lib/ace/commands/command_manager.js index 380611eb..b919dbc1 100644 --- a/lib/ace/commands/command_manager.js +++ b/lib/ace/commands/command_manager.js @@ -5,6 +5,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 = {}; @@ -13,7 +31,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 || {}); }); }; @@ -33,8 +51,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() { diff --git a/lib/ace/commands/command_manager_test.js b/lib/ace/commands/command_manager_test.js index 752047fd..3ad11d59 100644 --- a/lib/ace/commands/command_manager_test.js +++ b/lib/ace/commands/command_manager_test.js @@ -190,4 +190,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js index f109b336..d12478a3 100644 --- a/lib/ace/commands/default_commands.js +++ b/lib/ace/commands/default_commands.js @@ -311,7 +311,7 @@ exports.commands = [{ multiSelectAction: "forEach" }, { name: "togglecomment", - bindKey: bindKey("Ctrl-7", "Command-7"), + bindKey: bindKey("Ctrl-/", "Command-/"), exec: function(editor) { editor.toggleCommentLines(); }, multiSelectAction: "forEach" }, { diff --git a/lib/ace/commands/multi_select_commands.js b/lib/ace/commands/multi_select_commands.js index 71f0a3e5..a3c1a16d 100644 --- a/lib/ace/commands/multi_select_commands.js +++ b/lib/ace/commands/multi_select_commands.js @@ -84,17 +84,18 @@ 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); -}); \ No newline at end of file +}); diff --git a/lib/ace/config.js b/lib/ace/config.js index c8b0a015..969fc7e4 100644 --- a/lib/ace/config.js +++ b/lib/ace/config.js @@ -125,4 +125,4 @@ function deHyphenate(str) { return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); }); } -}); \ No newline at end of file +}); diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css index 83c21130..11831f03 100644 --- a/lib/ace/css/editor.css +++ b/lib/ace/css/editor.css @@ -1,4 +1,3 @@ -@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono); .ace_editor { position: absolute; @@ -37,6 +36,12 @@ z-index: 1000; } +.ace_gutter_active_line { + position: absolute; + right: 0; + width: 100%; +} + .ace_gutter.horscroll { box-shadow: 0px 0px 20px rgba(0,0,0,0.4); } @@ -95,8 +100,8 @@ .ace_editor textarea { position: fixed; z-index: 0; - width: 10px; - height: 30px; + width: 0.5em; + height: 1em; opacity: 0; background: transparent; appearance: none; @@ -131,6 +136,7 @@ .ace_text-layer { color: black; + font: inherit !important; } .ace_cjk { @@ -179,10 +185,6 @@ z-index: 2; } -.ace_gutter .ace_gutter_active_line{ - background-color : #dcdcdc; -} - .ace_marker-layer .ace_selected_word { position: absolute; z-index: 4; @@ -289,3 +291,25 @@ background-color: #FFB4B4; border-color: #DE5555; } + +.ace_fade-fold-widgets .ace_fold-widget { + -moz-transition: 0.5s opacity; + -webkit-transition: 0.5s opacity; + -o-transition: 0.5s opacity; + -ms-transition: 0.5s opacity; + transition: 0.5s opacity; + opacity: 0; +} +.ace_fade-fold-widgets:hover .ace_fold-widget { + -moz-transition-duration: 0.05s; + -webkit-transition-duration: 0.05s; + -o-transition-duration: 0.05s; + -ms-transition-duration: 0.05s; + transition-duration: 0.05s; + -moz-transition-delay: 0.2s; + -webkit-transition-delay: 0.2s; + -o-transition-delay: 0.2s; + -ms-transition-delay: 0.2s; + transition-delay: 0.2s; + opacity:1; +} diff --git a/lib/ace/document.js b/lib/ace/document.js index 237072ad..87130012 100644 --- a/lib/ace/document.js +++ b/lib/ace/document.js @@ -43,6 +43,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 = []; @@ -62,20 +77,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) { @@ -87,6 +130,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) { @@ -96,6 +144,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": @@ -111,6 +170,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; @@ -118,51 +183,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) { @@ -172,6 +278,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; @@ -195,6 +310,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}; @@ -213,6 +341,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] || ""; @@ -235,6 +374,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; @@ -259,6 +411,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); @@ -291,6 +452,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; @@ -311,12 +483,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); @@ -331,6 +506,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); @@ -348,6 +530,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; @@ -368,6 +562,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]; diff --git a/lib/ace/document_test.js b/lib/ace/document_test.js index f1bd9511..f140e3d4 100644 --- a/lib/ace/document_test.js +++ b/lib/ace/document_test.js @@ -311,4 +311,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js index 2bdfca46..32070ce4 100644 --- a/lib/ace/edit_session.js +++ b/lib/ace/edit_session.js @@ -52,6 +52,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 = []; @@ -77,10 +93,7 @@ var EditSession = function(text, mode) { } this.selection = new Selection(this); - if (mode) - this.setMode(mode); - else - this.setMode(new TextMode()); + this.setMode(mode); }; @@ -88,6 +101,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"); @@ -102,10 +122,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 = []; @@ -120,11 +153,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; @@ -148,6 +192,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); @@ -160,23 +211,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; @@ -198,6 +288,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); @@ -210,6 +306,11 @@ var EditSession = function(text, mode) { if (undoManager) { var self = this; + /** internal, hide + * EditSession.$syncInformUndoManager() + * + * + **/ this.$syncInformUndoManager = function() { self.$informUndoManager.cancel(); @@ -249,10 +350,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()); @@ -262,17 +373,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; @@ -281,15 +411,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; @@ -297,18 +445,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++; @@ -358,6 +551,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) @@ -370,11 +570,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, @@ -383,6 +590,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) { @@ -414,6 +644,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); @@ -445,7 +683,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); @@ -456,15 +700,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; @@ -476,10 +739,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); @@ -490,7 +763,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 { @@ -498,16 +771,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] @@ -518,33 +792,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(); @@ -579,6 +868,11 @@ var EditSession = function(text, mode) { this._emit("changeMode"); }; + /** internal, hide + * EditSession.stopWorker() + * + * + **/ this.$stopWorker = function() { if (this.$worker) this.$worker.terminate(); @@ -586,6 +880,11 @@ var EditSession = function(text, mode) { this.$worker = null; }; + /** internal, hide + * EditSession.$startWorker() + * + * + **/ this.$startWorker = function() { if (typeof Worker !== "undefined" && !require.noWorker) { try { @@ -600,11 +899,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) @@ -614,11 +924,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) @@ -628,15 +948,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; @@ -681,33 +1016,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; @@ -734,6 +1118,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; @@ -756,10 +1147,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 = @@ -814,19 +1216,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); @@ -857,12 +1276,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); @@ -887,6 +1324,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; @@ -895,6 +1342,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; @@ -903,6 +1359,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); @@ -914,6 +1381,7 @@ var EditSession = function(text, mode) { return addedRows; }; + this.$clipRowToDocument = function(row) { return Math.max(0, Math.min(row, this.doc.getLength()-1)); }; @@ -924,6 +1392,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); @@ -956,7 +1425,7 @@ var EditSession = function(text, mode) { range.start.column ); } - + var len = this.doc.getLength() - 1; if (range.end.row > len) { range.end.row = len; @@ -978,6 +1447,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; @@ -998,6 +1473,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; }; @@ -1006,6 +1486,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; @@ -1016,8 +1503,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) { @@ -1033,6 +1524,11 @@ var EditSession = function(text, mode) { return false; }; + /** internal, hide + * EditSession.$constrainWrapLimit(wrapLimit) + * + * + **/ this.$constrainWrapLimit = function(wrapLimit) { var min = this.$wrapLimitRange.min; if (min) @@ -1046,10 +1542,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 { @@ -1058,6 +1567,11 @@ var EditSession = function(text, mode) { }; }; + /** internal, hide + * EditSession.$updateInternalDataOnChange() + * + * + **/ this.$updateInternalDataOnChange = function(e) { var useWrapMode = this.$useWrapMode; var len; @@ -1173,6 +1687,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(); @@ -1232,6 +1751,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 []; @@ -1348,11 +1872,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; @@ -1384,15 +1910,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]; @@ -1425,8 +1955,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; @@ -1436,27 +1970,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; @@ -1466,20 +2025,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 { @@ -1575,6 +2157,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") @@ -1678,14 +2271,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; diff --git a/lib/ace/edit_session/bracket_match.js b/lib/ace/edit_session/bracket_match.js index 89e6506c..e3add27a 100644 --- a/lib/ace/edit_session/bracket_match.js +++ b/lib/ace/edit_session/bracket_match.js @@ -41,8 +41,34 @@ define(function(require, exports, module) { 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; diff --git a/lib/ace/edit_session/fold.js b/lib/ace/edit_session/fold.js index 8ce5e708..923d78a0 100644 --- a/lib/ace/edit_session/fold.js +++ b/lib/ace/edit_session/fold.js @@ -39,7 +39,7 @@ define(function(require, exports, module) { "use strict"; -/** +/* * Simple fold-data struct. **/ var Fold = exports.Fold = function(range, placeholder) { @@ -113,4 +113,4 @@ var Fold = exports.Fold = function(range, placeholder) { }).call(Fold.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/edit_session/fold_line.js b/lib/ace/edit_session/fold_line.js index e51ec7c4..5206dffc 100644 --- a/lib/ace/edit_session/fold_line.js +++ b/lib/ace/edit_session/fold_line.js @@ -41,7 +41,7 @@ define(function(require, exports, module) { var Range = require("../range").Range; -/** +/* * If an array is passed in, the folds are expected to be sorted already. */ function FoldLine(foldData, folds) { @@ -64,7 +64,7 @@ function FoldLine(foldData, folds) { } (function() { - /** + /* * Note: This doesn't update wrapData! */ this.shiftRow = function(shift) { @@ -177,7 +177,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); @@ -271,4 +273,4 @@ function FoldLine(foldData, folds) { }).call(FoldLine.prototype); exports.FoldLine = FoldLine; -}); \ No newline at end of file +}); diff --git a/lib/ace/edit_session/folding.js b/lib/ace/edit_session/folding.js index d6a08102..187bd0e6 100644 --- a/lib/ace/edit_session/folding.js +++ b/lib/ace/edit_session/folding.js @@ -45,7 +45,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 @@ -69,7 +69,7 @@ function Folding() { } }; - /** + /* * Returns all folds in the given range. Note, that this will return folds * */ @@ -115,7 +115,7 @@ function Folding() { return foundFolds; }; - /** + /* * Returns all folds in the document */ this.getAllFolds = function() { @@ -138,7 +138,7 @@ function Folding() { return folds; }; - /** + /* * Returns the string between folds at the given position. * E.g. * foob|arwolrd -> "bar" @@ -257,7 +257,7 @@ function Folding() { return foldLine; }; - /** + /* * Adds a new fold. * * @returns @@ -457,7 +457,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. **/ diff --git a/lib/ace/edit_session_test.js b/lib/ace/edit_session_test.js index c27cf854..e2bc7fae 100644 --- a/lib/ace/edit_session_test.js +++ b/lib/ace/edit_session_test.js @@ -982,4 +982,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 0e1df71b..85d7076b 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -58,12 +58,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 @@ -79,7 +96,6 @@ var Editor = function(renderer, session) { wrap: true }); - this.commands = new CommandManager(useragent.isMac ? "mac" : "win", defaultCommands); this.setSession(session || new EditSession("")); }; @@ -87,14 +103,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; @@ -194,39 +226,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); @@ -251,6 +328,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 @@ -262,26 +344,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; @@ -296,51 +409,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; @@ -351,11 +483,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(); @@ -376,34 +513,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. @@ -412,6 +589,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()) @@ -421,10 +603,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(); @@ -517,46 +729,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; @@ -565,23 +834,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; @@ -593,6 +899,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; }; @@ -605,6 +916,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; @@ -612,44 +929,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) @@ -660,13 +1034,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(); @@ -685,6 +1079,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(); @@ -693,6 +1092,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(); @@ -701,6 +1105,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(); @@ -709,6 +1118,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(); @@ -723,6 +1137,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()); @@ -734,6 +1153,11 @@ var Editor = function(renderer, session) { this.moveCursorToPosition(cursor); }; + /** + * Editor.transposeLetters() + * + * Transposes current line. + **/ this.transposeLetters = function() { if (!this.selection.isEmpty()) { return; @@ -757,6 +1181,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()) { @@ -769,6 +1198,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()) { @@ -781,6 +1215,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(); @@ -804,17 +1243,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; @@ -829,18 +1283,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; @@ -848,6 +1331,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); @@ -855,6 +1346,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); @@ -862,6 +1362,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; @@ -885,6 +1392,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(); @@ -894,141 +1409,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); @@ -1047,34 +1699,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; @@ -1089,6 +1777,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; @@ -1103,36 +1797,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); @@ -1153,6 +1888,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); @@ -1192,35 +1934,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())}); @@ -1229,35 +1994,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(); }; diff --git a/lib/ace/editor_change_document_test.js b/lib/ace/editor_change_document_test.js index 4382fa16..9464202d 100644 --- a/lib/ace/editor_change_document_test.js +++ b/lib/ace/editor_change_document_test.js @@ -192,4 +192,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/editor_highlight_selected_word_test.js b/lib/ace/editor_highlight_selected_word_test.js index afd28f1c..b734b63e 100644 --- a/lib/ace/editor_highlight_selected_word_test.js +++ b/lib/ace/editor_highlight_selected_word_test.js @@ -212,4 +212,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/editor_navigation_test.js b/lib/ace/editor_navigation_test.js index 93eaa2c2..ebd55a89 100644 --- a/lib/ace/editor_navigation_test.js +++ b/lib/ace/editor_navigation_test.js @@ -82,7 +82,7 @@ module.exports = { editor.navigateTo(0, 0); editor.gotoLine(101); assert.position(editor.getCursorPosition(), 100, 0); - assert.equal(editor.getFirstVisibleRow(), 90); + assert.equal(editor.getFirstVisibleRow(), 89); editor.navigateTo(100, 0); editor.gotoLine(11); @@ -102,7 +102,7 @@ module.exports = { editor.navigateTo(0, 0); editor.gotoLine(191); assert.position(editor.getCursorPosition(), 190, 0); - assert.equal(editor.getFirstVisibleRow(), 180); + assert.equal(editor.getFirstVisibleRow(), 179); editor.navigateTo(0, 0); editor.gotoLine(196); @@ -168,4 +168,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/editor_text_edit_test.js b/lib/ace/editor_text_edit_test.js index e1f5c234..171d40c7 100644 --- a/lib/ace/editor_text_edit_test.js +++ b/lib/ace/editor_text_edit_test.js @@ -151,7 +151,7 @@ module.exports = { editor.onTextInput("\n"); assert.equal(["", "{"].join("\n"), session.toString()); }, - + "test: outdent block" : function() { var session = new EditSession([" a12345", " b12345", " c12345"].join("\n")); var editor = new Editor(new MockRenderer(), session); @@ -559,4 +559,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/ext/static_highlight.js b/lib/ace/ext/static_highlight.js index e62ae3b2..6aecc59c 100644 --- a/lib/ace/ext/static_highlight.js +++ b/lib/ace/ext/static_highlight.js @@ -44,7 +44,7 @@ var EditSession = require("../edit_session").EditSession; var TextLayer = require("../layer/text").Text; var baseStyles = require("../requirejs/text!./static.css"); -/** Transforms a given input code snippet into HTML using the given mode +/* Transforms a given input code snippet into HTML using the given mode * * @param {string} input Code snippet * @param {mode} mode Mode loaded from /ace/mode (use 'ServerSideHiglighter.getMode') @@ -95,4 +95,4 @@ exports.render = function(input, mode, theme, lineStart) { }; }; -}); \ No newline at end of file +}); diff --git a/lib/ace/ext/static_highlight_test.js b/lib/ace/ext/static_highlight_test.js index 47f6aa05..f6e5c909 100644 --- a/lib/ace/ext/static_highlight_test.js +++ b/lib/ace/ext/static_highlight_test.js @@ -78,4 +78,4 @@ function hello (a, b, c) {\n\ if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/ext/textarea.js b/lib/ace/ext/textarea.js index 5dee3eca..2ca5b9c8 100644 --- a/lib/ace/ext/textarea.js +++ b/lib/ace/ext/textarea.js @@ -46,7 +46,7 @@ var ace = require("../ace"); require("ace/theme/textmate"); -/** +/* * Returns the CSS property of element. * 1) If the CSS property is on the style object of the element, use it, OR * 2) Compute the CSS property diff --git a/lib/ace/keyboard/hash_handler.js b/lib/ace/keyboard/hash_handler.js index 9a8f2899..53a9c9c4 100644 --- a/lib/ace/keyboard/hash_handler.js +++ b/lib/ace/keyboard/hash_handler.js @@ -78,6 +78,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]; @@ -100,18 +112,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]); @@ -127,10 +127,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]]) @@ -143,17 +143,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 { diff --git a/lib/ace/keyboard/keybinding.js b/lib/ace/keyboard/keybinding.js index 6e6656d5..79fb7aa9 100644 --- a/lib/ace/keyboard/keybinding.js +++ b/lib/ace/keyboard/keybinding.js @@ -47,15 +47,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) { @@ -93,7 +105,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; @@ -103,20 +115,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); diff --git a/lib/ace/keyboard/state_handler.js b/lib/ace/keyboard/state_handler.js index 541fa1cd..8e93ba30 100644 --- a/lib/ace/keyboard/state_handler.js +++ b/lib/ace/keyboard/state_handler.js @@ -47,7 +47,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. @@ -198,7 +198,7 @@ StateHandler.prototype = { } }, - /** + /* * This function is called by keyBinding. */ handleKeyboard: function(data, hashId, key, keyCode, e) { @@ -224,7 +224,7 @@ StateHandler.prototype = { } } -/** +/* * This is a useful matching function and therefore is defined here so that * users of KeyboardStateMapper can use it. * diff --git a/lib/ace/keyboard/textinput.js b/lib/ace/keyboard/textinput.js index bb917f5b..fa570e66 100644 --- a/lib/ace/keyboard/textinput.js +++ b/lib/ace/keyboard/textinput.js @@ -49,7 +49,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); @@ -72,13 +74,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 @@ -99,7 +106,7 @@ var TextInput = function(parentNode, host) { var onTextInput = function(e) { setTimeout(function () { if (!inCompostion) - sendText(e.data); + sendText(e.data); }, 0); }; @@ -155,6 +162,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) { diff --git a/lib/ace/layer/cursor.js b/lib/ace/layer/cursor.js index 1c55d7a8..f43b36b7 100644 --- a/lib/ace/layer/cursor.js +++ b/lib/ace/layer/cursor.js @@ -175,6 +175,9 @@ var Cursor = function(parentEl) { if (overwrite != this.overwrite) this.$setOverite(overwrite); + // cache for textarea and gutter highlight + this.$pixelPos = pixelPos; + this.restartTimer(); }; diff --git a/lib/ace/layer/marker.js b/lib/ace/layer/marker.js index 741a271d..990af0ad 100644 --- a/lib/ace/layer/marker.js +++ b/lib/ace/layer/marker.js @@ -111,9 +111,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; @@ -137,9 +135,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; @@ -186,9 +182,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; diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js index d4d39bc0..bb8d733d 100644 --- a/lib/ace/layer/text.js +++ b/lib/ace/layer/text.js @@ -390,21 +390,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"; @@ -413,13 +410,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 "= 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. * @@ -89,7 +89,7 @@ exports.OS = { WINDOWS: "WINDOWS" }; -/** +/* * Return an exports.OS constant */ exports.getOS = function() { diff --git a/lib/ace/mode/behaviour.js b/lib/ace/mode/behaviour.js index 36867c11..0559ff64 100644 --- a/lib/ace/mode/behaviour.js +++ b/lib/ace/mode/behaviour.js @@ -95,4 +95,4 @@ var Behaviour = function() { }).call(Behaviour.prototype); exports.Behaviour = Behaviour; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/behaviour/cstyle.js b/lib/ace/mode/behaviour/cstyle.js index e4976add..3db838ad 100644 --- a/lib/ace/mode/behaviour/cstyle.js +++ b/lib/ace/mode/behaviour/cstyle.js @@ -222,4 +222,4 @@ var CstyleBehaviour = function () { oop.inherits(CstyleBehaviour, Behaviour); exports.CstyleBehaviour = CstyleBehaviour; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/behaviour/xml.js b/lib/ace/mode/behaviour/xml.js index 568f1f28..bdfa9d82 100644 --- a/lib/ace/mode/behaviour/xml.js +++ b/lib/ace/mode/behaviour/xml.js @@ -89,4 +89,4 @@ var XmlBehaviour = function () { oop.inherits(XmlBehaviour, Behaviour); exports.XmlBehaviour = XmlBehaviour; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee.js b/lib/ace/mode/coffee.js index 7ceffe2f..4afc2896 100644 --- a/lib/ace/mode/coffee.js +++ b/lib/ace/mode/coffee.js @@ -118,4 +118,4 @@ oop.inherits(Mode, TextMode); exports.Mode = Mode; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee/coffee-script.js b/lib/ace/mode/coffee/coffee-script.js index a2ebce73..63bdcf5c 100644 --- a/lib/ace/mode/coffee/coffee-script.js +++ b/lib/ace/mode/coffee/coffee-script.js @@ -60,4 +60,4 @@ define(function(require, exports, module) { exports.parse = function(code) { return parser.parse(lexer.tokenize(code)); }; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee/helpers.js b/lib/ace/mode/coffee/helpers.js index bba243c7..69c55bc6 100644 --- a/lib/ace/mode/coffee/helpers.js +++ b/lib/ace/mode/coffee/helpers.js @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2011 Jeremy Ashkenas * * Permission is hereby granted, free of charge, to any person @@ -97,4 +97,4 @@ define(function(require, exports, module) { }; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee/lexer.js b/lib/ace/mode/coffee/lexer.js index dd80efa3..be857984 100644 --- a/lib/ace/mode/coffee/lexer.js +++ b/lib/ace/mode/coffee/lexer.js @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2011 Jeremy Ashkenas * * Permission is hereby granted, free of charge, to any person @@ -736,4 +736,4 @@ define(function(require, exports, module) { LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR']; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee/nodes.js b/lib/ace/mode/coffee/nodes.js index 5900473e..693976ea 100644 --- a/lib/ace/mode/coffee/nodes.js +++ b/lib/ace/mode/coffee/nodes.js @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2011 Jeremy Ashkenas * * Permission is hereby granted, free of charge, to any person @@ -2753,4 +2753,4 @@ define(function(require, exports, module) { }; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee/parser.js b/lib/ace/mode/coffee/parser.js index c6fdc88c..553179ca 100644 --- a/lib/ace/mode/coffee/parser.js +++ b/lib/ace/mode/coffee/parser.js @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2011 Jeremy Ashkenas * * Permission is hereby granted, free of charge, to any person @@ -600,4 +600,4 @@ parse: function parse(input) { module.exports = parser; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee/parser_test.js b/lib/ace/mode/coffee/parser_test.js index 692865c4..d7f70397 100644 --- a/lib/ace/mode/coffee/parser_test.js +++ b/lib/ace/mode/coffee/parser_test.js @@ -65,4 +65,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/mode/coffee/rewriter.js b/lib/ace/mode/coffee/rewriter.js index 80912bfc..b8e7a6a6 100644 --- a/lib/ace/mode/coffee/rewriter.js +++ b/lib/ace/mode/coffee/rewriter.js @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2011 Jeremy Ashkenas * * Permission is hereby granted, free of charge, to any person @@ -339,4 +339,4 @@ define(function(require, exports, module) { LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT']; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee/scope.js b/lib/ace/mode/coffee/scope.js index 7b0bcbfe..cf1cd9f3 100644 --- a/lib/ace/mode/coffee/scope.js +++ b/lib/ace/mode/coffee/scope.js @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2011 Jeremy Ashkenas * * Permission is hereby granted, free of charge, to any person @@ -151,4 +151,4 @@ define(function(require, exports, module) { })(); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/coffee_highlight_rules_test.js b/lib/ace/mode/coffee_highlight_rules_test.js index 546406a6..0393e659 100644 --- a/lib/ace/mode/coffee_highlight_rules_test.js +++ b/lib/ace/mode/coffee_highlight_rules_test.js @@ -69,4 +69,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/mode/coffee_worker.js b/lib/ace/mode/coffee_worker.js index 58150903..6268f192 100644 --- a/lib/ace/mode/coffee_worker.js +++ b/lib/ace/mode/coffee_worker.js @@ -89,4 +89,4 @@ oop.inherits(Worker, Mirror); }).call(Worker.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/css_highlight_rules_test.js b/lib/ace/mode/css_highlight_rules_test.js index e30d2d8f..536babb3 100644 --- a/lib/ace/mode/css_highlight_rules_test.js +++ b/lib/ace/mode/css_highlight_rules_test.js @@ -96,4 +96,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/mode/css_test.js b/lib/ace/mode/css_test.js index 0e1f47fb..47605823 100644 --- a/lib/ace/mode/css_test.js +++ b/lib/ace/mode/css_test.js @@ -82,4 +82,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/mode/css_worker.js b/lib/ace/mode/css_worker.js index a5c53491..cb59dfef 100644 --- a/lib/ace/mode/css_worker.js +++ b/lib/ace/mode/css_worker.js @@ -63,4 +63,4 @@ oop.inherits(Worker, Mirror); }).call(Worker.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/css_worker_test.js b/lib/ace/mode/css_worker_test.js index 6afe87b5..3b2ec67b 100644 --- a/lib/ace/mode/css_worker_test.js +++ b/lib/ace/mode/css_worker_test.js @@ -72,4 +72,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/mode/folding/cstyle.js b/lib/ace/mode/folding/cstyle.js index def02333..2a13c98d 100644 --- a/lib/ace/mode/folding/cstyle.js +++ b/lib/ace/mode/folding/cstyle.js @@ -92,4 +92,4 @@ oop.inherits(FoldMode, BaseFoldMode); }).call(FoldMode.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/folding/cstyle_test.js b/lib/ace/mode/folding/cstyle_test.js index 2790d7f6..d23643c8 100644 --- a/lib/ace/mode/folding/cstyle_test.js +++ b/lib/ace/mode/folding/cstyle_test.js @@ -89,4 +89,4 @@ module.exports = { }); if (typeof module !== "undefined" && module === require.main) - require("asyncjs").test.testcase(module.exports).exec(); \ No newline at end of file + require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/mode/folding/html.js b/lib/ace/mode/folding/html.js index 03e4a456..30691138 100644 --- a/lib/ace/mode/folding/html.js +++ b/lib/ace/mode/folding/html.js @@ -83,4 +83,4 @@ var FoldMode = exports.FoldMode = function() { oop.inherits(FoldMode, MixedFoldMode); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/folding/html_test.js b/lib/ace/mode/folding/html_test.js index dbf9dbec..06484979 100644 --- a/lib/ace/mode/folding/html_test.js +++ b/lib/ace/mode/folding/html_test.js @@ -166,4 +166,4 @@ module.exports = { }); if (typeof module !== "undefined" && module === require.main) - require("asyncjs").test.testcase(module.exports).exec(); \ No newline at end of file + require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/mode/folding/mixed.js b/lib/ace/mode/folding/mixed.js index 1bec524d..4ebc3acf 100644 --- a/lib/ace/mode/folding/mixed.js +++ b/lib/ace/mode/folding/mixed.js @@ -85,4 +85,4 @@ oop.inherits(FoldMode, BaseFoldMode); }).call(FoldMode.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/folding/pythonic.js b/lib/ace/mode/folding/pythonic.js index 4bb25813..90ab2aad 100644 --- a/lib/ace/mode/folding/pythonic.js +++ b/lib/ace/mode/folding/pythonic.js @@ -62,4 +62,4 @@ oop.inherits(FoldMode, BaseFoldMode); }).call(FoldMode.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/folding/pythonic_test.js b/lib/ace/mode/folding/pythonic_test.js index 595ff71a..6cfb1f77 100644 --- a/lib/ace/mode/folding/pythonic_test.js +++ b/lib/ace/mode/folding/pythonic_test.js @@ -99,4 +99,4 @@ module.exports = { }); if (typeof module !== "undefined" && module === require.main) - require("asyncjs").test.testcase(module.exports).exec(); \ No newline at end of file + require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/mode/folding/xml.js b/lib/ace/mode/folding/xml.js index 6efa8194..bfe368d3 100644 --- a/lib/ace/mode/folding/xml.js +++ b/lib/ace/mode/folding/xml.js @@ -101,7 +101,7 @@ oop.inherits(FoldMode, BaseFoldMode); }; }; - /** + /* * reads a full tag and places the iterator after the tag */ this._readTagForward = function(iterator) { @@ -259,4 +259,4 @@ oop.inherits(FoldMode, BaseFoldMode); }).call(FoldMode.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/folding/xml_test.js b/lib/ace/mode/folding/xml_test.js index 89cb9afb..49c95949 100644 --- a/lib/ace/mode/folding/xml_test.js +++ b/lib/ace/mode/folding/xml_test.js @@ -114,4 +114,4 @@ module.exports = { }); if (typeof module !== "undefined" && module === require.main) - require("asyncjs").test.testcase(module.exports).exec(); \ No newline at end of file + require("asyncjs").test.testcase(module.exports).exec(); diff --git a/lib/ace/mode/html_highlight_rules_test.js b/lib/ace/mode/html_highlight_rules_test.js index 998ca2fe..1b1431fc 100644 --- a/lib/ace/mode/html_highlight_rules_test.js +++ b/lib/ace/mode/html_highlight_rules_test.js @@ -90,4 +90,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/mode/html_test.js b/lib/ace/mode/html_test.js index cd7dd768..6b5549e8 100644 --- a/lib/ace/mode/html_test.js +++ b/lib/ace/mode/html_test.js @@ -71,4 +71,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/mode/javascript_highlight_rules_test.js b/lib/ace/mode/javascript_highlight_rules_test.js index 48fbbc15..dd9d2fb1 100644 --- a/lib/ace/mode/javascript_highlight_rules_test.js +++ b/lib/ace/mode/javascript_highlight_rules_test.js @@ -222,4 +222,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/mode/javascript_test.js b/lib/ace/mode/javascript_test.js index 3171a69b..20cf5935 100644 --- a/lib/ace/mode/javascript_test.js +++ b/lib/ace/mode/javascript_test.js @@ -162,4 +162,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/mode/javascript_worker.js b/lib/ace/mode/javascript_worker.js index 32e72bbb..d4aceb4b 100644 --- a/lib/ace/mode/javascript_worker.js +++ b/lib/ace/mode/javascript_worker.js @@ -85,4 +85,4 @@ oop.inherits(JavaScriptWorker, Mirror); }).call(JavaScriptWorker.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/javascript_worker_test.js b/lib/ace/mode/javascript_worker_test.js index 841d1de4..dd66e2ec 100644 --- a/lib/ace/mode/javascript_worker_test.js +++ b/lib/ace/mode/javascript_worker_test.js @@ -96,4 +96,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/mode/json.js b/lib/ace/mode/json.js index fc0b9583..d6dd98d7 100644 --- a/lib/ace/mode/json.js +++ b/lib/ace/mode/json.js @@ -97,4 +97,4 @@ oop.inherits(Mode, TextMode); }).call(Mode.prototype); exports.Mode = Mode; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/json/json_parse.js b/lib/ace/mode/json/json_parse.js index 8374d2af..7841ab70 100644 --- a/lib/ace/mode/json/json_parse.js +++ b/lib/ace/mode/json/json_parse.js @@ -343,4 +343,4 @@ define(function(require, exports, module) { return reviver.call(holder, key, value); }({'': result}, '') : result; }; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/json_worker.js b/lib/ace/mode/json_worker.js index 8759c0b9..ba207b3f 100644 --- a/lib/ace/mode/json_worker.js +++ b/lib/ace/mode/json_worker.js @@ -100,4 +100,4 @@ oop.inherits(JsonWorker, Mirror); }).call(JsonWorker.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/json_worker_test.js b/lib/ace/mode/json_worker_test.js index 261fc9c5..3dea50e6 100644 --- a/lib/ace/mode/json_worker_test.js +++ b/lib/ace/mode/json_worker_test.js @@ -105,4 +105,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/mode/lua.js b/lib/ace/mode/lua.js index 79b57ff3..af61d48e 100644 --- a/lib/ace/mode/lua.js +++ b/lib/ace/mode/lua.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") { diff --git a/lib/ace/mode/lua_highlight_rules.js b/lib/ace/mode/lua_highlight_rules.js index 7eb6daeb..57e5fead 100644 --- a/lib/ace/mode/lua_highlight_rules.js +++ b/lib/ace/mode/lua_highlight_rules.js @@ -111,7 +111,7 @@ var LuaHighlightRules = function() { this.$rules = { "start" : - + // bracketed comments [{ token : "comment", // --[[ comment @@ -132,9 +132,9 @@ var LuaHighlightRules = function() { token : "comment", // --[====+[ comment regex : strPre + '\\-\\-\\[\\={5}\\=*\\[.*\\]\\={5}\\=*\\]' }, - - // multiline bracketed comments - { + + // multiline bracketed comments + { token : "comment", // --[[ comment regex : strPre + '\\-\\-\\[\\[.*$', merge : true, @@ -184,7 +184,7 @@ var LuaHighlightRules = function() { }, // bracketed strings - { + { token : "string", // [[ string regex : strPre + '\\[\\[.*\\]\\]' }, { @@ -203,8 +203,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/lib/ace/mode/markdown.js b/lib/ace/mode/markdown.js index 04d8939f..99f7bf38 100644 --- a/lib/ace/mode/markdown.js +++ b/lib/ace/mode/markdown.js @@ -78,4 +78,4 @@ oop.inherits(Mode, TextMode); }).call(Mode.prototype); exports.Mode = Mode; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/markdown_highlight_rules.js b/lib/ace/mode/markdown_highlight_rules.js index 554d464e..09fcdff0 100644 --- a/lib/ace/mode/markdown_highlight_rules.js +++ b/lib/ace/mode/markdown_highlight_rules.js @@ -192,4 +192,4 @@ var MarkdownHighlightRules = function() { oop.inherits(MarkdownHighlightRules, TextHighlightRules); exports.MarkdownHighlightRules = MarkdownHighlightRules; -}); \ No newline at end of file +}); diff --git a/lib/ace/mode/python_test.js b/lib/ace/mode/python_test.js index 31655ee6..99a17b86 100644 --- a/lib/ace/mode/python_test.js +++ b/lib/ace/mode/python_test.js @@ -83,4 +83,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/mode/text_test.js b/lib/ace/mode/text_test.js index 0c8d1844..9b2650b1 100644 --- a/lib/ace/mode/text_test.js +++ b/lib/ace/mode/text_test.js @@ -68,4 +68,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/mode/xml_highlight_rules_test.js b/lib/ace/mode/xml_highlight_rules_test.js index 6dda1b02..8f764b2d 100644 --- a/lib/ace/mode/xml_highlight_rules_test.js +++ b/lib/ace/mode/xml_highlight_rules_test.js @@ -100,4 +100,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/mode/xml_test.js b/lib/ace/mode/xml_test.js index d27f6845..6985d4c5 100644 --- a/lib/ace/mode/xml_test.js +++ b/lib/ace/mode/xml_test.js @@ -79,4 +79,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/model/editor.js b/lib/ace/model/editor.js index 71ec3394..9c1414b8 100644 --- a/lib/ace/model/editor.js +++ b/lib/ace/model/editor.js @@ -67,4 +67,4 @@ var Editor = exports.Editor = function() { }).call(Editor.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/mouse/default_gutter_handler.js b/lib/ace/mouse/default_gutter_handler.js index a13edb15..d03e18ce 100644 --- a/lib/ace/mouse/default_gutter_handler.js +++ b/lib/ace/mouse/default_gutter_handler.js @@ -39,16 +39,27 @@ define(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; -}); \ No newline at end of file +}); diff --git a/lib/ace/mouse/default_handlers.js b/lib/ace/mouse/default_handlers.js index 14439ca2..34d6ef1b 100644 --- a/lib/ace/mouse/default_handlers.js +++ b/lib/ace/mouse/default_handlers.js @@ -22,6 +22,7 @@ * 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 @@ -40,237 +41,287 @@ define(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; diff --git a/lib/ace/mouse/fold_handler.js b/lib/ace/mouse/fold_handler.js index 986ca934..ecde7769 100644 --- a/lib/ace/mouse/fold_handler.js +++ b/lib/ace/mouse/fold_handler.js @@ -68,4 +68,4 @@ function FoldHandler(editor) { exports.FoldHandler = FoldHandler; -}); \ No newline at end of file +}); diff --git a/lib/ace/mouse/mouse_event.js b/lib/ace/mouse/mouse_event.js index 8e32f548..2c813cde 100644 --- a/lib/ace/mouse/mouse_event.js +++ b/lib/ace/mouse/mouse_event.js @@ -41,18 +41,15 @@ define(function(require, exports, module) { 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; @@ -78,7 +75,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 @@ -86,14 +83,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 @@ -119,7 +114,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 @@ -128,7 +123,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() { diff --git a/lib/ace/mouse/mouse_handler.js b/lib/ace/mouse/mouse_handler.js index df4f0640..a85e9672 100644 --- a/lib/ace/mouse/mouse_handler.js +++ b/lib/ace/mouse/mouse_handler.js @@ -47,10 +47,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); @@ -67,7 +67,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")); @@ -89,7 +89,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; @@ -113,10 +113,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; diff --git a/lib/ace/mouse/multi_select_handler.js b/lib/ace/mouse/multi_select_handler.js index 24b25cd4..880bc13c 100644 --- a/lib/ace/mouse/multi_select_handler.js +++ b/lib/ace/mouse/multi_select_handler.js @@ -76,10 +76,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() { @@ -164,4 +164,4 @@ function onMouseDown(e) { exports.onMouseDown = onMouseDown; -}); \ No newline at end of file +}); diff --git a/lib/ace/multi_select.js b/lib/ace/multi_select.js index 0b8850bc..2fe9c421 100644 --- a/lib/ace/multi_select.js +++ b/lib/ace/multi_select.js @@ -42,6 +42,7 @@ 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 @@ -71,10 +72,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) @@ -118,11 +121,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); @@ -132,10 +135,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(); @@ -193,6 +196,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]; @@ -209,11 +243,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 = []; @@ -283,21 +320,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) @@ -311,11 +349,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) @@ -346,13 +384,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; @@ -365,7 +403,7 @@ var Editor = require("./editor").Editor; this.renderer.updateCursor(); this.renderer.updateBackMarkers(); }; - + this.$onSingleSelect = function(e) { if (this.session.multiSelect.inVirtualMode) return; @@ -397,12 +435,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) @@ -433,11 +471,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) @@ -461,14 +499,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 || {}; @@ -481,10 +540,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); @@ -494,12 +553,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(); @@ -539,12 +598,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; @@ -562,7 +620,7 @@ var Editor = require("./editor").Editor; } } sel.mergeOverlappingRanges(); - + var words = []; for (var i = all.length; i--; ) { var range = all[i]; @@ -583,13 +641,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; @@ -656,12 +713,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); @@ -673,7 +727,7 @@ function MultiSelect(editor) { editor.on("mousedown", onMouseDown); editor.commands.addCommands(exports.commands.defaultCommands); - + addAltCursorListeners(editor); } @@ -681,7 +735,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"; @@ -691,9 +745,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 = ""; @@ -704,4 +758,4 @@ function addAltCursorListeners(editor){ exports.MultiSelect = MultiSelect; -}); \ No newline at end of file +}); diff --git a/lib/ace/multi_select_test.js b/lib/ace/multi_select_test.js index 8e0a4013..4fdac469 100644 --- a/lib/ace/multi_select_test.js +++ b/lib/ace/multi_select_test.js @@ -143,7 +143,7 @@ module.exports = { ]); editor = new Editor(new MockRenderer(), doc); MultiSelect(editor); - var selection = editor.selection; + var selection = editor.selection; var range1 = new Range(0, 2, 0, 4); editor.selection.fromOrientedRange(range1); @@ -168,4 +168,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/narcissus/definitions.js b/lib/ace/narcissus/definitions.js index 48a7c1e5..742f1c4f 100644 --- a/lib/ace/narcissus/definitions.js +++ b/lib/ace/narcissus/definitions.js @@ -693,4 +693,4 @@ exports.Dict = Dict; exports.WeakMap = _WeakMap; exports.Stack = Stack; -}); \ No newline at end of file +}); diff --git a/lib/ace/narcissus/lexer.js b/lib/ace/narcissus/lexer.js index de67ebdd..fff707c0 100644 --- a/lib/ace/narcissus/lexer.js +++ b/lib/ace/narcissus/lexer.js @@ -595,4 +595,4 @@ Tokenizer.prototype = { exports.isIdentifier = isIdentifier; exports.Tokenizer = Tokenizer; -}); \ No newline at end of file +}); diff --git a/lib/ace/narcissus/options.js b/lib/ace/narcissus/options.js index 7f617944..2793fcd2 100644 --- a/lib/ace/narcissus/options.js +++ b/lib/ace/narcissus/options.js @@ -58,4 +58,4 @@ exports.mozillaMode = true; // Allow experimental paren-free mode? exports.parenFreeMode = false; -}); \ No newline at end of file +}); diff --git a/lib/ace/narcissus/parser.js b/lib/ace/narcissus/parser.js index 4c93c63f..8cb9faa8 100644 --- a/lib/ace/narcissus/parser.js +++ b/lib/ace/narcissus/parser.js @@ -2069,4 +2069,4 @@ exports.Parser = Parser; exports.Module = Module; exports.Export = Export; -}); \ No newline at end of file +}); diff --git a/lib/ace/placeholder.js b/lib/ace/placeholder.js index 8092ca2e..8af180ed 100644 --- a/lib/ace/placeholder.js +++ b/lib/ace/placeholder.js @@ -41,6 +41,26 @@ var Range = require('./range').Range; var EventEmitter = require("./lib/event_emitter").EventEmitter; var oop = require("./lib/oop"); +/** + * class PlaceHolder + * + * TODO + * + **/ + +/** + * new PlaceHolder(session, length, pos, others, mainClass, othersClass) + * - session (Document): The document to associate with the anchor + * - length (Number): The starting row position + * - pos (Number): The starting column position + * - others (String): + * - mainClass (String): + * - othersClass (String): + * + * TODO + * + **/ + var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) { var _self = this; this.length = length; @@ -71,6 +91,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) oop.implement(this, EventEmitter); + /** + * PlaceHolder.setup() + * + * TODO + * + **/ this.setup = function() { var _self = this; var doc = this.doc; @@ -91,6 +117,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) session.setUndoSelect(false); }; + /** + * PlaceHolder.showOtherMarkers() + * + * TODO + * + **/ this.showOtherMarkers = function() { if(this.othersActive) return; var session = this.session; @@ -105,6 +137,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) }); }; + /** + * PlaceHolder.hideOtherMarkers() + * + * Hides all over markers in the [[EditSession `EditSession`]] that are not the currently selected one. + * + **/ this.hideOtherMarkers = function() { if(!this.othersActive) return; this.othersActive = false; @@ -113,6 +151,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) } }; + /** + * PlaceHolder@onUpdate(e) + * + * Emitted when the place holder updates. + * + **/ this.onUpdate = function(event) { var delta = event.data; var range = delta.range; @@ -175,6 +219,13 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.$updating = false; }; + /** + * PlaceHolder@onCursorChange(e) + * + * Emitted when the cursor changes. + * + **/ + this.onCursorChange = function(event) { if (this.$updating) return; var pos = this.session.selection.getCursor(); @@ -187,6 +238,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) } }; + /** + * PlaceHolder.detach() + * + * TODO + * + **/ this.detach = function() { this.session.removeMarker(this.markerId); this.hideOtherMarkers(); @@ -199,6 +256,12 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) this.session.setUndoSelect(true); }; + /** + * PlaceHolder.cancel() + * + * TODO + * + **/ this.cancel = function() { if(this.$undoStackDepth === -1) throw Error("Canceling placeholders only supported with undo manager attached to session."); diff --git a/lib/ace/placeholder_test.js b/lib/ace/placeholder_test.js index fb1ddf01..cc9f15bb 100644 --- a/lib/ace/placeholder_test.js +++ b/lib/ace/placeholder_test.js @@ -161,4 +161,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/range.js b/lib/ace/range.js index 0947d9f4..e09b850d 100644 --- a/lib/ace/range.js +++ b/lib/ace/range.js @@ -38,6 +38,23 @@ define(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, @@ -51,6 +68,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 && @@ -58,28 +82,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, @@ -109,27 +156,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; @@ -140,6 +246,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; @@ -150,6 +264,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)) { @@ -161,6 +283,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)) { @@ -172,6 +302,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)) { @@ -183,6 +321,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) { @@ -206,8 +365,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; @@ -217,8 +396,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; @@ -227,6 +424,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; @@ -237,6 +449,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 = { @@ -268,6 +488,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); @@ -281,33 +509,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) @@ -315,6 +546,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); @@ -329,7 +566,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); }; diff --git a/lib/ace/range_list_test.js b/lib/ace/range_list_test.js index 6c397369..e6304912 100644 --- a/lib/ace/range_list_test.js +++ b/lib/ace/range_list_test.js @@ -167,4 +167,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/range_test.js b/lib/ace/range_test.js index 5fbefdfe..d3d039b6 100644 --- a/lib/ace/range_test.js +++ b/lib/ace/range_test.js @@ -195,4 +195,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/renderloop.js b/lib/ace/renderloop.js index 9a754c52..71bcfd77 100644 --- a/lib/ace/renderloop.js +++ b/lib/ace/renderloop.js @@ -41,6 +41,19 @@ define(function(require, exports, module) { 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; @@ -50,6 +63,12 @@ var RenderLoop = function(onRender, win) { (function() { + /** internal, hide + * RenderLoop.schedule(change) + * - change (Array): + * + * + **/ this.schedule = function(change) { //this.onRender(change); //return; diff --git a/lib/ace/requirejs/text.js b/lib/ace/requirejs/text.js index 58e39cec..cf7ef666 100644 --- a/lib/ace/requirejs/text.js +++ b/lib/ace/requirejs/text.js @@ -35,7 +35,7 @@ * * ***** END LICENSE BLOCK ***** */ -/** +/* * Extremely simplified version of the requireJS text plugin */ @@ -55,4 +55,4 @@ define(function (require, exports, module) { }; }); -})(); \ No newline at end of file +})(); diff --git a/lib/ace/scrollbar.js b/lib/ace/scrollbar.js index 0bc7e675..66d9e214 100644 --- a/lib/ace/scrollbar.js +++ b/lib/ace/scrollbar.js @@ -44,6 +44,20 @@ var dom = require("./lib/dom"); var event = require("./lib/event"); var EventEmitter = require("./lib/event_emitter").EventEmitter; +/** + * class ScrollBar + * + * A set of methods for setting and retrieving the editor's scrollbar. + * + **/ + +/** + * new ScrollBar(parent) + * - parent (DOMElement): A DOM element + * + * Creates a new `ScrollBar`. `parent` is the owner of the scroll bar. + * + **/ var ScrollBar = function(parent) { this.element = dom.createElement("div"); this.element.className = "ace_sb"; @@ -67,22 +81,55 @@ var ScrollBar = function(parent) { (function() { oop.implement(this, EventEmitter); + /** + * ScrollBar@onScroll + * + * Emitted when the scroll bar, well, scrolls. + * + **/ this.onScroll = function() { this._emit("scroll", {data: this.element.scrollTop}); }; + /** + * ScrollBar.getWidth() -> 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) { diff --git a/lib/ace/search.js b/lib/ace/search.js index c15d0b16..846f3905 100644 --- a/lib/ace/search.js +++ b/lib/ace/search.js @@ -44,6 +44,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: "", @@ -61,15 +83,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; @@ -89,6 +131,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) @@ -115,6 +164,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); @@ -129,6 +190,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; @@ -163,6 +231,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; diff --git a/lib/ace/search_test.js b/lib/ace/search_test.js index bf1f53c9..e1f02c46 100644 --- a/lib/ace/search_test.js +++ b/lib/ace/search_test.js @@ -417,4 +417,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/selection.js b/lib/ace/selection.js index d2ae3c6a..5def4061 100644 --- a/lib/ace/selection.js +++ b/lib/ace/selection.js @@ -45,22 +45,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"); @@ -78,13 +86,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; @@ -93,12 +111,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; @@ -106,20 +136,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; }; @@ -138,15 +186,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); @@ -159,6 +217,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; @@ -166,12 +229,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); @@ -184,80 +260,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); @@ -267,22 +424,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)) { @@ -302,20 +483,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 @@ -323,9 +509,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. @@ -351,8 +542,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( @@ -361,19 +557,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); @@ -387,14 +598,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); @@ -403,7 +614,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; @@ -413,9 +624,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; @@ -428,19 +644,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); @@ -459,10 +675,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) { @@ -478,10 +787,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); @@ -491,13 +814,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); @@ -505,8 +836,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; } diff --git a/lib/ace/selection_test.js b/lib/ace/selection_test.js index 404addc9..a85fbb7a 100644 --- a/lib/ace/selection_test.js +++ b/lib/ace/selection_test.js @@ -102,6 +102,7 @@ module.exports = { ].join("\n")); var selection = session.getSelection(); + session.$selectLongWords = true; selection.moveCursorDown(); assert.position(selection.getCursor(), 1, 0); @@ -144,6 +145,7 @@ module.exports = { ].join("\n")); var selection = session.getSelection(); + session.$selectLongWords = true; selection.moveCursorDown(); selection.moveCursorLineEnd(); @@ -171,6 +173,7 @@ module.exports = { "test: moveCursor word left with umlauts" : function() { var session = new EditSession(" Fuß Füße"); + session.$selectLongWords = true; var selection = session.getSelection(); selection.moveCursorTo(0, 9) @@ -184,6 +187,7 @@ module.exports = { "test: select word left if cursor in word" : function() { var session = new EditSession("Juhu Kinners"); var selection = session.getSelection(); + session.$selectLongWords = true; selection.moveCursorTo(0, 8); @@ -244,6 +248,7 @@ module.exports = { "test: select word with cursor betwen white space and word should select the word" : function() { var session = new EditSession("Juhu Kinners"); var selection = session.getSelection(); + session.$selectLongWords = true; selection.moveCursorTo(0, 4); selection.selectWord(); @@ -263,6 +268,7 @@ module.exports = { "test: select word with cursor in white space should select white space" : function() { var session = new EditSession("Juhu Kinners"); var selection = session.getSelection(); + session.$selectLongWords = true; selection.moveCursorTo(0, 5); selection.selectWord(); @@ -275,6 +281,7 @@ module.exports = { "test: moving cursor should fire a 'changeCursor' event" : function() { var session = new EditSession("Juhu Kinners"); var selection = session.getSelection(); + session.$selectLongWords = true; selection.moveCursorTo(0, 5); @@ -290,6 +297,7 @@ module.exports = { "test: calling setCursor with the same position should not fire an event": function() { var session = new EditSession("Juhu Kinners"); var selection = session.getSelection(); + session.$selectLongWords = true; selection.moveCursorTo(0, 5); @@ -305,6 +313,7 @@ module.exports = { "test: moveWordright should move past || and [": function() { var session = new EditSession("||foo["); var selection = session.getSelection(); + session.$selectLongWords = true; // Move behind ||foo selection.moveCursorWordRight(); @@ -318,6 +327,7 @@ module.exports = { "test: moveWordLeft should move past || and [": function() { var session = new EditSession("||foo["); var selection = session.getSelection(); + session.$selectLongWords = true; selection.moveCursorTo(0, 6); diff --git a/lib/ace/split.js b/lib/ace/split.js index fc5ae07d..7d0e5902 100644 --- a/lib/ace/split.js +++ b/lib/ace/split.js @@ -47,6 +47,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; @@ -87,6 +104,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) { @@ -116,42 +140,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; @@ -187,6 +269,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) { @@ -213,10 +303,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; @@ -225,6 +328,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; @@ -255,6 +364,12 @@ var Split = function(container, theme, splits) { }).call(Split.prototype); + /** internal + * Split.UndoManagerProxy() -> Void + * + * + * + **/ function UndoManagerProxy(undoManager, session) { this.$u = undoManager; this.$doc = session; diff --git a/lib/ace/test/all.js b/lib/ace/test/all.js index 54942fa9..340f903d 100644 --- a/lib/ace/test/all.js +++ b/lib/ace/test/all.js @@ -39,4 +39,4 @@ require("amd-loader"); var test = require("asyncjs").test; -test.walkTestCases(__dirname + "/..").exec(); \ No newline at end of file +test.walkTestCases(__dirname + "/..").exec(); diff --git a/lib/ace/test/assertions.js b/lib/ace/test/assertions.js index ef04b8ce..861dbddc 100644 --- a/lib/ace/test/assertions.js +++ b/lib/ace/test/assertions.js @@ -60,4 +60,4 @@ exports.jsonEquals = function(foundJson, expectedJson) { module.exports = assert; -}); \ No newline at end of file +}); diff --git a/lib/ace/test/asyncjs/assert.js b/lib/ace/test/asyncjs/assert.js index 3ce1b31b..6cdc611a 100644 --- a/lib/ace/test/asyncjs/assert.js +++ b/lib/ace/test/asyncjs/assert.js @@ -310,4 +310,4 @@ assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { assert.ifError = function(err) { if (err) {throw err;}}; -}); \ No newline at end of file +}); diff --git a/lib/ace/test/asyncjs/async.js b/lib/ace/test/asyncjs/async.js index c439421b..e8265119 100644 --- a/lib/ace/test/asyncjs/async.js +++ b/lib/ace/test/asyncjs/async.js @@ -360,7 +360,7 @@ exports.Generator = function(source) { } this.end = function(breakOnError, callback) { - if (!callback) { + if (!callback) { callback = arguments[0] breakOnError = true } @@ -467,7 +467,7 @@ exports.keys = function(map, construct) { return exports.list(keys, construct) } -/** +/* * range([start,] stop[, step]) -> generator of integers * * Return a generator containing an arithmetic progression of integers. @@ -526,4 +526,4 @@ exports.plugin = function(members, constructors) { } } -}) \ No newline at end of file +}) diff --git a/lib/ace/test/asyncjs/index.js b/lib/ace/test/asyncjs/index.js index 8adee620..ed63914b 100644 --- a/lib/ace/test/asyncjs/index.js +++ b/lib/ace/test/asyncjs/index.js @@ -10,4 +10,4 @@ module.exports = require("./async") module.exports.test = require("./test") require("./utils") -}) \ No newline at end of file +}) diff --git a/lib/ace/test/asyncjs/test.js b/lib/ace/test/asyncjs/test.js index 7504a3e2..4374ef7c 100644 --- a/lib/ace/test/asyncjs/test.js +++ b/lib/ace/test/asyncjs/test.js @@ -192,4 +192,4 @@ exports.testcase = function(testcase, suiteName, timeout) { return async.list(tests, exports.TestGenerator) } -}) \ No newline at end of file +}) diff --git a/lib/ace/test/asyncjs/utils.js b/lib/ace/test/asyncjs/utils.js index d626b330..75fb3095 100644 --- a/lib/ace/test/asyncjs/utils.js +++ b/lib/ace/test/asyncjs/utils.js @@ -62,4 +62,4 @@ async.plugin({ } }) -}) \ No newline at end of file +}) diff --git a/lib/ace/test/benchmark.js b/lib/ace/test/benchmark.js index 512b7a1c..28adfcde 100644 --- a/lib/ace/test/benchmark.js +++ b/lib/ace/test/benchmark.js @@ -82,4 +82,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec(); -} \ No newline at end of file +} diff --git a/lib/ace/test/mockdom.js b/lib/ace/test/mockdom.js index ec696d4c..54991fc5 100644 --- a/lib/ace/test/mockdom.js +++ b/lib/ace/test/mockdom.js @@ -7,4 +7,4 @@ global.document = browser.document; global.window = browser.window; global.self = browser.self; global.navigator = browser.navigator; -global.location = browser.location; \ No newline at end of file +global.location = browser.location; diff --git a/lib/ace/test/mockrenderer.js b/lib/ace/test/mockrenderer.js index 8305705a..381a7918 100644 --- a/lib/ace/test/mockrenderer.js +++ b/lib/ace/test/mockrenderer.js @@ -107,6 +107,10 @@ MockRenderer.prototype.on = function() { MockRenderer.prototype.updateCursor = function() { }; +MockRenderer.prototype.animateScrolling = function(fromValue, callback) { + callback && callback(); +}; + MockRenderer.prototype.scrollToX = function(scrollTop) {}; MockRenderer.prototype.scrollToY = function(scrollLeft) {}; diff --git a/lib/ace/theme/monokai.js b/lib/ace/theme/monokai.js index ba5fca86..c31efa85 100644 --- a/lib/ace/theme/monokai.js +++ b/lib/ace/theme/monokai.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/lib/ace/theme/solarized_dark.js b/lib/ace/theme/solarized_dark.js index 35ff5ae9..5113467b 100644 --- a/lib/ace/theme/solarized_dark.js +++ b/lib/ace/theme/solarized_dark.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/lib/ace/theme/textmate.js b/lib/ace/theme/textmate.js index 76eb0673..cca31e29 100644 --- a/lib/ace/theme/textmate.js +++ b/lib/ace/theme/textmate.js @@ -101,8 +101,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 {\ @@ -189,6 +189,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);\ diff --git a/lib/ace/theme/tomorrow_night_blue.js b/lib/ace/theme/tomorrow_night_blue.js index 72ffb2bc..1dddf919 100644 --- a/lib/ace/theme/tomorrow_night_blue.js +++ b/lib/ace/theme/tomorrow_night_blue.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/lib/ace/token_iterator.js b/lib/ace/token_iterator.js index 6ddd6395..da32c74c 100644 --- a/lib/ace/token_iterator.js +++ b/lib/ace/token_iterator.js @@ -39,6 +39,22 @@ define(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; @@ -49,7 +65,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; @@ -66,7 +88,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; @@ -84,15 +111,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; diff --git a/lib/ace/token_iterator_test.js b/lib/ace/token_iterator_test.js index 97ba9778..34f7801c 100644 --- a/lib/ace/token_iterator_test.js +++ b/lib/ace/token_iterator_test.js @@ -216,4 +216,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index f24d2191..8e769103 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -38,6 +38,21 @@ define(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; @@ -83,6 +98,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]; diff --git a/lib/ace/undomanager.js b/lib/ace/undomanager.js index 7e594197..d53979bd 100644 --- a/lib/ace/undomanager.js +++ b/lib/ace/undomanager.js @@ -40,12 +40,33 @@ define(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]; @@ -53,6 +74,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; @@ -64,6 +91,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; @@ -75,15 +108,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; }; diff --git a/lib/ace/unicode.js b/lib/ace/unicode.js index 0f0745c1..5c291744 100644 --- a/lib/ace/unicode.js +++ b/lib/ace/unicode.js @@ -104,4 +104,4 @@ function addUnicodePackage (pack) { exports.packages[name] = pack[name].replace(codePoint, "\\u$&"); }; -}); \ No newline at end of file +}); diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 66e35222..fdff0160 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -58,6 +58,22 @@ var editorCss = require("ace/requirejs/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; @@ -66,6 +82,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"); @@ -83,8 +102,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); @@ -100,14 +121,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; @@ -118,12 +140,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 = { @@ -188,19 +207,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; @@ -223,26 +255,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; @@ -277,53 +321,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; @@ -332,6 +442,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; @@ -352,56 +500,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); @@ -412,10 +602,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; @@ -463,6 +664,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; } @@ -479,6 +682,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; } @@ -498,8 +703,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); @@ -576,7 +784,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"; @@ -622,55 +830,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; @@ -681,10 +945,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); } @@ -694,75 +960,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 @@ -772,6 +1091,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; @@ -781,11 +1107,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; @@ -794,32 +1134,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); @@ -833,14 +1179,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"); @@ -859,10 +1220,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(); @@ -883,6 +1255,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; @@ -937,6 +1315,11 @@ var VirtualRenderer = function(container, theme) { } }; + /** + * VirtualRenderer.getTheme() -> String + * + * [Returns the path of the current theme.]{: #VirtualRenderer.getTheme} + **/ this.getTheme = function() { return this.$themeValue; }; @@ -945,14 +1328,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(); diff --git a/lib/ace/virtual_renderer_test.js b/lib/ace/virtual_renderer_test.js index 0d146971..59d5b089 100644 --- a/lib/ace/virtual_renderer_test.js +++ b/lib/ace/virtual_renderer_test.js @@ -88,4 +88,4 @@ module.exports = { if (typeof module !== "undefined" && module === require.main) { require("asyncjs").test.testcase(module.exports).exec() -} \ No newline at end of file +} diff --git a/lib/ace/worker/jshint.js b/lib/ace/worker/jshint.js index 345c909d..ad54b555 100644 --- a/lib/ace/worker/jshint.js +++ b/lib/ace/worker/jshint.js @@ -4466,4 +4466,4 @@ loop: for (;;) { if (typeof exports === 'object' && exports) exports.JSHINT = JSHINT; -}); \ No newline at end of file +}); diff --git a/lib/ace/worker/jslint.js b/lib/ace/worker/jslint.js index bbeaf5b5..9e7eb443 100644 --- a/lib/ace/worker/jslint.js +++ b/lib/ace/worker/jslint.js @@ -6393,4 +6393,4 @@ klass: do { return itself; }()); -}); \ No newline at end of file +}); diff --git a/lib/ace/worker/mirror.js b/lib/ace/worker/mirror.js index 76f6e73f..9e6dda73 100644 --- a/lib/ace/worker/mirror.js +++ b/lib/ace/worker/mirror.js @@ -40,4 +40,4 @@ var Mirror = exports.Mirror = function(sender) { }).call(Mirror.prototype); -}); \ No newline at end of file +}); diff --git a/lib/ace/worker/worker_client.js b/lib/ace/worker/worker_client.js index e0097d2d..a992db8f 100644 --- a/lib/ace/worker/worker_client.js +++ b/lib/ace/worker/worker_client.js @@ -50,7 +50,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/lib/ace/worker/worker_sourcemint.js b/lib/ace/worker/worker_sourcemint.js new file mode 100644 index 00000000..bc305b79 --- /dev/null +++ b/lib/ace/worker/worker_sourcemint.js @@ -0,0 +1,73 @@ + +define(function(require, exports, module) { + + "no use strict"; + + exports.main = function() + { + var console = { + log: function(msg) { + postMessage({type: "log", data: msg}); + } + }; + + // NOTE: This sets the global `window` object used by workers. + // TODO: Pass into worker what it needs and don't set global here. + window = { + console: console + }; + + function initSender() { + + var EventEmitter = require("ace/lib/event_emitter").EventEmitter; + var oop = require("ace/lib/oop"); + + var Sender = function() {}; + + (function() { + + oop.implement(this, EventEmitter); + + this.callback = function(data, callbackId) { + postMessage({ + type: "call", + id: callbackId, + data: data + }); + }; + + this.emit = function(name, data) { + postMessage({ + type: "event", + name: name, + data: data + }); + }; + + }).call(Sender.prototype); + + return new Sender(); + } + + var main; + var sender; + + onmessage = function(e) { + var msg = e.data; + if (msg.command) { + main[msg.command].apply(main, msg.args); + } + else if (msg.init) { + require("ace/lib/fixoldbrowsers"); + sender = initSender(); + require.async(msg.module, function(WORKER) { + var clazz = WORKER[msg.classname]; + main = new clazz(sender); + }); + } + else if (msg.event && sender) { + sender._emit(msg.event, msg.data); + } + }; + } +}); diff --git a/package.json b/package.json index 513cecb3..39f778f1 100644 --- a/package.json +++ b/package.json @@ -18,18 +18,22 @@ "jsdom": "0.2.x", "amd-loader": "~0.0.4", "libxml": "0.0.x", - "dryice": "0.4.2" + "dryice": "0.4.2", + "panino" : "~1.0.15" + }, + "engines": { + "node": "~0.6.0" + }, + "mappings": { + "ace": "." }, - "licenses": [{ "type": "MPL", "url": "http://www.mozilla.org/MPL/" - }, - { + }, { "type": "GPL", "url": "http://www.gnu.org/licenses/gpl.html" - }, - { + }, { "type": "LGPL", "url": "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html" }], @@ -38,5 +42,28 @@ }, "scripts": { "test": "node lib/ace/test/all.js" + }, + "config": { + "github.com/sourcemint/bundler-js/0/-meta/config/0": { + "adapter": "github.com/sourcemint/sdk-requirejs/0", + "modules": { + "/lib/ace/virtual_renderer.js": { + "dynamicLinks": [ + "/lib/ace/theme/*.js" + ] + }, + "/lib/ace/worker/worker_client.js": { + "dynamicLinks": [ + "/lib/ace/worker/worker_sourcemint.js" + ] + }, + "/lib/ace/worker/worker_sourcemint.js": { + "bundleLoader": true, + "dynamicLinks": [ + "/lib/ace/mode/*_worker.js" + ] + } + } + } } } \ No newline at end of file diff --git a/sourcemint/.gitignore b/sourcemint/.gitignore new file mode 100644 index 00000000..81ce55f2 --- /dev/null +++ b/sourcemint/.gitignore @@ -0,0 +1,2 @@ +/dist/ +/node_modules/ \ No newline at end of file diff --git a/sourcemint/README.md b/sourcemint/README.md new file mode 100644 index 00000000..47e33462 --- /dev/null +++ b/sourcemint/README.md @@ -0,0 +1,63 @@ +Develop & Distribute ACE using the Sourcemint Loader +==================================================== + +The [Sourcemint JavaScript Loader](https://github.com/sourcemint/loader-js) is an optimized +module loader that boots sets of *statically linked* modules from *bundles*. An application may +load additional bundles by using *dynamic links*. + +*Bundles* are generated from the AMD formatted source files on the fly during development (using a server helper) +and in-batch for production builds. To generate bundles the Sourcemint [RequireJS SDK](https://github.com/sourcemint/sdk-requirejs) +and [Platform NodeJS](https://github.com/sourcemint/platform-nodejs) projects are used. + + +Development +=========== + +**Requirements:** + + * [NodeJS](http://nodejs.org/) + +**Install:** + + git clone git://github.com/ajaxorg/ace.git + cd ace + # TMP: Switch to sourcemint branch + git checkout sourcemint + cd sourcemint + npm install + +**Start development server:** + + node dev + +**NOTE:** Modified source files are automatically reloaded on browser refresh so there is no +need to restart the server during development. + + +Production +========== + +To generate production bundles, use the same setup as for *Development*, then run: + + // NOT YET IMPLEMENTED + node build ../demo/kitchen-sink ./dist + +Where `../demo/kitchen-sink` is the path to your ACE bootstrap package which embeds ACE in the page +or provides an interface for the rest of your application to interact with ACE. + +Everything needed for ACE (and your bootstrap package) to run will be written to the `./dist` directory which can be +used in a production application by serving these static files via a web server. To load the bootstrap file use: + + + + + + +See `../demo/kitchen-sink` for an example of how to write an ACE bootstrap package. + +See [Embedding Ace](https://github.com/ajaxorg/ace) and [Embedding API](https://github.com/ajaxorg/ace/wiki/Embedding---API) +for more information on how to embed and interact with ACE. diff --git a/sourcemint/dev.js b/sourcemint/dev.js new file mode 100644 index 00000000..5ce51b03 --- /dev/null +++ b/sourcemint/dev.js @@ -0,0 +1,47 @@ + +var PATH = require("path"), + FS = require("fs"), + CONNECT = require("connect"), + BUNDLER = require("sourcemint-platform-nodejs/lib/bundler"); + + +exports.main = function(options) { + + var server = CONNECT(); + + server.use(CONNECT.router(function(app) { + + app.get(/^\/loader.js/, CONNECT.static(PATH.dirname(require.resolve("sourcemint-loader-js/loader.js")))); + + app.get(/^(?:\/demo\/kitchen-sink)(?:\.js)?(\/.*)?$/, BUNDLER.hoist(PATH.dirname(__dirname) + "/demo/kitchen-sink", { + distributionBasePath: __dirname + "/dist", + packageIdHashSeed: "__ACE__", + bundleLoader: false, + logger: { + log: function() { + console.log.apply(null, arguments); + } + } + })); + + app.get(/^\//, function(req, res) + { + CONNECT.static(__dirname)(req, res, function() + { + res.writeHead(404); + res.end("Not found!"); + }); + }); + })); + + server.listen(options.port, "127.0.0.1"); + + console.log("ACE development server running at http://127.0.0.1:" + options.port + "/"); +} + +if (require.main === module) { + // TODO: Make configurable via command-line flag. + exports.main({ + port: 8888 + }); +} diff --git a/sourcemint/index.html b/sourcemint/index.html new file mode 100644 index 00000000..b149a1c5 --- /dev/null +++ b/sourcemint/index.html @@ -0,0 +1,16 @@ + + + + + + Ace Development Server + + + +

Demos

+ +

Kitchen Sink

+ + + diff --git a/sourcemint/kitchen-sink.html b/sourcemint/kitchen-sink.html new file mode 100644 index 00000000..035d17d2 --- /dev/null +++ b/sourcemint/kitchen-sink.html @@ -0,0 +1,209 @@ + + + + + + Ace Kitchen Sink + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ +
+
+ + + + + + diff --git a/sourcemint/package.json b/sourcemint/package.json new file mode 100644 index 00000000..6e186a9f --- /dev/null +++ b/sourcemint/package.json @@ -0,0 +1,12 @@ +{ + "name": "ajaxorg-ace-sourcemint", + "version": "0.1.0", + "engines": { + "node": "0.x" + }, + "dependencies": { + "connect": "1.x", + "sourcemint-platform-nodejs": "0.x", + "sourcemint-loader-js": "0.x" + } +} \ No newline at end of file